xref: /csrg-svn/sbin/mount/mount.c (revision 35341)
121156Sdist /*
221156Sdist  * Copyright (c) 1980 Regents of the University of California.
321156Sdist  * All rights reserved.  The Berkeley software License Agreement
421156Sdist  * specifies the terms and conditions for redistribution.
521156Sdist  */
621156Sdist 
710811Ssam #ifndef lint
821156Sdist char copyright[] =
921156Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1021156Sdist  All rights reserved.\n";
1121156Sdist #endif not lint
121057Sbill 
1321156Sdist #ifndef lint
14*35341Sbostic static char sccsid[] = "@(#)mount.c	5.4 (Berkeley) 08/05/88";
1521156Sdist #endif not lint
1621156Sdist 
1712808Ssam #include <sys/param.h>
1835339Sbostic #include <sys/file.h>
1910811Ssam #include <fstab.h>
2012808Ssam #include <mtab.h>
2116669Ssam #include <errno.h>
2235339Sbostic #include <stdio.h>
231057Sbill 
2435339Sbostic #define	BADTYPE(type) \
2535339Sbostic 	(strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \
2635339Sbostic 	    strcmp(type, FSTAB_RQ))
2735339Sbostic #define	SETTYPE(type) \
2835339Sbostic 	(!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ))
291057Sbill 
3035339Sbostic #define	MTAB	"/etc/mtab"
311057Sbill 
3235339Sbostic static struct mtab mtab[NMOUNT];
33*35341Sbostic static int fake, rval, verbose;
345073Sroot 
351057Sbill main(argc, argv)
365073Sroot 	int argc;
375073Sroot 	char **argv;
381057Sbill {
3935339Sbostic 	extern char *optarg;
4035339Sbostic 	extern int optind;
411057Sbill 	register struct mtab *mp;
4235339Sbostic 	register struct fstab *fs;
4335339Sbostic 	register int cnt;
4435339Sbostic 	int all, ch, fd;
4535339Sbostic 	char *type;
461057Sbill 
4735339Sbostic 	all = 0;
4835339Sbostic 	type = NULL;
4935339Sbostic 	while ((ch = getopt(argc, argv, "afrwv")) != EOF)
5035339Sbostic 		switch((char)ch) {
5135339Sbostic 		case 'a':
5235339Sbostic 			all = 1;
5335339Sbostic 			break;
5435339Sbostic 		case 'f':
5535339Sbostic 			fake = 1;
5635339Sbostic 			break;
5735339Sbostic 		case 'r':
5812808Ssam 			type = FSTAB_RO;
5935339Sbostic 			break;
6035339Sbostic 		case 'v':
6135339Sbostic 			verbose = 1;
6235339Sbostic 			break;
6335339Sbostic 		case 'w':
6435339Sbostic 			type = FSTAB_RW;
6535339Sbostic 			break;
6635339Sbostic 		case '?':
6735339Sbostic 		default:
6835339Sbostic 			usage();
695073Sroot 		}
7035339Sbostic 	argc -= optind;
7135339Sbostic 	argv += optind;
7235339Sbostic 
7335339Sbostic 	/* NOSTRICT */
7435339Sbostic 	if ((fd = open(MTAB, O_RDONLY, 0)) >= 0) {
7535339Sbostic 		if (read(fd, (char *)mtab, NMOUNT * sizeof(struct mtab)) < 0)
7635339Sbostic 			mtaberr();
7735339Sbostic 		(void)close(fd);
781057Sbill 	}
7935339Sbostic 
804460Sroot 	if (all) {
8135339Sbostic 		while ((fs = getfsent()))
8235339Sbostic 			if (strcmp(fs->fs_file, "/") && !BADTYPE(fs->fs_type))
8335339Sbostic 				mountfs(fs->fs_spec, fs->fs_file,
8435339Sbostic 				    type ? type : fs->fs_type);
85*35341Sbostic 		exit(rval);
8635339Sbostic 	}
875073Sroot 
8835339Sbostic 	if (argc == 0) {
8935339Sbostic 		if (verbose || fake || type)
9035339Sbostic 			usage();
9135339Sbostic 		for (mp = mtab, cnt = NMOUNT; cnt--; ++mp)
9235339Sbostic 			if (*mp->m_path)
9335339Sbostic 				prmtab(mp);
944460Sroot 		exit(0);
951057Sbill 	}
9612808Ssam 
9735339Sbostic 	if (all)
9835339Sbostic 		usage();
9935339Sbostic 
10035339Sbostic 	if (argc == 1) {
10135339Sbostic 		if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) {
10235339Sbostic 			fprintf(stderr,
10335339Sbostic 			    "mount: unknown special file or file system %s.\n",
10435339Sbostic 			    *argv);
10535339Sbostic 			exit(1);
10635339Sbostic 		}
10735339Sbostic 		if (BADTYPE(fs->fs_type)) {
10835339Sbostic 			fprintf(stderr,
10935339Sbostic 			    "mount: %s has unknown file system type.\n", *argv);
11035339Sbostic 			exit(1);
11135339Sbostic 		}
11235339Sbostic 		mountfs(fs->fs_spec, fs->fs_file, type ? type : fs->fs_type);
113*35341Sbostic 		exit(rval);
11412808Ssam 	}
1151057Sbill 
11635339Sbostic 	if (argc != 2)
11735339Sbostic 		usage();
11812808Ssam 
11935339Sbostic 	mountfs(argv[0], argv[1], type ? type : "rw");
120*35341Sbostic 	exit(rval);
12112808Ssam }
12212808Ssam 
12335339Sbostic static
12412808Ssam mountfs(spec, name, type)
12512808Ssam 	char *spec, *name, *type;
12612808Ssam {
12735339Sbostic 	extern int errno;
12835339Sbostic 	register struct mtab *mp, *space;
12935339Sbostic 	register int cnt;
13035339Sbostic 	register char *p;
13135339Sbostic 	int fd;
13235339Sbostic 	char *index(), *rindex(), *strcpy();
1331057Sbill 
13412808Ssam 	if (!fake) {
13535339Sbostic 		if (mount(spec, name, type)) {
136*35341Sbostic 			rval = 1;
13735339Sbostic 			fprintf(stderr, "%s on %s: ", spec, name);
13816669Ssam 			switch (errno) {
13916669Ssam 			case EMFILE:
14035339Sbostic 				fprintf(stderr, "Mount table full\n");
14116669Ssam 				break;
14216669Ssam 			case EINVAL:
14335339Sbostic 				fprintf(stderr, "Bogus super block\n");
14416669Ssam 				break;
14516669Ssam 			default:
14635339Sbostic 				perror((char *)NULL);
14735339Sbostic 				break;
14816669Ssam 			}
1494460Sroot 			return;
1504460Sroot 		}
15135339Sbostic 
15212808Ssam 		/* we don't do quotas.... */
15312808Ssam 		if (strcmp(type, FSTAB_RQ) == 0)
15412808Ssam 			type = FSTAB_RW;
1554460Sroot 	}
15635339Sbostic 
15735339Sbostic 	/* trim trailing /'s and find last component of name */
15835339Sbostic 	for (p = index(spec, '\0'); *--p == '/';);
15935339Sbostic 	*++p = '\0';
16035339Sbostic 	if (p = rindex(spec, '/')) {
16135339Sbostic 		*p = '\0';
16235339Sbostic 		spec = p + 1;
16312808Ssam 	}
16435339Sbostic 
16535339Sbostic 	for (mp = mtab, cnt = NMOUNT, space = NULL; cnt--; ++mp) {
16635339Sbostic 		if (!strcmp(mp->m_dname, spec))
16735339Sbostic 			break;
16835339Sbostic 		if (!space && !*mp->m_path)
16935339Sbostic 			space = mp;
17035339Sbostic 	}
17135339Sbostic 	if (cnt == -1) {
17235339Sbostic 		if (!space) {
17335339Sbostic 			fprintf(stderr, "mount: no more room in %s.\n", MTAB);
17435339Sbostic 			exit(1);
17535339Sbostic 		}
17635339Sbostic 		mp = space;
17735339Sbostic 	}
17835339Sbostic 
17935339Sbostic #define	DNMAX	(sizeof(mtab[0].m_dname) - 1)
18035339Sbostic #define	PNMAX	(sizeof(mtab[0].m_path) - 1)
18135339Sbostic 
18235339Sbostic 	(void)strncpy(mp->m_dname, spec, DNMAX);
18312808Ssam 	mp->m_dname[DNMAX] = '\0';
18435339Sbostic 	(void)strncpy(mp->m_path, name, PNMAX);
18512808Ssam 	mp->m_path[PNMAX] = '\0';
18635339Sbostic 	(void)strcpy(mp->m_type, type);
18735339Sbostic 
18812808Ssam 	if (verbose)
18912808Ssam 		prmtab(mp);
19035339Sbostic 
19135339Sbostic 	for (mp = mtab + NMOUNT - 1; mp > mtab && !*mp->m_path; --mp);
19235339Sbostic 	if ((fd = open(MTAB, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0)
19335339Sbostic 		mtaberr();
19435339Sbostic 	cnt = (mp - mtab + 1) * sizeof(struct mtab);
19535339Sbostic 	/* NOSTRICT */
19635339Sbostic 	if (write(fd, (char *)mtab, cnt) != cnt)
19735339Sbostic 		mtaberr();
19835339Sbostic 	(void)close(fd);
1991057Sbill }
20035339Sbostic 
20135339Sbostic static
20235339Sbostic prmtab(mp)
20335339Sbostic 	register struct mtab *mp;
20435339Sbostic {
20535339Sbostic 	printf("%s on %s", mp->m_dname, mp->m_path);
20635339Sbostic 	if (!strcmp(mp->m_type, FSTAB_RO))
20735339Sbostic 		printf("\t(read-only)");
20835339Sbostic 	else if (!strcmp(mp->m_type, FSTAB_RQ))
20935339Sbostic 		printf("\t(with quotas)");
21035339Sbostic 	printf("\n");
21135339Sbostic }
21235339Sbostic 
21335339Sbostic static
21435339Sbostic mtaberr()
21535339Sbostic {
21635339Sbostic 	fprintf(stderr, "mount: %s: ", MTAB);
21735339Sbostic 	perror((char *)NULL);
21835339Sbostic 	exit(1);
21935339Sbostic }
22035339Sbostic 
22135339Sbostic static
22235339Sbostic usage()
22335339Sbostic {
22435339Sbostic 	fprintf(stderr, "usage: mount [-arw]\nor mount [-rw] special | node\nor mount [-rw] special node\n");
22535339Sbostic 	exit(1);
22635339Sbostic }
227