121156Sdist /* 239322Smckusick * Copyright (c) 1980, 1989 The Regents of the University of California. 339322Smckusick * All rights reserved. 439322Smckusick * 542702Sbostic * %sccs.include.redist.c% 621156Sdist */ 721156Sdist 810811Ssam #ifndef lint 921156Sdist char copyright[] = 1039322Smckusick "@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\ 1121156Sdist All rights reserved.\n"; 1239322Smckusick #endif /* not lint */ 131057Sbill 1421156Sdist #ifndef lint 15*55394Spendry static char sccsid[] = "@(#)mount.c 5.50 (Berkeley) 07/19/92"; 1639322Smckusick #endif /* not lint */ 1721156Sdist 1812808Ssam #include <sys/param.h> 1935339Sbostic #include <sys/file.h> 2038445Smckusick #include <sys/time.h> 2139133Smckusick #include <sys/wait.h> 2245524Sbostic #include <sys/errno.h> 2345524Sbostic #include <sys/signal.h> 2452110Smckusick #include <sys/ucred.h> 2538445Smckusick #include <sys/mount.h> 2645524Sbostic #include <fstab.h> 2745524Sbostic #include <string.h> 2845524Sbostic #include <stdio.h> 2945524Sbostic #include <stdlib.h> 3045524Sbostic #include "pathnames.h" 311057Sbill 3240369Smckusick #define DEFAULT_ROOTUID -2 3340369Smckusick 3435339Sbostic #define BADTYPE(type) \ 3535339Sbostic (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 3635339Sbostic strcmp(type, FSTAB_RQ)) 3735339Sbostic #define SETTYPE(type) \ 3835339Sbostic (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 391057Sbill 4039333Smckusick int fake, verbose, updateflg, mnttype; 4139322Smckusick char *mntname, **envp; 4240051Smckusick char **vfslist, **makevfslist(); 4346708Sbostic static void prmount(); 4439131Smckusick 4539131Smckusick main(argc, argv, arge) 465073Sroot int argc; 475073Sroot char **argv; 4839131Smckusick char **arge; 491057Sbill { 5035339Sbostic extern char *optarg; 5135339Sbostic extern int optind; 5235339Sbostic register struct fstab *fs; 5340496Smckusick int all, ch, rval, flags, ret, pid, i; 5438632Smckusick long mntsize; 5539465Smckusick struct statfs *mntbuf, *getmntpt(); 5639131Smckusick char *type, *options = NULL; 5740496Smckusick FILE *pidfile; 581057Sbill 5939131Smckusick envp = arge; 6035339Sbostic all = 0; 6135339Sbostic type = NULL; 6238445Smckusick mnttype = MOUNT_UFS; 6339322Smckusick mntname = "ufs"; 6439333Smckusick while ((ch = getopt(argc, argv, "afrwuvt:o:")) != EOF) 6535339Sbostic switch((char)ch) { 6635339Sbostic case 'a': 6735339Sbostic all = 1; 6835339Sbostic break; 6935339Sbostic case 'f': 7035339Sbostic fake = 1; 7135339Sbostic break; 7235339Sbostic case 'r': 7312808Ssam type = FSTAB_RO; 7435339Sbostic break; 7539333Smckusick case 'u': 7641403Smckusick updateflg = MNT_UPDATE; 7739333Smckusick break; 7835339Sbostic case 'v': 7935339Sbostic verbose = 1; 8035339Sbostic break; 8135339Sbostic case 'w': 8235339Sbostic type = FSTAB_RW; 8335339Sbostic break; 8439131Smckusick case 'o': 8539131Smckusick options = optarg; 8639131Smckusick break; 8738445Smckusick case 't': 8840051Smckusick vfslist = makevfslist(optarg); 8939322Smckusick mnttype = getmnttype(optarg); 9039322Smckusick break; 9135339Sbostic case '?': 9235339Sbostic default: 9335339Sbostic usage(); 9439131Smckusick /* NOTREACHED */ 955073Sroot } 9635339Sbostic argc -= optind; 9735339Sbostic argv += optind; 9835339Sbostic 9935339Sbostic /* NOSTRICT */ 10035339Sbostic 1014460Sroot if (all) { 10235369Sbostic rval = 0; 10339333Smckusick while (fs = getfsent()) { 10435372Sbostic if (BADTYPE(fs->fs_type)) 10535372Sbostic continue; 10640844Smckusick if (badvfsname(fs->fs_vfstype, vfslist)) 10740051Smckusick continue; 10835372Sbostic /* `/' is special, it's always mounted */ 10935372Sbostic if (!strcmp(fs->fs_file, "/")) 11041403Smckusick flags = MNT_UPDATE; 11139333Smckusick else 11239333Smckusick flags = updateflg; 11339333Smckusick mnttype = getmnttype(fs->fs_vfstype); 11439333Smckusick rval |= mountfs(fs->fs_spec, fs->fs_file, flags, 11539333Smckusick type, options, fs->fs_mntops); 11635372Sbostic } 11735341Sbostic exit(rval); 11835339Sbostic } 1195073Sroot 12035339Sbostic if (argc == 0) { 12135339Sbostic if (verbose || fake || type) 12235339Sbostic usage(); 12340337Smckusick if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 12445689Smckusick (void) fprintf(stderr, 12539319Smckusick "mount: cannot get mount information\n"); 12638632Smckusick exit(1); 12738632Smckusick } 12840844Smckusick for (i = 0; i < mntsize; i++) { 12940844Smckusick if (badvfstype(mntbuf[i].f_type, vfslist)) 13040844Smckusick continue; 13138632Smckusick prmount(mntbuf[i].f_mntfromname, mntbuf[i].f_mntonname, 13239316Smckusick mntbuf[i].f_flags); 13340844Smckusick } 1344460Sroot exit(0); 1351057Sbill } 13612808Ssam 13739465Smckusick if (argc == 1 && updateflg) { 13839465Smckusick if ((mntbuf = getmntpt(*argv)) == NULL) { 13945689Smckusick (void) fprintf(stderr, 14039465Smckusick "mount: unknown special file or file system %s.\n", 14139465Smckusick *argv); 14239465Smckusick exit(1); 14339465Smckusick } 14439465Smckusick mnttype = mntbuf->f_type; 14553711Smckusick if ((fs = getfsfile(mntbuf->f_mntonname)) == NULL) { 14653711Smckusick (void) fprintf(stderr, 14753711Smckusick "mount: can't find fstab entry for %s.\n", *argv); 14853711Smckusick exit(1); 14940124Smckusick } 15053711Smckusick mntname = fs->fs_vfstype; 15153711Smckusick 15253711Smckusick /* 15353711Smckusick * Default type to fstab version if none specified on the 15453711Smckusick * command line. 15553711Smckusick */ 15653711Smckusick if (type == NULL) 15753711Smckusick type = fs->fs_type; 15853711Smckusick 15953711Smckusick /* 16053711Smckusick * Default options to fstab version if none specified on the 16153711Smckusick * command line. 16253711Smckusick */ 16353711Smckusick if (options == NULL) 16453711Smckusick options = fs->fs_mntops; 16553711Smckusick else { 16653711Smckusick register char *cp; 16753711Smckusick 16853711Smckusick /* 16953711Smckusick * Concat the two strings with the command line 17053711Smckusick * options last so that they will override the 17153711Smckusick * fstab options. 17253711Smckusick */ 17353711Smckusick i = strlen(fs->fs_mntops) + strlen(options) + 2; 17453711Smckusick if ((cp = malloc((size_t)i)) == NULL) { 17553711Smckusick (void) fprintf(stderr, 17653711Smckusick "mount: -u malloc failed\n"); 17753711Smckusick exit(1); 17853711Smckusick } 17953711Smckusick sprintf(cp, "%s,%s", fs->fs_mntops, options); 18053711Smckusick options = cp; 18153711Smckusick } 18253711Smckusick ret = mountfs(fs->fs_spec, mntbuf->f_mntonname, 18342253Sbostic updateflg, type, options, (char *)NULL); 18440496Smckusick } else if (argc == 1) { 18535339Sbostic if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 18645689Smckusick (void) fprintf(stderr, 18735339Sbostic "mount: unknown special file or file system %s.\n", 18835339Sbostic *argv); 18935339Sbostic exit(1); 19035339Sbostic } 19135339Sbostic if (BADTYPE(fs->fs_type)) { 19245689Smckusick (void) fprintf(stderr, 19335339Sbostic "mount: %s has unknown file system type.\n", *argv); 19435339Sbostic exit(1); 19535339Sbostic } 19639333Smckusick mnttype = getmnttype(fs->fs_vfstype); 19740496Smckusick ret = mountfs(fs->fs_spec, fs->fs_file, updateflg, 19840496Smckusick type, options, fs->fs_mntops); 19940496Smckusick } else if (argc != 2) { 20040496Smckusick usage(); 20140496Smckusick ret = 1; 20240496Smckusick } else { 20342857Smckusick /* 20442857Smckusick * If -t flag has not been specified, and spec 20542857Smckusick * contains either a ':' or a '@' then assume that 20642857Smckusick * an NFS filesystem is being specified ala Sun. 20742857Smckusick */ 20842857Smckusick if (vfslist == (char **)0 && 20952182Smckusick (index(argv[0], ':') || index(argv[0], '@'))) { 21042857Smckusick mnttype = MOUNT_NFS; 21152182Smckusick mntname = "nfs"; 21252182Smckusick } 21342253Sbostic ret = mountfs(argv[0], argv[1], updateflg, type, options, 21442253Sbostic (char *)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 { 23042253Sbostic union wait status; 23142253Sbostic pid_t pid; 23242253Sbostic int argc, 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) { 24452097Sbostic case MOUNT_LFS: 24539316Smckusick case MOUNT_UFS: 24639333Smckusick if (mntopts) 24739333Smckusick getufsopts(mntopts, &flags); 24839316Smckusick if (options) 24939316Smckusick getufsopts(options, &flags); 25039316Smckusick args.fspec = spec; 25140369Smckusick args.exroot = DEFAULT_ROOTUID; 25241403Smckusick if (flags & MNT_RDONLY) 25341403Smckusick args.exflags = MNT_EXRDONLY; 25440496Smckusick else 25540496Smckusick args.exflags = 0; 25639316Smckusick argp = (caddr_t)&args; 25739316Smckusick break; 25838632Smckusick 25952110Smckusick case MOUNT_MFS: 26039316Smckusick case MOUNT_NFS: 26139322Smckusick default: 26239322Smckusick argv[0] = mntname; 26339329Smckusick argc = 1; 26439322Smckusick if (flags) { 26539322Smckusick argv[argc++] = "-F"; 26639322Smckusick sprintf(flagval, "%d", flags); 26739322Smckusick argv[argc++] = flagval; 26839322Smckusick } 26939333Smckusick if (mntopts) 27039333Smckusick argc += getexecopts(mntopts, &argv[argc]); 27139329Smckusick if (options) 27239329Smckusick argc += getexecopts(options, &argv[argc]); 27339316Smckusick argv[argc++] = spec; 27439316Smckusick argv[argc++] = name; 27539521Smckusick argv[argc++] = NULL; 27639603Smckusick sprintf(execname, "%s/mount_%s", _PATH_EXECDIR, mntname); 27739316Smckusick if (verbose) { 27842253Sbostic (void)printf("exec: %s", execname); 27942253Sbostic for (i = 1; i < argc - 1; i++) 28042253Sbostic (void)printf(" %s", argv[i]); 28142253Sbostic (void)printf("\n"); 28239316Smckusick } 28339316Smckusick if (fake) 28439316Smckusick break; 28542253Sbostic if (pid = vfork()) { 28642253Sbostic if (pid == -1) { 28739322Smckusick perror("mount: vfork starting file system"); 28839316Smckusick return (1); 28939131Smckusick } 29046708Sbostic if (waitpid(pid, (int *)&status, 0) != -1 && 29139316Smckusick WIFEXITED(status) && 29239316Smckusick WEXITSTATUS(status) != 0) 29339316Smckusick return (WEXITSTATUS(status)); 29439322Smckusick spec = mntname; 29539316Smckusick goto out; 29639316Smckusick } 29739322Smckusick execve(execname, argv, envp); 29845689Smckusick (void) fprintf(stderr, "mount: cannot exec %s for %s: ", 29939603Smckusick execname, name); 30042253Sbostic perror((char *)NULL); 30139316Smckusick exit (1); 30239316Smckusick /* NOTREACHED */ 30338632Smckusick 30439316Smckusick } 30539316Smckusick if (!fake && mount(mnttype, name, flags, argp)) { 30645689Smckusick (void) fprintf(stderr, "%s on %s: ", spec, name); 30739316Smckusick switch (errno) { 30839316Smckusick case EMFILE: 30945689Smckusick (void) fprintf(stderr, "Mount table full\n"); 31039316Smckusick break; 31139316Smckusick case EINVAL: 31241403Smckusick if (flags & MNT_UPDATE) 31345689Smckusick (void) fprintf(stderr, "Specified device %s\n", 31445689Smckusick "does not match mounted device"); 31545569Skarels else if (mnttype == MOUNT_UFS) 31645689Smckusick (void) fprintf(stderr, "Bogus super block\n"); 31739333Smckusick else 31845569Skarels perror((char *)NULL); 31939316Smckusick break; 32039316Smckusick default: 32139316Smckusick perror((char *)NULL); 32239316Smckusick break; 3234460Sroot } 32439316Smckusick return(1); 3254460Sroot } 32635339Sbostic 32739131Smckusick out: 32812808Ssam if (verbose) 32939316Smckusick prmount(spec, name, flags); 33035339Sbostic 33142253Sbostic return(0); 3321057Sbill } 33335339Sbostic 33446708Sbostic static void 33539316Smckusick prmount(spec, name, flags) 33639316Smckusick char *spec, *name; 33742253Sbostic register short flags; 33835339Sbostic { 33942253Sbostic register int first; 34038632Smckusick 34142253Sbostic (void)printf("%s on %s", spec, name); 34242253Sbostic if (!(flags & MNT_VISFLAGMASK)) { 34342253Sbostic (void)printf("\n"); 34442253Sbostic return; 34542253Sbostic } 34642253Sbostic first = 0; 34742253Sbostic #define PR(msg) (void)printf("%s%s", !first++ ? " (" : ", ", msg) 34841403Smckusick if (flags & MNT_RDONLY) 34942253Sbostic PR("read-only"); 35041403Smckusick if (flags & MNT_NOEXEC) 35142253Sbostic PR("noexec"); 35241403Smckusick if (flags & MNT_NOSUID) 35342253Sbostic PR("nosuid"); 35441403Smckusick if (flags & MNT_NODEV) 35542253Sbostic PR("nodev"); 35641403Smckusick if (flags & MNT_SYNCHRONOUS) 35742253Sbostic PR("synchronous"); 35841403Smckusick if (flags & MNT_QUOTA) 35942253Sbostic PR("with quotas"); 36041403Smckusick if (flags & MNT_LOCAL) 36142253Sbostic PR("local"); 362*55394Spendry if (flags & MNT_UNION) 363*55394Spendry PR("union"); 36441403Smckusick if (flags & MNT_EXPORTED) 36552110Smckusick PR("NFS exported"); 36642253Sbostic (void)printf(")\n"); 36735339Sbostic } 36835339Sbostic 36939133Smckusick getmnttype(fstype) 37039133Smckusick char *fstype; 37139133Smckusick { 37239133Smckusick 37339322Smckusick mntname = fstype; 37439133Smckusick if (!strcmp(fstype, "ufs")) 37539133Smckusick return (MOUNT_UFS); 37639133Smckusick if (!strcmp(fstype, "nfs")) 37739133Smckusick return (MOUNT_NFS); 37839133Smckusick if (!strcmp(fstype, "mfs")) 37939133Smckusick return (MOUNT_MFS); 38052097Sbostic if (!strcmp(fstype, "lfs")) 38152097Sbostic return (MOUNT_LFS); 38239133Smckusick return (0); 38339133Smckusick } 38439133Smckusick 38538632Smckusick usage() 38635339Sbostic { 38740871Smckusick 38845689Smckusick (void) fprintf(stderr, 38945689Smckusick "usage:\n mount %s %s\n mount %s\n mount %s\n", 39052110Smckusick "[ -frwu ] [ -t ufs | external_type ]", 39140871Smckusick "[ -o options ] special node", 39252110Smckusick "[ -afrwu ] [ -t ufs | external_type ]", 39340871Smckusick "[ -frwu ] special | node"); 39435339Sbostic exit(1); 39535339Sbostic } 39635339Sbostic 39739316Smckusick getstdopts(options, flagp) 39839316Smckusick char *options; 39942253Sbostic int *flagp; 40039316Smckusick { 40139316Smckusick register char *opt; 40239316Smckusick int negative; 40342253Sbostic char optbuf[BUFSIZ]; 40439316Smckusick 40542253Sbostic (void)strcpy(optbuf, options); 40642253Sbostic for (opt = strtok(optbuf, ","); opt; opt = strtok((char *)NULL, ",")) { 40739316Smckusick if (opt[0] == 'n' && opt[1] == 'o') { 40839316Smckusick negative++; 40939316Smckusick opt += 2; 41039316Smckusick } else { 41139316Smckusick negative = 0; 41239316Smckusick } 41339333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RO)) { 41441403Smckusick *flagp |= MNT_RDONLY; 41539333Smckusick continue; 41639333Smckusick } 41739333Smckusick if (!negative && !strcasecmp(opt, FSTAB_RW)) { 41841403Smckusick *flagp &= ~MNT_RDONLY; 41939333Smckusick continue; 42039333Smckusick } 42139316Smckusick if (!strcasecmp(opt, "exec")) { 42239316Smckusick if (negative) 42341403Smckusick *flagp |= MNT_NOEXEC; 42439333Smckusick else 42541403Smckusick *flagp &= ~MNT_NOEXEC; 42639316Smckusick continue; 42739316Smckusick } 42839316Smckusick if (!strcasecmp(opt, "suid")) { 42939316Smckusick if (negative) 43041403Smckusick *flagp |= MNT_NOSUID; 43139333Smckusick else 43241403Smckusick *flagp &= ~MNT_NOSUID; 43339316Smckusick continue; 43439316Smckusick } 43539316Smckusick if (!strcasecmp(opt, "dev")) { 43639316Smckusick if (negative) 43741403Smckusick *flagp |= MNT_NODEV; 43839333Smckusick else 43941403Smckusick *flagp &= ~MNT_NODEV; 44039316Smckusick continue; 44139316Smckusick } 44239316Smckusick if (!strcasecmp(opt, "synchronous")) { 44339316Smckusick if (!negative) 44441403Smckusick *flagp |= MNT_SYNCHRONOUS; 44539333Smckusick else 44641403Smckusick *flagp &= ~MNT_SYNCHRONOUS; 44739316Smckusick continue; 44839316Smckusick } 449*55394Spendry if (!strcasecmp(opt, "union")) { 450*55394Spendry if (!negative) 451*55394Spendry *flagp |= MNT_UNION; 452*55394Spendry else 453*55394Spendry *flagp &= ~MNT_UNION; 454*55394Spendry continue; 455*55394Spendry } 45639316Smckusick } 45739316Smckusick } 45839316Smckusick 45942253Sbostic /* ARGSUSED */ 46039131Smckusick getufsopts(options, flagp) 46139131Smckusick char *options; 46242253Sbostic int *flagp; 46339131Smckusick { 46439131Smckusick return; 46539131Smckusick } 46639131Smckusick 46739329Smckusick getexecopts(options, argv) 46839131Smckusick char *options; 46939131Smckusick char **argv; 47039131Smckusick { 47139131Smckusick register int argc = 0; 47239131Smckusick register char *opt; 47339131Smckusick 47442253Sbostic for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) { 47539131Smckusick if (opt[0] != '-') 47639131Smckusick continue; 47739131Smckusick argv[argc++] = opt; 47839131Smckusick if (opt[2] == '\0' || opt[2] != '=') 47939131Smckusick continue; 48039131Smckusick opt[2] = '\0'; 48139131Smckusick argv[argc++] = &opt[3]; 48239131Smckusick } 48339131Smckusick return (argc); 48439131Smckusick } 48539131Smckusick 48639465Smckusick struct statfs * 48739465Smckusick getmntpt(name) 48839465Smckusick char *name; 48939465Smckusick { 49039465Smckusick long mntsize; 49139465Smckusick register long i; 49239465Smckusick struct statfs *mntbuf; 49339465Smckusick 49440337Smckusick mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 49539465Smckusick for (i = 0; i < mntsize; i++) { 49639465Smckusick if (!strcmp(mntbuf[i].f_mntfromname, name) || 49739465Smckusick !strcmp(mntbuf[i].f_mntonname, name)) 49839465Smckusick return (&mntbuf[i]); 49939465Smckusick } 50039465Smckusick return ((struct statfs *)0); 50139465Smckusick } 50239465Smckusick 50340051Smckusick static int skipvfs; 50440051Smckusick 50540051Smckusick badvfstype(vfstype, vfslist) 50642253Sbostic short vfstype; 50740051Smckusick char **vfslist; 50840051Smckusick { 50940051Smckusick 51040051Smckusick if (vfslist == 0) 51140051Smckusick return(0); 51240051Smckusick while (*vfslist) { 51340844Smckusick if (vfstype == getmnttype(*vfslist)) 51440051Smckusick return(skipvfs); 51540051Smckusick vfslist++; 51640051Smckusick } 51740051Smckusick return (!skipvfs); 51840051Smckusick } 51940051Smckusick 52040844Smckusick badvfsname(vfsname, vfslist) 52140844Smckusick char *vfsname; 52240844Smckusick char **vfslist; 52340844Smckusick { 52440844Smckusick 52540844Smckusick if (vfslist == 0) 52640844Smckusick return(0); 52740844Smckusick while (*vfslist) { 52840844Smckusick if (strcmp(vfsname, *vfslist) == 0) 52940844Smckusick return(skipvfs); 53040844Smckusick vfslist++; 53140844Smckusick } 53240844Smckusick return (!skipvfs); 53340844Smckusick } 53440844Smckusick 53540051Smckusick char ** 53640051Smckusick makevfslist(fslist) 53740051Smckusick char *fslist; 53840051Smckusick { 53940051Smckusick register char **av, *nextcp; 54040051Smckusick register int i; 54140051Smckusick 54240051Smckusick if (fslist == NULL) 54340051Smckusick return (NULL); 54440051Smckusick if (fslist[0] == 'n' && fslist[1] == 'o') { 54540051Smckusick fslist += 2; 54640051Smckusick skipvfs = 1; 54740051Smckusick } 54840051Smckusick for (i = 0, nextcp = fslist; *nextcp; nextcp++) 54940051Smckusick if (*nextcp == ',') 55040051Smckusick i++; 55142253Sbostic av = (char **)malloc((size_t)(i+2) * sizeof(char *)); 55240051Smckusick if (av == NULL) 55340051Smckusick return (NULL); 55440051Smckusick nextcp = fslist; 55540051Smckusick i = 0; 55640051Smckusick av[i++] = nextcp; 55740051Smckusick while (nextcp = index(nextcp, ',')) { 55840051Smckusick *nextcp++ = '\0'; 55940051Smckusick av[i++] = nextcp; 56040051Smckusick } 56140051Smckusick av[i++] = 0; 56240051Smckusick return (av); 56340051Smckusick } 564