add Berkeley copyright
[unix-history] / usr / src / sbin / mount / mount.c
index 3770601..a13583b 100644 (file)
-static char *sccsid = "@(#)mount.c     4.6 (Berkeley) %G%";
-#include <stdio.h>
-#include <fstab.h>
-
 /*
 /*
- * mount
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
  */
 
  */
 
-#define        NMOUNT  16
-#define        NAMSIZ  32
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif not lint
+
+#ifndef lint
+static char sccsid[] = "@(#)mount.c    5.4 (Berkeley) %G%";
+#endif not lint
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <fstab.h>
+#include <mtab.h>
+#include <errno.h>
+#include <stdio.h>
+
+#define        BADTYPE(type) \
+       (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \
+           strcmp(type, FSTAB_RQ))
+#define        SETTYPE(type) \
+       (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ))
 
 
-struct mtab {
-       char    file[NAMSIZ];
-       char    spec[NAMSIZ];
-} mtab[NMOUNT];
+#define        MTAB    "/etc/mtab"
 
 
-int    all;
-int    ro;
-int    fake;
-int    verbose;
+static struct mtab mtab[NMOUNT];
+static int fake, rval, verbose;
 
 main(argc, argv)
        int argc;
        char **argv;
 {
 
 main(argc, argv)
        int argc;
        char **argv;
 {
+       extern char *optarg;
+       extern int optind;
        register struct mtab *mp;
        register struct mtab *mp;
-       register char *np;
-       int mf;
-
-       mf = open("/etc/mtab", 0);
-       read(mf, (char *)mtab, NMOUNT*2*NAMSIZ);
-       if (argc==1) {
-               for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
-                       if (mp->file[0])
-                               printf("%s on %s\n", mp->spec, mp->file);
-               exit(0);
-       }
-top:
-       if (argc > 1) {
-               if (!strcmp(argv[1], "-a")) {
-                       all++;
-                       argc--, argv++;
-                       goto top;
-               }
-               if (!strcmp(argv[1], "-r")) {
-                       ro++;
-                       argc--, argv++;
-                       goto top;
-               }
-               if (!strcmp(argv[1], "-f")) {
-                       fake++;
-                       argc--, argv++;
-                       goto top;
-               }
-               if (!strcmp(argv[1], "-v")) {
-                       verbose++;
-                       argc--, argv++;
-                       goto top;
+       register struct fstab *fs;
+       register int cnt;
+       int all, ch, fd;
+       char *type;
+
+       all = 0;
+       type = NULL;
+       while ((ch = getopt(argc, argv, "afrwv")) != EOF)
+               switch((char)ch) {
+               case 'a':
+                       all = 1;
+                       break;
+               case 'f':
+                       fake = 1;
+                       break;
+               case 'r':
+                       type = FSTAB_RO;
+                       break;
+               case 'v':
+                       verbose = 1;
+                       break;
+               case 'w':
+                       type = FSTAB_RW;
+                       break;
+               case '?':
+               default:
+                       usage();
                }
                }
+       argc -= optind;
+       argv += optind;
+
+       /* NOSTRICT */
+       if ((fd = open(MTAB, O_RDONLY, 0)) >= 0) {
+               if (read(fd, (char *)mtab, NMOUNT * sizeof(struct mtab)) < 0)
+                       mtaberr();
+               (void)close(fd);
        }
        }
+
        if (all) {
        if (all) {
-               struct fstab *fsp;
-
-               if (argc > 1)
-                       goto argcnt;
-               close(2); dup(1);
-               if (setfsent() == 0)
-                       perror(FSTAB), exit(1);
-               while ( (fsp = getfsent()) != 0) {
-                       if (strcmp(fsp->fs_file, "/") == 0)
-                               continue;
-                       ro = !strcmp(fsp->fs_type, FSTAB_RO);
-                       if (ro==0 && strcmp(fsp->fs_type, FSTAB_RW))
-                               continue;
-                       mountfs(fsp->fs_spec, fsp->fs_file, ro);
-               }
+               while ((fs = getfsent()))
+                       if (strcmp(fs->fs_file, "/") && !BADTYPE(fs->fs_type))
+                               mountfs(fs->fs_spec, fs->fs_file,
+                                   type ? type : fs->fs_type);
+               exit(rval);
+       }
+
+       if (argc == 0) {
+               if (verbose || fake || type)
+                       usage();
+               for (mp = mtab, cnt = NMOUNT; cnt--; ++mp)
+                       if (*mp->m_path)
+                               prmtab(mp);
                exit(0);
        }
                exit(0);
        }
-       if (argc < 2 || argc > 3) {
-argcnt:
-               printf("arg count\n");
-               exit(1);
+
+       if (all)
+               usage();
+
+       if (argc == 1) {
+               if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) {
+                       fprintf(stderr,
+                           "mount: unknown special file or file system %s.\n",
+                           *argv);
+                       exit(1);
+               }
+               if (BADTYPE(fs->fs_type)) {
+                       fprintf(stderr,
+                           "mount: %s has unknown file system type.\n", *argv);
+                       exit(1);
+               }
+               mountfs(fs->fs_spec, fs->fs_file, type ? type : fs->fs_type);
+               exit(rval);
        }
        }
-       ro = 0;
-       if(argc > 3)
-               ro++;
-       mountfs(argv[1], argv[2], ro);
+
+       if (argc != 2)
+               usage();
+
+       mountfs(argv[0], argv[1], type ? type : "rw");
+       exit(rval);
 }
 
 }
 
-mountfs(spec, name, ro)
-       char *spec, *name;
+static
+mountfs(spec, name, type)
+       char *spec, *name, *type;
 {
 {
-       register char *np;
-       register struct mtab *mp;
-       int mf;
+       extern int errno;
+       register struct mtab *mp, *space;
+       register int cnt;
+       register char *p;
+       int fd;
+       char *index(), *rindex(), *strcpy();
 
 
-       if (fake==0) {
-               if (mount(spec, name, ro) < 0) {
-                       fprintf(stderr, "%s on ", spec);
-                       perror(name);
+       if (!fake) {
+               if (mount(spec, name, type)) {
+                       rval = 1;
+                       fprintf(stderr, "%s on %s: ", spec, name);
+                       switch (errno) {
+                       case EMFILE:
+                               fprintf(stderr, "Mount table full\n");
+                               break;
+                       case EINVAL:
+                               fprintf(stderr, "Bogus super block\n");
+                               break;
+                       default:
+                               perror((char *)NULL);
+                               break;
+                       }
                        return;
                }
                        return;
                }
+
+               /* we don't do quotas.... */
+               if (strcmp(type, FSTAB_RQ) == 0)
+                       type = FSTAB_RW;
+       }
+
+       /* trim trailing /'s and find last component of name */
+       for (p = index(spec, '\0'); *--p == '/';);
+       *++p = '\0';
+       if (p = rindex(spec, '/')) {
+               *p = '\0';
+               spec = p + 1;
+       }
+
+       for (mp = mtab, cnt = NMOUNT, space = NULL; cnt--; ++mp) {
+               if (!strcmp(mp->m_dname, spec))
+                       break;
+               if (!space && !*mp->m_path)
+                       space = mp;
+       }
+       if (cnt == -1) {
+               if (!space) {
+                       fprintf(stderr, "mount: no more room in %s.\n", MTAB);
+                       exit(1);
+               }
+               mp = space;
        }
        }
+
+#define        DNMAX   (sizeof(mtab[0].m_dname) - 1)
+#define        PNMAX   (sizeof(mtab[0].m_path) - 1)
+
+       (void)strncpy(mp->m_dname, spec, DNMAX);
+       mp->m_dname[DNMAX] = '\0';
+       (void)strncpy(mp->m_path, name, PNMAX);
+       mp->m_path[PNMAX] = '\0';
+       (void)strcpy(mp->m_type, type);
+
        if (verbose)
        if (verbose)
-               fprintf(stderr, "%s on %s%s\n", spec, name,
-                   ro ? " read only" : "");
-       np = spec;
-       while (*np++)
-               ;
-       np--;
-       while (*--np == '/')
-               *np = '\0';
-       while (np > spec && *--np != '/')
-               ;
-       if (*np == '/')
-               np++;
-       spec = np;
-       for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
-               if (!strcmp(mp->spec, spec))
-                       goto replace;
-       for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
-               if (mp->file[0] == 0)
-                       goto replace;
-       return;
-replace:
-       for (np = mp->spec; np < &mp->spec[NAMSIZ-1];)
-               if ((*np++ = *spec++) == 0)
-                       spec--;
-       for (np = mp->file; np < &mp->file[NAMSIZ-1];)
-               if ((*np++ = *name++) == 0)
-                       name--;
-       mp = &mtab[NMOUNT];
-       while ((--mp)->file[0] == 0);
-       mf = creat("/etc/mtab", 0644);
-       write(mf, (char *)mtab, (mp-mtab+1)*2*NAMSIZ);
-       close(mf);
-       return;
+               prmtab(mp);
+
+       for (mp = mtab + NMOUNT - 1; mp > mtab && !*mp->m_path; --mp);
+       if ((fd = open(MTAB, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0)
+               mtaberr();
+       cnt = (mp - mtab + 1) * sizeof(struct mtab);
+       /* NOSTRICT */
+       if (write(fd, (char *)mtab, cnt) != cnt)
+               mtaberr();
+       (void)close(fd);
+}
+
+static
+prmtab(mp)
+       register struct mtab *mp;
+{
+       printf("%s on %s", mp->m_dname, mp->m_path);
+       if (!strcmp(mp->m_type, FSTAB_RO))
+               printf("\t(read-only)");
+       else if (!strcmp(mp->m_type, FSTAB_RQ))
+               printf("\t(with quotas)");
+       printf("\n");
+}
+
+static
+mtaberr()
+{
+       fprintf(stderr, "mount: %s: ", MTAB);
+       perror((char *)NULL);
+       exit(1);
+}
+
+static
+usage()
+{
+       fprintf(stderr, "usage: mount [-arw]\nor mount [-rw] special | node\nor mount [-rw] special node\n");
+       exit(1);
 }
 }