// Check the registry for any installations of Python that we can use. // TODO: Refactor the common checks/logic/etc from this and find_in_path // into a static function. static int find_in_registry() { char sPythonBuf[MAX_PATH+1] = {0}; char sCheck[MAX_PATH+1] = {0}; long szPythonBuf = MAX_PATH + 1; int i = 0; // Some debugging. debug("Searching the registry for a python installation."); for(i = PYTHON2_MINOR_MIN; i <= PYTHON2_MINOR_MAX; i++) { if(!check_registry(2, i, sPythonBuf, &szPythonBuf)) continue; // RegQueryValueA includes the trailing zero in the length. szPythonBuf--; // Double check our result. if(!sPythonBuf || szPythonBuf <= 0) continue; // Set up our temporary work variable. strcpy(sCheck, sPythonBuf); // Remove trailing slashes. if(!remove_trailing_slashes(sCheck, (size_t*)&szPythonBuf)) { debug( "After removing all trailing slashes, path's length was less than 3. This " "indicates an invalid path in your registry." ); debug("Original: %s", sPythonBuf); debug("Result: %s", sCheck); continue; } // Max sure our resulting string wont be too big. if(!(check_python_length(szPythonBuf))) { debug( "Length of path, \"%s\" (%d) added to length of \"\\" PYTHON_EXE "\" (%d) results " "in a length that is bigger than the maximum file path length. Skipping.", sPythonBuf, szPythonBuf, szPyExe ); continue; } // Assemble our python path and check it. strcat(sCheck, "\\" PYTHON_EXE); if(!check_python(sCheck)) continue; // If we make it here, we have successfully found our python installation. strcpy(python_exe, sCheck); break; } // Some debugging. debug("find_in_registry resulted in \"%s\"", python_exe); return *python_exe != 0; }
static int fs_match(char *in1, char *in2) { char *n1; char *n2; int ret; n1 = strdup(in1); n2 = strdup(in2); remove_trailing_slashes(n1); remove_trailing_slashes(n2); ret = !strcmp(n1, n2); free(n1); free(n2); return ret; }
const char *lxc_global_config_value(const char *option_name) { static const char * const options[][2] = { { "lxc.bdev.lvm.vg", DEFAULT_VG }, { "lxc.bdev.lvm.thin_pool", DEFAULT_THIN_POOL }, { "lxc.bdev.zfs.root", DEFAULT_ZFSROOT }, { "lxc.lxcpath", NULL }, { "lxc.default_config", NULL }, { "lxc.cgroup.pattern", DEFAULT_CGROUP_PATTERN }, { "lxc.cgroup.use", NULL }, { NULL, NULL }, }; /* placed in the thread local storage pool for non-bionic targets */ #ifdef HAVE_TLS static __thread const char *values[sizeof(options) / sizeof(options[0])] = { 0 }; #else static const char *values[sizeof(options) / sizeof(options[0])] = { 0 }; #endif char *user_config_path = NULL; char *user_default_config_path = NULL; char *user_lxc_path = NULL; if (geteuid() > 0) { const char *user_home = getenv("HOME"); if (!user_home) user_home = "/"; user_config_path = malloc(sizeof(char) * (22 + strlen(user_home))); user_default_config_path = malloc(sizeof(char) * (26 + strlen(user_home))); user_lxc_path = malloc(sizeof(char) * (19 + strlen(user_home))); sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home); sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home); sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home); } else { user_config_path = strdup(LXC_GLOBAL_CONF); user_default_config_path = strdup(LXC_DEFAULT_CONFIG); user_lxc_path = strdup(LXCPATH); } const char * const (*ptr)[2]; size_t i; char buf[1024], *p, *p2; FILE *fin = NULL; for (i = 0, ptr = options; (*ptr)[0]; ptr++, i++) { if (!strcmp(option_name, (*ptr)[0])) break; } if (!(*ptr)[0]) { free(user_config_path); free(user_default_config_path); free(user_lxc_path); errno = EINVAL; return NULL; } if (values[i]) { free(user_config_path); free(user_default_config_path); free(user_lxc_path); return values[i]; } fin = fopen_cloexec(user_config_path, "r"); free(user_config_path); if (fin) { while (fgets(buf, 1024, fin)) { if (buf[0] == '#') continue; p = strstr(buf, option_name); if (!p) continue; /* see if there was just white space in front * of the option name */ for (p2 = buf; p2 < p; p2++) { if (*p2 != ' ' && *p2 != '\t') break; } if (p2 < p) continue; p = strchr(p, '='); if (!p) continue; /* see if there was just white space after * the option name */ for (p2 += strlen(option_name); p2 < p; p2++) { if (*p2 != ' ' && *p2 != '\t') break; } if (p2 < p) continue; p++; while (*p && (*p == ' ' || *p == '\t')) p++; if (!*p) continue; free(user_default_config_path); if (strcmp(option_name, "lxc.lxcpath") == 0) { free(user_lxc_path); user_lxc_path = copy_global_config_value(p); remove_trailing_slashes(user_lxc_path); values[i] = user_lxc_path; goto out; } values[i] = copy_global_config_value(p); free(user_lxc_path); goto out; } } /* could not find value, use default */ if (strcmp(option_name, "lxc.lxcpath") == 0) { remove_trailing_slashes(user_lxc_path); values[i] = user_lxc_path; free(user_default_config_path); } else if (strcmp(option_name, "lxc.default_config") == 0) { values[i] = user_default_config_path; free(user_lxc_path); } else { free(user_default_config_path); free(user_lxc_path); values[i] = (*ptr)[1]; } /* special case: if default value is NULL, * and there is no config, don't view that * as an error... */ if (!values[i]) errno = 0; out: if (fin) fclose(fin); return values[i]; }
extern int lxc_arguments_parse(struct lxc_arguments *args, int argc, char *const argv[]) { int ret = 0; char shortopts[256]; ret = build_shortopts(args->options, shortopts, sizeof(shortopts)); if (ret < 0) { lxc_error(args, "build_shortopts() failed : %s", strerror(errno)); return ret; } while (true) { int c; int index = 0; c = getopt_long(argc, argv, shortopts, args->options, &index); if (c == -1) break; switch (c) { case 'n': args->name = optarg; break; case 'o': args->log_file = optarg; break; case 'l': args->log_priority = optarg; break; case 'q': args->quiet = 1; break; case OPT_RCFILE: args->rcfile = optarg; break; case 'P': remove_trailing_slashes(optarg); ret = lxc_arguments_lxcpath_add(args, optarg); if (ret < 0) return ret; break; case OPT_USAGE: print_usage(args->options, args); case OPT_VERSION: print_version(); case '?': print_help(args, 1); case 'h': print_help(args, 0); default: if (args->parser) { ret = args->parser(args, c, optarg); if (ret) goto error; } } } /* * Reclaim the remaining command arguments */ args->argv = &argv[optind]; args->argc = argc - optind; /* If no lxcpaths were given, use default */ if (!args->lxcpath_cnt) { ret = lxc_arguments_lxcpath_add( args, lxc_global_config_value("lxc.lxcpath")); if (ret < 0) return ret; } /* Check the command options */ if (!args->name && strcmp(args->progname, "lxc-autostart") != 0) { lxc_error(args, "missing container name, use --name option"); return -1; } if (args->checker) ret = args->checker(args); error: if (ret) lxc_error(args, "could not parse command line"); return ret; }
// Attempt to find python on the PATH environment variable. // Note: We're not using any of the built in APIs like _searchenv, // because we don't want just the first executable on PATH. We need // to iterate through all matches until we find one that's valid // for our configuration. static int find_in_path() { char *sSearch, *sBuffer; char sCheck[MAX_PATH+1] = {0}; size_t szSearch; // Some debugging. debug("Searching the PATH for a valid python executable."); if(is_null(sBuffer = getenv(PATH_ENV))) { debug("Could not get PATH environment variable."); return 0; } if(is_null(sSearch = var_split(sBuffer))) { debug("Could not split PATH environment variable by ';'"); debug("PATH = %s", sBuffer); return 0; } do { if(!(szSearch = strlen(sSearch))) continue; if(szSearch > MAX_PATH) { debug("Encounted a path in the PATH variable that is too big."); debug("Path: %s", sSearch); debug("Length: %d", szSearch); continue; } // Set up our temporary work variable. strcpy(sCheck, sSearch); // Remove trailing slashes. if(!remove_trailing_slashes(sCheck, &szSearch)) { debug( "After removing all trailing slashes, path's length was less than 3. This " "indicates an invalid path in your environment variables." ); debug("Original: %s", sSearch); debug("Result: %s", sCheck); continue; } // Max sure our resulting string wont be too big. if(!(check_python_length(szSearch))) { debug( "Length of path, \"%s\" (%d) added to length of \"\\" PYTHON_EXE "\" (%d) results " "in a length that is bigger than the maximum file path length. Skipping.", sSearch, szSearch, szPyExe ); continue; } // Assemble our python path and check it. strcat(sCheck, "\\" PYTHON_EXE); if(!check_python(sCheck)) continue; // If we make it here, we have successfully found our python installation. strcpy(python_exe, sCheck); break; } while(!is_null(next_var(sSearch))); // Some debugging. debug("find_in_path resulted in \"%s\"", python_exe); return *python_exe != 0; }
static Package *parse_manifest (Options *op) { char *buf, *c, *tmpstr; int line; int fd, ret, len = 0; struct stat stat_buf; Package *p; char *manifest = MAP_FAILED, *ptr; int opengl_files_packaged = FALSE; p = (Package *) nvalloc(sizeof (Package)); /* open the manifest file */ if ((fd = open(".manifest", O_RDONLY)) == -1) { ui_error(op, "No package found for installation. Please run " "this utility with the '--help' option for usage " "information."); goto fail; } if (fstat(fd, &stat_buf) == -1) goto cannot_open; len = stat_buf.st_size; manifest = mmap(0, len, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0); if (manifest == MAP_FAILED) goto cannot_open; /* the first line is the description */ line = 1; p->description = get_next_line(manifest, &ptr, manifest, len); if (!p->description) goto invalid_manifest_file; /* the second line is the version */ line++; p->version = get_next_line(ptr, &ptr, manifest, len); if (!p->version) goto invalid_manifest_file; /* Ignore the third line */ line++; nvfree(get_next_line(ptr, &ptr, manifest, len)); /* the fourth line is the list of kernel modules. */ line++; tmpstr = get_next_line(ptr, &ptr, manifest, len); if (parse_kernel_modules_list(p, tmpstr) == 0) { goto invalid_manifest_file; } nvfree(tmpstr); /* * set the default value of excluded_kernel_modules to an empty, heap * allocated string so that it can be freed and won't prematurely end * an nvstrcat()ed string when unset. */ p->excluded_kernel_modules = nvstrdup(""); /* * ignore the fifth and sixth lines */ line++; nvfree(get_next_line(ptr, &ptr, manifest, len)); line++; nvfree(get_next_line(ptr, &ptr, manifest, len)); /* the seventh line is the kernel module build directory */ line++; p->kernel_module_build_directory = get_next_line(ptr, &ptr, manifest, len); if (!p->kernel_module_build_directory) goto invalid_manifest_file; remove_trailing_slashes(p->kernel_module_build_directory); /* * the eigth line is the directory containing precompiled kernel * interfaces */ line++; p->precompiled_kernel_interface_directory = get_next_line(ptr, &ptr, manifest, len); if (!p->precompiled_kernel_interface_directory) goto invalid_manifest_file; remove_trailing_slashes(p->precompiled_kernel_interface_directory); /* the rest of the file is file entries */ line++; for (; (buf = get_next_line(ptr, &ptr, manifest, len)); line++) { char *flag = NULL; PackageEntry entry; int entry_success = FALSE; if (buf[0] == '\0') { free(buf); break; } /* initialize the new entry */ memset(&entry, 0, sizeof(PackageEntry)); /* read the file name and permissions */ c = buf; entry.file = read_next_word(buf, &c); if (!entry.file) goto entry_done; tmpstr = read_next_word(c, &c); if (!tmpstr) goto entry_done; /* translate the mode string into an octal mode */ ret = mode_string_to_mode(op, tmpstr, &entry.mode); free(tmpstr); if (!ret) goto entry_done; /* every file has a type field */ entry.type = FILE_TYPE_NONE; flag = read_next_word(c, &c); if (!flag) goto entry_done; entry.type = parse_manifest_file_type(flag, &entry.caps); if (entry.type == FILE_TYPE_NONE) { goto entry_done; } /* Track whether certain file types were packaged */ switch (entry.type) { case FILE_TYPE_XMODULE_SHARED_LIB: op->x_files_packaged = TRUE; break; default: break; } /* set opengl_files_packaged if any OpenGL files were packaged */ if (entry.caps.is_opengl) { opengl_files_packaged = TRUE; } /* some libs/symlinks have an arch field */ entry.compat_arch = FILE_COMPAT_ARCH_NONE; if (entry.caps.has_arch) { nvfree(flag); flag = read_next_word(c, &c); if (!flag) goto entry_done; if (strcmp(flag, "COMPAT32") == 0) entry.compat_arch = FILE_COMPAT_ARCH_COMPAT32; else if (strcmp(flag, "NATIVE") == 0) entry.compat_arch = FILE_COMPAT_ARCH_NATIVE; else { goto entry_done; } } /* if compat32 files are packaged, set compat32_files_packaged */ if (entry.compat_arch == FILE_COMPAT_ARCH_COMPAT32) { op->compat32_files_packaged = TRUE; } /* some libs/symlinks have a class field */ entry.tls_class = FILE_TLS_CLASS_NONE; if (entry.caps.has_tls_class) { nvfree(flag); flag = read_next_word(c, &c); if (!flag) goto entry_done; if (strcmp(flag, "CLASSIC") == 0) entry.tls_class = FILE_TLS_CLASS_CLASSIC; else if (strcmp(flag, "NEW") == 0) entry.tls_class = FILE_TLS_CLASS_NEW; else { goto entry_done; } } /* some file types have a path field, or inherit their paths */ if (entry.caps.has_path) { entry.path = read_next_word(c, &c); if (!entry.path) goto invalid_manifest_file; } else if (entry.caps.inherit_path) { int i; char *path, *depth, *slash; const char * const depth_marker = "INHERIT_PATH_DEPTH:"; depth = read_next_word(c, &c); if (!depth || strncmp(depth, depth_marker, strlen(depth_marker)) != 0) { goto invalid_manifest_file; } entry.inherit_path_depth = atoi(depth + strlen(depth_marker)); nvfree(depth); /* Remove the file component from the packaged filename */ path = entry.path = nvstrdup(entry.file); slash = strrchr(path, '/'); if (slash == NULL) { goto invalid_manifest_file; } slash[1] = '\0'; /* Strip leading directory components from the path */ for (i = 0; i < entry.inherit_path_depth; i++) { slash = strchr(entry.path, '/'); if (slash == NULL) { goto invalid_manifest_file; } entry.path = slash + 1; } entry.path = nvstrdup(entry.path); nvfree(path); } else { entry.path = NULL; } /* symlinks have a target */ if (entry.caps.is_symlink) { entry.target = read_next_word(c, &c); if (!entry.target) goto invalid_manifest_file; } else { entry.target = NULL; } /* * as a convenience for later, set the 'name' pointer to * the basename contained in 'file' (ie the portion of * 'file' without any leading directory components */ entry.name = strrchr(entry.file, '/'); if (entry.name) entry.name++; if (!entry.name) entry.name = entry.file; add_package_entry(p, entry.file, entry.path, entry.name, entry.target, entry.dst, entry.type, entry.tls_class, entry.compat_arch, entry.mode); entry_success = TRUE; entry_done: /* clean up */ nvfree(buf); nvfree(flag); if (!entry_success) { goto invalid_manifest_file; } } /* If no OpenGL files were packaged, we can't install them. Set the * no_opengl_files flag so that everything we skip when explicitly * excluding OpenGL is also skipped when OpenGL is not packaged. */ if (!opengl_files_packaged) { op->no_opengl_files = TRUE; } munmap(manifest, len); if (fd != -1) close(fd); return p; cannot_open: ui_error(op, "Failure opening package's .manifest file (%s).", strerror(errno)); goto fail; invalid_manifest_file: ui_error(op, "Invalid .manifest file; error on line %d.", line); goto fail; fail: free_package(p); if (manifest != MAP_FAILED) munmap(manifest, len); if (fd != -1) close(fd); return NULL; } /* parse_manifest() */