121156Sdist /* 239322Smckusick * Copyright (c) 1980, 1989 The Regents of the University of California. 339322Smckusick * All rights reserved. 439322Smckusick * 539322Smckusick * Redistribution and use in source and binary forms are permitted 639322Smckusick * provided that the above copyright notice and this paragraph are 739322Smckusick * duplicated in all such forms and that any documentation, 839322Smckusick * advertising materials, and other materials related to such 939322Smckusick * distribution and use acknowledge that the software was developed 1039322Smckusick * by the University of California, Berkeley. The name of the 1139322Smckusick * University may not be used to endorse or promote products derived 1239322Smckusick * from this software without specific prior written permission. 1339322Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1439322Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1539322Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621156Sdist */ 1721156Sdist 1810811Ssam #ifndef lint 1921156Sdist char copyright[] = 2039322Smckusick "@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\ 2121156Sdist All rights reserved.\n"; 2239322Smckusick #endif /* not lint */ 231057Sbill 2421156Sdist #ifndef lint 25*42040Sbostic static char sccsid[] = "@(#)mount.c 5.35 (Berkeley) 05/15/90"; 2639322Smckusick #endif /* not lint */ 2721156Sdist 2839131Smckusick #include "pathnames.h" 2912808Ssam #include <sys/param.h> 3035339Sbostic #include <sys/file.h> 3138445Smckusick #include <sys/time.h> 3239133Smckusick #include <sys/wait.h> 3310811Ssam #include <fstab.h> 3416669Ssam #include <errno.h> 3535339Sbostic #include <stdio.h> 3640496Smckusick #include <signal.h> 37*42040Sbostic #include <string.h> 3838445Smckusick #include <sys/mount.h> 3938445Smckusick #ifdef NFS 4038445Smckusick #include <sys/socket.h> 4138445Smckusick #include <sys/socketvar.h> 4238445Smckusick #include <netdb.h> 4338445Smckusick #include <rpc/rpc.h> 4438445Smckusick #include <rpc/pmap_clnt.h> 4538445Smckusick #include <rpc/pmap_prot.h> 4638445Smckusick #include <nfs/rpcv2.h> 4738445Smckusick #include <nfs/nfsv2.h> 4838445Smckusick #include <nfs/nfs.h> 4938445Smckusick #endif 501057Sbill 5140369Smckusick #define DEFAULT_ROOTUID -2 5240369Smckusick 5335339Sbostic #define BADTYPE(type) \ 5435339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 5535339Sbostic strcmp(type, FSTAB_RQ)) 5635339Sbostic #define SETTYPE(type) \ 5735339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 581057Sbill 5939333Smckusick int fake, verbose, updateflg, mnttype; 6039322Smckusick char *mntname, **envp; 6140051Smckusick char **vfslist, **makevfslist(); 6239131Smckusick 6338445Smckusick #ifdef NFS 6438445Smckusick int xdr_dir(), xdr_fh(); 6538632Smckusick char *getnfsargs(); 6641911Smckusick struct nfs_args nfsdefargs = { 6741911Smckusick (struct sockaddr *)0, 6841911Smckusick SOCK_DGRAM, 6941911Smckusick 0, 7038445Smckusick (nfsv2fh_t *)0, 7138445Smckusick 0, 7238445Smckusick NFS_WSIZE, 7338445Smckusick NFS_RSIZE, 7438445Smckusick NFS_TIMEO, 7538445Smckusick NFS_RETRANS, 7638445Smckusick (char *)0, 7738445Smckusick }; 785073Sroot 7938445Smckusick struct nfhret { 8038445Smckusick u_long stat; 8138445Smckusick nfsv2fh_t nfh; 8238445Smckusick }; 8340051Smckusick #define DEF_RETRY 10000 8440051Smckusick int retrycnt; 8538445Smckusick #define BGRND 1 8638445Smckusick #define ISBGRND 2 8738445Smckusick int opflags = 0; 8838445Smckusick #endif 8938445Smckusick 9039131Smckusick main(argc, argv, arge) 915073Sroot int argc; 925073Sroot char **argv; 9339131Smckusick char **arge; 941057Sbill { 9535339Sbostic extern char *optarg; 9635339Sbostic extern int optind; 9735339Sbostic register struct fstab *fs; 9835339Sbostic register int cnt; 9940496Smckusick int all, ch, rval, flags, ret, pid, i; 10038632Smckusick long mntsize; 10139465Smckusick struct statfs *mntbuf, *getmntpt(); 10239131Smckusick char *type, *options = NULL; 10340496Smckusick FILE *pidfile; 1041057Sbill 10539131Smckusick envp = arge; 10635339Sbostic all = 0; 10735339Sbostic type = NULL; 10838445Smckusick mnttype = MOUNT_UFS; 10939322Smckusick mntname = "ufs"; 11039333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 11135339Sbostic switch((char)ch) { 11235339Sbostic case 'a': 11335339Sbostic all = 1; 11435339Sbostic break; 11535339Sbostic case 'f': 11635339Sbostic fake = 1; 11735339Sbostic break; 11835339Sbostic case 'r': 11912808Ssam type = FSTAB_RO; 12035339Sbostic break; 12139333Smckusick case 'u': 12241403Smckusick updateflg = MNT_UPDATE; 12339333Smckusick break; 12435339Sbostic case 'v': 12535339Sbostic verbose = 1; 12635339Sbostic break; 12735339Sbostic case 'w': 12835339Sbostic type = FSTAB_RW; 12935339Sbostic break; 13039131Smckusick case 'o': 13139131Smckusick options = optarg; 13239131Smckusick break; 13338445Smckusick case 't': 13440051Smckusick vfslist = makevfslist(optarg); 13539322Smckusick mnttype = getmnttype(optarg); 13639322Smckusick break; 13735339Sbostic case '?': 13835339Sbostic default: 13935339Sbostic usage(); 14039131Smckusick /* NOTREACHED */ 1415073Sroot } 14235339Sbostic argc -= optind; 14335339Sbostic argv += optind; 14435339Sbostic 14535339Sbostic /* NOSTRICT */ 14635339Sbostic 1474460Sroot if (all) { 14835369Sbostic rval = 0; 14939333Smckusick while (fs = getfsent()) { 15035372Sbostic if (BADTYPE(fs->fs_type)) 15135372Sbostic continue; 15240844Smckusick if (badvfsname(fs->fs_vfstype, vfslist)) 15340051Smckusick continue; 15435372Sbostic /* `/' is special, it's always mounted */ 15535372Sbostic if (!strcmp(fs->fs_file, "/")) 15641403Smckusick flags = MNT_UPDATE; 15739333Smckusick else 15839333Smckusick flags = updateflg; 15939333Smckusick mnttype = getmnttype(fs->fs_vfstype); 16039333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 16139333Smckusick type, options, fs->fs_mntops); 16235372Sbostic } 16335341Sbostic exit(rval); 16435339Sbostic } 1655073Sroot 16635339Sbostic if (argc == 0) { 16735339Sbostic if (verbose || fake || type) 16835339Sbostic usage(); 16940337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 17039319Smckusick fprintf(stderr, 17139319Smckusick "mount: cannot get mount information\n"); 17238632Smckusick exit(1); 17338632Smckusick } 17440844Smckusick for (i = 0; i < mntsize; i++) { 17540844Smckusick if (badvfstype(mntbuf[i].f_type, vfslist)) 17640844Smckusick continue; 17738632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 17839316Smckusick mntbuf[i].f_flags); 17940844Smckusick } 1804460Sroot exit(0); 1811057Sbill } 18212808Ssam 18339465Smckusick if (argc == 1 && updateflg) { 18439465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 18539465Smckusick fprintf(stderr, 18639465Smckusick "mount: unknown special file or file system %s.\n", 18739465Smckusick *argv); 18839465Smckusick exit(1); 18939465Smckusick } 19039465Smckusick mnttype = mntbuf->f_type; 19140124Smckusick if (!strcmp(mntbuf->f_mntfromname, "root_device")) { 19240124Smckusick fs = getfsfile("/"); 19340124Smckusick strcpy(mntbuf->f_mntfromname, fs->fs_spec); 19440124Smckusick } 19540496Smckusick ret = mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname, 19640496Smckusick updateflg, type, options, NULL); 19740496Smckusick } else if (argc == 1) { 19835339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 19935339Sbostic fprintf(stderr, 20035339Sbostic "mount: unknown special file or file system %s.\n", 20135339Sbostic *argv); 20235339Sbostic exit(1); 20335339Sbostic } 20435339Sbostic if (BADTYPE(fs->fs_type)) { 20535339Sbostic fprintf(stderr, 20635339Sbostic "mount: %s has unknown file system type.\n", *argv); 20735339Sbostic exit(1); 20835339Sbostic } 20939333Smckusick mnttype = getmnttype(fs->fs_vfstype); 21040496Smckusick ret = mountfs(fs->fs_spec, fs->fs_file, updateflg, 21140496Smckusick type, options, fs->fs_mntops); 21240496Smckusick } else if (argc != 2) { 21340496Smckusick usage(); 21440496Smckusick ret = 1; 21540496Smckusick } else { 21640496Smckusick ret = mountfs(argv[0], argv[1], updateflg, type, options, NULL); 21712808Ssam } 21840496Smckusick if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 21940496Smckusick pid = 0; 22040496Smckusick fscanf(pidfile, "%d", &pid); 22140496Smckusick fclose(pidfile); 22240496Smckusick if (pid > 0) 22340496Smckusick kill(pid, SIGHUP); 22440496Smckusick } 22540496Smckusick exit (ret); 22612808Ssam } 22712808Ssam 22839333Smckusick mountfs(spec, name, flags, type, options, mntopts) 22939131Smckusick char *spec, *name, *type, *options, *mntopts; 23039333Smckusick int flags; 23112808Ssam { 23235339Sbostic extern int errno; 23335339Sbostic register int cnt; 23439333Smckusick int argc, status, i; 23538070Smckusick struct ufs_args args; 23641911Smckusick struct nfs_args nfsargs; 23739131Smckusick char *argp, *argv[50]; 23839322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2391057Sbill 24041911Smckusick nfsargs = nfsdefargs; 24139333Smckusick if (mntopts) 24239333Smckusick getstdopts(mntopts, &flags); 24339316Smckusick if (options) 24439316Smckusick getstdopts(options, &flags); 24539333Smckusick if (type) 24639333Smckusick getstdopts(type, &flags); 24739316Smckusick switch (mnttype) { 24839316Smckusick case MOUNT_UFS: 24939333Smckusick if (mntopts) 25039333Smckusick getufsopts(mntopts, &flags); 25139316Smckusick if (options) 25239316Smckusick getufsopts(options, &flags); 25339316Smckusick args.fspec = spec; 25440369Smckusick args.exroot = DEFAULT_ROOTUID; 25541403Smckusick if (flags & MNT_RDONLY) 25641403Smckusick args.exflags = MNT_EXRDONLY; 25740496Smckusick else 25840496Smckusick args.exflags = 0; 25939316Smckusick argp = (caddr_t)&args; 26039316Smckusick break; 26138632Smckusick 26238632Smckusick #ifdef NFS 26339316Smckusick case MOUNT_NFS: 26440051Smckusick retrycnt = DEF_RETRY; 26539333Smckusick if (mntopts) 26639333Smckusick getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt); 26739316Smckusick if (options) 26839333Smckusick getnfsopts(options, &nfsargs, &opflags, &retrycnt); 26941911Smckusick if (argp = getnfsargs(spec, &nfsargs)) 27039316Smckusick break; 27139316Smckusick return (1); 27238632Smckusick #endif /* NFS */ 27338632Smckusick 27439316Smckusick case MOUNT_MFS: 27539322Smckusick default: 27639322Smckusick argv[0] = mntname; 27739329Smckusick argc = 1; 27839322Smckusick if (flags) { 27939322Smckusick argv[argc++] = "-F"; 28039322Smckusick sprintf(flagval, "%d", flags); 28139322Smckusick argv[argc++] = flagval; 28239322Smckusick } 28339333Smckusick if (mntopts) 28439333Smckusick argc += getexecopts(mntopts, &argv[argc]); 28539329Smckusick if (options) 28639329Smckusick argc += getexecopts(options, &argv[argc]); 28739316Smckusick argv[argc++] = spec; 28839316Smckusick argv[argc++] = name; 28939521Smckusick argv[argc++] = NULL; 29039603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 29139316Smckusick if (verbose) { 29239322Smckusick printf("exec: %s", execname); 29339322Smckusick for (i = 1; i < argc; i++) 29439316Smckusick printf(" %s", argv[i]); 29539316Smckusick printf("\n"); 29639316Smckusick } 29739316Smckusick if (fake) 29839316Smckusick break; 29939316Smckusick if (i = vfork()) { 30039316Smckusick if (i == -1) { 30139322Smckusick perror("mount: vfork starting file system"); 30239316Smckusick return (1); 30339131Smckusick } 30439316Smckusick if (waitpid(i, &status, 0) != -1 && 30539316Smckusick WIFEXITED(status) && 30639316Smckusick WEXITSTATUS(status) != 0) 30739316Smckusick return (WEXITSTATUS(status)); 30839322Smckusick spec = mntname; 30939316Smckusick goto out; 31039316Smckusick } 31139322Smckusick execve(execname, argv, envp); 31239603Smckusick fprintf(stderr, "mount: cannot exec %s for %s: ", 31339603Smckusick execname, name); 31439603Smckusick perror(""); 31539316Smckusick exit (1); 31639316Smckusick /* NOTREACHED */ 31738632Smckusick 31839316Smckusick } 31939316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 32039316Smckusick if (opflags & ISBGRND) 32139316Smckusick exit(1); 32239316Smckusick fprintf(stderr, "%s on %s: ", spec, name); 32339316Smckusick switch (errno) { 32439316Smckusick case EMFILE: 32539316Smckusick fprintf(stderr, "Mount table full\n"); 32639316Smckusick break; 32739316Smckusick case EINVAL: 32841403Smckusick if (flags & MNT_UPDATE) 32939333Smckusick fprintf(stderr, "Specified device does %s\n", 33039333Smckusick "not match mounted device"); 33139333Smckusick else 33239333Smckusick fprintf(stderr, "Bogus super block\n"); 33339316Smckusick break; 33439333Smckusick case EOPNOTSUPP: 33539333Smckusick fprintf(stderr, "Operation not supported\n"); 33639333Smckusick break; 33739316Smckusick default: 33839316Smckusick perror((char *)NULL); 33939316Smckusick break; 3404460Sroot } 34139316Smckusick return(1); 3424460Sroot } 34335339Sbostic 34439131Smckusick out: 34512808Ssam if (verbose) 34639316Smckusick prmount(spec, name, flags); 34735339Sbostic 34838445Smckusick if (opflags & ISBGRND) 34938445Smckusick exit(); 35038445Smckusick else 35138445Smckusick return(0); 3521057Sbill } 35335339Sbostic 35435339Sbostic static 35539316Smckusick prmount(spec, name, flags) 35639316Smckusick char *spec, *name; 35739316Smckusick long flags; 35835339Sbostic { 35938632Smckusick 36038445Smckusick if (opflags & ISBGRND) 36138445Smckusick return; 36238632Smckusick printf("%s on %s", spec, name); 36341403Smckusick if (flags & MNT_RDONLY) 36439316Smckusick printf(" (read-only)"); 36541403Smckusick if (flags & MNT_NOEXEC) 36639316Smckusick printf(" (noexec)"); 36741403Smckusick if (flags & MNT_NOSUID) 36839316Smckusick printf(" (nosuid)"); 36941403Smckusick if (flags & MNT_NODEV) 37039316Smckusick printf(" (nodev)"); 37141403Smckusick if (flags & MNT_SYNCHRONOUS) 37239316Smckusick printf(" (synchronous)"); 37341403Smckusick if (flags & MNT_QUOTA) 37441285Smckusick printf(" (with quotas)"); 37541403Smckusick if (flags & MNT_LOCAL) 37641285Smckusick printf(" (local)"); 37741403Smckusick if (flags & MNT_EXPORTED) 37841403Smckusick if (flags & MNT_EXRDONLY) 37941285Smckusick printf(" (NFS exported read-only)"); 38041285Smckusick else 38141285Smckusick printf(" (NFS exported)"); 38235339Sbostic printf("\n"); 38335339Sbostic } 38435339Sbostic 38539133Smckusick getmnttype(fstype) 38639133Smckusick char *fstype; 38739133Smckusick { 38839133Smckusick 38939322Smckusick mntname = fstype; 39039133Smckusick if (!strcmp(fstype, "ufs")) 39139133Smckusick return (MOUNT_UFS); 39239133Smckusick if (!strcmp(fstype, "nfs")) 39339133Smckusick return (MOUNT_NFS); 39439133Smckusick if (!strcmp(fstype, "mfs")) 39539133Smckusick return (MOUNT_MFS); 39639133Smckusick return (0); 39739133Smckusick } 39839133Smckusick 39938632Smckusick usage() 40035339Sbostic { 40140871Smckusick 40240871Smckusick fprintf(stderr, "usage:\n mount %s %s\n mount %s\n mount %s\n", 40340871Smckusick "[ -frwu ] [ -t nfs | ufs | external_type ]", 40440871Smckusick "[ -o options ] special node", 40540871Smckusick "[ -afrwu ] [ -t nfs | ufs | external_type ]", 40640871Smckusick "[ -frwu ] special | node"); 40735339Sbostic exit(1); 40835339Sbostic } 40935339Sbostic 41039316Smckusick getstdopts(options, flagp) 41139316Smckusick char *options; 41239316Smckusick long *flagp; 41339316Smckusick { 41439316Smckusick register char *opt; 41539316Smckusick int negative; 41639316Smckusick char *optbuf[BUFSIZ], *strtok(); 41739316Smckusick 41839316Smckusick strcpy(optbuf, options); 41939316Smckusick for (opt = strtok(optbuf, ","); opt; opt = strtok(NULL, ",")) { 42039316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 42139316Smckusick negative++; 42239316Smckusick opt += 2; 42339316Smckusick } else { 42439316Smckusick negative = 0; 42539316Smckusick } 42639333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 42741403Smckusick *flagp |= MNT_RDONLY; 42839333Smckusick continue; 42939333Smckusick } 43039333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 43141403Smckusick *flagp &= ~MNT_RDONLY; 43239333Smckusick continue; 43339333Smckusick } 43439316Smckusick if (!strcasecmp(opt, "exec")) { 43539316Smckusick if (negative) 43641403Smckusick *flagp |= MNT_NOEXEC; 43739333Smckusick else 43841403Smckusick *flagp &= ~MNT_NOEXEC; 43939316Smckusick continue; 44039316Smckusick } 44139316Smckusick if (!strcasecmp(opt, "suid")) { 44239316Smckusick if (negative) 44341403Smckusick *flagp |= MNT_NOSUID; 44439333Smckusick else 44541403Smckusick *flagp &= ~MNT_NOSUID; 44639316Smckusick continue; 44739316Smckusick } 44839316Smckusick if (!strcasecmp(opt, "dev")) { 44939316Smckusick if (negative) 45041403Smckusick *flagp |= MNT_NODEV; 45139333Smckusick else 45241403Smckusick *flagp &= ~MNT_NODEV; 45339316Smckusick continue; 45439316Smckusick } 45539316Smckusick if (!strcasecmp(opt, "synchronous")) { 45639316Smckusick if (!negative) 45741403Smckusick *flagp |= MNT_SYNCHRONOUS; 45839333Smckusick else 45941403Smckusick *flagp &= ~MNT_SYNCHRONOUS; 46039316Smckusick continue; 46139316Smckusick } 46239316Smckusick } 46339316Smckusick } 46439316Smckusick 46539131Smckusick getufsopts(options, flagp) 46639131Smckusick char *options; 46739131Smckusick long *flagp; 46839131Smckusick { 46939131Smckusick 47039131Smckusick return; 47139131Smckusick } 47239131Smckusick 47339329Smckusick getexecopts(options, argv) 47439131Smckusick char *options; 47539131Smckusick char **argv; 47639131Smckusick { 47739131Smckusick register int argc = 0; 47839131Smckusick register char *opt; 47939131Smckusick char *strtok(); 48039131Smckusick 48139131Smckusick for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { 48239131Smckusick if (opt[0] != '-') 48339131Smckusick continue; 48439131Smckusick argv[argc++] = opt; 48539131Smckusick if (opt[2] == '\0' || opt[2] != '=') 48639131Smckusick continue; 48739131Smckusick opt[2] = '\0'; 48839131Smckusick argv[argc++] = &opt[3]; 48939131Smckusick } 49039131Smckusick return (argc); 49139131Smckusick } 49239131Smckusick 49339465Smckusick struct statfs * 49439465Smckusick getmntpt(name) 49539465Smckusick char *name; 49639465Smckusick { 49739465Smckusick long mntsize; 49839465Smckusick register long i; 49939465Smckusick struct statfs *mntbuf; 50039465Smckusick 50140337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 50239465Smckusick for (i = 0; i < mntsize; i++) { 50339465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 50439465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 50539465Smckusick return (&mntbuf[i]); 50639465Smckusick } 50739465Smckusick return ((struct statfs *)0); 50839465Smckusick } 50939465Smckusick 51040051Smckusick static int skipvfs; 51140051Smckusick 51240051Smckusick badvfstype(vfstype, vfslist) 51340844Smckusick long vfstype; 51440051Smckusick char **vfslist; 51540051Smckusick { 51640051Smckusick 51740051Smckusick if (vfslist == 0) 51840051Smckusick return(0); 51940051Smckusick while (*vfslist) { 52040844Smckusick if (vfstype == getmnttype(*vfslist)) 52140051Smckusick return(skipvfs); 52240051Smckusick vfslist++; 52340051Smckusick } 52440051Smckusick return (!skipvfs); 52540051Smckusick } 52640051Smckusick 52740844Smckusick badvfsname(vfsname, vfslist) 52840844Smckusick char *vfsname; 52940844Smckusick char **vfslist; 53040844Smckusick { 53140844Smckusick 53240844Smckusick if (vfslist == 0) 53340844Smckusick return(0); 53440844Smckusick while (*vfslist) { 53540844Smckusick if (strcmp(vfsname, *vfslist) == 0) 53640844Smckusick return(skipvfs); 53740844Smckusick vfslist++; 53840844Smckusick } 53940844Smckusick return (!skipvfs); 54040844Smckusick } 54140844Smckusick 54240051Smckusick char ** 54340051Smckusick makevfslist(fslist) 54440051Smckusick char *fslist; 54540051Smckusick { 54640051Smckusick register char **av, *nextcp; 54740051Smckusick register int i; 54840051Smckusick char *malloc(); 54940051Smckusick 55040051Smckusick if (fslist == NULL) 55140051Smckusick return (NULL); 55240051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 55340051Smckusick fslist += 2; 55440051Smckusick skipvfs = 1; 55540051Smckusick } 55640051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 55740051Smckusick if (*nextcp == ',') 55840051Smckusick i++; 55940051Smckusick av = (char **)malloc((i+2) * sizeof(char *)); 56040051Smckusick if (av == NULL) 56140051Smckusick return (NULL); 56240051Smckusick nextcp = fslist; 56340051Smckusick i = 0; 56440051Smckusick av[i++] = nextcp; 56540051Smckusick while (nextcp = index(nextcp, ',')) { 56640051Smckusick *nextcp++ = '\0'; 56740051Smckusick av[i++] = nextcp; 56840051Smckusick } 56940051Smckusick av[i++] = 0; 57040051Smckusick return (av); 57140051Smckusick } 57240051Smckusick 57338632Smckusick #ifdef NFS 57439131Smckusick /* 57539131Smckusick * Handle the getoption arg. 57639131Smckusick * Essentially update "opflags", "retrycnt" and "nfsargs" 57739131Smckusick */ 57839131Smckusick getnfsopts(optarg, nfsargsp, opflagsp, retrycntp) 57939131Smckusick char *optarg; 58039131Smckusick struct nfs_args *nfsargsp; 58139131Smckusick int *opflagsp; 58239131Smckusick int *retrycntp; 58339131Smckusick { 58439131Smckusick register char *cp, *nextcp; 58539131Smckusick int num; 58639131Smckusick char *nump; 58739131Smckusick 58839131Smckusick cp = optarg; 58939131Smckusick while (cp != NULL && *cp != '\0') { 59039131Smckusick if ((nextcp = index(cp, ',')) != NULL) 59139131Smckusick *nextcp++ = '\0'; 59239131Smckusick if ((nump = index(cp, '=')) != NULL) { 59339131Smckusick *nump++ = '\0'; 59439131Smckusick num = atoi(nump); 59539131Smckusick } else 59639131Smckusick num = -1; 59739131Smckusick /* 59839131Smckusick * Just test for a string match and do it 59939131Smckusick */ 60039131Smckusick if (!strcmp(cp, "bg")) { 60139131Smckusick *opflagsp |= BGRND; 60239131Smckusick } else if (!strcmp(cp, "soft")) { 60339131Smckusick nfsargsp->flags |= NFSMNT_SOFT; 60439131Smckusick } else if (!strcmp(cp, "intr")) { 60539131Smckusick nfsargsp->flags |= NFSMNT_INT; 60641911Smckusick } else if (!strcmp(cp, "tcp")) { 60741911Smckusick nfsargsp->sotype = SOCK_STREAM; 60841911Smckusick } else if (!strcmp(cp, "noconn")) { 60941911Smckusick nfsargsp->flags |= NFSMNT_NOCONN; 61039131Smckusick } else if (!strcmp(cp, "retry") && num > 0) { 61139131Smckusick *retrycntp = num; 61239131Smckusick } else if (!strcmp(cp, "rsize") && num > 0) { 61339131Smckusick nfsargsp->rsize = num; 61439131Smckusick nfsargsp->flags |= NFSMNT_RSIZE; 61539131Smckusick } else if (!strcmp(cp, "wsize") && num > 0) { 61639131Smckusick nfsargsp->wsize = num; 61739131Smckusick nfsargsp->flags |= NFSMNT_WSIZE; 61839131Smckusick } else if (!strcmp(cp, "timeo") && num > 0) { 61939131Smckusick nfsargsp->timeo = num; 62039131Smckusick nfsargsp->flags |= NFSMNT_TIMEO; 62139131Smckusick } else if (!strcmp(cp, "retrans") && num > 0) { 62239131Smckusick nfsargsp->retrans = num; 62339131Smckusick nfsargsp->flags |= NFSMNT_RETRANS; 62439131Smckusick } 62539131Smckusick cp = nextcp; 62639131Smckusick } 62739131Smckusick } 62839131Smckusick 62938632Smckusick char * 63041911Smckusick getnfsargs(spec, nfsargsp) 63138632Smckusick char *spec; 63241911Smckusick struct nfs_args *nfsargsp; 63335339Sbostic { 63440273Sbostic extern int errno; 63538632Smckusick register CLIENT *clp; 63638632Smckusick struct hostent *hp; 63739604Smckusick static struct sockaddr_in saddr; 63838632Smckusick struct timeval pertry, try; 63938632Smckusick enum clnt_stat clnt_stat; 64038632Smckusick int so = RPC_ANYSOCK; 64138632Smckusick char *hostp, *delimp; 64238632Smckusick u_short tport; 64339604Smckusick static struct nfhret nfhret; 64439604Smckusick static char nam[MNAMELEN + 1]; 64538632Smckusick 64638632Smckusick strncpy(nam, spec, MNAMELEN); 64738632Smckusick nam[MNAMELEN] = '\0'; 64838632Smckusick if ((delimp = index(spec, '@')) != NULL) { 64938632Smckusick hostp = delimp + 1; 65038632Smckusick } else if ((delimp = index(spec, ':')) != NULL) { 65138632Smckusick hostp = spec; 65238632Smckusick spec = delimp + 1; 65338632Smckusick } else { 65438632Smckusick fprintf(stderr, 65538632Smckusick "No <host>:<dirpath> or <dirpath>@<host> spec\n"); 65638632Smckusick return (0); 65738632Smckusick } 65838632Smckusick *delimp = '\0'; 65938632Smckusick if ((hp = gethostbyname(hostp)) == NULL) { 66038632Smckusick fprintf(stderr, "Can't get net id for host\n"); 66138632Smckusick return (0); 66238632Smckusick } 66338632Smckusick bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 66438632Smckusick nfhret.stat = EACCES; /* Mark not yet successful */ 66538632Smckusick while (retrycnt > 0) { 66638632Smckusick saddr.sin_family = AF_INET; 66738632Smckusick saddr.sin_port = htons(PMAPPORT); 66838632Smckusick if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 66938632Smckusick NFS_VER2, IPPROTO_UDP)) == 0) { 67038632Smckusick if ((opflags & ISBGRND) == 0) 67138632Smckusick clnt_pcreateerror("NFS Portmap"); 67238632Smckusick } else { 67338632Smckusick saddr.sin_port = 0; 67438632Smckusick pertry.tv_sec = 10; 67538632Smckusick pertry.tv_usec = 0; 67638632Smckusick if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 67738632Smckusick RPCMNT_VER1, pertry, &so)) == NULL) { 67838632Smckusick if ((opflags & ISBGRND) == 0) 67938632Smckusick clnt_pcreateerror("Cannot MNT PRC"); 68038632Smckusick } else { 68138632Smckusick clp->cl_auth = authunix_create_default(); 68238632Smckusick try.tv_sec = 10; 68338632Smckusick try.tv_usec = 0; 68438632Smckusick clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 68538632Smckusick xdr_dir, spec, xdr_fh, &nfhret, try); 68638632Smckusick if (clnt_stat != RPC_SUCCESS) { 68738632Smckusick if ((opflags & ISBGRND) == 0) 68838632Smckusick clnt_perror(clp, "Bad MNT RPC"); 68938632Smckusick } else { 69038632Smckusick auth_destroy(clp->cl_auth); 69138632Smckusick clnt_destroy(clp); 69238632Smckusick retrycnt = 0; 69338632Smckusick } 69438632Smckusick } 69538632Smckusick } 69638632Smckusick if (--retrycnt > 0) { 69738632Smckusick if (opflags & BGRND) { 69838632Smckusick opflags &= ~BGRND; 69938632Smckusick if (fork()) 70038632Smckusick return (0); 70138632Smckusick else 70238632Smckusick opflags |= ISBGRND; 70338632Smckusick } 70438632Smckusick sleep(10); 70538632Smckusick } 70638632Smckusick } 70738632Smckusick if (nfhret.stat) { 70838632Smckusick if (opflags & ISBGRND) 70938632Smckusick exit(1); 71039521Smckusick fprintf(stderr, "Can't access %s: ", spec); 71139521Smckusick errno = nfhret.stat; 71239521Smckusick perror(NULL); 71338632Smckusick return (0); 71438632Smckusick } 71538632Smckusick saddr.sin_port = htons(tport); 71641911Smckusick nfsargsp->addr = (struct sockaddr *) &saddr; 71741911Smckusick nfsargsp->fh = &nfhret.nfh; 71841911Smckusick nfsargsp->hostname = nam; 71941911Smckusick return ((caddr_t)nfsargsp); 72035339Sbostic } 72138445Smckusick 72238445Smckusick /* 72338445Smckusick * xdr routines for mount rpc's 72438445Smckusick */ 72538445Smckusick xdr_dir(xdrsp, dirp) 72638445Smckusick XDR *xdrsp; 72738445Smckusick char *dirp; 72838445Smckusick { 72938445Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 73038445Smckusick } 73138445Smckusick 73238445Smckusick xdr_fh(xdrsp, np) 73338445Smckusick XDR *xdrsp; 73438445Smckusick struct nfhret *np; 73538445Smckusick { 73638445Smckusick if (!xdr_u_long(xdrsp, &(np->stat))) 73738445Smckusick return (0); 73838445Smckusick if (np->stat) 73938445Smckusick return (1); 74038445Smckusick return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 74138445Smckusick } 74238632Smckusick #endif /* NFS */ 743