/* * Returns false on error * true on OK, with full_path set to where config file should be */ static bool find_config_file(const char *config_file, char *full_path, int max_path) { int file_length = strlen(config_file) + 1; /* If a full path specified, use it */ if (first_path_separator(config_file) != NULL) { if (file_length > max_path) { return false; } bstrncpy(full_path, config_file, file_length); return true; } /* config_file is default file name, now find default dir */ const char *config_dir = get_default_configdir(); int dir_length = strlen(config_dir); if ((dir_length + 1 + file_length) > max_path) { return false; } memcpy(full_path, config_dir, dir_length + 1); if (!IsPathSeparator(full_path[dir_length - 1])) { full_path[dir_length++] = '/'; } memcpy(&full_path[dir_length], config_file, file_length); return true; }
/* * Do a relative cwd -- i.e. relative to current node rather than root node */ TREE_NODE *tree_relcwd(char *path, TREE_ROOT *root, TREE_NODE *node) { char *p; int len; TREE_NODE *cd; char save_char; int match; if (*path == 0) { return node; } /* * Check the current segment only */ if ((p = first_path_separator(path)) != NULL) { len = p - path; } else { len = strlen(path); } Dmsg2(100, "tree_relcwd: len=%d path=%s\n", len, path); foreach_child(cd, node) { Dmsg1(100, "tree_relcwd: test cd=%s\n", cd->fname); if (cd->fname[0] == path[0] && len == (int)strlen(cd->fname) && bstrncmp(cd->fname, path, len)) { break; } /* * fnmatch has no len in call so we truncate the string */ save_char = path[len]; path[len] = 0; match = fnmatch(path, cd->fname, 0) == 0; path[len] = save_char; if (match) { break; } }
/* * find_my_exec -- find an absolute path to a valid executable * * argv0 is the name passed on the command line * retpath is the output area (must be of size MAXPGPATH) * Returns 0 if OK, -1 if error. * * The reason we have to work so hard to find an absolute path is that * on some platforms we can't do dynamic loading unless we know the * executable's location. Also, we need a full path not a relative * path because we will later change working directory. Finally, we want * a true path not a symlink location, so that we can locate other files * that are part of our installation relative to the executable. * * This function is not thread-safe because it calls validate_exec(), * which calls getgrgid(). This function should be used only in * non-threaded binaries, not in library routines. */ int find_my_exec(const char *argv0, char *retpath) { char cwd[MAXPGPATH], test_path[MAXPGPATH]; char *path; if (!getcwd(cwd, MAXPGPATH)) { log_error(_("could not identify current directory: %s"), strerror(errno)); return -1; } /* * If argv0 contains a separator, then PATH wasn't used. */ if (first_dir_separator(argv0) != NULL) { if (is_absolute_path(argv0)) StrNCpy(retpath, argv0, MAXPGPATH); else join_path_components(retpath, cwd, argv0); canonicalize_path(retpath); if (validate_exec(retpath) == 0) return resolve_symlinks(retpath); log_error(_("invalid binary \"%s\""), retpath); return -1; } #ifdef WIN32 /* Win32 checks the current directory first for names without slashes */ join_path_components(retpath, cwd, argv0); if (validate_exec(retpath) == 0) return resolve_symlinks(retpath); #endif /* * Since no explicit path was supplied, the user must have been relying on * PATH. We'll search the same PATH. */ if ((path = getenv("PATH")) && *path) { char *startp = NULL, *endp = NULL; do { if (!startp) startp = path; else startp = endp + 1; endp = first_path_separator(startp); if (!endp) endp = startp + strlen(startp); /* point to end */ StrNCpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH)); if (is_absolute_path(test_path)) join_path_components(retpath, test_path, argv0); else { join_path_components(retpath, cwd, test_path); join_path_components(retpath, retpath, argv0); } canonicalize_path(retpath); switch (validate_exec(retpath)) { case 0: /* found ok */ return resolve_symlinks(retpath); case -1: /* wasn't even a candidate, keep looking */ break; case -2: /* found but disqualified */ log_error(_("could not read binary \"%s\""), retpath); break; } } while (*endp); } log_error(_("could not find a \"%s\" to execute"), argv0); return -1; }
/* * mode is the mode bits to use in creating a new directory * * parent_mode are the parent's modes if we need to create parent * directories. * * owner and group are to set on any created dirs * * keep_dir_modes if set means don't change mode bits if dir exists */ bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode, uid_t owner, gid_t group, int keep_dir_modes) { struct stat statp; mode_t omask, tmode; char *path = (char *)apath; char *p; int len; bool ok = false; int created; char new_dir[5000]; int ndir = 0; int i = 0; int max_dirs = (int)sizeof(new_dir); JCR *jcr = attr->jcr; if (stat(path, &statp) == 0) { /* Does dir exist? */ if (!S_ISDIR(statp.st_mode)) { Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path); return false; } /* Full path exists */ if (keep_dir_modes) { return true; } set_own_mod(attr, path, owner, group, mode); return true; } omask = umask(0); umask(omask); len = strlen(apath); path = (char *)alloca(len+1); bstrncpy(path, apath, len+1); strip_trailing_slashes(path); /* * Now for one of the complexities. If we are not running as root, * then if the parent_mode does not have wx user perms, or we are * setting the userid or group, and the parent_mode has setuid, setgid, * or sticky bits, we must create the dir with open permissions, then * go back and patch all the dirs up with the correct perms. * Solution, set everything to 0777, then go back and reset them at the * end. */ tmode = 0777; #if defined(HAVE_WIN32) /* Validate drive letter */ if (path[1] == ':') { char drive[4] = "X:\\"; drive[0] = path[0]; UINT drive_type = GetDriveType(drive); if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) { Jmsg1(jcr, M_ERROR, 0, _("%c: is not a valid drive.\n"), path[0]); goto bail_out; } if (path[2] == '\0') { /* attempt to create a drive */ ok = true; goto bail_out; /* OK, it is already there */ } p = &path[3]; } else { p = path; } #else p = path; #endif /* Skip leading slash(es) */ while (IsPathSeparator(*p)) { p++; } while ((p = first_path_separator(p))) { char save_p; save_p = *p; *p = 0; if (!makedir(jcr, path, tmode, &created)) { goto bail_out; } if (ndir < max_dirs) { new_dir[ndir++] = created; } *p = save_p; while (IsPathSeparator(*p)) { p++; } } /* Create final component */ if (!makedir(jcr, path, tmode, &created)) { goto bail_out; } if (ndir < max_dirs) { new_dir[ndir++] = created; } if (ndir >= max_dirs) { Jmsg0(jcr, M_WARNING, 0, _("Too many subdirectories. Some permissions not reset.\n")); } /* Now set the proper owner and modes */ #if defined(HAVE_WIN32) /* Don't propagate the hidden or encrypted attributes to parent directories */ parent_mode &= ~S_ISVTX; parent_mode &= ~S_ISGID; if (path[1] == ':') { p = &path[3]; } else { p = path; } #else p = path; #endif /* Skip leading slash(es) */ while (IsPathSeparator(*p)) { p++; } while ((p = first_path_separator(p))) { char save_p; save_p = *p; *p = 0; if (i < ndir && new_dir[i++] && !keep_dir_modes) { set_own_mod(attr, path, owner, group, parent_mode); } *p = save_p; while (IsPathSeparator(*p)) { p++; } } /* Set for final component */ if (i < ndir && new_dir[i++]) { set_own_mod(attr, path, owner, group, mode); } ok = true; bail_out: umask(omask); return ok; }
/* * Returns false on error * true on OK, with full_path set to where config file should be */ static bool find_config_file(const char *config_file, char *full_path, int max_path) { int dir_length, file_length; const char *config_dir; #if defined(HAVE_SETENV) || defined(HAVE_PUTENV) char *bp; POOL_MEM env_string(PM_NAME); #endif /* * If a full path specified, use it */ file_length = strlen(config_file) + 1; if (first_path_separator(config_file) != NULL) { if (file_length > max_path) { return false; } bstrncpy(full_path, config_file, file_length); #ifdef HAVE_SETENV pm_strcpy(env_string, config_file); bp = (char *)last_path_separator(env_string.c_str()); *bp = '\0'; setenv("BAREOS_CFGDIR", env_string.c_str(), 1); #elif HAVE_PUTENV Mmsg(env_string, "BAREOS_CFGDIR=%s", config_file); bp = (char *)last_path_separator(env_string.c_str()); *bp = '\0'; putenv(bstrdup(env_string.c_str())); #endif return true; } /* * config_file is default file name, now find default dir */ config_dir = get_default_configdir(); dir_length = strlen(config_dir); if ((dir_length + 1 + file_length) > max_path) { return false; } #ifdef HAVE_SETENV pm_strcpy(env_string, config_dir); setenv("BAREOS_CFGDIR", env_string.c_str(), 1); #elif HAVE_PUTENV Mmsg(env_string, "BAREOS_CFGDIR=%s", config_dir); putenv(bstrdup(env_string.c_str())); #endif memcpy(full_path, config_dir, dir_length + 1); if (!IsPathSeparator(full_path[dir_length - 1])) { full_path[dir_length++] = '/'; } memcpy(full_path + dir_length, config_file, file_length); return true; }