mountd.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,539 行 · 第 1/5 页
C
2,539 行
if export is not in kernel's exportfsdata, add it */ if (k_ptr == NULL) {#ifdef DEBUG_FULL (void) fprintf(stderr, "Adding new export %s to kernel\n", ex2->ex_name);#endif DEBUG_FULL extokex(ex2, &kbuf); if ((exportfs(EXPORTFS_CREATE, NULL, &kbuf)) < 0) { syslog(LOG_ERR, "exportfs CREATE of %s: %m", kbuf.e_path); exit (1); } } /* * if kernel's exportfsdata struct is not uptodate, replace it */ else if (!(ex_same(k_ptr, ex2))) {#ifdef DEBUG_FULL (void) fprintf(stderr, "Fixing kernel export %s\n", ex2->ex_name);#endif DEBUG_FULL extokex(k_ptr, &kbuf); if ((exportfs (EXPORTFS_REMOVE, NULL, &kbuf))< 0) { syslog(LOG_ERR, "exportfs REMOVE of %s: %m", kbuf.e_path); exit (1); } extokex(ex2, &kbuf); if ((exportfs(EXPORTFS_CREATE, NULL, &kbuf)) < 0) { syslog(LOG_ERR, "exportfs CREATE(2) of %s: %m", kbuf.e_path); exit (1); } k_ptr->ex_name= "CHECKED"; } else k_ptr->ex_name= "CHECKED"; } } /* * Loop through k_ex list looking for entries that need to be * removed from kernel's exportfsdata list. */ for (k_ptr=k_ex; k_ptr!=NULL; k_ptr=k_ptr->ex_next) { if (strcmp(k_ptr->ex_name, "CHECKED") != 0) {#ifdef DEBUG_FULL (void)fprintf(stderr,"Removing kernel export %s\n", k_ptr->ex_name);#endif DEBUG_FULL extokex(k_ptr, &kbuf); if ((exportfs (EXPORTFS_REMOVE, NULL, &kbuf)) < 0) { syslog(LOG_ERR, "exportfs REMOVE(2) of %s: %m", kbuf.e_path); exit (1); } } } freeex(k_ex);#ifdef DEBUG_FULL (void) fprintf (stderr, "*** Kernel exportfsdata after changes ***\n"); cookie = 0; for (;;) { if ((exportfs (EXPORTFS_READ, &cookie, &kbuf)) < 0) { syslog(LOG_ERR, "exportfs READ(2): %m"); exit (1); } (void)fprintf(stderr,"export name %s", kbuf.e_path); (void)fprintf(stderr,"-r=%d dev: %d ino: %d", kbuf.e_rootmap, kbuf.e_fsid, kbuf.e_gnum); if (kbuf.e_flags & M_EXRONLY) (void)fprintf(stderr," (M_EXRONLY)"); (void)fprintf(stderr, "\n"); if (kbuf.e_more == 0) break; } (void)fprintf(stderr, "\n");#endif DEBUG_FULL}/* * Compare kernel's export entry to mountd's */ex_same (k_ex, ex) struct exports *k_ex, *ex;{ if ((k_ex->ex_rootmap!=ex->ex_rootmap) || (k_ex->ex_flags!=ex->ex_flags) || (k_ex->ex_ino != ex->ex_ino) || (k_ex->ex_gen != ex->ex_gen) || (k_ex->ex_dev != ex->ex_dev)) return (FALSE); return (TRUE);}newdev (name, dev, ino, gen) char *name; dev_t dev; ino_t ino; u_long gen;{ struct exports *new; char *newname; new = (struct exports *)exmalloc(sizeof(*new)); newname = (char *)exmalloc(strlen(name) + 1); (void) strcpy(newname, name); new->ex_name = newname; new->ex_dev = dev; new->ex_ino = ino; new->ex_gen = gen; new->ex_next = NULL; new->ex_rootmap = -2; /* Initialize to nobody */ new->ex_flags = 0; new->ex_groups = NULL; /* Groups ptr */ new->ex_devptr = exports; exports = new;}struct exports *newex(name, next, dev, ino, gen, rootmap, flags) char *name; struct exports *next; dev_t dev; ino_t ino; u_long gen; short rootmap; u_int flags;{ struct exports *new; char *newname; new = (struct exports *)exmalloc(sizeof(*new)); newname = (char *)exmalloc(strlen(name) + 1); (void) strcpy(newname, name); new->ex_name = newname; new->ex_dev = dev; new->ex_ino = ino; new->ex_gen = gen; new->ex_rootmap = rootmap; new->ex_flags = flags; new->ex_next = next; new->ex_groups = NULL; /* Groups ptr */ new->ex_devptr = NULL; return (new);}extokex(ex, kex) struct exports *ex; struct exportfsdata *kex;{ (void)strcpy (kex->e_path, ex->ex_name); kex->e_fsid = ex->ex_dev; kex->e_gnum = ex->ex_ino; kex->e_gen = ex->ex_gen; kex->e_rootmap = ex->ex_rootmap; kex->e_flags = ex->ex_flags; kex->e_more = 0;}struct groups *newgroup(name, next) char *name; struct groups *next;{ struct groups *new; char *newname; new = (struct groups *)exmalloc(sizeof(*new)); newname = (char *)exmalloc(strlen(name) + 1); (void) strcpy(newname, name); new->g_name = newname; new->g_next = next; new->g_hbit = 0; return (new);}setopt(str, ex) char *str; struct exports *ex;{ char *m, *n; /* * Parse options */ switch (str[0]) { case 'r': /* * If r, then set root mapping field */ m = str; m++; if (*m != '=') { syslog(LOG_ERR, "%s bad export option format in %s", str, EXPORTS); return; } else { m++; if (*m == '-') n = ++m; else n = m; for (; !n ; n++) if (!isdigit(*n)) { /* * Bad string */ syslog(LOG_ERR, "%c unknown root mapping integer in %s", *m, EXPORTS); return; } ex->ex_rootmap = atoi(m); } break; case 'n': /* * if n, ignore (no filehandle obsolete) */ break; case 'o': /* * if o, set flags field for readonly */ ex->ex_flags |= M_EXRONLY; break; default: /* * Bad option */ syslog(LOG_ERR, "%c unknown export option in %s", str[0], EXPORTS); break; } return;}/* * Flatten exports list to show directory entries. */flatten_exports(){ struct exports *ex, *ex2; struct exports *exnew = NULL; struct groups *groups; struct groups *groupsnew = NULL;#ifdef DEBUG_FULL (void) fprintf(stderr, "\n******* Flattening exports: *******\n");#endif DEBUG_FULL for (ex = exports; ex != NULL; ex = ex->ex_devptr) { for (ex2 = ex; ex2 != NULL; ex2 = ex2->ex_next) {#ifdef DEBUG_FULL (void) fprintf(stderr, "making newex for %s\n", ex2->ex_name);#endif DEBUG_FULL exnew = newex(ex2->ex_name, exnew, NULL, NULL, NULL, NULL, NULL); for (groups = ex2->ex_groups, groupsnew = NULL; groups != NULL; groups = groups->g_next) {#ifdef DEBUG_FULL (void) fprintf(stderr, "making newgroup for %s\n", groups->g_name);#endif DEBUG_FULL groupsnew = newgroup(groups->g_name, groupsnew); } exnew->ex_groups = groupsnew; } } flatexports = exnew;}char *exmalloc(size) int size;{ char *ret; if ((ret = (char *)malloc((unsigned) size)) == 0) { syslog(LOG_ERR, "Memory allocation failed in exmalloc: %m"); exit(1); } return (ret);}/* * Free entire ex list */freeex(ex) struct exports *ex;{ struct exports *next_ex, *next_dev; struct groups *group_ptr, *next_group; while (ex) { next_dev = ex->ex_devptr; while (ex) { next_ex = ex->ex_next; group_ptr = ex->ex_groups; while (group_ptr) { next_group = group_ptr->g_next; free (group_ptr->g_name); free ((char *)group_ptr); group_ptr = next_group; } free (ex->ex_name); free ((char *)ex); ex = next_ex; } ex = next_dev; }}#ifdef DEBUGprint_exports(ex) struct exports *ex;{ struct groups *groups; struct exports *ex2; (void) fprintf(stderr, "\nexport list begin:\n"); for (; ex != NULL; ex = ex->ex_devptr) { for (ex2 = ex; ex2 != NULL; ex2 = ex2->ex_next) { (void) fprintf(stderr, "fs or dir: %s dev: %x", ex2->ex_name, ex2->ex_dev); (void) fprintf(stderr, " -r=%d ", ex2->ex_rootmap); if (ex2->ex_flags & M_EXRONLY) (void) fprintf(stderr, " ( M_EXRONLY )"); (void) fprintf(stderr, "\n\tdev: %d, ino: %d", ex2->ex_dev, ex2->ex_ino); for (groups= ex2->ex_groups; groups!= NULL; groups= groups->g_next) (void) fprintf(stderr, " %s, hbit: %d", groups->g_name, groups->g_hbit); (void) fprintf(stderr, "\n"); } (void) fprintf(stderr, "finish exports for this dev\n"); } (void) fprintf(stderr, "export list end:\n\n");}#endif DEBUGusage(){ (void) fprintf(stderr,"usage: mountd [-i -d -s]\n"); (void) fflush(stderr); exit(1);}mtd_abort(){ /* * This routine is a do-nothing to replace the libc abort, to prevent * mountd from crashing all the time. It is safe to remove this stub * if running under inetd, since inetd will just restart us when we * crash and the core dumps may be useful. */}/* * Restore saved mount state; rewrite file without commented out * entries */rmtab_load(){ char *path; char *name; char *end; struct mountdlist *ml; char line[MAXRMTABLINELEN]; int fd; f = fopen(RMTAB, "r"); if (f != NULL) { while (fgets(line, sizeof(line), f) != NULL) { name = line; path = strchr(name, ':'); if (*name != '#' && path != NULL) { *path = 0; path++; end = strchr(path, '\n'); if (end != NULL) { *end = 0; } ml = (struct mountdlist *) exmalloc(sizeof(struct mountdlist)); ml->ml_path = (char *) exmalloc(strlen(path) + 1); (void)strcpy(ml->ml_path, path); ml->ml_name = (char *) exmalloc(strlen(name) + 1); (void)strcpy(ml->ml_name, name); ml->ml_nxt = mountlist; mountlist = ml; } } (void)fclose(f); } fd = open(RMTAB, O_CREAT|O_TRUNC|O_RDWR, 0644); f = fdopen(fd, "r+"); if (f != NULL) { for (ml = mountlist; ml != NULL; ml = ml->ml_nxt) { ml->ml_pos = rmtab_insert(ml->ml_name, ml->ml_path); } return(fd); } return(-1);}longrmtab_insert(name, path) char *name; char *path;{ long pos; if (f == NULL || fseek(f, 0L, 2) == -1) { return (-1); } pos = ftell(f); if (fprintf(f, "%s:%s\n", name, path) == EOF) { return (-1); } fflush(f); return (pos);}rmtab_delete(pos) long pos;{ if (f != NULL && pos != -1 && fseek(f, pos, 0) == 0) { (void) fprintf(f, "#"); fflush(f); }}build_ngcache(){ int err, i; struct ypall_callback cbinfo; cbinfo.foreach = getkeys; cbinfo.data = NULL; err = yp_all(mydomain, "netgroup", &cbinfo); if (err) { if (err != YPERR_MAP) syslog(LOG_ERR, "YP error building netgroup cache: %s", yperr_string(err)); return; } for (i=0; i< num_ngs; i++) { (void)expand_ng(ng_names[i]); free(ng_names[i]); } }/* * Called for each netgroup in yp database. Returns 0 to have yp_all * call it again to process the next netgroup. */static intgetkeys(status, key, kl, val, vl, data) int status; char *key; int kl; char *val; int vl; char *data;{ int size; if (status == YP_TRUE) { size = kl + 1; ng_names[num_ngs] = (char *)malloc((unsigned) size); strncpy(ng_names[num_ngs], key, kl); ng_names[num_ngs++][kl] = '\0'; /* * initial cache size is limited to 100 netgroups */ if (num_ngs == 100) return(1); return(0); } if (status != YP_NOMORE) syslog(LOG_ERR, "YP error expanding netgroups: %s", yperr_string(ypprot_err(status))); return(1);}intexpand_ng(ngname) char *ngname;{ char *machp, *userp, *domainp; int is_a_ng=0; setnetgrent(ngname); while (getnetgrent(&machp, &userp, &domainp)) { if (is_a_ng++ == 0) new_ng(ngname); if ((domainp == NULL) || (strcmp(domainp, mydomain) == 0)) { if (machp == NULL) { new_ng_host("everyone"); break; } else if (isalnum(*machp) || (*machp == '_')) new_ng_host(machp); } } endnetgrent();#ifdef DEBUG (void)fprintf(stderr,"Expand ng of %s returning %d\n", ngname, is_a_ng);#endif DEBUG return(is_a_ng);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?