xref: /csrg-svn/sbin/mount/mount.c (revision 35369)
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*35369Sbostic static char sccsid[] = "@(#)mount.c	5.5 (Berkeley) 08/15/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*35369Sbostic static int fake, 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;
44*35369Sbostic 	int all, ch, fd, rval;
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) {
81*35369Sbostic 		rval = 0;
8235339Sbostic 		while ((fs = getfsent()))
8335339Sbostic 			if (strcmp(fs->fs_file, "/") && !BADTYPE(fs->fs_type))
84*35369Sbostic 				rval |= mountfs(fs->fs_spec, fs->fs_file,
8535339Sbostic 				    type ? type : fs->fs_type);
8635341Sbostic 		exit(rval);
8735339Sbostic 	}
885073Sroot 
8935339Sbostic 	if (argc == 0) {
9035339Sbostic 		if (verbose || fake || type)
9135339Sbostic 			usage();
9235339Sbostic 		for (mp = mtab, cnt = NMOUNT; cnt--; ++mp)
9335339Sbostic 			if (*mp->m_path)
9435339Sbostic 				prmtab(mp);
954460Sroot 		exit(0);
961057Sbill 	}
9712808Ssam 
9835339Sbostic 	if (all)
9935339Sbostic 		usage();
10035339Sbostic 
10135339Sbostic 	if (argc == 1) {
10235339Sbostic 		if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) {
10335339Sbostic 			fprintf(stderr,
10435339Sbostic 			    "mount: unknown special file or file system %s.\n",
10535339Sbostic 			    *argv);
10635339Sbostic 			exit(1);
10735339Sbostic 		}
10835339Sbostic 		if (BADTYPE(fs->fs_type)) {
10935339Sbostic 			fprintf(stderr,
11035339Sbostic 			    "mount: %s has unknown file system type.\n", *argv);
11135339Sbostic 			exit(1);
11235339Sbostic 		}
113*35369Sbostic 		exit(mountfs(fs->fs_spec, fs->fs_file,
114*35369Sbostic 		    type ? type : fs->fs_type));
11512808Ssam 	}
1161057Sbill 
11735339Sbostic 	if (argc != 2)
11835339Sbostic 		usage();
11912808Ssam 
120*35369Sbostic 	exit(mountfs(argv[0], argv[1], type ? type : "rw"));
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) {
135*35369Sbostic 		if (mount(spec, name, !strcmp(type, FSTAB_RO))) {
13635339Sbostic 			fprintf(stderr, "%s on %s: ", spec, name);
13716669Ssam 			switch (errno) {
13816669Ssam 			case EMFILE:
13935339Sbostic 				fprintf(stderr, "Mount table full\n");
14016669Ssam 				break;
14116669Ssam 			case EINVAL:
14235339Sbostic 				fprintf(stderr, "Bogus super block\n");
14316669Ssam 				break;
14416669Ssam 			default:
14535339Sbostic 				perror((char *)NULL);
14635339Sbostic 				break;
14716669Ssam 			}
148*35369Sbostic 			return(1);
1494460Sroot 		}
15035339Sbostic 
15112808Ssam 		/* we don't do quotas.... */
15212808Ssam 		if (strcmp(type, FSTAB_RQ) == 0)
15312808Ssam 			type = FSTAB_RW;
1544460Sroot 	}
15535339Sbostic 
15635339Sbostic 	/* trim trailing /'s and find last component of name */
15735339Sbostic 	for (p = index(spec, '\0'); *--p == '/';);
15835339Sbostic 	*++p = '\0';
15935339Sbostic 	if (p = rindex(spec, '/')) {
16035339Sbostic 		*p = '\0';
16135339Sbostic 		spec = p + 1;
16212808Ssam 	}
16335339Sbostic 
16435339Sbostic 	for (mp = mtab, cnt = NMOUNT, space = NULL; cnt--; ++mp) {
16535339Sbostic 		if (!strcmp(mp->m_dname, spec))
16635339Sbostic 			break;
16735339Sbostic 		if (!space && !*mp->m_path)
16835339Sbostic 			space = mp;
16935339Sbostic 	}
17035339Sbostic 	if (cnt == -1) {
17135339Sbostic 		if (!space) {
17235339Sbostic 			fprintf(stderr, "mount: no more room in %s.\n", MTAB);
17335339Sbostic 			exit(1);
17435339Sbostic 		}
17535339Sbostic 		mp = space;
17635339Sbostic 	}
17735339Sbostic 
17835339Sbostic #define	DNMAX	(sizeof(mtab[0].m_dname) - 1)
17935339Sbostic #define	PNMAX	(sizeof(mtab[0].m_path) - 1)
18035339Sbostic 
18135339Sbostic 	(void)strncpy(mp->m_dname, spec, DNMAX);
18212808Ssam 	mp->m_dname[DNMAX] = '\0';
18335339Sbostic 	(void)strncpy(mp->m_path, name, PNMAX);
18412808Ssam 	mp->m_path[PNMAX] = '\0';
18535339Sbostic 	(void)strcpy(mp->m_type, type);
18635339Sbostic 
18712808Ssam 	if (verbose)
18812808Ssam 		prmtab(mp);
18935339Sbostic 
19035339Sbostic 	for (mp = mtab + NMOUNT - 1; mp > mtab && !*mp->m_path; --mp);
19135339Sbostic 	if ((fd = open(MTAB, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0)
19235339Sbostic 		mtaberr();
19335339Sbostic 	cnt = (mp - mtab + 1) * sizeof(struct mtab);
19435339Sbostic 	/* NOSTRICT */
19535339Sbostic 	if (write(fd, (char *)mtab, cnt) != cnt)
19635339Sbostic 		mtaberr();
19735339Sbostic 	(void)close(fd);
198*35369Sbostic 	return(0);
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 {
224*35369Sbostic 	fprintf(stderr, "usage: mount [-afrw]\nor mount [-frw] special | node\nor mount [-frw] special node\n");
22535339Sbostic 	exit(1);
22635339Sbostic }
227