int mktemp_main(int argc, char **argv) { unsigned long flags = getopt32(argc, argv, "dqt"); char *chp; if (optind + 1 != argc) bb_show_usage(); chp = argv[optind]; if (flags & 4) { char *dir = getenv("TMPDIR"); if (dir && *dir != '\0') chp = concat_path_file(dir, chp); else chp = concat_path_file("/tmp/", chp); } if (flags & 1) { if (mkdtemp(chp) == NULL) return EXIT_FAILURE; } else { if (mkstemp(chp) < 0) return EXIT_FAILURE; } puts(chp); return EXIT_SUCCESS; }
/* search (*PATHp) for an executable file; * return allocated string containing full path if found; * PATHp points to the component after the one where it was found * (or NULL), * you may call find_executable again with this PATHp to continue * (if it's not NULL). * return NULL otherwise; (PATHp is undefined) * in all cases (*PATHp) contents will be trashed (s/:/NUL/). */ char* FAST_FUNC find_executable(const char *filename, char **PATHp) { /* About empty components in $PATH: * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html * 8.3 Other Environment Variables - PATH * A zero-length prefix is a legacy feature that indicates the current * working directory. It appears as two adjacent colons ( "::" ), as an * initial colon preceding the rest of the list, or as a trailing colon * following the rest of the list. */ char *p, *n; p = *PATHp; while (p) { n = strchr(p, ':'); if (n) *n++ = '\0'; p = concat_path_file( p[0] ? p : ".", /* handle "::" case */ filename ); if (file_is_executable(p)) { *PATHp = n; return p; } free(p); p = n; } /* on loop exit p == NULL */ return p; }
static struct dump_dir *try_dd_create(const char *base_dir_name, const char *dir_name, uid_t uid) { char *path = concat_path_file(base_dir_name, dir_name); struct dump_dir *dd = dd_create(path, uid, DEFAULT_DUMP_DIR_MODE); free(path); return dd; }
int save_abrt_plugin_conf_file(const char *file, map_string_t *settings) { char *path = concat_path_file(PLUGINS_CONF_DIR, file); int retval = save_conf_file(path, settings); free(path); return retval; }
double get_dirsize(const char *pPath) { DIR *dp = opendir(pPath); if (dp == NULL) return 0; struct dirent *ep; struct stat statbuf; double size = 0; while ((ep = readdir(dp)) != NULL) { if (dot_or_dotdot(ep->d_name)) continue; char *dname = concat_path_file(pPath, ep->d_name); if (lstat(dname, &statbuf) != 0) { goto next; } if (S_ISDIR(statbuf.st_mode)) { size += get_dirsize(dname); } else if (S_ISREG(statbuf.st_mode)) { size += statbuf.st_size; } next: free(dname); } closedir(dp); return size; }
int who_main(int argc, char **argv) { char str6[6]; struct utmp *ut; struct stat st; char *name; if (argc > 1) { bb_show_usage(); } setutent(); printf("USER TTY IDLE TIME HOST\n"); while ((ut = getutent()) != NULL) { if (ut->ut_user[0] && ut->ut_type == USER_PROCESS) { time_t thyme = ut->ut_tv.tv_sec; /* ut->ut_line is device name of tty - "/dev/" */ name = concat_path_file("/dev", ut->ut_line); str6[0] = '?'; str6[1] = '\0'; if (stat(name, &st) == 0) idle_string(str6, st.st_atime); printf("%-10s %-8s %-9s %-14.14s %s\n", ut->ut_user, ut->ut_line, str6, ctime(&thyme) + 4, ut->ut_host); if (ENABLE_FEATURE_CLEAN_UP) free(name); } } if (ENABLE_FEATURE_CLEAN_UP) endutent(); return 0; }
// Recursively delete contents of rootfs. static void delete_contents(const char *directory, dev_t rootdev) { DIR *dir; struct dirent *d; struct stat st; // Don't descend into other filesystems if (lstat(directory, &st) || st.st_dev != rootdev) return; // Recursively delete the contents of directories. if (S_ISDIR(st.st_mode)) { dir = opendir(directory); if (dir) { while ((d = readdir(dir))) { char *newdir = d->d_name; // Skip . and .. if (DOT_OR_DOTDOT(newdir)) continue; // Recurse to delete contents newdir = concat_path_file(directory, newdir); delete_contents(newdir, rootdev); free(newdir); } closedir(dir); // Directory should now be empty. Zap it. rmdir(directory); } // It wasn't a directory. Zap it. } else unlink(directory); }
int dd_exist(const struct dump_dir *dd, const char *path) { char *full_path = concat_path_file(dd->dd_dirname, path); int ret = exist_file_dir(full_path); free(full_path); return ret; }
int wall_main(int argc UNUSED_PARAM, char **argv) { struct utmpx *ut; char *msg; int fd; fd = STDIN_FILENO; if (argv[1]) { /* The applet is setuid. * Access to the file must be under user's uid/gid. */ fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid()); } msg = xmalloc_read(fd, NULL); if (ENABLE_FEATURE_CLEAN_UP && argv[1]) close(fd); setutxent(); while ((ut = getutxent()) != NULL) { char *line; if (ut->ut_type != USER_PROCESS) continue; line = concat_path_file("/dev", ut->ut_line); xopen_xwrite_close(line, msg); free(line); } if (ENABLE_FEATURE_CLEAN_UP) { endutxent(); free(msg); } return EXIT_SUCCESS; }
static double get_dir_size(const char *dirname, char **worst_file, double *worst_file_size) { DIR *dp = opendir(dirname); if (!dp) return 0; /* "now" is used only if caller wants to know worst_file */ time_t now = worst_file ? time(NULL) : 0; struct dirent *dent; struct stat stats; double size = 0; while ((dent = readdir(dp)) != NULL) { if (dot_or_dotdot(dent->d_name)) continue; char *fullname = concat_path_file(dirname, dent->d_name); if (lstat(fullname, &stats) != 0) { free(fullname); continue; } if (S_ISDIR(stats.st_mode)) { double sz = get_dir_size(fullname, worst_file, worst_file_size); size += sz; } else if (S_ISREG(stats.st_mode)) { double sz = stats.st_size; size += sz; if (worst_file) { /* Calculate "weighted" size and age * w = sz_kbytes * age_mins */ sz /= 1024; long age = (now - stats.st_mtime) / 60; if (age > 0) sz *= age; if (sz > *worst_file_size) { *worst_file_size = sz; free(*worst_file); *worst_file = fullname; fullname = NULL; } } } free(fullname); } closedir(dp); return size; }
int mktemp_main(int argc UNUSED_PARAM, char **argv) { const char *path; char *chp; unsigned opts; enum { OPT_d = 1 << 0, OPT_q = 1 << 1, OPT_t = 1 << 2, OPT_p = 1 << 3, OPT_u = 1 << 4, }; path = getenv("TMPDIR"); if (!path || path[0] == '\0') path = "/tmp"; opt_complementary = "?1"; /* 1 argument max */ opts = getopt32(argv, "dqtp:u", &path); chp = argv[optind]; if (!chp) { /* GNU coreutils 8.4: * bare "mktemp" -> "mktemp -t tmp.XXXXXX" */ chp = xstrdup("tmp.XXXXXX"); opts |= OPT_t; } #if 0 /* Don't allow directory separator in template */ if ((opts & OPT_t) && bb_basename(chp) != chp) { errno = EINVAL; goto error; } #endif if (opts & (OPT_t|OPT_p)) chp = concat_path_file(path, chp); if (opts & OPT_u) { chp = mktemp(chp); if (chp[0] == '\0') goto error; } else if (opts & OPT_d) { if (mkdtemp(chp) == NULL) goto error; } else { if (mkstemp(chp) < 0) goto error; } puts(chp); return EXIT_SUCCESS; error: if (opts & OPT_q) return EXIT_FAILURE; /* don't use chp as it gets mangled in case of error */ bb_perror_nomsg_and_die(); }
/* The function expects that FILENAME_COUNT dump dir element is created by * abrtd after all post-create events are successfully done. Thus if * FILENAME_COUNT element doesn't exist abrtd can consider the dump directory * as unprocessed. * * Relying on content of dump directory has one problem. If a hook provides * FILENAME_COUNT abrtd will consider the dump directory as processed. */ static void mark_unprocessed_dump_dirs_not_reportable(const char *path) { log_notice("Searching for unprocessed dump directories"); DIR *dp = opendir(path); if (!dp) { perror_msg("Can't open directory '%s'", path); return; } struct dirent *dent; while ((dent = readdir(dp)) != NULL) { if (dot_or_dotdot(dent->d_name)) continue; /* skip "." and ".." */ char *full_name = concat_path_file(path, dent->d_name); struct stat stat_buf; if (stat(full_name, &stat_buf) != 0) { perror_msg("Can't access path '%s'", full_name); goto next_dd; } if (S_ISDIR(stat_buf.st_mode) == 0) /* This is expected. The dump location contains some aux files */ goto next_dd; struct dump_dir *dd = dd_opendir(full_name, /*flags*/0); if (dd) { if (!problem_dump_dir_is_complete(dd) && !dd_exist(dd, FILENAME_NOT_REPORTABLE)) { log_warning("Marking '%s' not reportable (no '"FILENAME_COUNT"' item)", full_name); dd_save_text(dd, FILENAME_NOT_REPORTABLE, _("The problem data are " "incomplete. This usually happens when a problem " "is detected while computer is shutting down or " "user is logging out. In order to provide " "valuable problem reports, ABRT will not allow " "you to submit this problem. If you have time and " "want to help the developers in their effort to " "sort out this problem, please contact them directly.")); } dd_close(dd); } next_dd: free(full_name); } closedir(dp); }
static void set_settings(struct bugzilla_struct *b, map_string_t *settings) { const char *environ; environ = getenv("Bugzilla_Login"); b->b_login = xstrdup(environ ? environ : get_map_string_item_or_empty(settings, "Login")); environ = getenv("Bugzilla_Password"); b->b_password = xstrdup(environ ? environ : get_map_string_item_or_empty(settings, "Password")); environ = getenv("Bugzilla_BugzillaURL"); b->b_bugzilla_url = environ ? environ : get_map_string_item_or_empty(settings, "BugzillaURL"); if (!b->b_bugzilla_url[0]) b->b_bugzilla_url = "https://bugzilla.redhat.com"; else { /* We don't want trailing '/': "https://host/dir/" -> "https://host/dir" */ char *last_slash = strrchr(b->b_bugzilla_url, '/'); if (last_slash && last_slash[1] == '\0') *last_slash = '\0'; } b->b_bugzilla_xmlrpc = concat_path_file(b->b_bugzilla_url, "xmlrpc.cgi"); environ = getenv("Bugzilla_Product"); if (environ) { b->b_product = xstrdup(environ); environ = getenv("Bugzilla_ProductVersion"); if (environ) b->b_product_version = xstrdup(environ); } else { const char *option = get_map_string_item_or_NULL(settings, "Product"); if (option) b->b_product = xstrdup(option); option = get_map_string_item_or_NULL(settings, "ProductVersion"); if (option) b->b_product_version = xstrdup(option); } if (!b->b_product) { /* Compat, remove it later (2014?). */ environ = getenv("Bugzilla_OSRelease"); if (environ) parse_release_for_bz(environ, &b->b_product, &b->b_product_version); } environ = getenv("Bugzilla_SSLVerify"); b->b_ssl_verify = string_to_bool(environ ? environ : get_map_string_item_or_empty(settings, "SSLVerify")); environ = getenv("Bugzilla_DontMatchComponents"); b->b_DontMatchComponents = environ ? environ : get_map_string_item_or_empty(settings, "DontMatchComponents"); }
void dump_lxc_info(struct dump_dir *dd, const char *lxc_cmd) { if (!dd_exist(dd, FILENAME_CONTAINER)) dd_save_text(dd, FILENAME_CONTAINER, "lxc"); char *mntnf_path = concat_path_file(dd->dd_dirname, FILENAME_MOUNTINFO); FILE *mntnf_file = fopen(mntnf_path, "r"); free(mntnf_path); struct mountinfo mntnf; int r = get_mountinfo_for_mount_point(mntnf_file, &mntnf, "/"); fclose(mntnf_file); if (r != 0) { error_msg("lxc processes must have re-mounted root"); goto dump_lxc_info_cleanup; } const char *mnt_root = MOUNTINFO_ROOT(mntnf); const char *last_slash = strrchr(mnt_root, '/'); if (last_slash == NULL || (strcmp("rootfs", last_slash +1) != 0)) { error_msg("Invalid root path '%s'", mnt_root); goto dump_lxc_info_cleanup; } if (last_slash == mnt_root) { error_msg("root path misses container id: '%s'", mnt_root); goto dump_lxc_info_cleanup; } const char *tmp = strrchr(last_slash - 1, '/'); if (tmp == NULL) { error_msg("root path misses first /: '%s'", mnt_root); goto dump_lxc_info_cleanup; } char *container_id = xstrndup(tmp + 1, (last_slash - tmp) - 1); dd_save_text(dd, FILENAME_CONTAINER_ID, container_id); dd_save_text(dd, FILENAME_CONTAINER_UUID, container_id); free(container_id); /* TODO: make a copy of 'config' */ /* get mount point for MOUNTINFO_MOUNT_SOURCE(mntnf) + MOUNTINFO_ROOT(mntnf) */ dump_lxc_info_cleanup: mountinfo_destroy(&mntnf); }
/** * @param[in] argc Argument count from command line * @param[in] argv List of input arguments */ static int do_cp(int argc, char *argv[]) { int ret = 1; struct stat statbuf; int last_is_dir = 0; int i; int opt; int verbose = 0; int argc_min; while ((opt = getopt(argc, argv, "v")) > 0) { switch (opt) { case 'v': verbose = 1; break; } } argc_min = optind + 2; if (argc < argc_min) return COMMAND_ERROR_USAGE; if (!stat(argv[argc - 1], &statbuf)) { if (S_ISDIR(statbuf.st_mode)) last_is_dir = 1; } if (argc > argc_min && !last_is_dir) { printf("cp: target `%s' is not a directory\n", argv[argc - 1]); return 1; } for (i = optind; i < argc - 1; i++) { if (last_is_dir) { char *dst; dst = concat_path_file(argv[argc - 1], basename(argv[i])); ret = copy_file(argv[i], dst, verbose); free(dst); if (ret) goto out; } else { ret = copy_file(argv[i], argv[argc - 1], verbose); if (ret) goto out; } } ret = 0; out: return ret; }
extern int which_main(int argc, char **argv) { char *path_list, *path_n; int i, count=1, found, status = EXIT_SUCCESS; if (argc <= 1 || **(argv + 1) == '-') bb_show_usage(); argc--; path_list = getenv("PATH"); if (path_list != NULL) { for(i=strlen(path_list); i > 0; i--) if (path_list[i]==':') { path_list[i]=0; count++; } } else { path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin"; count = 5; } while(argc-- > 0) { char *buf; path_n = path_list; argv++; found = 0; /* * Check if we were given the full path, first. * Otherwise see if the file exists in our $PATH. */ buf = *argv; if (file_exists(buf)) { puts(buf); found = 1; } else { for (i = 0; i < count; i++) { buf = concat_path_file(path_n, *argv); if (file_exists(buf)) { puts(buf); found = 1; break; } free(buf); path_n += (strlen(path_n) + 1); } } if (!found) status = EXIT_FAILURE; } return status; }
static char *get_user_config_file_path(const char *name, const char *suffix) { char *s, *conf; if (suffix != NULL) s = xasprintf(BASE_DIR_FOR_USER_CONFIG_FILE"%s.%s", name, suffix); else s = xasprintf(BASE_DIR_FOR_USER_CONFIG_FILE"%s", name); conf = concat_path_file(g_get_user_config_dir(), s); free(s); return conf; }
/* * Read a sysctl setting */ static int sysctl_read_setting(const char *name) { int retval; char *tmpname, *outname, *cptr; char inbuf[1025]; FILE *fp; if (!*name) { if (option_mask32 & FLAG_SHOW_KEY_ERRORS) bb_error_msg(ERR_INVALID_KEY, name); return -1; } tmpname = concat_path_file(PROC_SYS, name); outname = xstrdup(tmpname + strlen_PROC_SYS); while ((cptr = strchr(tmpname, '.')) != NULL) *cptr = '/'; while ((cptr = strchr(outname, '/')) != NULL) *cptr = '.'; fp = fopen(tmpname, "r"); if (fp == NULL) { switch (errno) { case ENOENT: if (option_mask32 & FLAG_SHOW_KEY_ERRORS) bb_error_msg(ERR_INVALID_KEY, outname); break; case EACCES: bb_error_msg(ERR_PERMISSION_DENIED, outname); break; default: bb_perror_msg(ERR_UNKNOWN_READING, outname); break; } retval = EXIT_FAILURE; } else { while (fgets(inbuf, sizeof(inbuf) - 1, fp)) { if (option_mask32 & FLAG_SHOW_KEYS) { printf("%s = ", outname); } fputs(inbuf, stdout); } fclose(fp); retval = EXIT_SUCCESS; } free(tmpname); free(outname); return retval; } /* end sysctl_read_setting() */
/* * Read a sysctl setting * */ int sysctl_read_setting(const char *setting, int output) { int retval = 0; char *tmpname, *outname, *cptr; char inbuf[1025]; const char *name = setting; FILE *fp; if (!setting || !*setting) bb_error_msg(ERR_INVALID_KEY, setting); tmpname = concat_path_file(PROC_PATH, name); outname = xstrdup(tmpname + strlen(PROC_PATH)); while ((cptr = strchr(tmpname, '.')) != NULL) *cptr = '/'; while ((cptr = strchr(outname, '/')) != NULL) *cptr = '.'; if ((fp = fopen(tmpname, "r")) == NULL) { switch (errno) { case ENOENT: bb_error_msg(ERR_INVALID_KEY, outname); break; case EACCES: bb_error_msg(ERR_PERMISSION_DENIED, outname); break; default: bb_error_msg(ERR_UNKNOWN_READING, errno, outname); break; } retval = -1; } else { while (fgets(inbuf, sizeof(inbuf) - 1, fp)) { if (output) { dwrite_str(STDOUT_FILENO, outname); dwrite_str(STDOUT_FILENO, " = "); } dwrite_str(STDOUT_FILENO, inbuf); } fclose(fp); } free(tmpname); free(outname); return retval; } /* end sysctl_read_setting() */
extern char *find_real_root_device_name(const char* name) { DIR *dir; struct dirent *entry; struct stat statBuf, rootStat; char *fileName = NULL; dev_t dev; if (stat("/", &rootStat) != 0) bb_perror_msg("could not stat '/'"); else { /* This check is here in case they pass in /dev name */ if ((rootStat.st_mode & S_IFMT) == S_IFBLK) dev = rootStat.st_rdev; else dev = rootStat.st_dev; dir = opendir("/dev"); if (!dir) bb_perror_msg("could not open '/dev'"); else { while((entry = readdir(dir)) != NULL) { const char *myname = entry->d_name; /* Must skip ".." since that is "/", and so we * would get a false positive on ".." */ if (myname[0] == '.' && myname[1] == '.' && !myname[2]) continue; fileName = concat_path_file("/dev", myname); /* Some char devices have the same dev_t as block * devices, so make sure this is a block device */ if (stat(fileName, &statBuf) == 0 && S_ISBLK(statBuf.st_mode)!=0 && statBuf.st_rdev == dev) break; free(fileName); fileName=NULL; } closedir(dir); } } if(fileName==NULL) fileName = bb_xstrdup("/dev/root"); return fileName; }
int nohup_main(int argc UNUSED_PARAM, char **argv) { const char *nohupout; char *home; xfunc_error_retval = 127; if (!argv[1]) { bb_show_usage(); } /* If stdin is a tty, detach from it. */ if (isatty(STDIN_FILENO)) { /* bb_error_msg("ignoring input"); */ close(STDIN_FILENO); xopen(bb_dev_null, O_RDONLY); /* will be fd 0 (STDIN_FILENO) */ } nohupout = "nohup.out"; /* Redirect stdout to nohup.out, either in "." or in "$HOME". */ if (isatty(STDOUT_FILENO)) { close(STDOUT_FILENO); if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) { home = getenv("HOME"); if (home) { nohupout = concat_path_file(home, nohupout); xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR); } else { xopen(bb_dev_null, O_RDONLY); /* will be fd 1 */ } } bb_error_msg("appending output to %s", nohupout); } /* If we have a tty on stderr, redirect to stdout. */ if (isatty(STDERR_FILENO)) { /* if (stdout_wasnt_a_tty) bb_error_msg("redirecting stderr to stdout"); */ dup2(STDOUT_FILENO, STDERR_FILENO); } signal(SIGHUP, SIG_IGN); BB_EXECVP(argv[1], argv+1); bb_simple_perror_msg_and_die(argv[1]); }
int nohup_main(int argc, char **argv) { int nullfd; const char *nohupout; char *home = NULL; xfunc_error_retval = 127; if (argc < 2) bb_show_usage(); nullfd = xopen(bb_dev_null, O_WRONLY|O_APPEND); /* If stdin is a tty, detach from it. */ if (isatty(STDIN_FILENO)) dup2(nullfd, STDIN_FILENO); nohupout = "nohup.out"; /* Redirect stdout to nohup.out, either in "." or in "$HOME". */ if (isatty(STDOUT_FILENO)) { close(STDOUT_FILENO); if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) { home = getenv("HOME"); if (home) { nohupout = concat_path_file(home, nohupout); xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR); } } } else dup2(nullfd, STDOUT_FILENO); /* If we have a tty on stderr, announce filename and redirect to stdout. * Else redirect to /dev/null. */ if (isatty(STDERR_FILENO)) { bb_error_msg("appending to %s", nohupout); dup2(STDOUT_FILENO, STDERR_FILENO); } else dup2(nullfd, STDERR_FILENO); if (nullfd > 2) close(nullfd); signal(SIGHUP, SIG_IGN); BB_EXECVP(argv[1], argv+1); if (ENABLE_FEATURE_CLEAN_UP && home) free((char*)nohupout); bb_simple_perror_msg_and_die(argv[1]); }
int nohup_main(int argc, char *argv[]) { int temp, nullfd; char *nohupout = "nohup.out", *home = NULL; // I have no idea why the standard cares about this. bb_default_error_retval = 127; if (argc<2) bb_show_usage(); nullfd = bb_xopen(bb_dev_null, O_WRONLY|O_APPEND); // If stdin is a tty, detach from it. if (isatty(0)) dup2(nullfd, 0); // Redirect stdout to nohup.out, either in "." or in "$HOME". if (isatty(1)) { close(1); if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) { home = getenv("HOME"); if (home) { home = concat_path_file(home, nohupout); bb_xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR); } } } else dup2(nullfd, 1); // If we have a tty on strderr, announce filename and redirect to stdout. // Else redirect to /dev/null. temp = isatty(2); if (temp) fdprintf(2,"Writing to %s\n", home ? home : nohupout); dup2(temp ? 1 : nullfd, 2); close(nullfd); signal (SIGHUP, SIG_IGN); // Exec our new program. execvp(argv[1],argv+1); if (ENABLE_FEATURE_CLEAN_UP) free(home); bb_error_msg_and_die("exec %s",argv[1]); }
extern int which_main(int argc, char **argv) { char *path_list, *path_n; struct stat filestat; int i, count=1, found, status = EXIT_SUCCESS; if (argc <= 1 || **(argv + 1) == '-') show_usage(); argc--; path_list = getenv("PATH"); if (path_list != NULL) { for(i=strlen(path_list); i > 0; i--) if (path_list[i]==':') { path_list[i]=0; count++; } } else { path_list = "/bin\0/sbin\0/usr/bin\0/usr/sbin\0/usr/local/bin"; count = 5; } while(argc-- > 0) { path_n = path_list; argv++; found = 0; for (i = 0; i < count; i++) { char *buf; buf = concat_path_file(path_n, *argv); if (stat (buf, &filestat) == 0 && filestat.st_mode & S_IXUSR) { puts(buf); found = 1; break; } free(buf); path_n += (strlen(path_n) + 1); } if (!found) status = EXIT_FAILURE; } return status; }
extern char *find_real_root_device_name(const char* name) { DIR *dir; struct dirent *entry; struct stat statBuf, rootStat; char *fileName = NULL; dev_t dev; if (stat("/", &rootStat) != 0) perror_msg("could not stat '/'"); else { if ((dev = rootStat.st_rdev)==0) dev=rootStat.st_dev; dir = opendir("/dev"); if (!dir) perror_msg("could not open '/dev'"); else { while((entry = readdir(dir)) != NULL) { /* Must skip ".." since that is "/", and so we * would get a false positive on ".." */ if (strcmp(entry->d_name, "..") == 0) continue; fileName = concat_path_file("/dev", entry->d_name); /* Some char devices have the same dev_t as block * devices, so make sure this is a block device */ if (stat(fileName, &statBuf) == 0 && S_ISBLK(statBuf.st_mode)!=0 && statBuf.st_rdev == dev) break; free(fileName); fileName=NULL; } closedir(dir); } } if(fileName==NULL) fileName=xstrdup("/dev/root"); return fileName; }
char *bb_simplify_path(const char *path) { char *s, *start, *p; if (path[0] == '/') start = xstrdup(path); else { s = xrealloc_getcwd_or_warn(NULL); start = concat_path_file(s, path); free(s); } p = s = start; do { if (*p == '/') { if (*s == '/') { /* skip duplicate (or initial) slash */ continue; } if (*s == '.') { if (s[1] == '/' || !s[1]) { /* remove extra '.' */ continue; } if ((s[1] == '.') && (s[2] == '/' || !s[2])) { ++s; if (p > start) { while (*--p != '/') /* omit previous dir */ continue; } continue; } } } *++p = *s; } while (*++s); if ((p == start) || (*p != '/')) { /* not a trailing slash */ ++p; /* so keep last character */ } *p = 0; return start; }
/* Builds an alias path. * This function potentionally reallocates the alias parameter. * Only used for ENABLE_FEATURE_MDEV_RENAME */ static char *build_alias(char *alias, const char *device_name) { char *dest; /* ">bar/": rename to bar/device_name */ /* ">bar[/]baz": rename to bar[/]baz */ dest = strrchr(alias, '/'); if (dest) { /* ">bar/[baz]" ? */ *dest = '\0'; /* mkdir bar */ bb_make_directory(alias, 0755, FILEUTILS_RECUR); *dest = '/'; if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */ dest = alias; alias = concat_path_file(alias, device_name); free(dest); } } return alias; }
static void save_bt_to_dump_dir(const char *bt, const char *exe, const char *reason) { time_t t = time(NULL); const char *iso_date = iso_date_string(&t); pid_t my_pid = getpid(); char base[sizeof("xorg-YYYY-MM-DD-hh:mm:ss-%lu-%lu") + 2 * sizeof(long)*3]; sprintf(base, "xorg-%s-%lu-%u", iso_date, (long)my_pid, g_bt_count); char *path = concat_path_file(debug_dumps_dir, base); struct dump_dir *dd = dd_create(path, /*fs owner*/0, DEFAULT_DUMP_DIR_MODE); if (dd) { dd_create_basic_files(dd, /*no uid*/(uid_t)-1L, NULL); dd_save_text(dd, FILENAME_ABRT_VERSION, VERSION); dd_save_text(dd, FILENAME_ANALYZER, "abrt-xorg"); dd_save_text(dd, FILENAME_TYPE, "xorg"); dd_save_text(dd, FILENAME_REASON, reason); dd_save_text(dd, FILENAME_BACKTRACE, bt); /* * Reporters usually need component name to file a bug. * It is usually derived from executable. * We _guess_ X server's executable name as a last resort. * Better ideas? */ if (!exe) { exe = "/usr/bin/X"; if (access("/usr/bin/Xorg", X_OK) == 0) exe = "/usr/bin/Xorg"; } dd_save_text(dd, FILENAME_EXECUTABLE, exe); if (!(g_opts & OPT_x)) dd_set_no_owner(dd); dd_close(dd); notify_new_path(path); } free(path); }
/* create (sym)links for each applet */ static void install_links(const char *busybox, int use_symbolic_links) { __link_f Link = link; char *fpc; int i; int rc; if (use_symbolic_links) Link = symlink; for (i = 0; applets[i].name != NULL; i++) { fpc = concat_path_file( install_dir[applets[i].location], applets[i].name); rc = Link(busybox, fpc); if (rc!=0 && errno!=EEXIST) { perror_msg("%s", fpc); } free(fpc); } }
/* search (*PATHp) for an executable file; * return allocated string containing full path if found; * PATHp points to the component after the one where it was found * (or NULL), * you may call find_execable again with this PATHp to continue * (if it's not NULL). * return NULL otherwise; (PATHp is undefined) * in all cases (*PATHp) contents will be trashed (s/:/NUL/). */ char* FAST_FUNC find_execable(const char *filename, char **PATHp) { char *p, *n; p = *PATHp; while (p) { n = strchr(p, ':'); if (n) *n++ = '\0'; if (*p != '\0') { /* it's not a PATH="foo::bar" situation */ p = concat_path_file(p, filename); if (execable_file(p)) { *PATHp = n; return p; } free(p); } p = n; } /* on loop exit p == NULL */ return p; }