more changes from rick adams.
[unix-history] / usr / src / sbin / umount / umount.c
index d6e68b2..197a8d5 100644 (file)
-static char *sccsid = "@(#)umount.c    4.1 (Berkeley) %G%";
-#include <stdio.h>
-#include <fstab.h>
+#ifndef lint
+static char *sccsid = "@(#)umount.c    4.8 (Berkeley) %G%";
+#endif
+
 /*
 /*
- *     umount name
- *
- *     umount -a
- *             This tries to unmount all of the block special file names
- *             as given in /etc/fstab.
+ * umount
  */
  */
+#include <sys/param.h>
 
 
-#define        NMOUNT  16
-#define        NAMSIZ  32
+#include <stdio.h>
+#include <fstab.h>
+#include <mtab.h>
+
+struct mtab mtab[NMOUNT];
 
 
-struct mtab {
-       char    file[NAMSIZ];
-       char    spec[NAMSIZ];
-} mtab[NMOUNT];
+char   *rindex();
+int    vflag, all, errs;
 
 main(argc, argv)
 
 main(argc, argv)
-char **argv;
+       int argc;
+       char **argv;
 {
        register struct mtab *mp;
        register char *p1, *p2;
        int mf;
 
 {
        register struct mtab *mp;
        register char *p1, *p2;
        int mf;
 
+       argc--, argv++;
        sync();
        mf = open("/etc/mtab", 0);
        sync();
        mf = open("/etc/mtab", 0);
-       read(mf, (char *)mtab, NMOUNT*2*NAMSIZ);
-       if(argc != 2) {
-               printf("arg count\n");
-               return(1);
+       read(mf, (char *)mtab, sizeof (mtab));
+again:
+       if (argc > 0 && !strcmp(*argv, "-v")) {
+               vflag++;
+               argc--, argv++;
+               goto again;
+       }
+       if (argc > 0 && !strcmp(*argv, "-a")) {
+               all++;
+               argc--, argv++;
+               goto again;
+       }
+       if (argc == 0 && !all) {
+               fprintf(stderr, "Usage: umount [ -a ] [ -v ] [ dev ... ]\n");
+               exit(1);
+       }
+       if (all) {
+               if (setfsent() == 0)
+                       perror(FSTAB), exit(1);
+               umountall();
+               exit(0);
+       }
+       while (argc > 0) {
+               if (umountfs(*argv++) == 0)
+                       errs++;
+               argc--;
+       }
+       exit(errs);
+}
+
+umountall()
+{
+       struct fstab *fs, *allocfsent();
+
+       if ((fs = getfsent()) == 0)
+               return;
+       fs = allocfsent(fs);
+       umountall();
+       if (strcmp(fs->fs_file, "/") == 0) {
+               freefsent(fs);
+               return;
        }
        }
-       if (strcmp(argv[1], "-a") == 0){
-               FILE    *fs_file;
-               struct  fstab   fs;
-               if ( (fs_file = fopen(FSTAB, "r")) == NULL){
-                       perror(FSTAB);
-                       exit(1);
-               }
-               while (!feof(fs_file)){
-                       fscanf(fs_file, FSTABFMT, FSTABARG(&fs));
-                       if (strcmp(fs.fs_file, "/") == 0)
-                               continue;
-                       fprintf(stderr, "Unmounting special file %s\n",
-                               fs.fs_spec);
-                       fflush(stderr);
-                       if (umountfs(fs.fs_spec))
-                               continue;
-               }
-               fclose(fs_file);
-       } else {
-               if (umountfs(argv[1]))
-                       exit(1);
+       if (strcmp(fs->fs_type, FSTAB_RW) &&
+           strcmp(fs->fs_type, FSTAB_RO) &&
+           strcmp(fs->fs_type, FSTAB_RQ)) {
+               freefsent(fs);
+               return;
        }
        }
-       exit(0);
+       if (umountfs(fs->fs_spec) < 0)
+               perror(fs->fs_spec);
+       freefsent(fs);
 }
 
 }
 
-int umountfs(name)
-       char    *name;
+struct fstab *
+allocfsent(fs)
+       register struct fstab *fs;
 {
 {
-       register        char    *p1, *p2;
-       register        struct  mtab    *mp;
-       int     mf;
+       register struct fstab *new;
+       register char *cp;
+       char *malloc();
+
+       new = (struct fstab *)malloc(sizeof (*fs));
+       cp = malloc(strlen(fs->fs_file) + 1);
+       strcpy(cp, fs->fs_file);
+       new->fs_file = cp;
+       cp = malloc(strlen(fs->fs_type) + 1);
+       strcpy(cp, fs->fs_type);
+       new->fs_type = cp;
+       cp = malloc(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);
+}
+
+struct mtab zeromtab;
+
+umountfs(name)
+       char *name;
+{
+       register char *p1, *p2;
+       register struct mtab *mp;
+       int mf;
+       struct fstab *fs;
 
 
+       fs = getfsfile(name);
+       if (fs != NULL)
+               name = fs->fs_spec;
        if (umount(name) < 0) {
        if (umount(name) < 0) {
-               perror("umount");
-               return(1);
+               perror(name);
+               return (0);
        }
        }
-       p1 = name;
-       while(*p1++)
-               ;
-       p1--;
-       while(*--p1 == '/')
-               *p1 = '\0';
-       while(p1 > name && *--p1 != '/')
-               ;
-       if(*p1 == '/')
-               p1++;
-       name = p1;
+       if (vflag)
+               fprintf(stderr, "%s: Unmounted\n", name);
+       while ((p1 = rindex(name, '/')) && p1[1] == 0)
+               *p1 = 0;
+       if (p1)
+               name = p1 + 1;
        for (mp = mtab; mp < &mtab[NMOUNT]; mp++) {
        for (mp = mtab; mp < &mtab[NMOUNT]; mp++) {
-               p1 = name;
-               p2 = &mp->spec[0];
-               while (*p1++ == *p2)
-                       if (*p2++ == 0) {
-                               for (p1 = mp->file; p1 < &mp->file[NAMSIZ*2];)
-                                       *p1++ = 0;
-                               mp = &mtab[NMOUNT];
-                               while ((--mp)->file[0] == 0);
-                               mf = creat("/etc/mtab", 0644);
-                               write(mf, (char *)mtab, (mp-mtab+1)*2*NAMSIZ);
-                               return(0);
-                       }
+               if (strncmp(mp->m_dname, name, sizeof (mp->m_dname)))
+                       continue;
+               *mp = zeromtab;
+               for (mp = &mtab[NMOUNT]; mp >= mtab; mp--)
+                       if (mp->m_path[0])
+                               break;
+               mp++;
+               mf = creat("/etc/mtab", 0644);
+               write(mf, (char *)mtab, (mp-mtab) * sizeof (struct mtab));
+               return (1);
        }
        }
-       printf("%s not in mount table\n", name);
-       return(1);
+       fprintf(stderr, "%s: Not mounted\n", name);
+       return (0);
 }
 }