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*40051Smckusick static char sccsid[] = "@(#)mount.c 5.22 (Berkeley) 02/09/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> 3638445Smckusick #include <strings.h> 3738445Smckusick #include <sys/dir.h> 3838445Smckusick #include <sys/uio.h> 3938445Smckusick #include <sys/namei.h> 4038445Smckusick #include <sys/mount.h> 4138445Smckusick #ifdef NFS 4238445Smckusick #include <sys/socket.h> 4338445Smckusick #include <sys/socketvar.h> 4438445Smckusick #include <netdb.h> 4538445Smckusick #include <rpc/rpc.h> 4638445Smckusick #include <rpc/pmap_clnt.h> 4738445Smckusick #include <rpc/pmap_prot.h> 4838445Smckusick #include <nfs/rpcv2.h> 4938445Smckusick #include <nfs/nfsv2.h> 5038445Smckusick #include <nfs/nfs.h> 5138445Smckusick #endif 521057Sbill 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; 61*40051Smckusick 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 }; 81*40051Smckusick #define DEF_RETRY 10000 82*40051Smckusick 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; 9739333Smckusick int all, ch, rval, flags, i; 9838632Smckusick long mntsize; 9939465Smckusick struct statfs *mntbuf, *getmntpt(); 10039131Smckusick char *type, *options = NULL; 1011057Sbill 10239131Smckusick envp = arge; 10335339Sbostic all = 0; 10435339Sbostic type = NULL; 10538445Smckusick mnttype = MOUNT_UFS; 10639322Smckusick mntname = "ufs"; 10739333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 10835339Sbostic switch((char)ch) { 10935339Sbostic case 'a': 11035339Sbostic all = 1; 11135339Sbostic break; 11235339Sbostic case 'f': 11335339Sbostic fake = 1; 11435339Sbostic break; 11535339Sbostic case 'r': 11612808Ssam type = FSTAB_RO; 11735339Sbostic break; 11839333Smckusick case 'u': 11939333Smckusick updateflg = M_UPDATE; 12039333Smckusick break; 12135339Sbostic case 'v': 12235339Sbostic verbose = 1; 12335339Sbostic break; 12435339Sbostic case 'w': 12535339Sbostic type = FSTAB_RW; 12635339Sbostic break; 12739131Smckusick case 'o': 12839131Smckusick options = optarg; 12939131Smckusick break; 13038445Smckusick case 't': 131*40051Smckusick vfslist = makevfslist(optarg); 13239322Smckusick mnttype = getmnttype(optarg); 13339322Smckusick break; 13435339Sbostic case '?': 13535339Sbostic default: 13635339Sbostic usage(); 13739131Smckusick /* NOTREACHED */ 1385073Sroot } 13935339Sbostic argc -= optind; 14035339Sbostic argv += optind; 14135339Sbostic 14235339Sbostic /* NOSTRICT */ 14335339Sbostic 1444460Sroot if (all) { 14535369Sbostic rval = 0; 14639333Smckusick while (fs = getfsent()) { 14735372Sbostic if (BADTYPE(fs->fs_type)) 14835372Sbostic continue; 149*40051Smckusick if (badvfstype(fs->fs_vfstype, vfslist)) 150*40051Smckusick continue; 15135372Sbostic /* `/' is special, it's always mounted */ 15235372Sbostic if (!strcmp(fs->fs_file, "/")) 15339333Smckusick flags = M_UPDATE; 15439333Smckusick else 15539333Smckusick flags = updateflg; 15639333Smckusick mnttype = getmnttype(fs->fs_vfstype); 15739333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 15839333Smckusick type, options, fs->fs_mntops); 15935372Sbostic } 16035341Sbostic exit(rval); 16135339Sbostic } 1625073Sroot 16335339Sbostic if (argc == 0) { 16435339Sbostic if (verbose || fake || type) 16535339Sbostic usage(); 16639319Smckusick if ((mntsize = getmntinfo(&mntbuf)) == 0) { 16739319Smckusick fprintf(stderr, 16839319Smckusick "mount: cannot get mount information\n"); 16938632Smckusick exit(1); 17038632Smckusick } 17139316Smckusick for (i = 0; i < mntsize; i++) 17238632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 17339316Smckusick mntbuf[i].f_flags); 1744460Sroot exit(0); 1751057Sbill } 17612808Ssam 17739465Smckusick if (argc == 1 && updateflg) { 17839465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 17939465Smckusick fprintf(stderr, 18039465Smckusick "mount: unknown special file or file system %s.\n", 18139465Smckusick *argv); 18239465Smckusick exit(1); 18339465Smckusick } 18439465Smckusick mnttype = mntbuf->f_type; 18539465Smckusick exit(mountfs(mntbuf->f_mntfromname, mntbuf->f_mntonname, 18639465Smckusick updateflg, type, options, NULL)); 18739465Smckusick } 18839465Smckusick 18935339Sbostic if (argc == 1) { 19035339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 19135339Sbostic fprintf(stderr, 19235339Sbostic "mount: unknown special file or file system %s.\n", 19335339Sbostic *argv); 19435339Sbostic exit(1); 19535339Sbostic } 19635339Sbostic if (BADTYPE(fs->fs_type)) { 19735339Sbostic fprintf(stderr, 19835339Sbostic "mount: %s has unknown file system type.\n", *argv); 19935339Sbostic exit(1); 20035339Sbostic } 20139333Smckusick mnttype = getmnttype(fs->fs_vfstype); 20239333Smckusick exit(mountfs(fs->fs_spec, fs->fs_file, updateflg, 20339333Smckusick type, options, fs->fs_mntops)); 20412808Ssam } 2051057Sbill 20635339Sbostic if (argc != 2) 20735339Sbostic usage(); 20812808Ssam 20939333Smckusick exit(mountfs(argv[0], argv[1], updateflg, type, options, NULL)); 21012808Ssam } 21112808Ssam 21239333Smckusick mountfs(spec, name, flags, type, options, mntopts) 21339131Smckusick char *spec, *name, *type, *options, *mntopts; 21439333Smckusick int flags; 21512808Ssam { 21635339Sbostic extern int errno; 21735339Sbostic register int cnt; 21839333Smckusick int argc, status, i; 21938070Smckusick struct ufs_args args; 22039131Smckusick char *argp, *argv[50]; 22139322Smckusick char execname[MAXPATHLEN + 1], flagval[12]; 2221057Sbill 22339333Smckusick if (mntopts) 22439333Smckusick getstdopts(mntopts, &flags); 22539316Smckusick if (options) 22639316Smckusick getstdopts(options, &flags); 22739333Smckusick if (type) 22839333Smckusick getstdopts(type, &flags); 22939316Smckusick switch (mnttype) { 23039316Smckusick case MOUNT_UFS: 23139333Smckusick if (mntopts) 23239333Smckusick getufsopts(mntopts, &flags); 23339316Smckusick if (options) 23439316Smckusick getufsopts(options, &flags); 23539316Smckusick args.fspec = spec; 23639316Smckusick argp = (caddr_t)&args; 23739316Smckusick break; 23838632Smckusick 23938632Smckusick #ifdef NFS 24039316Smckusick case MOUNT_NFS: 241*40051Smckusick retrycnt = DEF_RETRY; 24239333Smckusick if (mntopts) 24339333Smckusick getnfsopts(mntopts, &nfsargs, &opflags, &retrycnt); 24439316Smckusick if (options) 24539333Smckusick getnfsopts(options, &nfsargs, &opflags, &retrycnt); 24639316Smckusick if (argp = getnfsargs(spec, name, type)) 24739316Smckusick break; 24839316Smckusick return (1); 24938632Smckusick #endif /* NFS */ 25038632Smckusick 25139316Smckusick case MOUNT_MFS: 25239322Smckusick default: 25339322Smckusick argv[0] = mntname; 25439329Smckusick argc = 1; 25539322Smckusick if (flags) { 25639322Smckusick argv[argc++] = "-F"; 25739322Smckusick sprintf(flagval, "%d", flags); 25839322Smckusick argv[argc++] = flagval; 25939322Smckusick } 26039333Smckusick if (mntopts) 26139333Smckusick argc += getexecopts(mntopts, &argv[argc]); 26239329Smckusick if (options) 26339329Smckusick argc += getexecopts(options, &argv[argc]); 26439316Smckusick argv[argc++] = spec; 26539316Smckusick argv[argc++] = name; 26639521Smckusick argv[argc++] = NULL; 26739603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 26839316Smckusick if (verbose) { 26939322Smckusick printf("exec: %s", execname); 27039322Smckusick for (i = 1; i < argc; i++) 27139316Smckusick printf(" %s", argv[i]); 27239316Smckusick printf("\n"); 27339316Smckusick } 27439316Smckusick if (fake) 27539316Smckusick break; 27639316Smckusick if (i = vfork()) { 27739316Smckusick if (i == -1) { 27839322Smckusick perror("mount: vfork starting file system"); 27939316Smckusick return (1); 28039131Smckusick } 28139316Smckusick if (waitpid(i, &status, 0) != -1 && 28239316Smckusick WIFEXITED(status) && 28339316Smckusick WEXITSTATUS(status) != 0) 28439316Smckusick return (WEXITSTATUS(status)); 28539322Smckusick spec = mntname; 28639316Smckusick goto out; 28739316Smckusick } 28839322Smckusick execve(execname, argv, envp); 28939603Smckusick fprintf(stderr, "mount: cannot exec %s for %s: ", 29039603Smckusick execname, name); 29139603Smckusick perror(""); 29239316Smckusick exit (1); 29339316Smckusick /* NOTREACHED */ 29438632Smckusick 29539316Smckusick } 29639316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 29739316Smckusick if (opflags & ISBGRND) 29839316Smckusick exit(1); 29939316Smckusick fprintf(stderr, "%s on %s: ", spec, name); 30039316Smckusick switch (errno) { 30139316Smckusick case EMFILE: 30239316Smckusick fprintf(stderr, "Mount table full\n"); 30339316Smckusick break; 30439316Smckusick case EINVAL: 30539333Smckusick if (flags & M_UPDATE) 30639333Smckusick fprintf(stderr, "Specified device does %s\n", 30739333Smckusick "not match mounted device"); 30839333Smckusick else 30939333Smckusick fprintf(stderr, "Bogus super block\n"); 31039316Smckusick break; 31139333Smckusick case EOPNOTSUPP: 31239333Smckusick fprintf(stderr, "Operation not supported\n"); 31339333Smckusick break; 31439316Smckusick default: 31539316Smckusick perror((char *)NULL); 31639316Smckusick break; 3174460Sroot } 31839316Smckusick return(1); 3194460Sroot } 32035339Sbostic 32139131Smckusick out: 32212808Ssam if (verbose) 32339316Smckusick prmount(spec, name, flags); 32435339Sbostic 32538445Smckusick if (opflags & ISBGRND) 32638445Smckusick exit(); 32738445Smckusick else 32838445Smckusick return(0); 3291057Sbill } 33035339Sbostic 33135339Sbostic static 33239316Smckusick prmount(spec, name, flags) 33339316Smckusick char *spec, *name; 33439316Smckusick long flags; 33535339Sbostic { 33638632Smckusick register char *root; 33738632Smckusick 33838445Smckusick if (opflags & ISBGRND) 33938445Smckusick return; 34038632Smckusick /* 34138632Smckusick * trim trailing /'s and find last component of name 34238632Smckusick */ 34338632Smckusick for (root = index(spec, '\0'); *--root == '/';) 34438632Smckusick /* void */; 34538632Smckusick *++root = '\0'; 34638632Smckusick if (root = rindex(spec, '/')) 34738632Smckusick spec = root + 1; 34838632Smckusick printf("%s on %s", spec, name); 34939316Smckusick if (flags & M_RDONLY) 35039316Smckusick printf(" (read-only)"); 35139316Smckusick if (flags & M_NOEXEC) 35239316Smckusick printf(" (noexec)"); 35339316Smckusick if (flags & M_NOSUID) 35439316Smckusick printf(" (nosuid)"); 35539316Smckusick if (flags & M_NODEV) 35639316Smckusick printf(" (nodev)"); 35739316Smckusick if (flags & M_SYNCHRONOUS) 35839316Smckusick printf(" (synchronous)"); 35939333Smckusick if (flags & M_UPDATE) 36039333Smckusick printf(" (update only)"); 36135339Sbostic printf("\n"); 36235339Sbostic } 36335339Sbostic 36439133Smckusick getmnttype(fstype) 36539133Smckusick char *fstype; 36639133Smckusick { 36739133Smckusick 36839322Smckusick mntname = fstype; 36939133Smckusick if (!strcmp(fstype, "ufs")) 37039133Smckusick return (MOUNT_UFS); 37139133Smckusick if (!strcmp(fstype, "nfs")) 37239133Smckusick return (MOUNT_NFS); 37339133Smckusick if (!strcmp(fstype, "mfs")) 37439133Smckusick return (MOUNT_MFS); 37539133Smckusick return (0); 37639133Smckusick } 37739133Smckusick 37838632Smckusick usage() 37935339Sbostic { 38039333Smckusick fprintf(stderr, "usage: mount [-afurw]\nor mount [-furw] special | node\nor mount [-furw] special node\n"); 38135339Sbostic exit(1); 38235339Sbostic } 38335339Sbostic 38439316Smckusick getstdopts(options, flagp) 38539316Smckusick char *options; 38639316Smckusick long *flagp; 38739316Smckusick { 38839316Smckusick register char *opt; 38939316Smckusick int negative; 39039316Smckusick char *optbuf[BUFSIZ], *strtok(); 39139316Smckusick 39239316Smckusick strcpy(optbuf, options); 39339316Smckusick for (opt = strtok(optbuf, ","); opt; opt = strtok(NULL, ",")) { 39439316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 39539316Smckusick negative++; 39639316Smckusick opt += 2; 39739316Smckusick } else { 39839316Smckusick negative = 0; 39939316Smckusick } 40039333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 40139333Smckusick *flagp |= M_RDONLY; 40239333Smckusick continue; 40339333Smckusick } 40439333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 40539333Smckusick *flagp &= ~M_RDONLY; 40639333Smckusick continue; 40739333Smckusick } 40839316Smckusick if (!strcasecmp(opt, "exec")) { 40939316Smckusick if (negative) 41039316Smckusick *flagp |= M_NOEXEC; 41139333Smckusick else 41239333Smckusick *flagp &= ~M_NOEXEC; 41339316Smckusick continue; 41439316Smckusick } 41539316Smckusick if (!strcasecmp(opt, "suid")) { 41639316Smckusick if (negative) 41739316Smckusick *flagp |= M_NOSUID; 41839333Smckusick else 41939333Smckusick *flagp &= ~M_NOSUID; 42039316Smckusick continue; 42139316Smckusick } 42239316Smckusick if (!strcasecmp(opt, "dev")) { 42339316Smckusick if (negative) 42439316Smckusick *flagp |= M_NODEV; 42539333Smckusick else 42639333Smckusick *flagp &= ~M_NODEV; 42739316Smckusick continue; 42839316Smckusick } 42939316Smckusick if (!strcasecmp(opt, "synchronous")) { 43039316Smckusick if (!negative) 43139316Smckusick *flagp |= M_SYNCHRONOUS; 43239333Smckusick else 43339333Smckusick *flagp &= ~M_SYNCHRONOUS; 43439316Smckusick continue; 43539316Smckusick } 43639316Smckusick } 43739316Smckusick } 43839316Smckusick 43939131Smckusick getufsopts(options, flagp) 44039131Smckusick char *options; 44139131Smckusick long *flagp; 44239131Smckusick { 44339131Smckusick 44439131Smckusick return; 44539131Smckusick } 44639131Smckusick 44739329Smckusick getexecopts(options, argv) 44839131Smckusick char *options; 44939131Smckusick char **argv; 45039131Smckusick { 45139131Smckusick register int argc = 0; 45239131Smckusick register char *opt; 45339131Smckusick char *strtok(); 45439131Smckusick 45539131Smckusick for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) { 45639131Smckusick if (opt[0] != '-') 45739131Smckusick continue; 45839131Smckusick argv[argc++] = opt; 45939131Smckusick if (opt[2] == '\0' || opt[2] != '=') 46039131Smckusick continue; 46139131Smckusick opt[2] = '\0'; 46239131Smckusick argv[argc++] = &opt[3]; 46339131Smckusick } 46439131Smckusick return (argc); 46539131Smckusick } 46639131Smckusick 46739465Smckusick struct statfs * 46839465Smckusick getmntpt(name) 46939465Smckusick char *name; 47039465Smckusick { 47139465Smckusick long mntsize; 47239465Smckusick register long i; 47339465Smckusick struct statfs *mntbuf; 47439465Smckusick 47539465Smckusick mntsize = getmntinfo(&mntbuf); 47639465Smckusick for (i = 0; i < mntsize; i++) { 47739465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 47839465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 47939465Smckusick return (&mntbuf[i]); 48039465Smckusick } 48139465Smckusick return ((struct statfs *)0); 48239465Smckusick } 48339465Smckusick 484*40051Smckusick static int skipvfs; 485*40051Smckusick 486*40051Smckusick badvfstype(vfstype, vfslist) 487*40051Smckusick char *vfstype; 488*40051Smckusick char **vfslist; 489*40051Smckusick { 490*40051Smckusick 491*40051Smckusick if (vfslist == 0) 492*40051Smckusick return(0); 493*40051Smckusick while (*vfslist) { 494*40051Smckusick if (strcmp(vfstype, *vfslist) == 0) 495*40051Smckusick return(skipvfs); 496*40051Smckusick vfslist++; 497*40051Smckusick } 498*40051Smckusick return (!skipvfs); 499*40051Smckusick } 500*40051Smckusick 501*40051Smckusick char ** 502*40051Smckusick makevfslist(fslist) 503*40051Smckusick char *fslist; 504*40051Smckusick { 505*40051Smckusick register char **av, *nextcp; 506*40051Smckusick register int i; 507*40051Smckusick char *malloc(); 508*40051Smckusick 509*40051Smckusick if (fslist == NULL) 510*40051Smckusick return (NULL); 511*40051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 512*40051Smckusick fslist += 2; 513*40051Smckusick skipvfs = 1; 514*40051Smckusick } 515*40051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 516*40051Smckusick if (*nextcp == ',') 517*40051Smckusick i++; 518*40051Smckusick av = (char **)malloc((i+2) * sizeof(char *)); 519*40051Smckusick if (av == NULL) 520*40051Smckusick return (NULL); 521*40051Smckusick nextcp = fslist; 522*40051Smckusick i = 0; 523*40051Smckusick av[i++] = nextcp; 524*40051Smckusick while (nextcp = index(nextcp, ',')) { 525*40051Smckusick *nextcp++ = '\0'; 526*40051Smckusick av[i++] = nextcp; 527*40051Smckusick } 528*40051Smckusick av[i++] = 0; 529*40051Smckusick return (av); 530*40051Smckusick } 531*40051Smckusick 53238632Smckusick #ifdef NFS 53339131Smckusick /* 53439131Smckusick * Handle the getoption arg. 53539131Smckusick * Essentially update "opflags", "retrycnt" and "nfsargs" 53639131Smckusick */ 53739131Smckusick getnfsopts(optarg, nfsargsp, opflagsp, retrycntp) 53839131Smckusick char *optarg; 53939131Smckusick struct nfs_args *nfsargsp; 54039131Smckusick int *opflagsp; 54139131Smckusick int *retrycntp; 54239131Smckusick { 54339131Smckusick register char *cp, *nextcp; 54439131Smckusick int num; 54539131Smckusick char *nump; 54639131Smckusick 54739131Smckusick cp = optarg; 54839131Smckusick while (cp != NULL && *cp != '\0') { 54939131Smckusick if ((nextcp = index(cp, ',')) != NULL) 55039131Smckusick *nextcp++ = '\0'; 55139131Smckusick if ((nump = index(cp, '=')) != NULL) { 55239131Smckusick *nump++ = '\0'; 55339131Smckusick num = atoi(nump); 55439131Smckusick } else 55539131Smckusick num = -1; 55639131Smckusick /* 55739131Smckusick * Just test for a string match and do it 55839131Smckusick */ 55939131Smckusick if (!strcmp(cp, "bg")) { 56039131Smckusick *opflagsp |= BGRND; 56139131Smckusick } else if (!strcmp(cp, "soft")) { 56239131Smckusick nfsargsp->flags |= NFSMNT_SOFT; 56339131Smckusick } else if (!strcmp(cp, "intr")) { 56439131Smckusick nfsargsp->flags |= NFSMNT_INT; 56539131Smckusick } else if (!strcmp(cp, "retry") && num > 0) { 56639131Smckusick *retrycntp = num; 56739131Smckusick } else if (!strcmp(cp, "rsize") && num > 0) { 56839131Smckusick nfsargsp->rsize = num; 56939131Smckusick nfsargsp->flags |= NFSMNT_RSIZE; 57039131Smckusick } else if (!strcmp(cp, "wsize") && num > 0) { 57139131Smckusick nfsargsp->wsize = num; 57239131Smckusick nfsargsp->flags |= NFSMNT_WSIZE; 57339131Smckusick } else if (!strcmp(cp, "timeo") && num > 0) { 57439131Smckusick nfsargsp->timeo = num; 57539131Smckusick nfsargsp->flags |= NFSMNT_TIMEO; 57639131Smckusick } else if (!strcmp(cp, "retrans") && num > 0) { 57739131Smckusick nfsargsp->retrans = num; 57839131Smckusick nfsargsp->flags |= NFSMNT_RETRANS; 57939131Smckusick } 58039131Smckusick cp = nextcp; 58139131Smckusick } 58239131Smckusick } 58339131Smckusick 58438632Smckusick char * 58538632Smckusick getnfsargs(spec) 58638632Smckusick char *spec; 58735339Sbostic { 58838632Smckusick register CLIENT *clp; 58938632Smckusick struct hostent *hp; 59039604Smckusick static struct sockaddr_in saddr; 59138632Smckusick struct timeval pertry, try; 59238632Smckusick enum clnt_stat clnt_stat; 59338632Smckusick int so = RPC_ANYSOCK; 59438632Smckusick char *hostp, *delimp; 59538632Smckusick u_short tport; 59639604Smckusick static struct nfhret nfhret; 59739604Smckusick static char nam[MNAMELEN + 1]; 59838632Smckusick 59938632Smckusick strncpy(nam, spec, MNAMELEN); 60038632Smckusick nam[MNAMELEN] = '\0'; 60138632Smckusick if ((delimp = index(spec, '@')) != NULL) { 60238632Smckusick hostp = delimp + 1; 60338632Smckusick } else if ((delimp = index(spec, ':')) != NULL) { 60438632Smckusick hostp = spec; 60538632Smckusick spec = delimp + 1; 60638632Smckusick } else { 60738632Smckusick fprintf(stderr, 60838632Smckusick "No <host>:<dirpath> or <dirpath>@<host> spec\n"); 60938632Smckusick return (0); 61038632Smckusick } 61138632Smckusick *delimp = '\0'; 61238632Smckusick if ((hp = gethostbyname(hostp)) == NULL) { 61338632Smckusick fprintf(stderr, "Can't get net id for host\n"); 61438632Smckusick return (0); 61538632Smckusick } 61638632Smckusick bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 61738632Smckusick nfhret.stat = EACCES; /* Mark not yet successful */ 61838632Smckusick while (retrycnt > 0) { 61938632Smckusick saddr.sin_family = AF_INET; 62038632Smckusick saddr.sin_port = htons(PMAPPORT); 62138632Smckusick if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 62238632Smckusick NFS_VER2, IPPROTO_UDP)) == 0) { 62338632Smckusick if ((opflags & ISBGRND) == 0) 62438632Smckusick clnt_pcreateerror("NFS Portmap"); 62538632Smckusick } else { 62638632Smckusick saddr.sin_port = 0; 62738632Smckusick pertry.tv_sec = 10; 62838632Smckusick pertry.tv_usec = 0; 62938632Smckusick if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 63038632Smckusick RPCMNT_VER1, pertry, &so)) == NULL) { 63138632Smckusick if ((opflags & ISBGRND) == 0) 63238632Smckusick clnt_pcreateerror("Cannot MNT PRC"); 63338632Smckusick } else { 63438632Smckusick clp->cl_auth = authunix_create_default(); 63538632Smckusick try.tv_sec = 10; 63638632Smckusick try.tv_usec = 0; 63738632Smckusick clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 63838632Smckusick xdr_dir, spec, xdr_fh, &nfhret, try); 63938632Smckusick if (clnt_stat != RPC_SUCCESS) { 64038632Smckusick if ((opflags & ISBGRND) == 0) 64138632Smckusick clnt_perror(clp, "Bad MNT RPC"); 64238632Smckusick } else { 64338632Smckusick auth_destroy(clp->cl_auth); 64438632Smckusick clnt_destroy(clp); 64538632Smckusick retrycnt = 0; 64638632Smckusick } 64738632Smckusick } 64838632Smckusick } 64938632Smckusick if (--retrycnt > 0) { 65038632Smckusick if (opflags & BGRND) { 65138632Smckusick opflags &= ~BGRND; 65238632Smckusick if (fork()) 65338632Smckusick return (0); 65438632Smckusick else 65538632Smckusick opflags |= ISBGRND; 65638632Smckusick } 65738632Smckusick sleep(10); 65838632Smckusick } 65938632Smckusick } 66038632Smckusick if (nfhret.stat) { 66138632Smckusick if (opflags & ISBGRND) 66238632Smckusick exit(1); 66339521Smckusick fprintf(stderr, "Can't access %s: ", spec); 66439521Smckusick errno = nfhret.stat; 66539521Smckusick perror(NULL); 66638632Smckusick return (0); 66738632Smckusick } 66838632Smckusick saddr.sin_port = htons(tport); 66938632Smckusick nfsargs.addr = &saddr; 67038632Smckusick nfsargs.fh = &nfhret.nfh; 67138632Smckusick nfsargs.hostname = nam; 67238632Smckusick return ((caddr_t)&nfsargs); 67335339Sbostic } 67438445Smckusick 67538445Smckusick /* 67638445Smckusick * xdr routines for mount rpc's 67738445Smckusick */ 67838445Smckusick xdr_dir(xdrsp, dirp) 67938445Smckusick XDR *xdrsp; 68038445Smckusick char *dirp; 68138445Smckusick { 68238445Smckusick return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 68338445Smckusick } 68438445Smckusick 68538445Smckusick xdr_fh(xdrsp, np) 68638445Smckusick XDR *xdrsp; 68738445Smckusick struct nfhret *np; 68838445Smckusick { 68938445Smckusick if (!xdr_u_long(xdrsp, &(np->stat))) 69038445Smckusick return (0); 69138445Smckusick if (np->stat) 69238445Smckusick return (1); 69338445Smckusick return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 69438445Smckusick } 69538632Smckusick #endif /* NFS */ 696