static char * getvfsspecial(char *path, int raw_special) { FILE *fp; struct vfstab vp; struct vfstab ref_vp; if ((fp = fopen("/etc/vfstab", "r")) == NULL) return (NULL); (void) memset(&ref_vp, 0, sizeof (struct vfstab)); if (raw_special) ref_vp.vfs_special = path; else ref_vp.vfs_fsckdev = path; if (getvfsany(fp, &vp, &ref_vp)) { (void) fclose(fp); return (NULL); } (void) fclose(fp); if (raw_special) return (vp.vfs_fsckdev); return (vp.vfs_special); }
static void lookup(void) { FILE *fd; int ret; struct vfstab vget, vref; if ((fd = fopen(vfstab, "r")) == NULL) { fprintf(stderr, "%s: cannot open vfstab\n", cbasename); exit(1); } vfsnull(&vref); vref.vfs_special = special; ret = getvfsany(fd, &vget, &vref); if (ret == -1) { rewind(fd); vfsnull(&vref); vref.vfs_fsckdev = special; ret = getvfsany(fd, &vget, &vref); } fclose(fd); switch (ret) { case -1: fstype = default_fstype(special); break; case 0: fstype = vget.vfs_fstype; break; case VFS_TOOLONG: fprintf(stderr, "%s: line in vfstab exceeds %d characters\n", cbasename, VFS_LINE_MAX-2); exit(1); break; case VFS_TOOFEW: fprintf(stderr, "%s: line in vfstab has too few entries\n", cbasename); exit(1); break; case VFS_TOOMANY: fprintf(stderr, "%s: line in vfstab has too many entries\n", cbasename); exit(1); break; } }
/* * This is /usr/sbin/mount: the generic command that in turn * execs the appropriate /usr/lib/fs/{fstype}/mount. * The -F flag and argument are NOT passed. * If the usr file system is not mounted a duplicate copy * can be found in /sbin and this version execs the * appropriate /etc/fs/{fstype}/mount * * If the -F fstype, special or directory are missing, * /etc/vfstab is searched to fill in the missing arguments. * * -V will print the built command on the stdout. * It isn't passed either. */ int main(int argc, char *argv[]) { char *special, /* argument of special/resource */ *mountp, /* argument of mount directory */ *fstype, /* wherein the fstype name is filled */ *newargv[ARGV_MAX], /* arg list for specific command */ *farg = NULL, *Farg = NULL; int ii, ret, cc, fscnt; struct stat64 stbuf; struct vfstab vget, vref; mode_t mode; FILE *fd; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); myname = strrchr(argv[0], '/'); if (myname) myname++; else myname = argv[0]; if (myname == 0) myname = "path unknown"; /* Process the args. */ while ((cc = getopt(argc, argv, "?acd:f:F:gmno:pqrvVO")) != -1) switch (cc) { case 'a': aflg++; break; case 'c': cflg++; break; #ifdef DEBUG case 'd': dflg = atoi(optarg); break; #endif case 'f': fflg++; farg = optarg; break; case 'F': Fflg++; Farg = optarg; break; case 'g': gflg++; break; case 'm': mflg++; break; /* do not update /etc/mnttab */ case 'o': oflg++; if ((specific_opts = strdup(optarg)) == NULL) nomem(); break; /* fstype dependent options */ case 'O': Oflg++; break; case 'p': pflg++; break; case 'q': qflg++; break; case 'r': rflg++; generic_opts = "ro"; break; case 'v': vflg++; break; case 'V': Vflg++; break; case '?': questflg++; break; } /* copy '--' to specific */ if (strcmp(argv[optind-1], "--") == 0) dashflg++; /* option checking */ /* more than two args not allowed if !aflg */ if (!aflg && (argc - optind > 2)) usage(); /* pv mututally exclusive */ if (pflg + vflg + aflg > 1) { fprintf(stderr, gettext ("%s: -a, -p, and -v are mutually exclusive\n"), myname); usage(); } /* * Can't have overlaying mounts on the same mount point during * a parallel mount. */ if (aflg && Oflg) { fprintf(stderr, gettext ("%s: -a and -O are mutually exclusive\n"), myname); usage(); } /* dfF mutually exclusive */ if (fflg + Fflg > 1) { fprintf(stderr, gettext ("%s: More than one FSType specified\n"), myname); usage(); } /* no arguments, only allow p,v,V or [F]? */ if (!aflg && optind == argc) { if (cflg || fflg || mflg || oflg || rflg || qflg) usage(); if (Fflg && !questflg) usage(); if (questflg) { if (Fflg) { newargv[2] = "-?"; newargv[3] = NULL; doexec(Farg, newargv); } usage(); } } if (questflg) usage(); /* one or two args, allow any but p,v */ if (optind != argc && (pflg || vflg)) { fprintf(stderr, gettext("%s: Cannot use -p and -v with arguments\n"), myname); usage(); } /* if only reporting mnttab, generic prints mnttab and exits */ if (!aflg && optind == argc) { if (Vflg) { printf("%s", myname); if (pflg) printf(" -p"); if (vflg) printf(" -v"); printf("\n"); exit(0); } print_mnttab(vflg, pflg); exit(0); } /* * Get filesystem type here. If "-F FStype" is specified, use * that fs type. Otherwise, determine the fs type from /etc/vfstab * if the entry exists. Otherwise, determine the local or remote * fs type from /etc/default/df or /etc/dfs/fstypes respectively. */ if (fflg) { if ((strcmp(farg, "S51K") != 0) && (strcmp(farg, "S52K") != 0)) { fstype = farg; } else fstype = "ufs"; } else /* if (Fflg) */ fstype = Farg; fscnt = argc - optind; if (aflg && (fscnt != 1)) exit(parmount(argv + optind, fscnt, fstype)); /* * Then don't bother with the parallel over head. Everything * from this point is simple/normal single execution. */ aflg = 0; /* get special and/or mount-point from arg(s) */ if (fscnt == 2) special = argv[optind++]; else special = NULL; if (optind < argc) mountp = argv[optind++]; else mountp = NULL; /* lookup only if we need to */ if (fstype == NULL || specific_opts == NULL || special == NULL || mountp == NULL) { if ((fd = fopen(vfstab, "r")) == NULL) { if (fstype == NULL || special == NULL || mountp == NULL) { fprintf(stderr, gettext( "%s: Cannot open %s\n"), myname, vfstab); exit(1); } else { /* * No vfstab, but we know what we want * to mount. */ goto out; } } vfsnull(&vref); vref.vfs_special = special; vref.vfs_mountp = mountp; vref.vfs_fstype = fstype; /* get a vfstab entry matching mountp or special */ while ((ret = getvfsany(fd, &vget, &vref)) > 0) vfserror(ret, vget.vfs_special); /* if no entry and there was only one argument */ /* then the argument could be the special */ /* and not mount point as we thought earlier */ if (ret == -1 && special == NULL) { rewind(fd); special = vref.vfs_special = mountp; mountp = vref.vfs_mountp = NULL; /* skip erroneous lines; they were reported above */ while ((ret = getvfsany(fd, &vget, &vref)) > 0) ; } fclose(fd); if (ret == 0) { if (fstype == NULL) fstype = vget.vfs_fstype; if (special == NULL) special = vget.vfs_special; if (mountp == NULL) mountp = vget.vfs_mountp; if (oflg == 0 && vget.vfs_mntopts) { oflg++; specific_opts = vget.vfs_mntopts; } } else if (special == NULL) { if (stat64(mountp, &stbuf) == -1) { fprintf(stderr, gettext("%s: cannot stat %s\n"), myname, mountp); exit(2); } if (((mode = (stbuf.st_mode & S_IFMT)) == S_IFBLK) || (mode == S_IFCHR)) { fprintf(stderr, gettext("%s: mount point cannot be determined\n"), myname); exit(1); } else { fprintf(stderr, gettext("%s: special cannot be determined\n"), myname); exit(1); } } else if (fstype == NULL) fstype = default_fstype(special); } out: if (realpath(mountp, realdir) == NULL) { (void) fprintf(stderr, "mount: "); perror(mountp); exit(1); } if ((mountp = strdup(realdir)) == NULL) nomem(); if (check_fields(fstype, mountp)) exit(1); /* create the new arg list, and end the list with a null pointer */ ii = 2; if (cflg) newargv[ii++] = "-c"; if (gflg) newargv[ii++] = "-g"; if (mflg) newargv[ii++] = "-m"; /* * The q option needs to go before the -o option as some * filesystems complain during first pass option parsing. */ if (qflg) newargv[ii++] = "-q"; if (oflg) { newargv[ii++] = "-o"; newargv[ii++] = specific_opts; } if (Oflg) newargv[ii++] = "-O"; if (rflg) newargv[ii++] = "-r"; if (dashflg) newargv[ii++] = "--"; newargv[ii++] = special; newargv[ii++] = mountp; newargv[ii] = NULL; doexec(fstype, newargv); return (0); }