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*40871Smckusick static char sccsid[] = "@(#)mount.c 5.31 (Berkeley) 04/10/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> 3738445Smckusick #include <strings.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(); 6638445Smckusick struct nfs_args nfsargs = { 6738445Smckusick (struct sockaddr_in *)0, 6838445Smckusick (nfsv2fh_t *)0, 6938445Smckusick 0, 7038445Smckusick NFS_WSIZE, 7138445Smckusick NFS_RSIZE, 7238445Smckusick NFS_TIMEO, 7338445Smckusick NFS_RETRANS, 7438445Smckusick (char *)0, 7538445Smckusick }; 765073Sroot 7738445Smckusick struct nfhret { 7838445Smckusick u_long stat; 7938445Smckusick nfsv2fh_t nfh; 8038445Smckusick }; 8140051Smckusick #define DEF_RETRY 10000 8240051Smckusick int retrycnt; 8338445Smckusick #define BGRND 1 8438445Smckusick #define ISBGRND 2 8538445Smckusick int opflags = 0; 8638445Smckusick #endif 8738445Smckusick 8839131Smckusick main(argc, argv, arge) 895073Sroot int argc; 905073Sroot char **argv; 9139131Smckusick char **arge; 921057Sbill { 9335339Sbostic extern char *optarg; 9435339Sbostic extern int optind; 9535339Sbostic register struct fstab *fs; 9635339Sbostic register int cnt; 9740496Smckusick int all, ch, rval, flags, ret, pid, i; 9838632Smckusick long mntsize; 9939465Smckusick struct statfs *mntbuf, *getmntpt(); 10039131Smckusick char *type, *options = NULL; 10140496Smckusick FILE *pidfile; 1021057Sbill 10339131Smckusick envp = arge; 10435339Sbostic all = 0; 10535339Sbostic type = NULL; 10638445Smckusick mnttype = MOUNT_UFS; 10739322Smckusick mntname = "ufs"; 10839333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 10935339Sbostic switch((char)ch) { 11035339Sbostic case 'a': 11135339Sbostic all = 1; 11235339Sbostic break; 11335339Sbostic case 'f': 11435339Sbostic fake = 1; 11535339Sbostic break; 11635339Sbostic case 'r': 11712808Ssam type = FSTAB_RO; 11835339Sbostic break; 11939333Smckusick case 'u': 12039333Smckusick updateflg = M_UPDATE; 12139333Smckusick break; 12235339Sbostic case 'v': 12335339Sbostic verbose = 1; 12435339Sbostic break; 12535339Sbostic case 'w': 12635339Sbostic type = FSTAB_RW; 12735339Sbostic break; 12839131Smckusick case 'o': 12939131Smckusick options = optarg; 13039131Smckusick break; 13138445Smckusick case 't': 13240051Smckusick vfslist = makevfslist(optarg); 13339322Smckusick mnttype = getmnttype(optarg); 13439322Smckusick break; 13535339Sbostic case '?': 13635339Sbostic default: 13735339Sbostic usage(); 13839131Smckusick /* NOTREACHED */ 1395073Sroot } 14035339Sbostic argc -= optind; 14135339Sbostic argv += optind; 14235339Sbostic 14335339Sbostic /* NOSTRICT */ 14435339Sbostic 1454460Sroot if (all) { 14635369Sbostic rval = 0; 14739333Smckusick while (fs = getfsent()) { 14835372Sbostic if (BADTYPE(fs->fs_type)) 14935372Sbostic continue; 15040844Smckusick if (badvfsname(fs->fs_vfstype, vfslist)) 15140051Smckusick continue; 15235372Sbostic /* `/' is special, it's always mounted */ 15335372Sbostic if (!strcmp(fs->fs_file, "/")) 15439333Smckusick flags = M_UPDATE; 15539333Smckusick else 15639333Smckusick flags = updateflg; 15739333Smckusick mnttype = getmnttype(fs->fs_vfstype); 15839333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 15939333Smckusick type, options, fs->fs_mntops); 16035372Sbostic } 16135341Sbostic exit(rval); 16235339Sbostic } 1635073Sroot 16435339Sbostic if (argc == 0) { 16535339Sbostic if (verbose || fake || type) 16635339Sbostic usage(); 16740337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 16839319Smckusick fprintf(stderr, 16939319Smckusick "mount: cannot get mount information\n"); 17038632Smckusick exit(1); 17138632Smckusick } 17240844Smckusick for (i = 0; i < mntsize; i++) { 17340844Smckusick if (badvfstype(mntbuf[i].f_type, vfslist)) 17440844Smckusick continue; 17538632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 17639316Smckusick mntbuf[i].f_flags); 17740844Smckusick } 1784460Sroot exit(0); 1791057Sbill } 18012808Ssam 18139465Smckusick if (argc == 1 && updateflg) { 18239465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 18339465Smckusick fprintf(stderr, 18439465Smckusick "mount: unknown special file or file system %s.\n", 18539465Smckusick *argv); 18639465Smckusick exit(1); 18739465Smckusick } 18839465Smckusick mnttype = mntbuf->f_type; 18940124Smckusick if (!strcmp(mntbuf->f_mntfromname, "root_device")) { 19040124Smckusick fs = getfsfile("/"); 19140124Smckusick strcpy(mntbuf->f_mntfromname, fs->fs_spec); 19240124Smckusick } 19340496Smckusick ret = mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname, 19440496Smckusick updateflg, type, options, NULL); 19540496Smckusick } else if (argc == 1) { 19635339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 19735339Sbostic fprintf(stderr, 19835339Sbostic "mount: unknown special file or file system %s.\n", 19935339Sbostic *argv); 20035339Sbostic exit(1); 20135339Sbostic } 20235339Sbostic if (BADTYPE(fs->fs_type)) { 20335339Sbostic fprintf(stderr, 20435339Sbostic "mount: %s has unknown file system type.\n", *argv); 20535339Sbostic exit(1); 20635339Sbostic } 20739333Smckusick mnttype = getmnttype(fs->fs_vfstype); 20840496Smckusick ret = mountfs(fs->fs_spec, fs->fs_file, updateflg, 20940496Smckusick type, options, fs->fs_mntops); 21040496Smckusick } else if (argc != 2) { 21140496Smckusick usage(); 21240496Smckusick ret = 1; 21340496Smckusick } else { 21440496Smckusick ret = mountfs(argv[0], argv[1], updateflg, type, options, NULL); 21512808Ssam } 21640496Smckusick if ((pidfile = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 21740496Smckusick pid = 0; 21840496Smckusick fscanf(pidfile, "%d", &pid); 21940496Smckusick fclose(pidfile); 22040496Smckusick if (pid > 0) 22140496Smckusick kill(pid, SIGHUP); 22240496Smckusick } 22340496Smckusick exit (ret); 22412808Ssam } 22512808Ssam 22639333Smckusick mountfs(spec, name, flags, type, options, mntopts) 22739131Smckusick char *spec, *name, *type, *options, *mntopts; 22839333Smckusick int flags; 22912808Ssam { 23035339Sbostic extern int errno; 23135339Sbostic register int cnt; 23239333Smckusick int argc, status, i; 23338070Smckusick struct ufs_args args; 23439131Smckusick char *argp, *argv[50]; 23539322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2361057Sbill 23739333Smckusick if (mntopts) 23839333Smckusick getstdopts(mntopts, &flags); 23939316Smckusick if (options) 24039316Smckusick getstdopts(options, &flags); 24139333Smckusick if (type) 24239333Smckusick getstdopts(type, &flags); 24339316Smckusick switch (mnttype) { 24439316Smckusick case MOUNT_UFS: 24539333Smckusick if (mntopts) 24639333Smckusick getufsopts(mntopts, &flags); 24739316Smckusick if (options) 24839316Smckusick getufsopts(options, &flags); 24939316Smckusick args.fspec = spec; 25040369Smckusick args.exroot = DEFAULT_ROOTUID; 25140496Smckusick if (flags & M_RDONLY) 25240496Smckusick args.exflags = M_EXRDONLY; 25340496Smckusick else 25440496Smckusick args.exflags = 0; 25539316Smckusick argp = (caddr_t)&args; 25639316Smckusick break; 25738632Smckusick 25838632Smckusick #ifdef NFS 25939316Smckusick case MOUNT_NFS: 26040051Smckusick retrycnt = DEF_RETRY; 26139333Smckusick if (mntopts) 26239333Smckusick getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt); 26339316Smckusick if (options) 26439333Smckusick getnfsopts(options, &nfsargs, &opflags, &retrycnt); 26539316Smckusick if (argp = getnfsargs(spec, name, type)) 26639316Smckusick break; 26739316Smckusick return (1); 26838632Smckusick #endif /* NFS */ 26938632Smckusick 27039316Smckusick case MOUNT_MFS: 27139322Smckusick default: 27239322Smckusick argv[0] = mntname; 27339329Smckusick argc = 1; 27439322Smckusick if (flags) { 27539322Smckusick argv[argc++] = "-F"; 27639322Smckusick sprintf(flagval, "%d", flags); 27739322Smckusick argv[argc++] = flagval; 27839322Smckusick } 27939333Smckusick if (mntopts) 28039333Smckusick argc += getexecopts(mntopts, &argv[argc]); 28139329Smckusick if (options) 28239329Smckusick argc += getexecopts(options, &argv[argc]); 28339316Smckusick argv[argc++] = spec; 28439316Smckusick argv[argc++] = name; 28539521Smckusick argv[argc++] = NULL; 28639603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 28739316Smckusick if (verbose) { 28839322Smckusick printf("exec: %s", execname); 28939322Smckusick for (i = 1; i < argc; i++) 29039316Smckusick printf(" %s", argv[i]); 29139316Smckusick printf("\n"); 29239316Smckusick } 29339316Smckusick if (fake) 29439316Smckusick break; 29539316Smckusick if (i = vfork()) { 29639316Smckusick if (i == -1) { 29739322Smckusick perror("mount: vfork starting file system"); 29839316Smckusick return (1); 29939131Smckusick } 30039316Smckusick if (waitpid(i, &status, 0) != -1 && 30139316Smckusick WIFEXITED(status) && 30239316Smckusick WEXITSTATUS(status) != 0) 30339316Smckusick return (WEXITSTATUS(status)); 30439322Smckusick spec = mntname; 30539316Smckusick goto out; 30639316Smckusick } 30739322Smckusick execve(execname, argv, envp); 30839603Smckusick fprintf(stderr, "mount: cannot exec %s for %s: ", 30939603Smckusick execname, name); 31039603Smckusick perror(""); 31139316Smckusick exit (1); 31239316Smckusick /* NOTREACHED */ 31338632Smckusick 31439316Smckusick } 31539316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 31639316Smckusick if (opflags & ISBGRND) 31739316Smckusick exit(1); 31839316Smckusick fprintf(stderr, "%s on %s: ", spec, name); 31939316Smckusick switch (errno) { 32039316Smckusick case EMFILE: 32139316Smckusick fprintf(stderr, "Mount table full\n"); 32239316Smckusick break; 32339316Smckusick case EINVAL: 32439333Smckusick if (flags & M_UPDATE) 32539333Smckusick fprintf(stderr, "Specified device does %s\n", 32639333Smckusick "not match mounted device"); 32739333Smckusick else 32839333Smckusick fprintf(stderr, "Bogus super block\n"); 32939316Smckusick break; 33039333Smckusick case EOPNOTSUPP: 33139333Smckusick fprintf(stderr, "Operation not supported\n"); 33239333Smckusick break; 33339316Smckusick default: 33439316Smckusick perror((char *)NULL); 33539316Smckusick break; 3364460Sroot } 33739316Smckusick return(1); 3384460Sroot } 33935339Sbostic 34039131Smckusick out: 34112808Ssam if (verbose) 34239316Smckusick prmount(spec, name, flags); 34335339Sbostic 34438445Smckusick if (opflags & ISBGRND) 34538445Smckusick exit(); 34638445Smckusick else 34738445Smckusick return(0); 3481057Sbill } 34935339Sbostic 35035339Sbostic static 35139316Smckusick prmount(spec, name, flags) 35239316Smckusick char *spec, *name; 35339316Smckusick long flags; 35435339Sbostic { 35538632Smckusick 35638445Smckusick if (opflags & ISBGRND) 35738445Smckusick return; 35838632Smckusick printf("%s on %s", spec, name); 35939316Smckusick if (flags & M_RDONLY) 36039316Smckusick printf(" (read-only)"); 36139316Smckusick if (flags & M_NOEXEC) 36239316Smckusick printf(" (noexec)"); 36339316Smckusick if (flags & M_NOSUID) 36439316Smckusick printf(" (nosuid)"); 36539316Smckusick if (flags & M_NODEV) 36639316Smckusick printf(" (nodev)"); 36739316Smckusick if (flags & M_SYNCHRONOUS) 36839316Smckusick printf(" (synchronous)"); 36939333Smckusick if (flags & M_UPDATE) 37039333Smckusick printf(" (update only)"); 37135339Sbostic printf("\n"); 37235339Sbostic } 37335339Sbostic 37439133Smckusick getmnttype(fstype) 37539133Smckusick char *fstype; 37639133Smckusick { 37739133Smckusick 37839322Smckusick mntname = fstype; 37939133Smckusick if (!strcmp(fstype, "ufs")) 38039133Smckusick return (MOUNT_UFS); 38139133Smckusick if (!strcmp(fstype, "nfs")) 38239133Smckusick return (MOUNT_NFS); 38339133Smckusick if (!strcmp(fstype, "mfs")) 38439133Smckusick return (MOUNT_MFS); 38539133Smckusick return (0); 38639133Smckusick } 38739133Smckusick 38838632Smckusick usage() 38935339Sbostic { 390*40871Smckusick 391*40871Smckusick fprintf(stderr, "usage:\n mount %s %s\n mount %s\n mount %s\n", 392*40871Smckusick "[ -frwu ] [ -t nfs | ufs | external_type ]", 393*40871Smckusick "[ -o options ] special node", 394*40871Smckusick "[ -afrwu ] [ -t nfs | ufs | external_type ]", 395*40871Smckusick "[ -frwu ] special | node"); 39635339Sbostic exit(1); 39735339Sbostic } 39835339Sbostic 39939316Smckusick getstdopts(options, flagp) 40039316Smckusick char *options; 40139316Smckusick long *flagp; 40239316Smckusick { 40339316Smckusick register char *opt; 40439316Smckusick int negative; 40539316Smckusick char *optbuf[BUFSIZ], *strtok(); 40639316Smckusick 40739316Smckusick strcpy(optbuf, options); 40839316Smckusick for (opt = strtok(optbuf, ","); opt; opt = strtok(NULL, ",")) { 40939316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 41039316Smckusick negative++; 41139316Smckusick opt += 2; 41239316Smckusick } else { 41339316Smckusick negative = 0; 41439316Smckusick } 41539333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 41639333Smckusick *flagp |= M_RDONLY; 41739333Smckusick continue; 41839333Smckusick } 41939333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 42039333Smckusick *flagp &= ~M_RDONLY; 42139333Smckusick continue; 42239333Smckusick } 42339316Smckusick if (!strcasecmp(opt, "exec")) { 42439316Smckusick if (negative) 42539316Smckusick *flagp |= M_NOEXEC; 42639333Smckusick else 42739333Smckusick *flagp &= ~M_NOEXEC; 42839316Smckusick continue; 42939316Smckusick } 43039316Smckusick if (!strcasecmp(opt, "suid")) { 43139316Smckusick if (negative) 43239316Smckusick *flagp |= M_NOSUID; 43339333Smckusick else 43439333Smckusick *flagp &= ~M_NOSUID; 43539316Smckusick continue; 43639316Smckusick } 43739316Smckusick if (!strcasecmp(opt, "dev")) { 43839316Smckusick if (negative) 43939316Smckusick *flagp |= M_NODEV; 44039333Smckusick else 44139333Smckusick *flagp &= ~M_NODEV; 44239316Smckusick continue; 44339316Smckusick } 44439316Smckusick if (!strcasecmp(opt, "synchronous")) { 44539316Smckusick if (!negative) 44639316Smckusick *flagp |= M_SYNCHRONOUS; 44739333Smckusick else 44839333Smckusick *flagp &= ~M_SYNCHRONOUS; 44939316Smckusick continue; 45039316Smckusick } 45139316Smckusick } 45239316Smckusick } 45339316Smckusick 45439131Smckusick getufsopts(options, flagp) 45539131Smckusick char *options; 45639131Smckusick long *flagp; 45739131Smckusick { 45839131Smckusick 45939131Smckusick return; 46039131Smckusick } 46139131Smckusick 46239329Smckusick getexecopts(options, argv) 46339131Smckusick char *options; 46439131Smckusick char **argv; 46539131Smckusick { 46639131Smckusick register int argc = 0; 46739131Smckusick register char *opt; 46839131Smckusick char *strtok(); 46939131Smckusick 47039131Smckusick for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { 47139131Smckusick if (opt[0] != '-') 47239131Smckusick continue; 47339131Smckusick argv[argc++] = opt; 47439131Smckusick if (opt[2] == '\0' || opt[2] != '=') 47539131Smckusick continue; 47639131Smckusick opt[2] = '\0'; 47739131Smckusick argv[argc++] = &opt[3]; 47839131Smckusick } 47939131Smckusick return (argc); 48039131Smckusick } 48139131Smckusick 48239465Smckusick struct statfs * 48339465Smckusick getmntpt(name) 48439465Smckusick char *name; 48539465Smckusick { 48639465Smckusick long mntsize; 48739465Smckusick register long i; 48839465Smckusick struct statfs *mntbuf; 48939465Smckusick 49040337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 49139465Smckusick for (i = 0; i < mntsize; i++) { 49239465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 49339465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 49439465Smckusick return (&mntbuf[i]); 49539465Smckusick } 49639465Smckusick return ((struct statfs *)0); 49739465Smckusick } 49839465Smckusick 49940051Smckusick static int skipvfs; 50040051Smckusick 50140051Smckusick badvfstype(vfstype, vfslist) 50240844Smckusick long vfstype; 50340051Smckusick char **vfslist; 50440051Smckusick { 50540051Smckusick 50640051Smckusick if (vfslist == 0) 50740051Smckusick return(0); 50840051Smckusick while (*vfslist) { 50940844Smckusick if (vfstype == getmnttype(*vfslist)) 51040051Smckusick return(skipvfs); 51140051Smckusick vfslist++; 51240051Smckusick } 51340051Smckusick return (!skipvfs); 51440051Smckusick } 51540051Smckusick 51640844Smckusick badvfsname(vfsname, vfslist) 51740844Smckusick char *vfsname; 51840844Smckusick char **vfslist; 51940844Smckusick { 52040844Smckusick 52140844Smckusick if (vfslist == 0) 52240844Smckusick return(0); 52340844Smckusick while (*vfslist) { 52440844Smckusick if (strcmp(vfsname, *vfslist) == 0) 52540844Smckusick return(skipvfs); 52640844Smckusick vfslist++; 52740844Smckusick } 52840844Smckusick return (!skipvfs); 52940844Smckusick } 53040844Smckusick 53140051Smckusick char ** 53240051Smckusick makevfslist(fslist) 53340051Smckusick char *fslist; 53440051Smckusick { 53540051Smckusick register char **av, *nextcp; 53640051Smckusick register int i; 53740051Smckusick char *malloc(); 53840051Smckusick 53940051Smckusick if (fslist == NULL) 54040051Smckusick return (NULL); 54140051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 54240051Smckusick fslist += 2; 54340051Smckusick skipvfs = 1; 54440051Smckusick } 54540051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 54640051Smckusick if (*nextcp == ',') 54740051Smckusick i++; 54840051Smckusick av = (char **)malloc((i+2) * sizeof(char *)); 54940051Smckusick if (av == NULL) 55040051Smckusick return (NULL); 55140051Smckusick nextcp = fslist; 55240051Smckusick i = 0; 55340051Smckusick av[i++] = nextcp; 55440051Smckusick while (nextcp = index(nextcp, ',')) { 55540051Smckusick *nextcp++ = '\0'; 55640051Smckusick av[i++] = nextcp; 55740051Smckusick } 55840051Smckusick av[i++] = 0; 55940051Smckusick return (av); 56040051Smckusick } 56140051Smckusick 56238632Smckusick #ifdef NFS 56339131Smckusick /* 56439131Smckusick * Handle the getoption arg. 56539131Smckusick * Essentially update "opflags", "retrycnt" and "nfsargs" 56639131Smckusick */ 56739131Smckusick getnfsopts(optarg, nfsargsp, opflagsp, retrycntp) 56839131Smckusick char *optarg; 56939131Smckusick struct nfs_args *nfsargsp; 57039131Smckusick int *opflagsp; 57139131Smckusick int *retrycntp; 57239131Smckusick { 57339131Smckusick register char *cp, *nextcp; 57439131Smckusick int num; 57539131Smckusick char *nump; 57639131Smckusick 57739131Smckusick cp = optarg; 57839131Smckusick while (cp != NULL && *cp != '\0') { 57939131Smckusick if ((nextcp = index(cp, ',')) != NULL) 58039131Smckusick *nextcp++ = '\0'; 58139131Smckusick if ((nump = index(cp, '=')) != NULL) { 58239131Smckusick *nump++ = '\0'; 58339131Smckusick num = atoi(nump); 58439131Smckusick } else 58539131Smckusick num = -1; 58639131Smckusick /* 58739131Smckusick * Just test for a string match and do it 58839131Smckusick */ 58939131Smckusick if (!strcmp(cp, "bg")) { 59039131Smckusick *opflagsp |= BGRND; 59139131Smckusick } else if (!strcmp(cp, "soft")) { 59239131Smckusick nfsargsp->flags |= NFSMNT_SOFT; 59339131Smckusick } else if (!strcmp(cp, "intr")) { 59439131Smckusick nfsargsp->flags |= NFSMNT_INT; 59539131Smckusick } else if (!strcmp(cp, "retry") && num > 0) { 59639131Smckusick *retrycntp = num; 59739131Smckusick } else if (!strcmp(cp, "rsize") && num > 0) { 59839131Smckusick nfsargsp->rsize = num; 59939131Smckusick nfsargsp->flags |= NFSMNT_RSIZE; 60039131Smckusick } else if (!strcmp(cp, "wsize") && num > 0) { 60139131Smckusick nfsargsp->wsize = num; 60239131Smckusick nfsargsp->flags |= NFSMNT_WSIZE; 60339131Smckusick } else if (!strcmp(cp, "timeo") && num > 0) { 60439131Smckusick nfsargsp->timeo = num; 60539131Smckusick nfsargsp->flags |= NFSMNT_TIMEO; 60639131Smckusick } else if (!strcmp(cp, "retrans") && num > 0) { 60739131Smckusick nfsargsp->retrans = num; 60839131Smckusick nfsargsp->flags |= NFSMNT_RETRANS; 60939131Smckusick } 61039131Smckusick cp = nextcp; 61139131Smckusick } 61239131Smckusick } 61339131Smckusick 61438632Smckusick char * 61538632Smckusick getnfsargs(spec) 61638632Smckusick char *spec; 61735339Sbostic { 61840273Sbostic extern int errno; 61938632Smckusick register CLIENT *clp; 62038632Smckusick struct hostent *hp; 62139604Smckusick static struct sockaddr_in saddr; 62238632Smckusick struct timeval pertry, try; 62338632Smckusick enum clnt_stat clnt_stat; 62438632Smckusick int so = RPC_ANYSOCK; 62538632Smckusick char *hostp, *delimp; 62638632Smckusick u_short tport; 62739604Smckusick static struct nfhret nfhret; 62839604Smckusick static char nam[MNAMELEN + 1]; 62938632Smckusick 63038632Smckusick strncpy(nam, spec, MNAMELEN); 63138632Smckusick nam[MNAMELEN] = '\0'; 63238632Smckusick if ((delimp = index(spec, '@')) != NULL) { 63338632Smckusick hostp = delimp + 1; 63438632Smckusick } else if ((delimp = index(spec, ':')) != NULL) { 63538632Smckusick hostp = spec; 63638632Smckusick spec = delimp + 1; 63738632Smckusick } else { 63838632Smckusick fprintf(stderr, 63938632Smckusick "No <host>:<dirpath> or <dirpath>@<host> spec\n"); 64038632Smckusick return (0); 64138632Smckusick } 64238632Smckusick *delimp = '\0'; 64338632Smckusick if ((hp = gethostbyname(hostp)) == NULL) { 64438632Smckusick fprintf(stderr, "Can't get net id for host\n"); 64538632Smckusick return (0); 64638632Smckusick } 64738632Smckusick bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 64838632Smckusick nfhret.stat = EACCES; /* Mark not yet successful */ 64938632Smckusick while (retrycnt > 0) { 65038632Smckusick saddr.sin_family = AF_INET; 65138632Smckusick saddr.sin_port = htons(PMAPPORT); 65238632Smckusick if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 65338632Smckusick NFS_VER2, IPPROTO_UDP)) == 0) { 65438632Smckusick if ((opflags & ISBGRND) == 0) 65538632Smckusick clnt_pcreateerror("NFS Portmap"); 65638632Smckusick } else { 65738632Smckusick saddr.sin_port = 0; 65838632Smckusick pertry.tv_sec = 10; 65938632Smckusick pertry.tv_usec = 0; 66038632Smckusick if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 66138632Smckusick RPCMNT_VER1, pertry, &so)) == NULL) { 66238632Smckusick if ((opflags & ISBGRND) == 0) 66338632Smckusick clnt_pcreateerror("Cannot MNT PRC"); 66438632Smckusick } else { 66538632Smckusick clp->cl_auth = authunix_create_default(); 66638632Smckusick try.tv_sec = 10; 66738632Smckusick try.tv_usec = 0; 66838632Smckusick clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 66938632Smckusick xdr_dir, spec, xdr_fh, &nfhret, try); 67038632Smckusick if (clnt_stat != RPC_SUCCESS) { 67138632Smckusick if ((opflags & ISBGRND) == 0) 67238632Smckusick clnt_perror(clp, "Bad MNT RPC"); 67338632Smckusick } else { 67438632Smckusick auth_destroy(clp->cl_auth); 67538632Smckusick clnt_destroy(clp); 67638632Smckusick retrycnt = 0; 67738632Smckusick } 67838632Smckusick } 67938632Smckusick } 68038632Smckusick if (--retrycnt > 0) { 68138632Smckusick if (opflags & BGRND) { 68238632Smckusick opflags &= ~BGRND; 68338632Smckusick if (fork()) 68438632Smckusick return (0); 68538632Smckusick else 68638632Smckusick opflags |= ISBGRND; 68738632Smckusick } 68838632Smckusick sleep(10); 68938632Smckusick } 69038632Smckusick } 69138632Smckusick if (nfhret.stat) { 69238632Smckusick if (opflags & ISBGRND) 69338632Smckusick exit(1); 69439521Smckusick fprintf(stderr, "Can't access %s: ", spec); 69539521Smckusick errno = nfhret.stat; 69639521Smckusick perror(NULL); 69738632Smckusick return (0); 69838632Smckusick } 69938632Smckusick saddr.sin_port = htons(tport); 70038632Smckusick nfsargs.addr = &saddr; 70138632Smckusick nfsargs.fh = &nfhret.nfh; 70238632Smckusick nfsargs.hostname = nam; 70338632Smckusick return ((caddr_t)&nfsargs); 70435339Sbostic } 70538445Smckusick 70638445Smckusick /* 70738445Smckusick * xdr routines for mount rpc's 70838445Smckusick */ 70938445Smckusick xdr_dir(xdrsp, dirp) 71038445Smckusick XDR *xdrsp; 71138445Smckusick char *dirp; 71238445Smckusick { 71338445Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 71438445Smckusick } 71538445Smckusick 71638445Smckusick xdr_fh(xdrsp, np) 71738445Smckusick XDR *xdrsp; 71838445Smckusick struct nfhret *np; 71938445Smckusick { 72038445Smckusick if (!xdr_u_long(xdrsp, &(np->stat))) 72138445Smckusick return (0); 72238445Smckusick if (np->stat) 72338445Smckusick return (1); 72438445Smckusick return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 72538445Smckusick } 72638632Smckusick #endif /* NFS */ 727