void makedir(char *dir, int mode, int owner, int group) /* Install a directory, and set it's modes. */ { struct stat st; if (stat(dir, &st) < 0) { if (errno != ENOENT) { report(dir); return; } /* The target doesn't exist, make it. */ if (mode == -1) mode= 0755; if (owner == -1) owner= getuid(); if (group == -1) group= getgid(); if (mkdirp(dir, mode, owner, group) < 0) { report(dir); return; } } else { /* The target does exist, change mode and ownership. */ if (mode == -1) mode= (st.st_mode & 07777) | 0555; if ((st.st_mode & 07777) != mode) { if (chmod(dir, mode) < 0) { report(dir); return; } } if (owner == -1) owner= st.st_uid; if (group == -1) group= st.st_gid; if (st.st_uid != owner || st.st_gid != group) { if (chown(dir, owner, group) < 0 && errno != EPERM) { report(dir); return; } /* Set the mode again, chown may have wrecked it. */ (void) chmod(dir, mode); } } }
/* * This routine uses the 'net' and the 'cid' to generate the client's * keystore filename and, if requested, creates the directory path to * the file if any of the directories do not exist. If directory path * creation is not requested and any of the directories do not exist, * then an error is returned. * * Returns: * KEYGEN_SUCCESS or KEYGEN_ERROR. */ static int create_client_filename(char *filename, size_t len, const char *net, const char *cid, boolean_t create) { struct in_addr addr; size_t size; if (net == NULL) { size = snprintf(filename, len, "%s", CLIENT_KEY_DIR); } else if (inet_pton(AF_INET, net, &addr) != 1) { wbku_printerr("%s is not a valid network address\n", net); return (KEYGEN_ERROR); } else if (cid == NULL) { size = snprintf(filename, len, "%s/%s", CLIENT_KEY_DIR, net); } else if (!isxstring(cid)) { wbku_printerr( "%s must be an even number of hexadecimal characters\n", cid); return (KEYGEN_ERROR); } else { size = snprintf(filename, len, "%s/%s/%s", CLIENT_KEY_DIR, net, cid); } /* * Shouldn't be a problem, but make sure buffer was big enough. */ if (size >= len) { wbku_printerr("Keystore path too long\n"); return (KEYGEN_ERROR); } /* * If directory creation is allowed, then try to create it. * If the directory already exists, then march on. */ if (create) { if (mkdirp(filename, S_IRWXU) == -1 && errno != EEXIST) { wbku_printerr("Cannot create client keystore"); return (KEYGEN_ERROR); } } /* * Append the filename. */ if (strlcat(filename, "/keystore", len) >= len) { wbku_printerr("Keystore path too long\n"); return (KEYGEN_ERROR); } return (KEYGEN_SUCCESS); }
/* * create the directory dir. This function will not fail if the directory * already exists. */ int create_dir( ctx_t *ctx /* ARGSUSED */, upath_t dir) { struct stat dir_stat; /* make the dir rwx by owner, and rx by other and group */ static mode_t perms = 0 | S_IRWXU | S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP; if (ISNULL(dir)) { return (-1); } Trace(TR_MISC, "creating directory %s", dir); errno = 0; if (stat(dir, &dir_stat) == 0) { if (!S_ISDIR(dir_stat.st_mode)) { samerrno = SE_CREATE_DIR_FAILED; snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(SE_CREATE_DIR_FAILED), dir, ""); strlcat(samerrmsg, strerror(ENOTDIR), MAX_MSG_LEN); Trace(TR_ERR, "creating directory failed: %s", samerrmsg); return (-1); } Trace(TR_MISC, "directory %s already exists", dir); return (0); } if (errno == ENOENT) { errno = 0; if (mkdirp(dir, perms) == 0) { Trace(TR_MISC, "created directory %s", dir); return (0); } } samerrno = SE_CREATE_DIR_FAILED; snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(SE_CREATE_DIR_FAILED), dir, ""); strlcat(samerrmsg, strerror(errno), MAX_MSG_LEN); Trace(TR_ERR, "creating directory failed: %s", samerrmsg); return (-1); }
static int mkdirp(const char *pathname, mode_t mode) { char parent[PATH_MAX], *p; /* make a parent directory path */ strncpy(parent, pathname, sizeof(parent)); parent[sizeof(parent) - 1] = '\0'; for(p = parent + strlen(parent); *p != '/' && p != parent; p--); *p = '\0'; /* try make parent directory */ if(p != parent && mkdirp(parent, mode) != 0) return -1; /* make this one if parent has been made */ if(mkdir(pathname, mode) == 0) return 0; /* if it already exists that is fine */ if(errno == EEXIST) return 0; return -1; }
static afs_uint32 directory_cb(afs_vnode * v, XFILE * X, void *refcon) { char *vnodepath; int r, use = 0; /* Should we even use this? */ if (!use_vnum) { if ((r = Path_Build(X, &phi, v->vnode, &vnodepath, !use_realpath))) return r; if (!(use = usevnode(X, v->vnode, vnodepath))) { free(vnodepath); return 0; } } /* Print it out */ if (verbose) { if (use_vnum) printf("d%s %3d %-11d %11d %s #%d:%d\n", modestr(v->mode), v->nlinks, v->owner, v->size, datestr(v->server_date), v->vnode, v->vuniq); else printf("d%s %3d %-11d %11d %s %s\n", modestr(v->mode), v->nlinks, v->owner, v->size, datestr(v->server_date), vnodepath); } else if (!quiet && !use_vnum) printf("%s\n", vnodepath); /* Make the directory, if needed */ if (!nomode && !use_vnum && use != 2) { if (strcmp(vnodepath, "/") && (r = mkdirp(vnodepath + 1))) { free(vnodepath); return r; } if (do_acls) { /* XXX do ACL's later */ } } if (!use_vnum) free(vnodepath); return 0; }
int sar_it_x_root(struct sar_it *it, const char *root) { FILE *out; char name[256]; short rlen = strlen(root), nlen = strlen(it->cur.fname); /* make the string with path */ strncpy(name, root, sizeof(name)); strncpy(name+rlen, it->cur.fname, sizeof(name) - nlen); mkdirp(name); if (!(out = fopen(name, "wb"))) return 0; fseek(it->wp, it->cur.beg, SEEK_SET); docpy(it->wp, out, it->cur.size); assert(!fclose(out)); return 1; }
int skd_dirs(void) { int um = umask(0); char buf[512]; int fd; if (mkdirp(cfg.home, 0700)) return 1; snprintf(buf, sizeof(buf), "%s/%s", cfg.home, SNIFFER); close(open(buf, O_CREAT|O_WRONLY, 0222)); /* fake passwd with _our_ home for things like ssh(1) * (i.e. no longer your known_hosts in real root's home) */ snprintf(buf, sizeof(buf), "%s/%s", cfg.home, PWDHACK); fd = creat(buf, 0600); write(fd, buf, sprintf(buf, "root::0:0::%s:/bin/bash\n", cfg.home)); close(fd); umask(um); return 0; }
int main(int argc, char *argv[]) { int i; int error = 0; int verbose = 0; int parents = 0; /* look for 'verbose' option */ while(extract(&argc, &argv, "-v")) verbose = 1; while(extract(&argc, &argv, "--verbose")) verbose = 1; /* look for 'verbose' option */ while(extract(&argc, &argv, "-p")) parents = 1; while(extract(&argc, &argv, "--parents")) parents = 1; if(argc == 1) { usage(argv[0]); return 1; } for(i = 1; i < argc; i++) { if(parents) { if(mkdirp(argv[i], 0777, verbose)) error = 1; } else if(mkdir(argv[i], 0777)) { if(parents && errno == EEXIST) { fprintf(stderr, "mkdir: '%s': %s\n", argv[i], strerror(errno)); error = 1; } } else if(verbose) printf("mkdir: created directory '%s'\n", argv[i]); } return error; }
int mkdirp(char *dname) { struct stat st; int err = stat(dname, &st); if(err == -1) { if(errno == ENOENT) { if(DEBUG_LEVEL >= 2) { printf("Directory %s does not exist, creating it.\n", dname); } char *ddname = dirnameof(dname); mkdirp(ddname); free(ddname); err = mkdir(dname, 0777); if(err == -1) { printf("%s Exists\n", dname); perror("mkdir"); return 0; } else { return 0; } } else { perror("stat"); return -1; } } else if(err == 0) { if(S_ISDIR(st.st_mode)) { if(DEBUG_LEVEL >= 3) { printf("Directory %s exists. Do nothing.\n", dname); } return 0; } else { if(DEBUG_LEVEL >= 3) { printf("%s exists, but is not a directory\n", dname); } return -1; } } else { perror("stat:"); exit(EXIT_FAILURE); } }
int DevCtlServiceReg::mkdirp(zhandle_t *zkhandle, const char * path, const char * lpath) { int c = '/'; const char * p = strchr(path, c); if (p == NULL) { return -1; } else { const char * n = p+1; if (n == NULL) { return -1; } const char * p2 = strchr(n, '/'); if (p2 == NULL) { //the leaf node return createNode(zkhandle, lpath, ZOO_EPHEMERAL|ZOO_SEQUENCE); } else { int len = p2 - lpath; if (p2 - n <= 0) { return -1; } else { char * tmp = (char *)malloc(len+1); strncpy(tmp, lpath, len); tmp[len] = 0; int ret = createNode(zkhandle, tmp, 0); free(tmp); tmp = NULL; if (ret != 0) { return -1; } ret = mkdirp(zkhandle, p2, lpath); return ret; } } } }
bool file_changed(const char* path) { bool res; FILE* file = fopen(path, "r"); if (file == NULL) { return true; } char* current_md5 = md5sum(file); size_t cache_path_len = strlen(REMODEL_DIR) + 1 + strlen(path) + 1; char* cache_path = malloc(cache_path_len); snprintf(cache_path, cache_path_len, "%s/%s", REMODEL_DIR, path); mkdirp(cache_path, 0755); FILE* cache_file = fopen(cache_path, "r+"); if (cache_file == NULL) { res = true; cache_file = fopen(cache_path, "w+"); } else { char* old_md5 = read_file(cache_file); res = strcmp(old_md5, current_md5) != 0; free(old_md5); } // try to open the cache file for writing, and write the current md5 sum back to // the cache. it is possible for multiple threads to try and check if a file has // changed concurrently (e.g. bar.c <- foo.c, baz.c <- foo.c) fseek(cache_file, 0, SEEK_SET); if (fwrite(current_md5, strlen(current_md5), 1, cache_file) == 0) { fprintf(stderr, "error: fwrite: %s\n", strerror(errno)); } fclose(cache_file); fclose(file); free(current_md5); free(cache_path); return res; }
/* * This function is used when copying the category from another * locale. Note that the copy is actually performed using a hard * link for efficiency. */ void copy_category(char *src) { char srcpath[PATH_MAX]; int rv; (void) snprintf(srcpath, sizeof (srcpath), "%s/%s/LCL_DATA", src, category_name()); rv = access(srcpath, R_OK); if ((rv != 0) && (strchr(srcpath, '/') == NULL)) { /* Maybe we should try the system locale */ (void) snprintf(srcpath, sizeof (srcpath), "/usr/lib/locale/%s/%s/LCL_DATA", src, category_name()); rv = access(srcpath, R_OK); } if (rv != 0) { errf(_("source locale data unavailable"), src); return; } if (verbose > 1) { (void) printf(_("Copying category %s from %s: "), category_name(), src); (void) fflush(stdout); } /* make the parent directory */ (void) mkdirp(dirname(category_file()), 0755); if (link(srcpath, category_file()) != 0) { errf(_("unable to copy locale data: %s"), strerror(errno)); return; } if (verbose > 1) { (void) printf(_("done.\n")); } }
FILE * open_category(void) { FILE *file; if (verbose) { (void) printf(_("Writing category %s: "), category_name()); (void) fflush(stdout); } /* make the parent directory */ (void) mkdirp(dirname(category_file()), 0755); /* * note that we have to regenerate the file name, as dirname * clobbered it. */ file = fopen(category_file(), "w"); if (file == NULL) { errf(strerror(errno)); return (NULL); } return (file); }
int main(int argc, char **argv) { int c; char *lfname = NULL; char *cfname = NULL; char *wfname = NULL; DIR *dir; init_charmap(); init_collate(); init_ctype(); init_messages(); init_monetary(); init_numeric(); init_time(); yydebug = 0; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); while ((c = getopt(argc, argv, "w:i:cf:u:vU")) != -1) { switch (c) { case 'v': verbose++; break; case 'i': lfname = optarg; break; case 'u': set_wide_encoding(optarg); break; case 'f': cfname = optarg; break; case 'U': undefok++; break; case 'c': warnok++; break; case 'w': wfname = optarg; break; case '?': usage(); break; } } if ((argc - 1) != (optind)) { usage(); } locname = argv[argc - 1]; if (verbose) { (void) printf(_("Processing locale %s.\n"), locname); } if (cfname) { if (verbose) (void) printf(_("Loading charmap %s.\n"), cfname); reset_scanner(cfname); (void) yyparse(); } if (wfname) { if (verbose) (void) printf(_("Loading widths %s.\n"), wfname); reset_scanner(wfname); (void) yyparse(); } if (verbose) { (void) printf(_("Loading POSIX portable characters.\n")); } add_charmap_posix(); if (lfname) { reset_scanner(lfname); } else { reset_scanner(NULL); } /* make the directory for the locale if not already present */ while ((dir = opendir(locname)) == NULL) { if ((errno != ENOENT) || (mkdir(locname, 0755) < 0)) { errf(strerror(errno)); } } (void) closedir(dir); (void) mkdirp(dirname(category_file()), 0755); (void) yyparse(); if (verbose) { (void) printf(_("All done.\n")); } return (warnings ? 1 : 0); }
/* * This should be done before the program is open for business. * As such, it does not need to be reentrant. */ int open_db_env(char *topdir) { DB_ENV *tmpenv = NULL; int st; struct stat64 sbuf; char logdir[MAXPATHLEN+1]; char tmpdir[MAXPATHLEN+1]; char *dirarr[3]; int i; if (topdir == NULL) { return (-1); } snprintf(logdir, sizeof (tmpdir), "%s/.logs", topdir); snprintf(tmpdir, sizeof (tmpdir), "%s/.tmp", topdir); dirarr[0] = topdir; dirarr[1] = logdir; dirarr[2] = tmpdir; /* first, set up the environment */ st = db_env_create(&tmpenv, 0); if (st != 0) { return (st); } /* make sure the directories exist */ for (i = 0; i < 3; i++) { st = stat64(dirarr[i], &sbuf); if ((st != 0) && (errno == ENOENT)) { st = mkdirp(dirarr[i], 0744); if (st == 0) { st = stat64(dirarr[i], &sbuf); } } if ((st == 0) && (!S_ISDIR(sbuf.st_mode))) { st = -1; break; } } if (st != 0) { return (st); } st = tmpenv->set_data_dir(tmpenv, topdir); if (st != 0) { return (st); } st = tmpenv->set_lg_dir(tmpenv, logdir); if (st != 0) { return (st); } st = tmpenv->set_tmp_dir(tmpenv, tmpdir); if (st != 0) { return (st); } st = tmpenv->set_flags(tmpenv, env_fl, 1); if (st != 0) { return (st); } /* overall database cache size */ st = tmpenv->set_cachesize(tmpenv, 0, (60 * MEGA), 1); st = tmpenv->set_shm_key(tmpenv, FSM_SHM_MASTER_KEY); if (st != 0) { return (st); } /* log buffer in memory */ st = tmpenv->set_lg_bsize(tmpenv, (30 * MEGA)); if (st != 0) { return (st); } /* set up additional error logging */ tmpenv->set_errcall(tmpenv, fsmdb_log_err); /* Increase the number of locks available */ tmpenv->set_lk_max_locks(tmpenv, 10000); tmpenv->set_lk_max_lockers(tmpenv, 10000); tmpenv->set_lk_max_objects(tmpenv, 10000); /* Increase the number of concurrent transactions available */ /* Note: Default in 4.4-20 is '20'. In later versions it's 100 */ tmpenv->set_tx_max(tmpenv, 100); st = tmpenv->open(tmpenv, topdir, env_ofl, 0644); if (st != 0) { /* check for a major failure */ if (st == DB_RUNRECOVERY) { st = tmpenv->open(tmpenv, topdir, env_ffl, 0644); } /* log catastrophic failure and remove all db files. */ if (st == DB_RUNRECOVERY) { fsmdb_log_err(dbEnv, NULL, "Database files corrupt, cannot recover. " "Files will be removed. Please re-index any " "recovery points to regenerate the database."); fsmdb_remove_all(topdir); } } if (st != 0) { return (st); } /* clear out unneeded log files */ tmpenv->log_archive(tmpenv, NULL, DB_ARCH_REMOVE); /* all set, ready to use */ dbEnv = tmpenv; return (st); }
/* * Open and lock the [zcp] state_file. * Return 0 on success, -1 on error. * * FIXME: Move state information into kernel. */ int zed_conf_open_state(struct zed_conf *zcp) { char dirbuf[PATH_MAX]; mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; int n; char *p; int rv; if (!zcp || !zcp->state_file) { errno = EINVAL; zed_log_msg(LOG_ERR, "Failed to open state file: %s", strerror(errno)); return (-1); } n = strlcpy(dirbuf, zcp->state_file, sizeof (dirbuf)); if (n >= sizeof (dirbuf)) { errno = ENAMETOOLONG; zed_log_msg(LOG_WARNING, "Failed to open state file: %s", strerror(errno)); return (-1); } p = strrchr(dirbuf, '/'); if (p) *p = '\0'; if ((mkdirp(dirbuf, dirmode) < 0) && (errno != EEXIST)) { zed_log_msg(LOG_WARNING, "Failed to create directory \"%s\": %s", dirbuf, strerror(errno)); return (-1); } if (zcp->state_fd >= 0) { if (close(zcp->state_fd) < 0) { zed_log_msg(LOG_WARNING, "Failed to close state file \"%s\": %s", zcp->state_file, strerror(errno)); return (-1); } } if (zcp->do_zero) (void) unlink(zcp->state_file); zcp->state_fd = open(zcp->state_file, (O_RDWR | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); if (zcp->state_fd < 0) { zed_log_msg(LOG_WARNING, "Failed to open state file \"%s\": %s", zcp->state_file, strerror(errno)); return (-1); } rv = zed_file_lock(zcp->state_fd); if (rv < 0) { zed_log_msg(LOG_WARNING, "Failed to lock state file \"%s\": %s", zcp->state_file, strerror(errno)); return (-1); } if (rv > 0) { pid_t pid = zed_file_is_locked(zcp->state_fd); if (pid < 0) { zed_log_msg(LOG_WARNING, "Failed to test lock on state file \"%s\"", zcp->state_file); } else if (pid > 0) { zed_log_msg(LOG_WARNING, "Found PID %d bound to state file \"%s\"", pid, zcp->state_file); } else { zed_log_msg(LOG_WARNING, "Inconsistent lock state on state file \"%s\"", zcp->state_file); } return (-1); } return (0); }
int admin_lock(int argc, char **argv) { FINDLOCK_T tResult; LOCK_T theLock; char *RFlag = "/"; /* altRoot */ char *endptr; char *kFlag = ""; /* key */ char *oFlag = ""; /* object */ char *p; char c; int aFlag = 0; /* acquire lock */ int eFlag = 0; /* exclusive lock */ int exclusive = 1; /* exclusive vs shared lock */ int fd; int qFlag = 0; /* quiet */ int rFlag = 0; /* release lock */ int result; int sFlag = 0; /* shared lock */ int tFlag = 0; /* test comparison */ int wFlag = 0; /* wait */ long WFlag = 0; /* wait timeout */ pid_t pFlag = 0; /* process # */ struct sigaction nact; struct sigaction oact; void (*funcSighup)(); void (*funcSigint)(); zoneid_t zFlag = -1; /* zone i.d. */ while ((c = getopt(argc, argv, ":aek:o:p:qrR:stwW:z:")) != EOF) { switch (c) { case 'a': /* acquire lock */ aFlag++; break; case 'e': /* exclusive lock */ eFlag++; break; case 'k': /* lock-key */ kFlag = optarg; if (strlen(optarg) > LOCK_KEY_MAXLEN) { log_msg(LOG_MSG_ERR, MSG_LOCK_kARG_TOOLONG, strlen(optarg), LOCK_KEY_MAXLEN); return (1); } break; case 'o': /* object */ oFlag = optarg; if (strlen(optarg) > LOCK_OBJECT_MAXLEN) { log_msg(LOG_MSG_ERR, MSG_LOCK_oARG_TOOLONG, strlen(optarg), LOCK_OBJECT_MAXLEN); return (1); } break; case 'p': /* process i.d. */ errno = 0; endptr = 0; pFlag = strtol(optarg, &endptr, 10); if ((endptr != (char *)NULL) && (*endptr != '\0')) { log_msg(LOG_MSG_ERR, MSG_LOCK_pFLAG_BADINT, optarg, *endptr); return (1); } if ((pFlag == 0) && (errno != 0)) { log_msg(LOG_MSG_ERR, MSG_LOCK_pFLAG_ERROR, optarg, strerror(errno)); return (1); } break; case 'q': /* quiet */ qFlag++; break; case 'r': /* release lock */ rFlag++; break; case 'R': /* alternative root */ /* if root directory is not absolute path, error */ if (*optarg != '/') { log_msg(LOG_MSG_ERR, MSG_LOCK_RARG_NOT_ABSOLUTE, optarg); return (1); } /* if root directory does not exist, create it */ if (access(optarg, F_OK) != 0) { /* create top level root directory */ if (mkdirp(optarg, 0755) != 0) { log_msg(LOG_MSG_ERR, MSG_LOCK_ALTROOT_CANTCREATE, optarg, strerror(errno)); return (1); } } /* if $ALTROOT/tmp directory does not exist create it */ p = pkgstrPrintf("%s/tmp", optarg); if (access(p, F_OK) != 0) { /* create $ALTROOT/tmp directory */ if (mkdirp(p, 0777) != 0) { log_msg(LOG_MSG_ERR, MSG_LOCK_ALTROOT_CANTCREATE, p, strerror(errno)); return (1); } } /* if $ALTROOT/tmp directory cannot be created, exit */ if (access(p, F_OK) != 0) { log_msg(LOG_MSG_ERR, MSG_LOCK_ALTROOT_NONEXIST, optarg, strerror(errno)); return (1); } (void) free(p); RFlag = optarg; break; case 's': /* shared */ sFlag++; break; case 't': /* test comparison */ tFlag++; break; case 'w': /* wait */ wFlag++; break; case 'W': /* wait with timeout */ errno = 0; endptr = 0; WFlag = strtol(optarg, &endptr, 10); if ((endptr != (char *)NULL) && (*endptr != '\0')) { log_msg(LOG_MSG_ERR, MSG_LOCK_WFLAG_BADINT, optarg, *endptr); return (1); } if ((WFlag == 0) && (errno != 0)) { log_msg(LOG_MSG_ERR, MSG_LOCK_WFLAG_ERROR, optarg, strerror(errno)); return (1); } wFlag++; break; case 'z': /* zone i.d. */ errno = 0; endptr = 0; zFlag = strtol(optarg, &endptr, 10); if ((endptr != (char *)NULL) && (*endptr != '\0')) { log_msg(LOG_MSG_ERR, MSG_LOCK_zFLAG_BADINT, optarg, *endptr); return (1); } if ((zFlag == 0) && (errno != 0)) { log_msg(LOG_MSG_ERR, MSG_LOCK_zFLAG_ERROR, optarg, strerror(errno)); return (1); } break; case ':': log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt); /* LINTED fallthrough on case statement */ case '?': default: log_msg(LOG_MSG_ERR, MSG_USAGE); return (1); } } /* * validate arguments */ /* if -t option is specified, override all other options */ if (tFlag) { int rs; int rx; int a; /* only 2 or 3 args are valid */ a = argc-optind; if ((a < 2) || (a > 3)) { (void) fprintf(stderr, MSG_T_OPTION_ARGS, argc-optind); return (1); } /* if 3rd argument given, it is return value to check */ if (a == 3) { rs = atoi(argv[optind+2]); } rx = _lockMatch(argv[optind+0], argv[optind+1]); /* if 3rd argument not given, code to check is code returned */ if (a == 2) { rs = rx; } /* report results */ if (a == 2) { (void) fprintf(stderr, MSG_T_RESULT_TWO, rx, argv[optind+0], argv[optind+1]); return (rx); } if (rx != rs) { (void) fprintf(stderr, MSG_T_RESULT_THREE, rs, rx, argv[optind+0], argv[optind+1]); } /* always successful */ return (rx == rs ? 0 : 1); } /* must be no non-option arguments left */ if ((argc-optind) > 0) { log_msg(LOG_MSG_ERR, MSG_USAGE); return (1); } /* -a and -r cannot be used together */ if (aFlag && rFlag) { log_msg(LOG_MSG_ERR, MSG_LOCK_ar_TOGETHER); return (1); } /* -e and -s cannot be used together */ if (eFlag && sFlag) { log_msg(LOG_MSG_ERR, MSG_LOCK_es_TOGETHER); return (1); } /* -e can only be used if -a is used */ if (!aFlag && eFlag) { log_msg(LOG_MSG_ERR, MSG_LOCK_e_without_a); return (1); } /* -s can only be used if -a is used */ if (!aFlag && sFlag) { log_msg(LOG_MSG_ERR, MSG_LOCK_s_without_a); return (1); } /* * perform the requested operation */ /* * hook SIGINT and SIGHUP interrupts into quit.c's trap handler */ /* hold SIGINT/SIGHUP interrupts */ (void) sighold(SIGHUP); (void) sighold(SIGINT); /* connect sigint_handler() to SIGINT */ nact.sa_handler = sigint_handler; nact.sa_flags = SA_RESTART; (void) sigemptyset(&nact.sa_mask); if (sigaction(SIGINT, &nact, &oact) < 0) { funcSigint = SIG_DFL; } else { funcSigint = oact.sa_handler; } /* connect sighupt_handler() to SIGHUP */ nact.sa_handler = sighup_handler; nact.sa_flags = SA_RESTART; (void) sigemptyset(&nact.sa_mask); if (sigaction(SIGHUP, &nact, &oact) < 0) { funcSighup = SIG_DFL; } else { funcSighup = oact.sa_handler; } /* release hold on signals */ (void) sigrelse(SIGHUP); (void) sigrelse(SIGINT); /* open the lock file */ fd = _openLockFile(RFlag); if (fd < 0) { return (1); } if (aFlag) { /* set "exclusive" mode based on -e/-s flag used */ if (sFlag) { exclusive = 0; } else if (eFlag) { exclusive = 1; } /* acquire lock */ tResult = lock_acquire(&theLock, &fd, RFlag, kFlag, oFlag, qFlag, wFlag, WFlag, exclusive, RFlag, pFlag, zFlag); switch (tResult) { case FINDLOCK_LOCKACQUIRED: (void) fprintf(stdout, "%s\n", theLock._lrLock.lockKey); result = 0; break; case FINDLOCK_LOCKED: (void) fprintf(stdout, "%s\n", theLock._lrLock.lockObject); result = 1; break; default: result = 1; break; } } else if (rFlag) { /* release lock */ result = lock_release(fd, kFlag, oFlag, qFlag); } else { /* lock status */ result = lock_status(fd, kFlag, oFlag, qFlag); } /* close the lock file */ (void) close(fd); /* return results of operation */ return (result); }
/* * Mount the given filesystem. */ int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; int remount = 0, rc; if (options == NULL) { (void) strlcpy(mntopts, MNTOPT_DEFAULTS, sizeof (mntopts)); } else { (void) strlcpy(mntopts, options, sizeof (mntopts)); } if (strstr(mntopts, MNTOPT_REMOUNT) != NULL) remount = 1; /* * If the pool is imported read-only then all mounts must be read-only */ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts)); /* * Load encryption key if required and not already present. * Don't need to check ZFS_PROP_ENCRYPTION because encrypted * datasets have keystatus of ZFS_CRYPT_KEY_NONE. */ fprintf(stderr, "zfs_mount: mount, keystatus is %d\r\n", zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS)); if (zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS) == ZFS_CRYPT_KEY_UNAVAILABLE) { fprintf(stderr, "loading KEY\r\n"); (void )zfs_key_load(zhp, B_FALSE, B_FALSE, B_FALSE); } /* * Append default mount options which apply to the mount point. * This is done because under Linux (unlike Solaris) multiple mount * points may reference a single super block. This means that just * given a super block there is no back reference to update the per * mount point options. */ rc = zfs_add_options(zhp, mntopts, sizeof (mntopts)); if (rc) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "default options unavailable")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* * Append zfsutil option so the mount helper allow the mount */ strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts)); if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); /* Create the directory if it doesn't already exist */ if (lstat(mountpoint, &buf) != 0) { if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } } /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if 'remount' is * specified or if overlay option(-O) is given */ if ((flags & MS_OVERLAY) == 0 && !remount && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* perform the mount */ rc = do_mount(zfs_get_name(zhp), mountpoint, mntopts); if (rc) { /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ if (rc == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); } else if (rc == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else if (rc == ENOTSUP) { char buf[256]; int spa_version; VERIFY(zfs_spa_version(zhp, &spa_version) == 0); (void) snprintf(buf, sizeof (buf), dgettext(TEXT_DOMAIN, "Can't mount a version %lld " "file system on a version %d pool. Pool must be" " upgraded to mount this file system."), (u_longlong_t)zfs_prop_get_int(zhp, ZFS_PROP_VERSION), spa_version); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf)); } else { zfs_error_aux(hdl, strerror(rc)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), zhp->zfs_name)); } /* remove the mounted entry before re-adding on remount */ if (remount) libzfs_mnttab_remove(hdl, zhp->zfs_name); /* add the mounted entry into our cache */ libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts); return (0); }
int main(int argc, char **argv) { MYSQL mysql; char query[255]; MYSQL_RES *res; MYSQL_ROW row; mysql_init(&mysql); if (!(mysql_real_connect(&mysql,"","tile","tile","tile",MYSQL_PORT,NULL,0))) { fprintf(stderr,"%s: %s\n",argv[0],mysql_error(&mysql)); exit(1); } mysql.reconnect= 1; snprintf(query, sizeof(query), "SELECT x,y,z,data,created_at FROM tiles"); if ((mysql_query(&mysql, query)) || !(res= mysql_use_result(&mysql))) { fprintf(stderr,"Cannot query tiles: %s\n", mysql_error(&mysql)); exit(1); } while ((row= mysql_fetch_row(res))) { ulong *lengths= mysql_fetch_lengths(res); char path[PATH_MAX]; unsigned long int x,y,z,length; time_t created_at; const char *data; struct tm date; int fd; struct utimbuf utb; assert(mysql_num_fields(res) == 5); //printf("x(%s) y(%s) z(%s) data_length(%lu): %s\n", row[0], row[1], row[2], lengths[3], row[4]); x = strtoul(row[0], NULL, 10); y = strtoul(row[1], NULL, 10); z = strtoul(row[2], NULL, 10); data = row[3]; length = lengths[3]; parseDate(&date, row[4]); created_at = mktime(&date); //printf("x(%lu) y(%lu) z(%lu) data_length(%lu): %s", x,y,z,length,ctime(&created_at)); if (!length) { printf("skipping empty tile x(%lu) y(%lu) z(%lu) data_length(%lu): %s", x,y,z,length,ctime(&created_at)); continue; } snprintf(path, PATH_MAX, WWW_ROOT TILE_PATH "/%lu/%lu/%lu.png", z, x, y); printf("%s\n", path); mkdirp(path); fd = open(path, O_CREAT | O_WRONLY, 0644); if (fd <0) { perror(path); exit(1); } if (write(fd, data, length) != length) { perror("writing tile"); exit(2); } close(fd); utb.actime = created_at; utb.modtime = created_at; if (utime(path, &utb) < 0) { perror("utime"); exit(3); } } printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(res)); mysql_free_result(res); mysql_close(&mysql); /* Close & free connection */ return 0; }
/* * Mount the given filesystem. */ int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; if (options == NULL) mntopts[0] = '\0'; else (void) strlcpy(mntopts, options, sizeof (mntopts)); if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); /* Create the directory if it doesn't already exist */ if (lstat(mountpoint, &buf) != 0) { if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } } /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if MS_OVERLAY is specified, which * would defeat the point. We also avoid this check if 'remount' is * specified. */ if ((flags & MS_OVERLAY) == 0 && strstr(mntopts, MNTOPT_REMOUNT) == NULL && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* perform the mount */ /* ZFSFUSE */ if (zfsfuse_mount(hdl, zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, strlen (mntopts)) != 0) { /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ if (errno == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); } else if (errno == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else { zfs_error_aux(hdl, strerror(errno)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), zhp->zfs_name)); } return (0); }
/* * Mount the given filesystem. */ int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; #ifdef __APPLE__ struct zfs_mount_args mnt_args = {0}; char devpath[MAXPATHLEN]; #endif if (options == NULL) mntopts[0] = '\0'; else (void) strlcpy(mntopts, options, sizeof (mntopts)); if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); #ifdef __APPLE__ /* * Check for optional paths */ if (hasoptionalpath(mntopts, "mountdev=", devpath, sizeof (devpath))) mnt_args.mountdev = devpath; if (hasoptionalpath(mntopts, "mountpoint=", mountpoint, sizeof (mountpoint))) goto callmount; #endif /* Create the directory if it doesn't already exist */ if (lstat(mountpoint, &buf) != 0) { if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } } #ifndef __APPLE__ /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if MS_OVERLAY is specified, which * would defeat the point. We also avoid this check if 'remount' is * specified. */ if ((flags & MS_OVERLAY) == 0 && strstr(mntopts, MNTOPT_REMOUNT) == NULL && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } #endif /*!__APPLE__*/ /* perform the mount */ #ifdef __APPLE__ callmount: mnt_args.dataset = zfs_get_name(zhp); mnt_args.flags = 0; if (mount(MNTTYPE_ZFS, mountpoint, flags, &mnt_args) != 0) { #else if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { #endif #ifdef __APPLE__ /* * If this was a top-level filesystem, then IOKit * probing may have already mounted it, causing * our call to mount() to fail. */ if (zfs_is_mounted(zhp, NULL)) { goto success; } #endif /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ if (errno == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); } else if (errno == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else { zfs_error_aux(hdl, strerror(errno)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), zhp->zfs_name)); } #ifdef __APPLE__ success: /* * Remove any legacy custom volume icons. */ { char path[MAXPATHLEN]; struct stat sbuf; snprintf(path, MAXPATHLEN, "%s/%s", mountpoint, MOUNT_POINT_CUSTOM_ICON); if (stat(path, &sbuf) == 0 && sbuf.st_size == 35014 && sbuf.st_uid == 0) { /* Clear "has custom icon" flag */ (void) removexattr(mountpoint, XATTR_FINDERINFO_NAME, 0); /* Clear custom icon file */ (void) unlink(path); } } #endif return (0); } #ifdef __APPLE__ /* * When unmounting, we first talk to diskarb and attempt to unmount via that * route. This allows diskarb to tell fsevents, mds, etc. to stop using the * filesystem. * * This code was borrowed from umount(8). */ #include <CoreFoundation/CoreFoundation.h> #include <TargetConditionals.h> #if !TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE #include <DiskArbitration/DiskArbitrationPrivate.h> static void __diskarb_unmount( DADiskRef disk, DADissenterRef dissenter, void * context ) { *( ( int * ) context ) = dissenter ? DADissenterGetStatus( dissenter ) : 0; CFRunLoopStop( CFRunLoopGetCurrent( ) ); }
int main( int argc, char *argv[] ) { FILE *out_a, *out_b; char *h1, *h2, *s, *q; char *id = NULL; char *outname_a = NULL, *outname_b = NULL, *outdirname = NULL; int i; struct options *o = options_new( ); struct tokenset *t = tokenset_new( ); struct fqreader *fq = fqreader_new( NULL ); /* Get the command line options */ options_cmdline( o, argc, argv ); if ( _IS_NULL( o->outname ) || strlen( o->outname ) == 0 ) { o->outname = realloc( o->outname, 4 * sizeof ( char ) ); strcpy( o->outname, "FQU" ); } /* Create the output directory if necessary */ outdirname = realloc( outdirname, sizeof ( char ) * ( 2 + strlen( o->outname ) ) ); strcpy( outdirname, o->outname ); if ( strchr( outdirname, '/' ) ) { /* not the current directory */ dirname( outdirname ); mkdirp( outdirname, S_IRWXU | S_IRWXG | S_IRWXO ); } /* Read the id files */ for ( i = o->optind; i < argc; i++ ) { char *line; struct linereader *z = linereader_new( ); linereader_init( z, argv[i] ); if ( _IS_NULL( z ) ) { fprintf( stderr, "[ERROR] %s: Cannot open input file \"%s\"\n", _I_AM, argv[i] ); exit( 1 ); } while ( ( line = ( char * ) linereader_next( z ) ) ) { unsigned len; stru_trim( line ); if ( line[0] == '#' || stru_is_ws( line ) ) continue; len = strcspn( line, "\f\n\r\t\v " ); line[len] = '\0'; tokenset_add( t, line ); } linereader_free( z ); } outname_a = realloc( outname_a, sizeof ( char ) * ( 6 + strlen( o->outname ) ) ); strcpy( outname_a, o->outname ); strcat( outname_a, "_A.fq" ); out_a = fopen( outname_a, "wb" ); if ( _IS_NULL( out_a ) ) { fprintf( stderr, "Could not open first output file \"%s\"\n", outname_a ); exit( 1 ); } outname_b = realloc( outname_b, sizeof ( char ) * ( 6 + strlen( o->outname ) ) ); strcpy( outname_b, o->outname ); strcat( outname_b, "_B.fq" ); out_b = fopen( outname_b, "wb" ); if ( _IS_NULL( out_b ) ) { fprintf( stderr, "Could not open second output file \"%s\"\n", outname_b ); exit( 1 ); } while ( fqreader_next( fq, &h1, &h2, &s, &q ) ) { utils_extract_id( &id, h1 ); /* get the identifier from header 1 */ if ( tokenset_exists( t, id ) ) fprintf( out_a, "@%s\n%s\n+%s\n%s\n", h1, s, h2, q ); else fprintf( out_b, "@%s\n%s\n+%s\n%s\n", h1, s, h2, q ); } fclose( out_a ); fclose( out_b ); _FREE( id ); _FREE( outname_a ); _FREE( outname_b ); fqreader_free( fq ); options_free( o ); tokenset_free( t ); return 0; }
static int do_restore_inode( char *filename, /* path where file is to be restored */ filedetails_t *details, /* ptr to file info */ dumpspec_t *ds, /* info about samfsdump */ replace_t replace /* if & how file should be replaced */ ) { int rval; int file_data = 0; int file_data_read; char path[MAXPATHLEN + 1]; char name[MAXPATHLEN + 1]; char slink[MAXPATHLEN + 1]; char *slash_loc; int skipping; struct sam_perm_inode perm_inode; struct sam_stat sb; struct sam_vsn_section *vsnp; struct sam_ioctl_idtime idtime; void *data; int n_acls; aclent_t *aclp; timestackvars_t tvars = {0}; permstackvars_t pvars = {0}; int out_dir_fd = -1; int dir_fd = -1; char *dirp; size_t namelen; /* * Read the dump file - seek to the specified file offset * * Offset is the location of the actual inode. To use the * common read functions, we need to back-up the length of the * provided name. */ namelen = strlen(details->file_name); gzseek(ds->fildmp, details->snapOffset - namelen, SEEK_SET); rval = common_csd_read(ds->fildmp, name, namelen, ds->byteswapped, &perm_inode); if (rval != 0) { return (-1); } data = NULL; vsnp = NULL; aclp = NULL; n_acls = 0; if (details->summary.flags & FL_HASDATA) { file_data_read = 0; file_data++; } else { file_data_read = file_data = 0; } if (S_ISREQ(perm_inode.di.mode)) { data = malloc(perm_inode.di.psize.rmfile); } /* read_next needs error handling... --SG */ common_csd_read_next(ds->fildmp, ds->byteswapped, ds->csdversion, &perm_inode, &vsnp, slink, data, &n_acls, &aclp); /* skip system files, shouldn't happen with indexes */ if (perm_inode.di.id.ino == 1 || perm_inode.di.id.ino == 4 || perm_inode.di.id.ino == 5) { goto skip_file; } /* * Make sure that we don't restore into a non-SAM-FS filesystem. * * Search backwards through path for a viable SAM-FS path. * by calling sam_stat() and checking the directory attributes */ rval = sam_stat(filename, &sb, sizeof (sb)); strlcpy(path, filename, sizeof (path)); dirp = dirname(path); if (rval == 0) { if (replace == REPLACE_NEVER) { /* can't do anything, file exists */ rval = -2; goto skip_file; } if (!SS_ISSAMFS(sb.attr)) { rval = -3; goto skip_file; } } else { /* * file doesn't exist * loop through path looking for samfs, create * path if necessary */ rval = sam_stat(path, &sb, sizeof (sb)); if ((rval == 0) && (!SS_ISSAMFS(sb.attr))) { rval = -3; goto skip_file; } /* only mkdir if parent directory does not exist */ if (rval != 0) { while ((slash_loc = strrchr(path, '/')) != NULL) { *slash_loc = '\0'; rval = sam_stat(path, &sb, sizeof (sb)); if (rval == 0) { break; } } if (rval != 0) { /* no part of path exists? */ rval = -1; goto skip_file; } if (!SS_ISSAMFS(sb.attr)) { rval = -3; goto skip_file; } strlcpy(path, filename, sizeof (path)); dirp = dirname(path); rval = mkdirp(dirp, S_IRWXU | S_IRWXG | S_IRWXO); if (rval != 0) { rval = -1; goto skip_file; } } } /* Open the parent directory so times can be properly reset */ idtime.id.ino = sb.st_ino; idtime.id.gen = sb.gen; idtime.atime = sb.st_atime; idtime.mtime = sb.st_mtime; idtime.xtime = sb.creation_time; idtime.ytime = sb.attribute_time; dir_fd = open64(dirp, O_RDONLY); /* ok, ready to start restoring ... */ /* * if segment index, we have to skip the data segment inodes * before we can get to the dumped data. */ if (!(S_ISSEGI(&perm_inode.di) && file_data)) { common_sam_restore_a_file(ds->fildmp, filename, &perm_inode, vsnp, slink, data, n_acls, aclp, file_data, &file_data_read, &out_dir_fd, replace, &tvars, &pvars); } if (S_ISSEGI(&perm_inode.di)) { struct sam_perm_inode seg_inode; struct sam_vsn_section *seg_vsnp; int i; offset_t seg_size; int no_seg; sam_id_t seg_parent_id = perm_inode.di.id; /* * If we are restoring the data, don't restore the data segment * inodes. This means we will lose the archive copies, if any. */ skipping = file_data; /* * Read each segment inode. If archive copies overflowed, * read vsn sections directly after each segment inode. */ seg_size = (offset_t)perm_inode.di.rm.info.dk.seg_size * SAM_MIN_SEGMENT_SIZE; no_seg = (perm_inode.di.rm.size + seg_size - 1) / seg_size; for (i = 0; i < no_seg; i++) { gzread(ds->fildmp, &seg_inode, sizeof (seg_inode)); /* * cs_restore keeps going on the segments even * on error. We'll do that here too, but I'm not * sure it's right. */ if (ds->byteswapped) { if (sam_byte_swap( sam_perm_inode_swap_descriptor, &seg_inode, sizeof (seg_inode))) { continue; } } if (!(SAM_CHECK_INODE_VERSION(seg_inode.di.version))) { continue; } if (skipping) { continue; } seg_inode.di.parent_id = seg_parent_id; seg_vsnp = NULL; common_csd_read_mve(ds->fildmp, ds->csdversion, &seg_inode, &seg_vsnp, ds->byteswapped); common_sam_restore_a_file(ds->fildmp, filename, &seg_inode, seg_vsnp, NULL, NULL, 0, NULL, file_data, NULL, &out_dir_fd, replace, &tvars, &pvars); if (seg_vsnp) { free(seg_vsnp); } } /* * Now that we have skipped the data segment inodes * we can restore the dumped data if any. */ if (file_data) { common_sam_restore_a_file(ds->fildmp, filename, &perm_inode, vsnp, slink, data, n_acls, aclp, file_data, &file_data_read, &out_dir_fd, replace, &tvars, &pvars); } } skip_file: if (data) { free(data); } if (vsnp) { free(vsnp); } if (aclp) { free(aclp); } if (file_data && file_data_read == 0) { common_skip_embedded_file_data(ds->fildmp); } common_pop_permissions_stack(&pvars); if (dir_fd > 0) { common_pop_times_stack(dir_fd, &tvars); ioctl(dir_fd, F_IDTIME, &idtime); close(dir_fd); } if (out_dir_fd > 0) { close(out_dir_fd); } return (rval); }
int clib_package_install(clib_package_t *pkg, const char *dir, int verbose) { if (!pkg || !dir) return -1; char *pkg_dir = path_join(dir, pkg->name); if (NULL == pkg_dir) { return -1; } if (-1 == mkdirp(pkg_dir, 0777)) { free(pkg_dir); return -1; } if (NULL == pkg->url) { pkg->url = clib_package_url(pkg->author, pkg->repo_name, pkg->version); } if (NULL == pkg->url) { free(pkg_dir); return -1; } if (NULL != pkg->src) { // write package.json char *package_json = path_join(pkg_dir, "package.json"); if (NULL == package_json) { free(pkg_dir); return -1; } fs_write(package_json, pkg->json); free(package_json); // write each source list_node_t *node; list_iterator_t *it = list_iterator_new(pkg->src, LIST_HEAD); while ((node = list_iterator_next(it))) { char *filename = node->val; // download source file char *file_url = clib_package_file_url(pkg->url, filename); char *file_path = path_join(pkg_dir, basename(filename)); if (NULL == file_url || NULL == file_path) { if (file_url) free(file_url); free(pkg_dir); return -1; } if (verbose) { clib_package_log("fetch", file_url); clib_package_log("save", file_path); } int rc = http_get_file(file_url, file_path); free(file_url); free(file_path); if (-1 == rc) { if (verbose) clib_package_error("error", "unable to fetch %s", file_url); free(pkg_dir); return -1; } } list_iterator_destroy(it); } return clib_package_install_dependencies(pkg, dir, verbose); }
int open_fs_db( char *dirnam, char *fsname, DB_ENV *p_env, boolean_t create, /* add new databases if not existing */ fs_db_t *fsdb) { DB *pdb; int st; char buf[MAXPATHLEN+1]; mode_t md = 0644; char namebuf[MAXPATHLEN+1] = {0}; struct stat64 sbuf; memset(fsdb, 0, sizeof (fs_db_t)); /* make sure fs-specific directory exists */ st = dbdir_from_fsname(fsname, namebuf, sizeof (namebuf)); if (st != 0) { goto err; } snprintf(buf, sizeof (buf), "%s/%s", dirnam, namebuf); if (!create) { if (stat64(buf, &sbuf) != 0) { return (ENOENT); } } (void) mkdirp(buf, 0744); if (fsdb->snapDB == NULL) { /* Create & open the snapshot database - RECNO */ snprintf(buf, sizeof (buf), "%s/snaps.db", namebuf); if ((st = db_create(&fsdb->snapDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->snapDB; if ((st = pdb->set_append_recno(pdb, set_snapid)) != 0) { goto err; } if ((st = pdb->open(pdb, NULL, buf, NULL, DB_RECNO, db_fl, md)) != 0) { goto err; } /* create the secondary for the snapdb */ snprintf(buf, sizeof (buf), "%s/snapid.db", namebuf); if ((st = db_create(&fsdb->snapidDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->snapidDB; pdb->set_bt_compare(pdb, compare_pathname); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } if ((st = (fsdb->snapDB)->associate(fsdb->snapDB, NULL, pdb, index_snapname, DB_CREATE)) != 0) { goto err; } } if (fsdb->fidDB == NULL) { /* Path components by FID - Primary, BTREE */ snprintf(buf, sizeof (buf), "%s/path_fid.db", namebuf); if ((st = db_create(&fsdb->fidDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->fidDB; pdb->set_bt_compare(pdb, bt_compare_uint64); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } /* pathname DB - BTREE */ snprintf(buf, sizeof (buf), "%s/path.db", namebuf); if ((st = db_create(&fsdb->pathDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->pathDB; pdb->set_bt_compare(pdb, compare_path_t); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } if ((st = (fsdb->fidDB)->associate(fsdb->fidDB, NULL, pdb, index_path, DB_CREATE|DB_IMMUTABLE_KEY)) != 0) { goto err; } /* * dirName DB - BTREE - full path for quick lookups * Note: This was a secondary database to fidDB, but * it was impossible to delete items from this DB because * we were breaking the reproducibility rules when creating * the secondary index. This db exists for performance * reasons when adding files/looking up full paths. The * "most right" answer is probably a directory name cache * and should be considered for a future enhancement. */ snprintf(buf, sizeof (buf), "%s/dir.db", namebuf); if ((st = db_create(&fsdb->dirDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->dirDB; pdb->set_bt_compare(pdb, compare_pathname); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } } if (fsdb->snapfileDB == NULL) { snprintf(buf, sizeof (buf), "%s/snapfiles.db", namebuf); /* snapfile DB */ if ((st = db_create(&fsdb->snapfileDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->snapfileDB; pdb->set_bt_compare(pdb, bt_compare_sfid); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } } if (fsdb->filesDB == NULL) { snprintf(buf, sizeof (buf), "%s/files.db", namebuf); /* next, the db for modified files */ if ((st = db_create(&fsdb->filesDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->filesDB; pdb->set_bt_compare(pdb, bt_compare_fuid); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } } /* VSNs by snapshot */ if (fsdb->snapvsnDB == NULL) { snprintf(buf, sizeof (buf), "%s/snapvsn.db", namebuf); if ((st = db_create(&fsdb->snapvsnDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->snapvsnDB; pdb->set_bt_compare(pdb, bt_compare_uint32); pdb->set_flags(pdb, DB_DUPSORT); pdb->set_dup_compare(pdb, bt_compare_uint32); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } } if (fsdb->metricsDB == NULL) { snprintf(buf, sizeof (buf), "%s/metrics.db", namebuf); /* next, the db for file metrics results. No duplicates. */ if ((st = db_create(&fsdb->metricsDB, p_env, 0)) != 0) { goto err; } pdb = fsdb->metricsDB; pdb->set_bt_compare(pdb, bt_compare_fmRpt); if ((st = pdb->open(pdb, NULL, buf, NULL, DB_BTREE, db_fl, md)) != 0) { goto err; } } return (0); err: close_fsdb(fsname, fsdb, FALSE); return (st); }
struct passwd * newacc(char *username) { char buf[PATH_MAX + 1]; struct passwd *pw; int i; if ((pw=getpwnam(username)) != 0) { fprintf(stderr,"user %s already exists\n", username); return 0; } if ((pw=malloc(sizeof *pw)) == 0) { return 0; } pw->pw_name = username; if ((pw->pw_uid = enter_uid()) == -1) { return 0; } if ((pw->pw_gid = enter_gid()) == -1) { return 0; } buf[0] = '\0'; if (get_string("Real name", buf) == -1) { return 0; } if ((pw->pw_comment=strdup(buf)) == 0) { return 0; } strncpy(buf, getdef_str("BASEDIR"), PATH_MAX); buf[PATH_MAX] = '\0'; if ((i = strlen(buf)) > 0) { if (buf[i - 1] != '/') { buf[i++] = '/'; } strncpy(buf + i, username, PATH_MAX - i); } if (get_string("Home directory", buf) == -1) { return 0; } if ((pw->pw_dir = strdup(buf)) == 0) { return 0; } strncpy(buf, getdef_str("SHELL"), PATH_MAX); buf[PATH_MAX] = '\0'; if (get_string("Login shell", buf) == -1) return 0; if ((pw->pw_shell = strdup(buf)) == 0) { return 0; } pw->pw_passwd = passwd_stub; while (mkdirp(pw->pw_dir, pw->pw_uid, pw->pw_gid) == -1) { *buf = '\0'; if (get_string("Enter a different home directory or enter to exit ", buf) == -1) return 0; if (*buf == '\0') return 0; free(pw->pw_dir); if ((pw->pw_dir=strdup(buf)) == 0) return 0; } return pw; }
/* * Mount the given filesystem. */ int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; if (options == NULL) mntopts[0] = '\0'; else (void) strlcpy(mntopts, options, sizeof (mntopts)); /* * If the pool is imported read-only then all mounts must be read-only */ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) flags |= MS_RDONLY; if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); /* Create the directory if it doesn't already exist */ if (lstat(mountpoint, &buf) != 0) { if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } } /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if MS_OVERLAY is specified, which * would defeat the point. We also avoid this check if 'remount' is * specified. */ if ((flags & MS_OVERLAY) == 0 && strstr(mntopts, MNTOPT_REMOUNT) == NULL && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* perform the mount */ if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ if (errno == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); } else if (errno == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else if (errno == ENOTSUP) { char buf[256]; int spa_version; VERIFY(zfs_spa_version(zhp, &spa_version) == 0); (void) snprintf(buf, sizeof (buf), dgettext(TEXT_DOMAIN, "Can't mount a version %lld " "file system on a version %d pool. Pool must be" " upgraded to mount this file system."), (u_longlong_t)zfs_prop_get_int(zhp, ZFS_PROP_VERSION), spa_version); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf)); } else { zfs_error_aux(hdl, strerror(errno)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), zhp->zfs_name)); } /* add the mounted entry into our cache */ libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts); return (0); }
int ipacman_init(const char* rootdir, alpm_cb_progress cb) { int ret = 0; alpm_errno_t err; /* Configure root path first. If it is set and dbpath/logfile were not * set, then set those as well to reside under the root. */ char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/var/lib/pacman/", rootdir); if(access(path, F_OK) != 0) { mkdirp(path, 0755); } /* initialize library */ handle = alpm_initialize(rootdir, path, &err); if(!handle) { printf("failed to initialize alpm library (%s)\n", alpm_strerror(err)); if(err == ALPM_ERR_DB_VERSION) { printf(" try running pacman-db-upgrade\n"); } return -1; } alpm_option_set_dlcb(handle, cb_dl_progress); alpm_option_set_eventcb(handle, cb_event); alpm_option_set_questioncb(handle, cb_question); alpm_option_set_progresscb(handle, cb?cb:cb_progress); snprintf(path, PATH_MAX, "%s/var/log/pacman.log", rootdir); ret = alpm_option_set_logfile(handle, path); if(ret != 0) { printf("problem setting logfile '%s' (%s)\n", path, alpm_strerror(alpm_errno(handle))); return ret; } /* Set GnuPG's home directory. This is not relative to rootdir, even if * rootdir is defined. Reasoning: gpgdir contains configuration data. */ snprintf(path, PATH_MAX, "%s/etc/pacman.d/gnupg/", rootdir); ret = alpm_option_set_gpgdir(handle, path); if(ret != 0) { printf("problem setting gpgdir '%s' (%s)\n", path, alpm_strerror(alpm_errno(handle))); return ret; } /* add a default cachedir if one wasn't specified */ snprintf(path, PATH_MAX, "%s/var/cache/pacman/pkg/", rootdir); alpm_option_add_cachedir(handle, path); //specialized for installer /*alpm_option_add_cachedir(handle, "/PKGS");*/ alpm_option_set_default_siglevel(handle, ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL | ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL); alpm_option_set_local_file_siglevel(handle, ALPM_SIG_USE_DEFAULT); alpm_option_set_remote_file_siglevel(handle, ALPM_SIG_USE_DEFAULT); alpm_option_set_totaldlcb(handle, cb_dl_total); struct utsname un; uname(&un); if (strcmp(un.machine, "mips64") == 0) alpm_option_set_arch(handle, "mipsel"); else alpm_option_set_arch(handle, un.machine); alpm_option_set_checkspace(handle, 1); alpm_option_set_usesyslog(handle, 1); alpm_option_set_deltaratio(handle, 0.7); /* the follow function use alpm_list_t* as arguments * use alpm_list_add() */ /* alpm_option_set_ignorepkgs(handle, ignorepkg); alpm_option_set_ignoregroups(handle, ignoregrp); alpm_option_set_noupgrades(handle, noupgrade); alpm_option_set_noextracts(handle, noextract); */ return 0; }
/* * Write the PID file specified in [zcp]. * Return 0 on success, -1 on error. * * This must be called after fork()ing to become a daemon (so the correct PID * is recorded), but before daemonization is complete and the parent process * exits (for synchronization with systemd). */ int zed_conf_write_pid(struct zed_conf *zcp) { const mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; const mode_t filemode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; char buf[PATH_MAX]; int n; char *p; mode_t mask; int rv; if (!zcp || !zcp->pid_file) { errno = EINVAL; zed_log_msg(LOG_ERR, "Failed to create PID file: %s", strerror(errno)); return (-1); } assert(zcp->pid_fd == -1); /* * Create PID file directory if needed. */ n = strlcpy(buf, zcp->pid_file, sizeof (buf)); if (n >= sizeof (buf)) { errno = ENAMETOOLONG; zed_log_msg(LOG_ERR, "Failed to create PID file: %s", strerror(errno)); goto err; } p = strrchr(buf, '/'); if (p) *p = '\0'; if ((mkdirp(buf, dirmode) < 0) && (errno != EEXIST)) { zed_log_msg(LOG_ERR, "Failed to create directory \"%s\": %s", buf, strerror(errno)); goto err; } /* * Obtain PID file lock. */ mask = umask(0); umask(mask | 022); zcp->pid_fd = open(zcp->pid_file, (O_RDWR | O_CREAT), filemode); umask(mask); if (zcp->pid_fd < 0) { zed_log_msg(LOG_ERR, "Failed to open PID file \"%s\": %s", zcp->pid_file, strerror(errno)); goto err; } rv = zed_file_lock(zcp->pid_fd); if (rv < 0) { zed_log_msg(LOG_ERR, "Failed to lock PID file \"%s\": %s", zcp->pid_file, strerror(errno)); goto err; } else if (rv > 0) { pid_t pid = zed_file_is_locked(zcp->pid_fd); if (pid < 0) { zed_log_msg(LOG_ERR, "Failed to test lock on PID file \"%s\"", zcp->pid_file); } else if (pid > 0) { zed_log_msg(LOG_ERR, "Found PID %d bound to PID file \"%s\"", pid, zcp->pid_file); } else { zed_log_msg(LOG_ERR, "Inconsistent lock state on PID file \"%s\"", zcp->pid_file); } goto err; } /* * Write PID file. */ n = snprintf(buf, sizeof (buf), "%d\n", (int) getpid()); if ((n < 0) || (n >= sizeof (buf))) { errno = ERANGE; zed_log_msg(LOG_ERR, "Failed to write PID file \"%s\": %s", zcp->pid_file, strerror(errno)); } else if (zed_file_write_n(zcp->pid_fd, buf, n) != n) { zed_log_msg(LOG_ERR, "Failed to write PID file \"%s\": %s", zcp->pid_file, strerror(errno)); } else if (fdatasync(zcp->pid_fd) < 0) { zed_log_msg(LOG_ERR, "Failed to sync PID file \"%s\": %s", zcp->pid_file, strerror(errno)); } else { return (0); } err: if (zcp->pid_fd >= 0) { (void) close(zcp->pid_fd); zcp->pid_fd = -1; } return (-1); }
/* * Mount the given filesystem. * * 'flags' appears pretty much always 0 here. */ int zfs_mount(zfs_handle_t *zhp, const char *options, int flags) { struct stat buf; char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; libzfs_handle_t *hdl = zhp->zfs_hdl; int remount; if (options == NULL) { mntopts[0] = '\0'; } else { (void) strlcpy(mntopts, options, sizeof (mntopts)); } if (strstr(mntopts, MNTOPT_REMOUNT) != NULL) remount = 1; /* * If the pool is imported read-only then all mounts must be read-only */ #ifdef __LINUX__ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts)); #else if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) flags |= MS_RDONLY; #endif /* __LINUX__ */ if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); #ifdef __LINUX__ /* * Append default mount options which apply to the mount point. * This is done because under Linux (unlike Solaris) multiple mount * points may reference a single super block. This means that just * given a super block there is no back reference to update the per * mount point options. */ rc = zfs_add_options(zhp, &flags); if (rc) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "default options unavailable")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* * Append zfsutil option so the mount helper allow the mount */ strlcat(mntopts, "," MNTOPT_ZFSUTIL, sizeof (mntopts)); #endif /* __LINUX__ */ /* Create the directory if it doesn't already exist */ #ifdef __APPLE__ if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT && lstat(mountpoint, &buf) != 0) { #else if (lstat(mountpoint, &buf) != 0) { #endif if (mkdirp(mountpoint, 0755) != 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to create mountpoint")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } } /* * Determine if the mountpoint is empty. If so, refuse to perform the * mount. We don't perform this check if 'remount' is * specified or if overlay option(-O) is given */ if ((flags & MS_OVERLAY) == 0 && !remount && !dir_is_empty(mountpoint)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "directory is not empty")); return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), mountpoint)); } /* perform the mount */ #ifdef __LINUX__ rc = do_mount(zfs_get_name(zhp), mountpoint, mntopts); #elif defined(__APPLE__) || defined (__FREEBSD__) if (zmount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { #elif defined(__illumos__) if (mount(zfs_get_name(zhp), mountpoint, MS_OPTIONSTR | flags, MNTTYPE_ZFS, NULL, 0, mntopts, sizeof (mntopts)) != 0) { #endif /* __LINUX__*/ /* * Generic errors are nasty, but there are just way too many * from mount(), and they're well-understood. We pick a few * common ones to improve upon. */ if (errno == EBUSY) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "mountpoint or dataset is busy")); } else if (errno == EPERM) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Insufficient privileges")); } else if (errno == ENOTSUP) { char buf[256]; int spa_version; VERIFY(zfs_spa_version(zhp, &spa_version) == 0); (void) snprintf(buf, sizeof (buf), dgettext(TEXT_DOMAIN, "Can't mount a version %lld " "file system on a version %d pool. Pool must be" " upgraded to mount this file system."), (u_longlong_t)zfs_prop_get_int(zhp, ZFS_PROP_VERSION), spa_version); zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, buf)); #ifdef __APPLE__ } else if (((errno == ESRCH) || (errno == EINVAL) || (errno == ENOENT && lstat(mountpoint, &buf) != 0)) && zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "The parent file system must be mounted first.")); #endif } else { zfs_error_aux(hdl, strerror(errno)); } return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot mount '%s'"), zhp->zfs_name)); } #ifdef __APPLE__ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) fprintf(stderr, "ZFS: snapshot mountpoint '%s'\n", mountpoint); if (!(flags & MS_RDONLY)) zfs_mount_seticon(mountpoint); #endif /* remove the mounted entry before re-adding on remount */ if (remount) libzfs_mnttab_remove(hdl, zhp->zfs_name); /* add the mounted entry into our cache */ libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint, mntopts); return (0); } /* * Unmount a single filesystem. */ static int unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags) { int error; #if 0 error = unmount(mountpoint, flags); if (unmount(mountpoint, flags) != 0) { return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), mountpoint)); } #else error = do_unmount(mountpoint, flags); if (error != 0) { return (zfs_error_fmt(hdl, EZFS_UMOUNTFAILED, dgettext(TEXT_DOMAIN, "cannot unmount '%s'"), mountpoint)); } #endif return (0); } /* * Unmount the given filesystem. */ int zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags) { libzfs_handle_t *hdl = zhp->zfs_hdl; #ifdef __LINUX__ struct mnttab search = { 0 }, entry; #else struct mnttab entry; #endif /* __LINUX__ */ char *mntpt = NULL; /* check to see if need to unmount the filesystem */ if (mountpoint != NULL || (((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) || (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)) && libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) { /* * mountpoint may have come from a call to * getmnt/getmntany if it isn't NULL. If it is NULL, * we know it comes from getmntany which can then get * overwritten later. We strdup it to play it safe. */ if (mountpoint == NULL) mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp); else mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint); /* * Unshare and unmount the filesystem */ #ifdef __illumos__ if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0) #else if (zfs_unshare_nfs(zhp, mntpt) != 0) #endif return (-1); if (unmount_one(hdl, mntpt, flags) != 0) { free(mntpt); #ifdef __illumos__ (void) zfs_shareall(zhp); #else (void) zfs_share_nfs(zhp); #endif return (-1); } libzfs_mnttab_remove(hdl, zhp->zfs_name); free(mntpt); } return (0); }