📄 mount_tfs.c
字号:
*/voidfind_subdirs(mnt, path, subdir_list) struct mntent *mnt; char *path; Nse_list subdir_list;{ struct stat statb; int len = strlen(path); char *dir; if (!NSE_STREQ(mnt->mnt_type, "tfs")) { return; } if (tfs_major_dev == 0 && stat(mnt->mnt_dir, &statb) == 0) { tfs_major_dev = statb.st_dev >> 8; } if (0 == strncmp(mnt->mnt_dir, path, len) && mnt->mnt_dir[len] == '/') { dir = mnt->mnt_dir + len + 1; while (*dir == '/') { dir++; } (void) nse_list_add_new_copy(subdir_list, dir); }}Nse_errbuild_subdirs(subdir, dir) char *subdir; char *dir;{ char path[MAXPATHLEN]; strcpy(path, dir); nse_pathcat(path, subdir); return make_directory(path);}/* * Set searchlinks from the directory 'from' to the directory 'to', so * that when 'from' is TFS-mounted, the tfsd will be able to follow the * searchlinks to make it appear to the user that the contents of 'from' * are overlaid over the contents of 'to'. Recursively set searchlinks * for all sub-directories of 'from' which have matching sub-directories * under 'to'. 'backmost' is TRUE if 'to' is the layer furthest in back * (i.e. the directory being mounted on.) */Nse_errbuild_searchlinks(from, to, backmost) char *from; char *to; bool_t backmost;{ char dir[MAXPATHLEN]; char searchlink[MAXPATHLEN]; char *str; Nse_err err; /* * First make sure that the directory is writeable, so that we can * print a decent error message if it isn't. (If the directory isn't * writeable, then we won't be able to write .tfs_info to set * searchlinks.) The directory will be unwriteable if either the * user doesn't have write permissions for the directory or the * directory is in a filesystem that was mounted read-only. */ strcpy(dir, from); nse_pathcat(dir, ".tfs_tmp"); if (open(dir, O_RDWR | O_CREAT, 0666) < 0) { err = nse_err_alloc_rec(errno, &str); sprintf(str, "%s is not writeable", from); return err; } if (unlink(dir) < 0) { fprintf(stderr, "%s: Warning: can't unlink %s\n", nse_get_cmdname(), dir); } strcpy(dir, from); strcpy(searchlink, to); return recursive_set_searchlinks(dir, searchlink, backmost);}Nse_errrecursive_set_searchlinks(path, searchlink, backmost) char *path; char *searchlink;{ DIR *dirp; struct direct *dp; struct stat statb; char *curname; Nse_err err; dirp = opendir(path); if (dirp == NULL) { return nse_err_format_errno("Opendir of '%s'\n", path); } while (dp = readdir(dirp)) { if (NSE_STREQ(dp->d_name, ".") || NSE_STREQ(dp->d_name, "..") || 0 == strncmp(dp->d_name, NSE_TFS_FILE_PREFIX, NSE_TFS_FILE_PREFIX_LEN)) { continue; } nse_pathcat(path, dp->d_name); if (lstat(path, &statb) < 0) { closedir(dirp); return nse_err_format_errno("Lstat of '%s'\n", path); } if (NSE_ISDIR(&statb)) { nse_pathcat(searchlink, dp->d_name); closedir(dirp); if (err = recursive_set_searchlinks(path, searchlink, backmost)) { return err; } curname = rindex(path, '/'); *curname++ = '\0'; *rindex(searchlink, '/') = '\0'; dirp = opendir(path); if (dirp == NULL) { return nse_err_format_errno( "Opendir of '%s'\n", path); } /* * Pick up where we left off. */ while (dp = readdir(dirp)) { if (NSE_STREQ(curname, dp->d_name)) { break; } } } else { *rindex(path, '/') = '\0'; } } closedir(dirp); return set_searchlink(path, searchlink, backmost);}/* * Sets searchlink of directory 'path' to point to directory 'back_path'. * Doesn't set searchlink if 'back_path' is a non-existent directory. */Nse_errset_searchlink(path, back_path, backmost) char *path; char *back_path; bool_t backmost;{ struct stat statb; char old_slink[MAXPATHLEN]; char back_slink[MAXPATHLEN]; char *searchlink = back_path; bool_t ok_to_set; bool_t is_tfs_dir; int euid; Nse_err err; if ((err = nse_get_searchlink(path, old_slink)) && err->code != ENOENT) { return err; } ok_to_set = (stat(back_path, &statb) == 0 && NSE_ISDIR(&statb)); if (ok_to_set && backmost) { /* * Determine if the directory in back is under an existing * TFS mount. (TFS mounts have a fixed major dev #.) */ is_tfs_dir = ((statb.st_dev >> 8) == tfs_major_dev); if (is_tfs_dir) { /* * If we're doing a TFS mount over an existing TFS * mount, then the searchlink should be set to the * tfsd's current frontmost layer for this dir, * which is the name returned by nse_tfs_getname(). * Make the RPC call to the tfsd as root, not as * the current effective user, so that the RPC * client handle can be used by root later to send * the TFS_MOUNT request to the tfsd. */ euid = geteuid(); setreuid(0, 0); setregid(0, 0); err = nse_tfs_getname(TFSD_ENV_NAME, back_path, back_slink); setregid(0, group_of_user(euid)); setreuid(0, euid); if (err) { if (err->code == NSE_TFS_NOT_UNDER_MOUNTPT) { is_tfs_dir = FALSE; } else { return err; } } } if (!is_tfs_dir) { /* * Searchlink to backmost directory points to * /tmp_mnt/Tfs_native/'back_path'. (See header * comments.) */ strcpy(back_slink, tfs_loopback_dir); strcat(back_slink, back_path); /* * If backmost directory contains a .tfs_info file, * remove it (otherwise, if there is a searchlink * in the .tfs_info, then there will be another * directory in back of the 'backmost' directory.) */ nse_pathcat(back_path, NSE_TFS_FILE); if (stat(back_path, &statb) == 0) { (void) unlink(back_path); } *rindex(back_path, '/') = '\0'; } searchlink = back_slink; } if (!ok_to_set) { if (old_slink[0] != '\0' && (err = nse_set_searchlink(path, ""))) { return err; } return NULL; } if (NSE_STREQ(searchlink, old_slink)) { return NULL; } return nse_set_searchlink(path, searchlink);}Nse_errmake_directory(dir) char *dir;{ char *cp; Nse_err err; if (access(dir, 0) == 0) { return NULL; } cp = rindex(dir, '/'); *cp = '\0'; if (err = make_directory(dir)) { return err; } *cp = '/'; if (mkdir(dir, 0775) < 0) { return nse_err_format_errno("Mkdir of '%s'\n", dir); } return NULL;}voidunmount_all(mtab_list) Nse_list mtab_list;{ struct mntent *mnt; Nse_listelem elem; Nse_listelem end; NSE_LIST_ITERATE_REV(mtab_list, struct mntent *, mnt, elem, end) { if (unmount(mnt->mnt_dir) < 0) { fprintf(stderr, "%s: Warning: can't unmount '%s': ", nse_get_cmdname(), mnt->mnt_dir); perror(""); } }}intgroup_of_user(uid) int uid;{ struct passwd *pwd; static int last_uid; static int last_gid; if (uid == last_uid) { return last_gid; } pwd = getpwuid(uid); if (pwd) { last_uid = uid; last_gid = pwd->pw_gid; return pwd->pw_gid; } else { last_uid = 0; last_gid = 0; return 0; }}char *str_copy(str) char *str;{ char *str2; if (str != NULL) { str2 = NSE_STRDUP(str); return(str2); } return(NULL);}/* * Ops vector for elements of a string list. */static Nse_listops_rec string_ops= { NULL, str_copy, (Nse_voidfunc) free, NULL, (Nse_boolfunc) _nse_streq_func,};/* * Create and return a string list. */Nse_listnse_stringlist_create(){ Nse_list list; list = nse_list_alloc(&string_ops); return list;}options(argcp, argvp) int *argcp; char ***argvp;{ char *opts; int argc; char **argv; argc = *argcp; argv = *argvp; while (argc && **argv == '-') { opts = &argv[0][1]; switch (*opts) { case 'r': read_only = TRUE; break; default: usage(); /* NOTREACHED */ } argv++; argc--; } *argcp = argc; *argvp = argv; return (0);}usage(){ fprintf(stderr, "Usage: %s [-r] fs1 fs2 ... fsN dir\n", nse_get_cmdname()); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -