zero link count table increased 50 => 500; corrupted directories now pfatal.
[unix-history] / usr / src / sbin / umount / umount.c
index d6e68b2..d094118 100644 (file)
@@ -1,12 +1,10 @@
-static char *sccsid = "@(#)umount.c    4.1 (Berkeley) %G%";
+static char *sccsid = "@(#)umount.c    4.6 (Berkeley) %G%";
+
 #include <stdio.h>
 #include <fstab.h>
 #include <stdio.h>
 #include <fstab.h>
+
 /*
 /*
- *     umount name
- *
- *     umount -a
- *             This tries to unmount all of the block special file names
- *             as given in /etc/fstab.
+ * umount
  */
 
 #define        NMOUNT  16
  */
 
 #define        NMOUNT  16
@@ -17,81 +15,99 @@ struct mtab {
        char    spec[NAMSIZ];
 } mtab[NMOUNT];
 
        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--;
        }
        }
-       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);
+       exit(errs);
+}
+
+umountall()
+{
+       struct fstab fs, *fsp;
+
+       if ((fsp = getfsent()) == 0)
+               return;
+       fs = *fsp;      /* save info locally; it is static from getfsent() */
+       umountall();
+       if (strcmp(fs.fs_file, "/") == 0)
+               return;
+       if (strcmp(fs.fs_type, FSTAB_RW) && strcmp(fs.fs_type, FSTAB_RO))
+               return;
+       if (umountfs(fs.fs_spec) < 0) {
+               perror(fs.fs_spec);
+               return;
        }
        }
-       exit(0);
 }
 
 }
 
-int umountfs(name)
-       char    *name;
+struct mtab zeromtab;
+
+umountfs(name)
+       char *name;
 {
 {
-       register        char    *p1, *p2;
-       register        struct  mtab    *mp;
-       int     mf;
+       register char *p1, *p2;
+       register struct mtab *mp;
+       int mf;
 
 
-       if (umount(name) < 0) {
-               perror("umount");
-               return(1);
+       if (unmount(name) < 0) {
+               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->spec, name, sizeof (mp->spec)))
+                       continue;
+               *mp = zeromtab;
+               for (mp = &mtab[NMOUNT]; mp >= mtab; mp--)
+                       if (mp->file[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);
 }
 }