pkg_t * pkg_find(const char *name, unsigned int flags) { char **path = NULL; size_t count = 0, iter = 0; const char *env_path; pkg_t *pkg = NULL; FILE *f; /* name might actually be a filename. */ if (str_has_suffix(name, PKG_CONFIG_EXT)) { if ((f = fopen(name, "r")) != NULL) return pkg_new_from_file(name, f); } /* PKG_CONFIG_PATH has to take precedence */ env_path = getenv("PKG_CONFIG_PATH"); if (env_path) { count = path_split(env_path, &path); for (iter = 0; iter < count; iter++) { pkg = pkg_try_specific_path(path[iter], name, flags); if (pkg != NULL) goto out; } path_free(path, count); } env_path = get_pkgconfig_path(); if (!(flags & PKGF_ENV_ONLY)) { count = path_split(env_path, &path); for (iter = 0; iter < count; iter++) { pkg = pkg_try_specific_path(path[iter], name, flags); if (pkg != NULL) goto out; } } #ifdef _WIN32 /* support getting PKG_CONFIG_PATH from registry */ pkg = pkg_find_in_registry_key(HKEY_CURRENT_USER, name, flags); if (!pkg) pkg = pkg_find_in_registry_key(HKEY_LOCAL_MACHINE, name, flags); #endif out: path_free(path, count); return pkg; }
/*! * \brief An strcmp() for paths * * This function will normalize \a path1 and \a path2 before they are passed to * std::string::compare(). This way, extra slashes, '.', '..', etc. are handled * before the string comparison is performed. * * \note This function does not traverse the filesystem at all. It works purely * on the given path strings. * * \return An integer less than, equal to, or greater than zero if \a path1 is * found, respectively, to be less than, equal to, or greater than * \a path2 lexicographically. */ int path_compare(const std::string &path1, const std::string &path2) { if (path1.empty() || path2.empty()) { return false; } std::vector<std::string> path1_pieces(path_split(path1)); std::vector<std::string> path2_pieces(path_split(path2)); normalize_path(path1_pieces); normalize_path(path2_pieces); return path_join(path1_pieces).compare(path_join(path2_pieces)); }
depsRef depsScanForHeaders(const char *path) { PATHSPLIT f; char buf[MAXJPATH]; time_t time; HEADER *h; if (!inState(DEPS_STATE_INIT | DEPS_STATE_SEARCH)) { if (!inState(DEPS_STATE_SEARCH)) setErr(DEPS_ERROR_NOT_SEARCH); if (!inState(DEPS_STATE_INIT)) setErr(DEPS_ERROR_NOT_INIT); return NULL; } setErr(0); path_split(path, &f); path_normalize(&f, NULL); path_tostring(&f, buf); timestamp(buf, &time); if (!time) return NULL; h = headers(buf, time); return (depsRef) h; }
char* path_basename( const char* path ) { char* basename; if (path_split(path, NULL, &basename) < 0) return NULL; return basename; }
char* path_dirname( const char* path ) { char* dirname; if (path_split(path, &dirname, NULL) < 0) return NULL; return dirname; }
/*! * \brief Get the relative path from a starting directory * * This function will get the relative path of \a path starting from \a start. * Both \a path and \a start will be normalized before calculating the relative * path. That way, paths containing '..' will be handled correctly. For example, * calling relative_path("/usr/bin", "/usr/include/glib-2.0/..") will return * "../bin" as expected. * * If, in the directory tree, \a start is at a higher level than the parent * directory of \a path, then the function will return false and set \a errno to * \a EINVAL. This is because there is no way of determining the intermediate * paths to form the relative path between the two directories. For example, if * we want to determine the relative path of "a/b" starting from "..", the * result would be "[some_dir]/a/b", but there is no way to determine what * \a some_dir is. * * \note This function does not traverse the filesystem at all. It works purely * on the given path strings. * * \return True if the relative path was successfully computed. False and errno * set to \a EINVAL if: * - \a path is absolute and \a start is relative or vice versa * - \a path or \a start is empty * - an intermediate path could not be computed */ bool relative_path(const std::string &path, const std::string &start, std::string &out) { if (path.empty() || start.empty() || (path[0] == '/' && start[0] != '/') || (path[0] != '/' && start[0] == '/')) { errno = EINVAL; return false; } std::vector<std::string> path_pieces(path_split(path)); std::vector<std::string> start_pieces(path_split(start)); std::vector<std::string> result_pieces; normalize_path(path_pieces); normalize_path(start_pieces); // Find the number of common path segments size_t common; for (common = 0; common < path_pieces.size() && common < start_pieces.size() && path_pieces[common] == start_pieces[common]; ++common); // Add '..' for the remaining path segments in 'start' for (size_t i = common; i < start_pieces.size(); ++i) { if (start_pieces[i] == "..") { errno = EINVAL; return false; } result_pieces.push_back(".."); } // Add remaining path segments in 'path' for (size_t i = common; i < path_pieces.size(); ++i) { result_pieces.push_back(path_pieces[i]); } out = path_join(result_pieces); return true; }
int securesoho_copy(const char *src, const char *dst){ char dirname[256], basename[256]; DIR *sdir; struct dirent *sdirent; if(!src || !dst) { fprintf(stderr, "%s:%d The src:0x%p or dst:%p is NULL\n", __FUNCTION__, __LINE__, src, dst); return -1; } if (path_split(src, dirname, basename) < 0){ fprintf(stderr, "%s:%d, Failed to get the dirname and basename\n", __FUNCTION__, __LINE__); return -1; } if (is_wildcard(dirname)){ fprintf(stderr, "%s:%d Don't support wildcard for directory\n", __FUNCTION__, __LINE__); return -1; } //FIXME: to make simple, we just consider following situaltion //The source file are wildcard string //The dest are directory if (!is_wildcard(src)){ if (is_dir(dst)){ char fullpath[512]; sprintf(fullpath, "%s/%s", dst, basename); return file_copy(src, fullpath); }else{ return file_copy(src, dst); } } sdir = opendir(dirname); if(NULL == sdir) { fprintf(stderr, "%s:%d Failed to open dir:%s\n", __FUNCTION__, __LINE__, dirname); return -1; } while((sdirent = readdir(sdir)) != NULL){ if (is_dir(sdirent->d_name)) { continue; } if (wild_match(basename, sdirent->d_name)){ char sfile[512], dfile[512]; sprintf(dfile, "%s/%s", dst, sdirent->d_name); sprintf(sfile, "%s/%s", dirname, sdirent->d_name); file_copy(sfile, dfile); } } if(sdir) closedir(sdir); return 0; }
int test_path_split() { std::vector<std::string> splits; splits = path_split("/a/b/c.yaml"); MU_CHECK_EQ(3, (int) splits.size()); MU_CHECK_EQ("a", splits[0]); MU_CHECK_EQ("b", splits[1]); MU_CHECK_EQ("c.yaml", splits[2]); return 0; }
static char* getSharedLibraryPath(const char* progName, const char* libName) { char* progDir; char* result = NULL; char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); /* Get program's directory name */ path_split(progName, &progDir, NULL); /* First, try to probe the program's directory itself, this corresponds * to the standalone build with ./android-configure.sh where the script * will copy the host shared library under external/qemu/objs where * the binaries are located. */ if (probePathForFile(progDir, libName)) { return progDir; } /* Try under $progDir/lib/, this should correspond to the SDK installation * where the binary is under tools/, and the libraries under tools/lib/ */ { p = bufprint(temp, end, "%s/lib", progDir); if (p < end && probePathForFile(temp, libName)) { result = strdup(temp); goto EXIT; } } /* try in $progDir/../lib, this corresponds to the platform build * where the emulator binary is under out/host/<system>/bin and * the libraries are under out/host/<system>/lib */ { char* parentDir = path_parent(progDir, 1); if (parentDir == NULL) { parentDir = strdup("."); } p = bufprint(temp, end, "%s/lib", parentDir); free(parentDir); if (p < end && probePathForFile(temp, libName)) { result = strdup(temp); goto EXIT; } } /* Nothing found! */ EXIT: free(progDir); return result; }
void test(const char *path) { PATHSPLIT f; char buf[1024]; printf("> %s\n", path); path_split(path, &f); path_print(&f); path_normalize(&f, NULL); path_tostring(&f, buf); printf("< %s\n", buf); }
void path_make_relative( unsigned char *out, size_t size, const unsigned char *path, const unsigned char *relto, const unsigned char *prefix) { path_t path1, relto1, prefix1; unsigned char **s_path = 0, **s_relto = 0, **s_prefix = 0; ASSERT(path); snprintf(path1, sizeof(path1), "%s", path); if (!relto || !prefix) goto do_nothing; snprintf(relto1, sizeof(relto1), "%s", relto); snprintf(prefix1, sizeof(prefix1), "%s", prefix); if (!os_IsAbsolutePath(path1) || !os_IsAbsolutePath(relto1) || !os_IsAbsolutePath(prefix1)) goto do_nothing; path_split(path1, &s_path); path_normalize_split(s_path); path_split(relto1, &s_relto); path_normalize_split(s_relto); path_split(prefix1, &s_prefix); path_normalize_split(s_prefix); if (!path_is_prefix(s_path, s_prefix) || !path_is_prefix(s_relto, s_prefix)) goto do_nothing; do_relative(out, size, s_path, s_relto); goto cleanup; do_nothing: snprintf(out, size, "%s", path1); cleanup: path_split_free(s_path); path_split_free(s_relto); path_split_free(s_prefix); }
static Eina_List * bt_append(Eina_List *btl, const char *btline) { Bt *bt = calloc(1, sizeof(Bt)); if (!bt) return btl; const char *translation; char *comment = NULL; char *bin = strdup(btline); unsigned long long offset = 0, base = 0; translation = bt_input_translate(btline, &comment); if (translation) btline = translation; // parse: // /usr/local/lib/libeina.so.1 0x1ec88 // /usr/local/lib/libelementary.so.1 0x10f695 // /usr/local/lib/libeo.so.1 0xa474 // /usr/local/lib/libelementary.so.1 0x139bd6 // /usr/local/bin/elementary_test 0x8196d // /usr/local/bin/elementary_test 0x81b6a if (sscanf(btline, "%s %llx %llx", bin, &offset, &base) == 3) { path_split(bin, &(bt->bin_dir), &(bt->bin_name)); if (!bt->bin_dir) bt->bin_dir = strdup(""); if (!bt->bin_name) bt->bin_name = strdup(""); if (!_translate(_prog, bt->bin_dir, bt->bin_name, offset - base, &(bt->file_dir), &(bt->file_name), &(bt->func_name), &(bt->line))) { if (!_translate(_prog, bt->bin_dir, bt->bin_name, offset, &(bt->file_dir), &(bt->file_name), &(bt->func_name), &(bt->line))) { bt->file_dir = strdup(""); bt->file_name = strdup(""); bt->func_name = strdup(""); } } bt->comment = comment; btl = eina_list_append(btl, bt); } else { free(comment); bt->comment = strdup(btline); btl = eina_list_append(btl, bt); } free(bin); return btl; }
void search_adddir(const char *path) { PATHSPLIT f; char buf[MAXJPATH]; path_split(path, &f); path_normalize(&f, NULL); /* path_setcwd() should have been called */ path_tostring(&f, buf); searchdirs = list_new(searchdirs, buf, 0); #ifdef SEARCH_OPTIM /* searchhash is only valid for a fixed set of search directories */ hashdone(searchhash); searchhash = 0; #endif }
void path_normalize(unsigned char *path, size_t size) { unsigned char **split = 0; int i, j, len; unsigned char *t; if (!os_IsAbsolutePath(path)) return; path_split(path, &split); i = j = 1; while (split[i]) { if (!strcmp(split[i], "..")) { if (j > 1) j--; i++; } else if (!strcmp(split[i], ".")) { i++; } else { if (i == j) { i++; j++; } else { t = split[j]; split[j] = split[i]; split[i] = t; i++; j++; } } } if (i != j) { t = split[j]; split[j] = split[i]; split[i] = t; } for (; i > j; i--) { xfree(split[i]); split[i] = 0; } len = 0; if (split[0][0] != '/') len += strlen(split[0]); for (len = 0, i = 1; split[i]; i++) len += strlen(split[i]) + 1; if (len >= size) goto cleanup; t = path; if (split[0][0] != '/') t += sprintf(t, "%s", split[0]); for (i = 1; split[i]; i++) t += sprintf(t, "/%s", split[i]); cleanup: for (i = 0; split[i]; i++) xfree(split[i]); xfree(split); }
void pkg_scan(const char *search_path, pkg_iteration_func_t func) { char **path = NULL; size_t count = 0, iter = 0; /* PKG_CONFIG_PATH has to take precedence */ if (search_path == NULL) return; count = path_split(search_path, &path); for (iter = 0; iter < count; iter++) pkg_scan_dir(path[iter], func); path_free(path, count); }
/* try to see if the skin name leads to a magic skin or skin path directly * returns 1 on success, 0 on error. * * on success, this sets up '*pSkinName' and '*pSkinDir' */ static int _getSkinPathFromName( const char* skinName, const char* sdkRootPath, char** pSkinName, char** pSkinDir ) { char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); /* if the skin name has the format 'NNNNxNNN' where * NNN is a decimal value, then this is a 'magic' skin * name that doesn't require a skin directory */ if (isdigit(skinName[0])) { int width, height; if (sscanf(skinName, "%dx%d", &width, &height) == 2) { D("'magic' skin format detected: %s", skinName); *pSkinName = ASTRDUP(skinName); *pSkinDir = NULL; return 1; } } /* is the skin name a direct path to the skin directory ? */ if (path_is_absolute(skinName) && _checkSkinPath(skinName)) { goto FOUND_IT; } /* is the skin name a relative path from the SDK root ? */ p = bufprint(temp, end, "%s/%s", sdkRootPath, skinName); if (p < end && _checkSkinPath(temp)) { skinName = temp; goto FOUND_IT; } /* nope */ return 0; FOUND_IT: if (path_split(skinName, pSkinDir, pSkinName) < 0) { derror("malformed skin name: %s", skinName); exit(2); } D("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); return 1; }
void depsTimeStamp(const char *path, time_t *time) { PATHSPLIT f; char buf[MAXJPATH]; if (!inState(DEPS_STATE_INIT)) { setErr(DEPS_ERROR_NOT_INIT); return; } setErr(0); path_split(path, &f); path_normalize(&f, NULL); path_tostring(&f, buf); timestamp(buf, time); }
std::string normalize(std::string &path) { if (path.size() < 1 || path[0] != '/') throw(std::runtime_error(std::string("path must start with /"))); std::vector<std::string> components = path_split(path); std::vector<std::string> filtered; for (auto &p : components) { if (p == ".") { continue; } else if (p == "..") { if (!filtered.empty()) filtered.pop_back(); continue; } else { filtered.push_back(p); } } return path_join(filtered); }
int path_chdir(const char *path) { char **arr, *cur; int i, r = -1; if((cur = path_absolute(path)) == NULL) return -1; i = path_split(cur, &arr); if(chdir("/") < 0) goto path_chdir_done; while(--i >= 0) if(chdir(arr[i]) < 0) goto path_chdir_done; r = 0; path_chdir_done: free(cur); free(arr); return r; }
int path_getdir(TSDCHAR *dst, const TSDCHAR *path) { int ret = 1; const TSDCHAR *dir; int dir_len; path_split(&dir, &dir_len, NULL, NULL, NULL, NULL, path); if (dir_len > MAX_PATH_LEN - 1) { dir_len = MAX_PATH_LEN - 1; ret = 0; } else if (dir_len == 0) { dst[0] = TSD_NULLCHAR; } memcpy(dst, dir, sizeof(TSDCHAR)*dir_len); dst[dir_len] = TSD_NULLCHAR; return ret; }
static Eina_Bool _addr2line(const char *prog, const char *bin_dir, const char *bin_name, unsigned long long addr, char **file_dir, char **file_name, char **func_name, int *file_line) { char buf[4096], func[4096], *f1 = NULL, *f2 = NULL; Eina_Bool ok = EINA_FALSE; int line; FILE *p; snprintf(buf, sizeof(buf), "%s -f -e %s/%s -C -a 0x%llx", prog, bin_dir, bin_name, addr); p = popen(buf, "r"); if (!p) return EINA_FALSE; if ((fscanf(p, "%4095s\n", buf) == 1) && (fscanf(p, "%4095s\n", func) == 1)) { if (fscanf(p, "%[^:]:%i\n", buf, &line) == 2) { path_split(buf, &(f1), &(f2)); if ((!f1) || (!f2)) { free(f1); free(f2); pclose(p); return EINA_FALSE; } } else { f1 = strdup("??"); f2 = strdup("??"); } *file_dir = f1; *file_name = f2; *func_name = strdup(func); *file_line = line; ok = EINA_TRUE; } pclose(p); return ok; }
/* Splits a point buffer into individual path segments. Loads the result into the given path buffer. */ void Optimizer_Context::find_paths(double split_angle) { fill_angle(); path_split(split_angle); fill_cycle(split_angle); }
/* NOTE: cwd and the memory cur points to are unreliable after calling this * function. * TODO: This code is rather fragile and inefficient. A rewrite is in order. */ static char *path_real_rec(char *cur, int *links) { int i, n, tmpl, lnkl = 0; char **arr, *tmp, *lnk = NULL, *ret = NULL; tmpl = strlen(cur)+1; tmp = malloc(tmpl); /* split path */ i = path_split(cur, &arr); /* re-create full path */ strcpy(tmp, "/"); if(i > 0) { lnkl = RPATH_CNKSZ; lnk = malloc(lnkl); if(chdir("/") < 0) goto path_real_done; } while(--i>=0) { if(arr[i][0] == 0) continue; /* check for symlink */ while((n = readlink(arr[i], lnk, lnkl)) == lnkl || (n < 0 && errno == ERANGE)) { lnkl += RPATH_CNKSZ; lnk = realloc(lnk, lnkl); } if(n < 0 && errno != EINVAL) goto path_real_done; if(n > 0) { if(++*links > LINK_MAX) { errno = ELOOP; goto path_real_done; } lnk[n++] = 0; /* create new path */ if(lnk[0] != '/') n += strlen(tmp); if(tmpl < n) { tmpl = n; tmp = realloc(tmp, tmpl); } if(lnk[0] != '/') strcat(tmp, lnk); else strcpy(tmp, lnk); /* append remaining directories */ while(--i>=0) { n += strlen(arr[i])+1; if(tmpl < n) { tmpl = n; tmp = realloc(tmp, tmpl); } strcat(tmp, "/"); strcat(tmp, arr[i]); } /* call path_real_rec() with the new path */ ret = path_real_rec(tmp, links); goto path_real_done; } /* not a symlink, append component and go to the next part */ strcat(tmp, arr[i]); if(i) { if(chdir(arr[i]) < 0) goto path_real_done; strcat(tmp, "/"); } } ret = tmp; path_real_done: if(ret != tmp) free(tmp); if(lnkl > 0) free(lnk); free(arr); return ret; }
/* Main routine */ int main(int argc, char** argv) { const char* avdName = NULL; char* avdArch = NULL; const char* gpu = NULL; char* emulatorPath; int force_32bit = 0; bool no_window = false; /* Define ANDROID_EMULATOR_DEBUG to 1 in your environment if you want to * see the debug messages from this launcher program. */ const char* debug = getenv("ANDROID_EMULATOR_DEBUG"); if (debug != NULL && *debug && *debug != '0') android_verbose = 1; /* Parse command-line and look for * 1) an avd name either in the form or '-avd <name>' or '@<name>' * 2) '-force-32bit' which always use 32-bit emulator on 64-bit platforms * 3) '-verbose', or '-debug-all' or '-debug all' to enable verbose mode. */ int nn; for (nn = 1; nn < argc; nn++) { const char* opt = argv[nn]; if (!strcmp(opt,"-qemu")) break; if (!strcmp(opt,"-verbose") || !strcmp(opt,"-debug-all")) { android_verbose = 1; } if (!strcmp(opt,"-debug") && nn + 1 < argc && !strcmp(argv[nn + 1], "all")) { android_verbose = 1; } if (!strcmp(opt,"-gpu") && nn + 1 < argc) { gpu = argv[nn + 1]; nn++; } if (!strcmp(opt,"-ranchu")) { ranchu = true; continue; } if (!strcmp(opt,"-force-32bit")) { force_32bit = 1; continue; } if (!strcmp(opt,"-no-window")) { no_window = true; continue; } if (!strcmp(opt,"-list-avds")) { AvdScanner* scanner = avdScanner_new(NULL); for (;;) { const char* name = avdScanner_next(scanner); if (!name) { break; } printf("%s\n", name); } avdScanner_free(scanner); exit(0); } if (!avdName) { if (!strcmp(opt,"-avd") && nn+1 < argc) { avdName = argv[nn+1]; } else if (opt[0] == '@' && opt[1] != '\0') { avdName = opt+1; } } } /* If ANDROID_EMULATOR_FORCE_32BIT is set to 'true' or '1' in the * environment, set -force-32bit automatically. */ { const char kEnvVar[] = "ANDROID_EMULATOR_FORCE_32BIT"; const char* val = getenv(kEnvVar); if (val && (!strcmp(val, "true") || !strcmp(val, "1"))) { if (!force_32bit) { D("Auto-config: -force-32bit (%s=%s)\n", kEnvVar, val); force_32bit = 1; } } } #if defined(__linux__) if (!force_32bit && android_getHostBitness() == 32) { fprintf(stderr, "ERROR: 32-bit Linux Android emulator binaries are DEPRECATED, to use them\n" " you will have to do at least one of the following:\n" "\n" " - Use the '-force-32bit' option when invoking 'emulator'.\n" " - Set ANDROID_EMULATOR_FORCE_32BIT to 'true' in your environment.\n" "\n" " Either one will allow you to use the 32-bit binaries, but please be\n" " aware that these will disappear in a future Android SDK release.\n" " Consider moving to a 64-bit Linux system before that happens.\n" "\n" ); exit(1); } #endif /* If there is an AVD name, we're going to extract its target architecture * by looking at its config.ini */ if (avdName != NULL) { D("Found AVD name '%s'\n", avdName); avdArch = path_getAvdTargetArch(avdName); D("Found AVD target architecture: %s\n", avdArch); } else { /* Otherwise, using the ANDROID_PRODUCT_OUT directory */ const char* androidOut = getenv("ANDROID_PRODUCT_OUT"); if (androidOut != NULL) { D("Found ANDROID_PRODUCT_OUT: %s\n", androidOut); avdArch = path_getBuildTargetArch(androidOut); D("Found build target architecture: %s\n", avdArch ? avdArch : "<NULL>"); } } if (avdArch == NULL) { avdArch = "arm"; D("Can't determine target AVD architecture: defaulting to %s\n", avdArch); } /* Find program directory. */ char* progDir = NULL; path_split(argv[0], &progDir, NULL); /* Only search in current path if there is no directory separator * in |progName|. */ #ifdef _WIN32 bool tryCurrentPath = (!strchr(argv[0], '/') && !strchr(argv[0], '\\')); #else bool tryCurrentPath = !strchr(argv[0], '/'); #endif /* Find the architecture-specific program in the same directory */ bool is_64bit = false; emulatorPath = getTargetEmulatorPath(progDir, tryCurrentPath, avdArch, force_32bit, &is_64bit); D("Found target-specific emulator binary: %s\n", emulatorPath); /* Replace it in our command-line */ argv[0] = emulatorPath; /* We need to find the location of the GLES emulation shared libraries * and modify either LD_LIBRARY_PATH or PATH accordingly */ bool gpuEnabled = false; const char* gpuMode = NULL; if (avdName) { gpuMode = path_getAvdGpuMode(avdName); gpuEnabled = (gpuMode != NULL); } EmuglConfig config; int bitness = is_64bit ? 64 : 32; if (!emuglConfig_init( &config, gpuEnabled, gpuMode, gpu, bitness, no_window)) { fprintf(stderr, "ERROR: %s\n", config.status); exit(1); } D("%s\n", config.status); emuglConfig_setupEnv(&config); /* For Qt-based UI backends, add <lib>/qt/ to the library search path. */ androidQtSetupEnv(is_64bit); #ifdef _WIN32 // Take care of quoting all parameters before sending them to execv(). // See the "Eveyone quotes command line arguments the wrong way" on // MSDN. int n; for (n = 0; n < argc; ++n) { // Technically, this leaks the quoted strings, but we don't care // since this process will terminate after the execv() anyway. argv[n] = win32_cmdline_quote(argv[n]); D("Quoted param: [%s]\n", argv[n]); } #endif if (android_verbose) { int i; printf("emulator: Running :%s\n", emulatorPath); for(i = 0; i < argc; i++) { printf("emulator: qemu backend: argv[%02d] = \"%s\"\n", i, argv[i]); } /* Dump final command-line parameters to make debugging easier */ printf("emulator: Concatenated backend parameters:\n"); for (i = 0; i < argc; i++) { /* To make it easier to copy-paste the output to a command-line, * quote anything that contains spaces. */ if (strchr(argv[i], ' ') != NULL) { printf(" '%s'", argv[i]); } else { printf(" %s", argv[i]); } } printf("\n"); } // Launch it with the same set of options ! // Note that on Windows, the first argument must _not_ be quoted or // Windows will fail to find the program. safe_execv(emulatorPath, argv); /* We could not launch the program ! */ fprintf(stderr, "Could not launch '%s': %s\n", emulatorPath, strerror(errno)); return errno; }
void avdInfo_getSkinInfo( AvdInfo* i, char** pSkinName, char** pSkinDir ) { char* skinName = NULL; char* skinPath; char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); *pSkinName = NULL; *pSkinDir = NULL; /* First, see if the config.ini contains a SKIN_PATH entry that * names the full directory path for the skin. */ if (i->configIni != NULL ) { skinPath = iniFile_getString( i->configIni, SKIN_PATH, NULL ); if (skinPath != NULL) { /* If this skin name is magic or a direct directory path * we have our result right here. */ if (_getSkinPathFromName(skinPath, i->sdkRootPath, pSkinName, pSkinDir )) { AFREE(skinPath); return; } } /* The SKIN_PATH entry was not valid, so look at SKIN_NAME */ D("Warning: config.ini contains invalid %s entry: %s", SKIN_PATH, skinPath); AFREE(skinPath); skinName = iniFile_getString( i->configIni, SKIN_NAME, NULL ); } if (skinName == NULL) { /* If there is no skin listed in the config.ini, try to see if * there is one single 'skin' directory in the content directory. */ p = bufprint(temp, end, "%s/skin", i->contentPath); if (p < end && _checkSkinPath(temp)) { D("using skin content from %s", temp); AFREE(i->skinName); *pSkinName = ASTRDUP("skin"); *pSkinDir = ASTRDUP(i->contentPath); return; } /* otherwise, use the default name */ skinName = ASTRDUP(SKIN_DEFAULT); } /* now try to find the skin directory for that name - */ do { /* first try the content directory, i.e. $CONTENT/skins/<name> */ skinPath = _checkSkinSkinsDir(i->contentPath, skinName); if (skinPath != NULL) break; #define PREBUILT_SKINS_ROOT "development/tools/emulator" /* if we are in the Android build, try the prebuilt directory */ if (i->inAndroidBuild) { p = bufprint( temp, end, "%s/%s", i->androidBuildRoot, PREBUILT_SKINS_ROOT ); if (p < end) { skinPath = _checkSkinSkinsDir(temp, skinName); if (skinPath != NULL) break; } /* or in the parent directory of the system dir */ { char* parentDir = path_parent(i->androidOut, 1); if (parentDir != NULL) { skinPath = _checkSkinSkinsDir(parentDir, skinName); AFREE(parentDir); if (skinPath != NULL) break; } } } /* look in the search paths. For each <dir> in the list, * look into <dir>/../skins/<name>/ */ { int nn; for (nn = 0; nn < i->numSearchPaths; nn++) { char* parentDir = path_parent(i->searchPaths[nn], 1); if (parentDir == NULL) continue; skinPath = _checkSkinSkinsDir(parentDir, skinName); AFREE(parentDir); if (skinPath != NULL) break; } if (nn < i->numSearchPaths) break; } /* We didn't find anything ! */ *pSkinName = skinName; return; } while (0); if (path_split(skinPath, pSkinDir, pSkinName) < 0) { derror("weird skin path: %s", skinPath); AFREE(skinPath); return; } DD("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); AFREE(skinPath); return; }
globus_result_t stat_entries(ds3_client * Client, char * Path, int FileOnly, int MaxEntries, globus_gfs_stat_t * GFSStatArray, int * CountOut, stat_state_t * State) { globus_result_t result = GLOBUS_SUCCESS; int i = 0; int expanding_search = 0; GlobusGFSName(stat_entries); if (!State->_bucket_name && !State->_object_name) path_split(Path, &State->_bucket_name, &State->_object_name); if (!State->_service_response) { result = gds3_get_service(Client, &State->_service_response); if (result != GLOBUS_SUCCESS) return result; } *CountOut = 0; /* No bucket_name means it _is_ '/' */ if (!State->_bucket_name) { if (FileOnly) { /* Return a stat of only '/'. */ result = stat_populate("/", S_IFDIR, State->_service_response->num_buckets + 2, 1024, ds3_str_value(State->_service_response->owner->name), NULL, &GFSStatArray[(*CountOut)++]); State->_complete = 1; return result; } else { /* Return the contents of '/'. */ if (State->_index++ == 0) { result = stat_populate(".", S_IFDIR, State->_service_response->num_buckets + 2, 1024, ds3_str_value(State->_service_response->owner->name), NULL, // XXX no modify time &GFSStatArray[(*CountOut)++]); if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries) return result; } if (State->_index++ == 1) { result = stat_populate("..", S_IFDIR, State->_service_response->num_buckets + 2, 1024, ds3_str_value(State->_service_response->owner->name), NULL, // XXX no modify time &GFSStatArray[(*CountOut)++]); if (State->_service_response->num_buckets == 0) State->_complete = 1; if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries) return result; } for (i = State->_index-2; i < State->_service_response->num_buckets && *CountOut < MaxEntries; i++) { result = stat_populate(ds3_str_value(State->_service_response->buckets[i].name), S_IFDIR, 2, 1024, ds3_str_value(State->_service_response->owner->name), ds3_str_value(State->_service_response->buckets[i].creation_date), &GFSStatArray[(*CountOut)++]); if (result != GLOBUS_SUCCESS) return result; } State->_complete = (i == State->_service_response->num_buckets); return result; } } /* No object_name means it is _in_ '/' */ if (!State->_object_name && FileOnly) { for (i = 0; i < State->_service_response->num_buckets; i++) { if (strcmp(State->_bucket_name, ds3_str_value(State->_service_response->buckets[i].name)) == 0) { result = stat_populate(ds3_str_value(State->_service_response->buckets[i].name), S_IFDIR, 2, 1024, ds3_str_value(State->_service_response->owner->name), ds3_str_value(State->_service_response->buckets[i].creation_date), &GFSStatArray[(*CountOut)++]); State->_complete = 1; return result; } } return GlobusGFSErrorGeneric("No such file or directory"); } /* Let's find this object. */ if (State->_object_name && State->_object_name[strlen(State->_object_name)-1] != '/') { do { /* Get the next response. */ if (!State->_bucket_response) { result = gds3_get_bucket(Client, State->_bucket_name, &State->_bucket_response, "/", /* Delimiter */ State->_object_name, State->_marker, MaxEntries); if (result) return result; } /* If it is an object... */ for (i = 0; i < State->_bucket_response->num_objects; i++) { if (strcmp(State->_object_name, ds3_str_value(State->_bucket_response->objects[i].name)) == 0) { char * last_modified = NULL; if (State->_bucket_response->objects[i].last_modified) last_modified = ds3_str_value(State->_bucket_response->objects[i].last_modified); result = stat_populate(basename(State->_object_name), S_IFREG, 1, State->_bucket_response->objects[i].size, ds3_str_value(State->_bucket_response->objects[i].owner->name), last_modified, &GFSStatArray[(*CountOut)++]); State->_complete = 1; return result; } } /* If it is a directory... */ for (i = 0; i < State->_bucket_response->num_common_prefixes; i++) { if (strncmp(State->_object_name, ds3_str_value(State->_bucket_response->common_prefixes[i]), ds3_str_size(State->_bucket_response->common_prefixes[i])-1) == 0 && State->_bucket_response->common_prefixes[i]->value[ State->_bucket_response->common_prefixes[i]->size-1] == '/') { /* If we do not need to expand the directory... */ if (FileOnly) { result = stat_populate(basename(State->_object_name), S_IFDIR, 2, 1024, ds3_str_value(State->_service_response->owner->name), NULL, &GFSStatArray[(*CountOut)++]); State->_complete = 1; return result; } else { char * new_object_name = malloc(strlen(State->_object_name)+2); sprintf(new_object_name, "%s/", State->_object_name); free(State->_object_name); State->_object_name = new_object_name; if (State->_bucket_response) ds3_free_bucket_response(State->_bucket_response); State->_bucket_response = NULL; if (State->_marker) free(State->_marker); State->_index = 0; expanding_search = 1; break; } } } } while (State->_marker); /* We could not find it. */ if (!expanding_search) return GlobusGFSErrorGeneric("No such file or directory"); } do { /* First pass. */ if (!State->_bucket_response && !State->_index) { result = stat_populate(".", S_IFDIR, 2, 1024, ds3_str_value(State->_service_response->owner->name), NULL, // XXX no modify time &GFSStatArray[(*CountOut)++]); if (result != GLOBUS_SUCCESS) return result; result = stat_populate("..", S_IFDIR, 2, 1024, ds3_str_value(State->_service_response->owner->name), NULL, // XXX no modify time &GFSStatArray[(*CountOut)++]); if (result != GLOBUS_SUCCESS) return result; } /* Get the next response. */ if (!State->_bucket_response) { result = gds3_get_bucket(Client, State->_bucket_name, &State->_bucket_response, "/", /* Delimiter */ State->_object_name, State->_marker, MaxEntries); if (result) return result; State->_index = 0; } for (i = State->_index; i < State->_bucket_response->num_objects; i++, State->_index++) { if (State->_object_name && strcmp(State->_bucket_response->objects[i].name->value, State->_object_name) == 0) continue; char * last_modified = NULL; if (State->_bucket_response->objects[i].last_modified) last_modified = ds3_str_value(State->_bucket_response->objects[i].last_modified); result = stat_populate(State->_bucket_response->objects[i].name->value + (State->_object_name ? strlen(State->_object_name) : 0), S_IFREG, 1, State->_bucket_response->objects[i].size, ds3_str_value(State->_bucket_response->objects[i].owner->name), last_modified, &GFSStatArray[(*CountOut)++]); if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries) return result; } for (i = State->_index - State->_bucket_response->num_objects; i < State->_bucket_response->num_common_prefixes; i++, State->_index++) { char * entry = malloc(State->_bucket_response->common_prefixes[i]->size); snprintf(entry, State->_bucket_response->common_prefixes[i]->size, "%s", State->_bucket_response->common_prefixes[i]->value); result = stat_populate(entry + (State->_object_name ? strlen(State->_object_name) : 0), S_IFDIR, 2, 1024, ds3_str_value(State->_service_response->owner->name), NULL, &GFSStatArray[(*CountOut)++]); free(entry); if (result != GLOBUS_SUCCESS || *CountOut == MaxEntries) return result; } ds3_free_bucket_response(State->_bucket_response); State->_bucket_response = NULL; } while (State->_marker); State->_complete = 1; return result; }
const char *explain_path_error(pool *p, int err_errno, const char *full_path, int flags, mode_t mode) { register unsigned int i; array_header *components = NULL; const char *explained = NULL, *path = NULL, *prev_path = NULL; unsigned long name_max, no_trunc; if (p == NULL || full_path == NULL) { errno = EINVAL; return NULL; } /* Try to get some of the easy cases out of the way first. */ if (err_errno == ENAMETOOLONG) { unsigned long path_max; path_max = explain_platform_path_max(p, full_path); if (path_max > 0) { size_t path_len; path_len = strlen(full_path); if (path_len > path_max) { explained = describe_enametoolong_path(p, full_path, path_len, path_max, flags); return explained; } } } /* Now we need to walk the path. Whee. * * To do this, we split the path into an array, one element per component. * This SHOULD make it easier to progressively construct the longer and * longer paths, leading up to the final component/full path, for checking * each fully qualified component along the way. */ components = path_split(p, full_path); name_max = explain_platform_name_max(p, full_path); no_trunc = explain_platform_no_trunc(p, full_path); for (i = 0; i < components->nelts; i++) { const char **elts, *component; int final_component = FALSE, res, xerrno = 0; struct stat st; pr_signals_handle(); elts = components->elts; component = elts[i]; if (err_errno == ENAMETOOLONG) { size_t component_len; component_len = strlen(component); /* Component names can be too long only if the filesystem on which * the path resides does not silently truncate long names. */ if (component_len > name_max && no_trunc == 1) { explained = describe_enametoolong_name(p, component, component_len, name_max, flags); return explained; } } if (path == NULL) { path = component; } else { path = pdircat(p, path, component, NULL); } /* The following are the checks on the non-final components. The final * component has different constraints. */ final_component = (i == (components->nelts-1)); res = pr_fsio_lstat(path, &st); xerrno = errno; if (res < 0) { pr_trace_msg(trace_channel, 3, "error checking component #%u (of %u), path '%s': %s", i+1, components->nelts, path, strerror(xerrno)); } if (final_component == FALSE) { if (res < 0) { switch (xerrno) { case ENOENT: explained = describe_enoent_dir(p, path, flags); break; case EACCES: explained = describe_eacces_dir(p, path, flags); break; default: pr_trace_msg(trace_channel, 3, "unexplained error [%s (%d)] for directory '%s'", strerror(xerrno), errno, path); } break; } /* XXX What if this is a symlink? */ if (!S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode)) { /* Explains ENOTDIR */ explained = pstrcat(p, "path '", path, "' does not refer to a directory", NULL); break; } /* if WANT_SEARCH and no search, EACCES */ /* if found, and a directory, set current lookup directory, and go to * next component. */ } else { /* Last component, full path, leaf file. */ if (res < 0) { switch (xerrno) { case ENOENT: explained = describe_enoent_file(p, path, flags); break; case EACCES: explained = describe_eacces_file(p, path, flags); break; default: pr_trace_msg(trace_channel, 3, "unexplained error [%s (%d)] for file '%s'", strerror(xerrno), errno, path); } break; } switch (err_errno) { case EACCES: explained = describe_eacces_file(p, path, flags); if (explained != NULL) { if (pr_fsio_lstat(prev_path, &st) == 0) { explained = pstrcat(p, explained, "; parent directory '", prev_path, "' has perms ", mode2s(p, st.st_mode), ", and is owned by UID ", pr_uid2str(p, st.st_uid), ", GID ", pr_gid2str(p, st.st_gid), NULL); } } break; default: pr_trace_msg(trace_channel, 3, "unexplained error [%s (%d)] for file '%s'", strerror(xerrno), errno, path); } } prev_path = path; } return explained; }
static void handle_connection (ipc_structure_type *ipc_structure) { message_parameter_type message_parameter; bool done = FALSE; uint8_t *data; unsigned int data_size = 16384; file_mount_type mount = { "servicefs" }; memory_allocate ((void **) &data, data_size); /* Mount ourselves. */ message_parameter.block = TRUE; message_parameter.data = &mount; message_parameter.protocol = IPC_PROTOCOL_FILE; message_parameter.message_class = IPC_FILE_MOUNT_VOLUME; message_parameter.length = sizeof (file_mount_type); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); message_parameter.block = TRUE; while (!done) { message_parameter.data = data; message_parameter.protocol = IPC_PROTOCOL_FILE; message_parameter.message_class = IPC_CLASS_NONE; message_parameter.length = data_size; if (ipc_receive (ipc_structure->input_mailbox_id, &message_parameter, &data_size) != IPC_RETURN_SUCCESS) { continue; } switch (message_parameter.message_class) { /* Read one or more directory entries. */ case IPC_FILE_DIRECTORY_ENTRY_READ: { file_directory_entry_read_type *directory_entry_read = (file_directory_entry_read_type *) data; service_protocol_type *protocol_info; unsigned int protocols = 50; unsigned int output_index = 0; unsigned int max_entries = directory_entry_read->entries; unsigned int input_index; char *path[10]; unsigned int elements = 10; path_split (directory_entry_read->path_name, path, &elements); log_print_formatted (&log_structure, LOG_URGENCY_DEBUG, "%u", elements); /* TODO: Do something more with the path array here. */ directory_entry_read->entries = 0; memory_allocate ((void **) &protocol_info, protocols * sizeof (service_protocol_type)); system_call_service_protocol_get (&protocols, protocol_info); for (input_index = directory_entry_read->start_entry; input_index < (directory_entry_read->start_entry + max_entries) && input_index < protocols; input_index++) { string_copy (directory_entry_read->entry[output_index].name, protocol_info[input_index].name); directory_entry_read->entry[output_index].type = FILE_ENTRY_TYPE_DIRECTORY; directory_entry_read->entries++; output_index++; } if (input_index == protocols) { directory_entry_read->end_reached = TRUE; } else { directory_entry_read->end_reached = FALSE; } message_parameter.length = (sizeof (file_directory_entry_read_type) + sizeof (file_directory_entry_type) * directory_entry_read->entries); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); break; } /* Get verbose information about the given file entry. */ case IPC_FILE_GET_INFO: { file_verbose_directory_entry_type *verbose_directory_entry = (file_verbose_directory_entry_type *) data; unsigned int protocols = 50; unsigned int index; service_protocol_type *protocol_info; memory_allocate ((void **) &protocol_info, protocols * sizeof (service_protocol_type)); system_call_service_protocol_get (&protocols, protocol_info); verbose_directory_entry->success = FALSE; for (index = 0; index < protocols; index++) { if (string_length (verbose_directory_entry->path_name) > 1 && string_compare (protocol_info[index].name, verbose_directory_entry->path_name + 1) == 0) { verbose_directory_entry->success = TRUE; verbose_directory_entry->type = FILE_ENTRY_TYPE_DIRECTORY; verbose_directory_entry->time = time_get (); verbose_directory_entry->size = protocol_info[index].number_of_services; break; } } message_parameter.length = sizeof (file_verbose_directory_entry_type); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); break; } /* Unsupported functions. */ case IPC_FILE_OPEN: /* FIXME: For READ, we first create a buffer, fills it with the content of the 'file' and then pass the requested part of the file to the caller. */ case IPC_FILE_READ: case IPC_FILE_CLOSE: case IPC_FILE_SEEK: case IPC_FILE_WRITE: case IPC_FILE_ACL_READ: case IPC_FILE_ACL_WRITE: case IPC_FILE_MOUNT_VOLUME: case IPC_FILE_UNMOUNT_VOLUME: default: { return_type return_value = IPC_RETURN_FILE_FUNCTION_UNSUPPORTED; message_parameter.data = &return_value; message_parameter.length = sizeof (return_type); ipc_send (ipc_structure->output_mailbox_id, &message_parameter); break; } } } }
const char *search(const char *source, const char *_header, time_t *time) { PATHNAME f[1]; char buf[MAXJPATH]; char buf2[MAXSYM], *header = buf2; char buf3[MAXJPATH]; int system = (_header[0] == '<'); LIST *list = searchdirs->next; /* D support */ int dMode=0; int fnlen=strlen(source); if(source[fnlen-2]=='.' && source[fnlen-1]=='d') dMode=1; /* <foo.h> --> foo.h */ strcpy(header, _header + 1); header[strlen(header) - 1] = '\0'; /* src/foo.c --> src */ path_parse(source, f); path_parent(f); path_build(f, buf3, 1); /* C::B patch: Fix bug with usage of root folder */ # if PATH_DELIM == '\\' /* Special case for D:/ - dirname is D:/, not "D:" */ if ((strlen(buf3)==3) && (buf3[1]==':') && ((buf3[2]=='\\') || (buf3[2]=='/'))) buf3[2] = 0; # endif if (DEBUG_SEARCH) printf( "search %s\n included by %s\n", _header, source); #ifdef SEARCH_OPTIM { char key[MAXJPATH] = ""; SEARCH search, *s = &search; if (!system) { strcpy(key, buf3); strcat(key, ","); } strcat(key, _header); s->key = key; if (!searchhash) searchhash = hashinit(sizeof(SEARCH), "search"); if (hashcheck(searchhash, (HASHDATA **)&s)) { if (DEBUG_SEARCH) printf(" %s: %s [CACHED]\n", _header, s->time ? s->path : "*missing*" ); *time = s->time; return s->path; } } #endif /* If this is "foo.h" not <foo.h> then set the first search directory * to the including file's directory */ if (!system) { searchdirs->string = buf3; list = searchdirs; } path_parse(header, f); f->f_grist.ptr = 0; f->f_grist.len = 0; for (; list; list = list->next) { f->f_root.ptr = list->string; f->f_root.len = strlen(list->string); path_build(f, buf, 1); { PATHSPLIT f; char buf2[MAXJPATH]; path_split(buf, &f); path_normalize(&f, NULL); path_tostring(&f, buf2); strcpy(buf, buf2); } if (DEBUG_SEARCH) printf(" %s: %s [TRY]\n", _header, buf); timestamp(buf, time); #ifdef SEARCH_OPTIM if (*time) { char key[MAXJPATH] = ""; SEARCH search, *s = &search; if (!system) { strcpy(key, buf3); strcat(key, ","); } strcat(key, _header); s->key = newstr(key); s->time = *time; s->path = newstr(buf); (void) hashenter(searchhash, (HASHDATA **)&s); } #endif if (*time) return newstr(buf); } if(!dMode) { #ifdef SEARCH_OPTIM /* remember that this file could not be found */ { char key[MAXJPATH] = ""; SEARCH search, *s = &search; if (!system) { strcpy(key, buf3); strcat(key, ","); } strcat(key, _header); s->key = newstr(key); s->time = 0; s->path = NULL; (void) hashenter(searchhash, (HASHDATA **)&s); } #endif /* C compilers do *not* look in the current directory for #include files */ *time = 0; return NULL; } /* D support (look in current directory) */ else { f->f_root.ptr = 0; f->f_root.len = 0; path_build( f, buf, 1 ); { PATHSPLIT f; char buf2[MAXJPATH]; path_split(buf, &f); path_normalize(&f, NULL); path_tostring(&f, buf2); strcpy(buf, buf2); } if( DEBUG_SEARCH ) printf( "search %s: %s\n", _header, buf ); timestamp( buf, time ); #ifdef SEARCH_OPTIM if (*time) { char key[MAXJPATH] = ""; SEARCH search, *s = &search; if (!system) { strcpy(key, buf3); strcat(key, ","); } strcat(key, _header); s->key = newstr(key); s->time = *time; s->path = newstr(buf); (void) hashenter(searchhash, (HASHDATA **)&s); } #endif if (*time) return newstr(buf); #ifdef SEARCH_OPTIM /* remember that this file could not be found */ { char key[MAXJPATH] = ""; SEARCH search, *s = &search; if (!system) { strcpy(key, buf3); strcat(key, ","); } strcat(key, _header); s->key = newstr(key); s->time = 0; s->path = NULL; (void) hashenter(searchhash, (HASHDATA **)&s); } #endif *time = 0; return NULL; } }
b_header *b_header_for_file(b_string *path, b_string *member_name, struct stat *st) { b_header *ret; struct path_data *path_data; if ((ret = malloc(sizeof(*ret))) == NULL) { goto error_malloc; } if ((path_data = path_split(member_name, st)) == NULL) { goto error_path_data; } ret->truncated = path_data->truncated; ret->prefix = path_data->prefix; ret->suffix = path_data->suffix; ret->mode = st->st_mode; ret->uid = st->st_uid; ret->gid = st->st_gid; ret->size = (st->st_mode & S_IFMT) == S_IFREG? st->st_size: 0; ret->mtime = st->st_mtime; ret->linktype = inode_linktype(st); ret->linkdest = NULL; ret->user = NULL; ret->group = NULL; /* * TODO: Implement major and minor (should be much easier than in Perl) */ ret->major = 0; ret->minor = 0; ret->truncated_link = 0; if ((st->st_mode & S_IFMT) == S_IFLNK) { if ((ret->linkdest = b_readlink(path, st)) == NULL) { goto error_readlink; } if (b_string_len(ret->linkdest) > B_HEADER_LINKDEST_SIZE) { ret->truncated_link = 1; } } /* * free() path_data, but keep its prefix and suffix with us, as we will free() those * ourselves b_header_destroy() */ free(path_data); return ret; error_readlink: b_string_free(path_data->prefix); b_string_free(path_data->suffix); free(path_data); error_path_data: free(ret); error_malloc: return NULL; }