static int mkdirpath (char *filename, void (*report) (const char *, ...)) { char *slash = strrchr (filename, '/'); char strbuf[ISC_STRERRORSIZE]; unsigned int mode; if (slash != NULL && slash != filename) { struct stat sb; *slash = '\0'; if (stat (filename, &sb) == -1) { if (errno != ENOENT) { isc__strerror (errno, strbuf, sizeof (strbuf)); (*report) ("couldn't stat '%s': %s", filename, strbuf); goto error; } if (mkdirpath (filename, report) == -1) goto error; /* * Handle "//", "/./" and "/../" in path. */ if (!strcmp (slash + 1, "") || !strcmp (slash + 1, ".") || !strcmp (slash + 1, "..")) { *slash = '/'; return (0); } mode = S_IRUSR | S_IWUSR | S_IXUSR; /* u=rwx */ mode |= S_IRGRP | S_IXGRP; /* g=rx */ mode |= S_IROTH | S_IXOTH; /* o=rx */ if (mkdir (filename, mode) == -1) { isc__strerror (errno, strbuf, sizeof (strbuf)); (*report) ("couldn't mkdir '%s': %s", filename, strbuf); goto error; } if (runas_pw != NULL && chown (filename, runas_pw->pw_uid, runas_pw->pw_gid) == -1) { isc__strerror (errno, strbuf, sizeof (strbuf)); (*report) ("couldn't chown '%s': %s", filename, strbuf); } } *slash = '/'; } return (0); error: *slash = '/'; return (-1); }
isc_boolean_t ns_os_issingleton(const char *filename) { char strbuf[ISC_STRERRORSIZE]; struct flock lock; if (singletonfd != -1) return (ISC_TRUE); if (strcasecmp(filename, "none") == 0) return (ISC_TRUE); /* * Make the containing directory if it doesn't exist. */ lockfile = strdup(filename); if (lockfile == NULL) { isc__strerror(errno, strbuf, sizeof(strbuf)); ns_main_earlyfatal("couldn't allocate memory for '%s': %s", filename, strbuf); } else { int ret = mkdirpath(lockfile, ns_main_earlywarning); if (ret == -1) { ns_main_earlywarning("couldn't create '%s'", filename); cleanup_lockfile(); return (ISC_FALSE); } } /* * ns_os_openfile() uses safeopen() which removes any existing * files. We can't use that here. */ singletonfd = open(filename, O_WRONLY | O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (singletonfd == -1) { cleanup_lockfile(); return (ISC_FALSE); } memset(&lock, 0, sizeof(lock)); lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 1; /* Non-blocking (does not wait for lock) */ if (fcntl(singletonfd, F_SETLK, &lock) == -1) { close(singletonfd); singletonfd = -1; return (ISC_FALSE); } return (ISC_TRUE); }
FILE * ns_os_openfile(const char *filename, mode_t mode, isc_boolean_t switch_user) { char strbuf[ISC_STRERRORSIZE], *f; FILE *fp; int fd; /* * Make the containing directory if it doesn't exist. */ f = strdup(filename); if (f == NULL) { isc__strerror(errno, strbuf, sizeof(strbuf)); ns_main_earlywarning("couldn't strdup() '%s': %s", filename, strbuf); return (NULL); } if (mkdirpath(f, ns_main_earlywarning) == -1) { free(f); return (NULL); } free(f); if (switch_user && runas_pw != NULL) { #ifndef HAVE_LINUXTHREADS gid_t oldgid = getgid(); #endif /* Set UID/GID to the one we'll be running with eventually */ setperms(runas_pw->pw_uid, runas_pw->pw_gid); fd = safe_open(filename, mode, ISC_FALSE); #ifndef HAVE_LINUXTHREADS /* Restore UID/GID to root */ setperms(0, oldgid); #endif /* HAVE_LINUXTHREADS */ if (fd == -1) { #ifndef HAVE_LINUXTHREADS fd = safe_open(filename, mode, ISC_FALSE); if (fd != -1) { ns_main_earlywarning("Required root " "permissions to open " "'%s'.", filename); } else { ns_main_earlywarning("Could not open " "'%s'.", filename); } ns_main_earlywarning("Please check file and " "directory permissions " "or reconfigure the filename."); #else /* HAVE_LINUXTHREADS */ ns_main_earlywarning("Could not open " "'%s'.", filename); ns_main_earlywarning("Please check file and " "directory permissions " "or reconfigure the filename."); #endif /* HAVE_LINUXTHREADS */ } } else { fd = safe_open(filename, mode, ISC_FALSE); } if (fd < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); ns_main_earlywarning("could not open file '%s': %s", filename, strbuf); return (NULL); } fp = fdopen(fd, "w"); if (fp == NULL) { isc__strerror(errno, strbuf, sizeof(strbuf)); ns_main_earlywarning("could not fdopen() file '%s': %s", filename, strbuf); } return (fp); }
int main(int argc, char **argv) { int ch; int layout = 0; /* handle command line options */ opt_list = 0; opt_verbose = 0; opt_skip = 0; while ((ch = getopt(argc, argv, "l:tsvVh?")) > 0) { switch (ch) { case 'l': if (optarg[0] < '0' || optarg[0] > '0' + max_layout || optarg[1] != '\0') usage(); layout = optarg[0] - '0'; break; case 't': opt_list = 1; break; case 'v': opt_verbose = 1; break; case 's': opt_skip = 1; break; case 'V': printf("V%s\n", VERSION); exit(0); break; case 'h': case '?': default: usage(); break; } } /* extract rest of command line parameters */ if ((argc - optind) < 1 || (argc - optind) > 2) usage(); if (strcmp(argv[optind], "-") == 0) { /* image file from stdin ? */ img_file = 0; } else { img_file = open(argv[optind], O_RDONLY); if (img_file < 0) prt_err(1, errno, "Open image file failed"); } if (layout == 0) { detect_chunk_size(); } else { chunk_size = possible_layouts[layout-1].chunk_size; spare_size = possible_layouts[layout-1].spare_size; } spare_data = data + chunk_size; // Skip first chunk if (opt_skip) lseek(img_file, chunk_size+spare_size, SEEK_SET); if ((argc - optind) == 2 && !opt_list) { if (mkdirpath(argv[optind+1]) < 0) prt_err(1, errno, "Can't mkdir %s", argv[optind+1]); if (chdir(argv[optind+1]) < 0) prt_err(1, errno, "Can't chdir to %s", argv[optind+1]); } umask(0); init_obj_list(); while (read_chunk()) { process_chunk(); } set_dirs_utime(); close(img_file); return 0; }
int main(int argc, char **argv) { int ch; char *ep; int opt_detect; int opt_bad; int opt_chunk; int opt_spare; /* handle command line options */ opt_detect = 0; opt_bad = 0; opt_chunk = 0; opt_spare = 0; opt_list = 0; opt_verbose = 0; while ((ch = getopt(argc, argv, "dbc:s:tvVh?")) > 0) { switch (ch) { case 'd': opt_detect = 1; break; case 'b': opt_bad = 1; break; case 'c': opt_chunk = strtol(optarg, &ep, 0); if (*ep != '\0' || opt_chunk < 0 || opt_chunk > (MAX_CHUNK_SIZE / 1024) ) usage(); break; case 's': opt_spare = strtol(optarg, &ep, 0); if (*ep != '\0' || opt_spare < 0 || opt_spare > MAX_SPARE_SIZE) usage(); break; case 't': opt_list = 1; break; case 'v': opt_verbose = 1; break; case 'V': printf("V%s\n", VERSION); exit(0); break; case 'h': case '?': default: usage(); break; } } /* extract rest of command line parameters */ if ((argc - optind) < 1 || (argc - optind) > 2) usage(); if (strcmp(argv[optind], "-") == 0) { /* image file from stdin ? */ img_file = 0; } else { img_file = open(argv[optind], O_RDONLY); if (img_file < 0) prt_err(1, errno, "Open image file failed"); } if (opt_detect) { detect_flash_layout(1, 0); return 0; } if (opt_chunk == 0 || opt_spare == 0) { detect_flash_layout(0, 1); if (opt_verbose) prt_err(0, 0, "Header check OK, chunk size = %dK, spare size = %d, %sbad block info.", chunk_size/1024, spare_size, spare_off ? "" : "no "); } else { chunk_size = opt_chunk * 1024; spare_size = opt_spare; spare_off = opt_bad ? 2 : 0; } spare_data = data + chunk_size; if ((argc - optind) == 2 && !opt_list) { if (mkdirpath(argv[optind+1], 0755) < 0) prt_err(1, errno, "Can't mkdir %s", argv[optind+1]); if (chdir(argv[optind+1]) < 0) prt_err(1, errno, "Can't chdir to %s", argv[optind+1]); } umask(0); init_obj_list(); saved_chunk.objectId = 0; while (read_chunk()) { process_chunk(); } set_dirs_utime(); close(img_file); if (warn_chown) #ifdef __CYGWIN__ prt_err(0, 0, "Warning: Can't restore owner/group attribute (limitation of Cygwin/Windows)"); #else prt_err(0, 0, "Warning: Can't restore owner/group attribute, run unyaffs as root"); #endif return 0; }