-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;
{
+ extern char *optarg;
+ extern int optind;
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) {
- 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);
}
- 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;
}
+
+ /* 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)
- 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);
}