+ }
+ (void) umountfs(fs->fs_file, typelist);
+ freefsent(fs);
+}
+
+struct fstab *
+allocfsent(fs)
+ register struct fstab *fs;
+{
+ register struct fstab *new;
+ register char *cp;
+
+ new = (struct fstab *)malloc((unsigned)sizeof (*fs));
+ cp = (char *)malloc((unsigned)strlen(fs->fs_file) + 1);
+ strcpy(cp, fs->fs_file);
+ new->fs_file = cp;
+ cp = (char *)malloc((unsigned)strlen(fs->fs_type) + 1);
+ strcpy(cp, fs->fs_type);
+ new->fs_type = cp;
+ cp = (char *)malloc((unsigned)strlen(fs->fs_spec) + 1);
+ strcpy(cp, fs->fs_spec);
+ new->fs_spec = cp;
+ new->fs_passno = fs->fs_passno;
+ new->fs_freq = fs->fs_freq;
+ return (new);
+}
+
+freefsent(fs)
+ register struct fstab *fs;
+{
+
+ if (fs->fs_file)
+ free(fs->fs_file);
+ if (fs->fs_spec)
+ free(fs->fs_spec);
+ if (fs->fs_type)
+ free(fs->fs_type);
+ free((char *)fs);
+}
+
+umountfs(name, typelist)
+ char *name;
+ int *typelist;
+{
+ char *mntpt;
+ struct stat stbuf;
+ int type;
+#ifdef NFS
+ register CLIENT *clp;
+ struct hostent *hp = 0;
+ struct sockaddr_in saddr;
+ struct timeval pertry, try;
+ enum clnt_stat clnt_stat;
+ int so = RPC_ANYSOCK;
+ char *hostp, *delimp;
+#endif /* NFS */
+
+ if (stat(name, &stbuf) < 0) {
+ if (getmntname(name, MNTFROM, &type) != 0)
+ mntpt = name;
+ else if ((mntpt = getmntname(name, MNTON, &type)) == 0) {
+ fprintf(stderr, "%s: not currently mounted\n", name);
+ return (0);
+ }
+ } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
+ if ((mntpt = getmntname(name, MNTON, &type)) == 0) {
+ fprintf(stderr, "%s: not currently mounted\n", name);
+ return (0);
+ }
+ } else if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
+ mntpt = name;
+ if (getmntname(mntpt, MNTFROM, &type) == 0) {
+ fprintf(stderr, "%s: not currently mounted\n", name);
+ return (0);
+ }
+ } else {
+ fprintf(stderr, "%s: not a directory or special device\n",
+ name);
+ return (0);
+ }
+
+ if (badtype(type, typelist))
+ return(1);
+#ifdef NFS
+ if ((delimp = index(name, '@')) != NULL) {
+ hostp = delimp + 1;
+ *delimp = '\0';
+ hp = gethostbyname(hostp);
+ *delimp = '@';
+ } else if ((delimp = index(name, ':')) != NULL) {
+ *delimp = '\0';
+ hostp = name;
+ hp = gethostbyname(hostp);
+ name = delimp+1;
+ *delimp = ':';
+ }
+
+ if (!namematch(hp, nfshost))
+ return(1);
+#endif /* NFS */
+ if (!fake && unmount(mntpt, fflag) < 0) {
+ perror(mntpt);
+ return (0);
+ }
+ if (vflag)
+ fprintf(stderr, "%s: Unmounted from %s\n", name, mntpt);
+
+#ifdef NFS
+ if (!fake && hp != NULL && (fflag & MNT_FORCE) == 0) {
+ *delimp = '\0';
+ bcopy(hp->h_addr,(caddr_t)&saddr.sin_addr,hp->h_length);
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0;
+ pertry.tv_sec = 3;
+ pertry.tv_usec = 0;
+ if ((clp = clntudp_create(&saddr, RPCPROG_MNT, RPCMNT_VER1,
+ pertry, &so)) == NULL) {
+ clnt_pcreateerror("Cannot MNT PRC");
+ return (1);
+ }
+ clp->cl_auth = authunix_create_default();
+ try.tv_sec = 20;
+ try.tv_usec = 0;
+ clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir, name,
+ xdr_void, (caddr_t)0, try);
+ if (clnt_stat != RPC_SUCCESS) {
+ clnt_perror(clp, "Bad MNT RPC");
+ return (1);
+ }
+ auth_destroy(clp->cl_auth);
+ clnt_destroy(clp);
+ }
+#endif /* NFS */
+ return (1);
+}
+
+char *
+getmntname(name, what, type)
+ char *name;
+ int what;
+ int *type;
+{
+ int mntsize, i;
+ struct statfs *mntbuf;
+
+ if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
+ perror("umount");
+ return (0);
+ }
+ for (i = 0; i < mntsize; i++) {
+ if (what == MNTON && !strcmp(mntbuf[i].f_mntfromname, name)) {
+ if (type)
+ *type = mntbuf[i].f_type;
+ return (mntbuf[i].f_mntonname);
+ }
+ if (what == MNTFROM && !strcmp(mntbuf[i].f_mntonname, name)) {
+ if (type)
+ *type = mntbuf[i].f_type;
+ return (mntbuf[i].f_mntfromname);
+ }
+ }
+ return (0);
+}
+
+static int skipvfs;
+
+badtype(type, typelist)
+ int type;
+ int *typelist;
+{
+ if (typelist == 0)
+ return(0);
+ while (*typelist) {
+ if (type == *typelist)
+ return(skipvfs);
+ typelist++;
+ }
+ return(!skipvfs);
+}
+
+int *
+maketypelist(fslist)
+ char *fslist;
+{
+ register char *nextcp;
+ register int *av, i;
+
+ if (fslist == NULL)
+ return(NULL);
+ if (fslist[0] == 'n' && fslist[1] == 'o') {
+ fslist += 2;
+ skipvfs = 1;
+ } else
+ skipvfs = 0;
+ for (i = 0, nextcp = fslist; *nextcp; nextcp++)
+ if (*nextcp == ',')
+ i++;
+ av = (int *)malloc((i+2) * sizeof(int));
+ if (av == NULL)
+ return(NULL);
+ for (i = 0; fslist; fslist = nextcp) {
+ if (nextcp = index(fslist, ','))
+ *nextcp++ = '\0';
+ if (strcmp(fslist, "ufs") == 0)
+ av[i++] = MOUNT_UFS;
+ else if (strcmp(fslist, "nfs") == 0)
+ av[i++] = MOUNT_NFS;
+ else if (strcmp(fslist, "mfs") == 0)
+ av[i++] = MOUNT_MFS;
+ else if (strcmp(fslist, "pc") == 0)
+ av[i++] = MOUNT_PC;
+ }
+ av[i++] = 0;
+ return(av);