pathName.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "common/h/headers.h"
00033 #include <ctype.h>
00034 #include <assert.h>
00035 #include <limits.h>
00036 #include "common/h/pathName.h"
00037
00038 #if defined(os_windows) //ccw 20 july 2000 : 29 mar 2001
00039
00040 #define S_ISDIR(x) ((x) & _S_IFDIR)
00041
00042 std::string expand_tilde_pathname(const std::string &dir) {
00043 return dir;
00044 }
00045
00046 #else
00047
00048 #include <sys/types.h>
00049 #include <sys/stat.h>
00050 #include <unistd.h>
00051
00052 #include <pwd.h>
00053
00054 std::string expand_tilde_pathname(const std::string &dir) {
00055
00056
00057
00058 if (dir.length()==0)
00059 return dir;
00060
00061 const char *dir_cstr = dir.c_str();
00062 if (dir_cstr[0] != '~')
00063 return dir;
00064
00065
00066
00067 if (dir_cstr[1] == '/' || dir_cstr[1] == '\0') {
00068
00069
00070
00071 char *home_dir = getenv("HOME");
00072 if (home_dir == NULL)
00073 return dir;
00074
00075 if (home_dir[strlen(home_dir)-1] == '/' && dir_cstr[1] != '\0')
00076 return std::string(home_dir) + &dir_cstr[2];
00077 else
00078 return std::string(home_dir) + &dir_cstr[1];
00079 }
00080
00081
00082
00083 std::string userName;
00084
00085 const char *ptr = strchr(&dir_cstr[1], '/');
00086 if (ptr == NULL)
00087 userName = std::string(&dir_cstr[1]);
00088 else {
00089 char user_name_buffer[200];
00090 unsigned user_name_len = ptr - &dir_cstr[1];
00091
00092 for (unsigned j=0; j < user_name_len; j++)
00093 user_name_buffer[j] = dir_cstr[1+j];
00094
00095 user_name_buffer[user_name_len] = '\0';
00096 userName = user_name_buffer;
00097 }
00098
00099 struct passwd *pwPtr = getpwnam(userName.c_str());
00100 if (pwPtr == NULL) {
00101 endpwent();
00102 return dir;
00103 }
00104
00105 std::string result = std::string(pwPtr->pw_dir) + std::string(ptr);
00106 endpwent();
00107 return result;
00108 }
00109 #endif
00110
00111 static std::string concat_pathname_components_simple(const std::string &comp1, const std::string &comp2)
00112 {
00113 std::string result = (comp1.length() ? comp1 : comp2);
00114 return result;
00115 }
00116
00117 std::string concat_pathname_components(const std::string &comp1, const std::string &comp2)
00118 {
00119 if (comp1.length() == 0 || comp2.length() == 0)
00120 return concat_pathname_components_simple(comp1, comp2);
00121
00122 bool needToAddSlash = true;
00123
00124
00125 const char *temp = comp1.c_str();
00126 if (temp[comp1.length()-1] == '/')
00127 needToAddSlash = false;
00128
00129
00130 if (comp2.length() && comp2[0] == '/')
00131 needToAddSlash = false;
00132 #if 0
00133 if (comp2.prefixed_by("/"))
00134 needToAddSlash = false;
00135 #endif
00136
00137 std::string result = comp1;
00138 if (needToAddSlash)
00139 result += "/";
00140 result += comp2;
00141
00142 return result;
00143 }
00144
00145 bool extractNextPathElem(const char * &ptr, std::string &result)
00146 {
00147
00148
00149
00150
00151 if ( ptr == NULL )
00152 return false;
00153
00154 while (isspace(*ptr))
00155 ptr++;
00156
00157 if (*ptr == '\0')
00158 return false;
00159
00160
00161 const char *start_ptr = ptr;
00162
00163 while (*ptr != ':' && *ptr != '\0')
00164 ptr++;
00165
00166 unsigned len = ptr - start_ptr;
00167
00168 result = std::string(start_ptr, len);
00169
00170
00171 assert(*ptr == ':' || *ptr == '\0');
00172 if (*ptr == ':')
00173 ptr++;
00174
00175
00176
00177 return true;
00178 }
00179
00180 bool exists_executable(const std::string &fullpathname)
00181 {
00182 struct stat stat_buffer;
00183 int result = stat(fullpathname.c_str(), &stat_buffer);
00184
00185 if (result == -1)
00186 return false;
00187
00188 if (S_ISDIR(stat_buffer.st_mode))
00189 return false;
00190
00191
00192
00193 return true;
00194 }
00195
00196 bool executableFromArgv0AndPathAndCwd(std::string &result,
00197 const std::string &i_argv0,
00198 const std::string &path,
00199 const std::string &cwd)
00200 {
00201
00202
00203
00204
00205
00206
00207 if (i_argv0.length() == 0)
00208 return false;
00209
00210 const std::string &argv0 = expand_tilde_pathname(i_argv0);
00211
00212
00213
00214 if ((argv0.c_str())[0] == '/')
00215 {
00216 if (exists_executable(argv0))
00217 {
00218 result = argv0;
00219 return true;
00220 }
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 bool contains_slash = false;
00231 const char *ptr = argv0.c_str();
00232
00233 while (*ptr != '\0')
00234 {
00235 if (*ptr++ == '/')
00236 {
00237 contains_slash = true;
00238 break;
00239 }
00240 }
00241
00242 if (!contains_slash)
00243 {
00244
00245
00246 ptr = path.c_str();
00247 std::string pathelem;
00248
00249 while (extractNextPathElem(ptr, pathelem))
00250 {
00251 std::string trystr = concat_pathname_components(pathelem, argv0);
00252
00253 if (exists_executable(trystr))
00254 {
00255 result = trystr;
00256 return true;
00257 }
00258 }
00259 }
00260
00261
00262
00263 std::string trystr = concat_pathname_components(cwd, argv0);
00264
00265 if (exists_executable(trystr))
00266 {
00267 result = trystr;
00268 return true;
00269 }
00270 return false;
00271 }
00272
00273 #if defined(os_windows)
00274 #define PATH_SEP ('\\')
00275 #define SECOND_PATH_SEP ('/')
00276 #else
00277 #define PATH_SEP ('/')
00278 #endif
00279
00280 std::string extract_pathname_tail(const std::string &path)
00281 {
00282 if (!path.length())
00283 {
00284 return std::string("");
00285 }
00286
00287 const char *path_str = path.c_str();
00288 if (!path_str)
00289 {
00290 return std::string("");
00291 }
00292
00293 const char *path_sep = P_strrchr(path_str, PATH_SEP);
00294
00295 #if defined(SECOND_PATH_SEP)
00296 const char *sec_path_sep = P_strrchr(path_str, SECOND_PATH_SEP);
00297 if (sec_path_sep && (!path_sep || sec_path_sep > path_sep))
00298 path_sep = sec_path_sep;
00299 #endif
00300
00301 std::string ret = (path_sep) ? (path_sep + 1) : (path_str);
00302 return ret;
00303 }
00304
00305 #if !defined (os_windows)
00306 static
00307 char *resolve_file_path_local(const char *fname, char *resolved_path)
00308 {
00309
00310
00311
00312 struct stat stat_buf;
00313 if( -1 == stat(fname, &stat_buf) ) {
00314 return NULL;
00315 }
00316
00317
00318 if (NULL == realpath(fname, resolved_path)) {
00319 return NULL;
00320 }
00321
00322
00323 if (!strpbrk(resolved_path, "/\\")) {
00324 char cwd[PATH_MAX];
00325 if (NULL == getcwd(cwd, PATH_MAX)) {
00326 return NULL;
00327 }
00328 char resolved_path_bak[PATH_MAX];
00329 strcpy(resolved_path_bak, resolved_path);
00330 sprintf(resolved_path, "%s/%s", cwd, resolved_path_bak);
00331 }
00332
00333
00334 if (!strpbrk(resolved_path, "~")) {
00335 std::string td_pathname = std::string(resolved_path);
00336 std::string no_td_pathname = expand_tilde_pathname(td_pathname);
00337 strcpy(resolved_path, no_td_pathname.c_str());
00338 }
00339
00340 return resolved_path;
00341 }
00342
00343 std::string resolve_file_path(const char *fname) {
00344 char path_buf[PATH_MAX];
00345 char *result = resolve_file_path_local(fname, path_buf);
00346 if ( result == NULL ) {
00347 return std::string();
00348 }
00349 std::string ret = result;
00350 return ret;
00351 }
00352
00353 #else
00354 std::string resolve_file_path(const char *fname) {
00355 assert(!"UNIMPLEMENTED ON WINDOWS");
00356 return std::string("");
00357 }
00358 #endif
00359