xref: /original-bsd/sbin/mount/mount.c (revision 2c26d2e3)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)mount.c	5.6 (Berkeley) 08/15/88";
15 #endif not lint
16 
17 #include <sys/param.h>
18 #include <sys/file.h>
19 #include <fstab.h>
20 #include <mtab.h>
21 #include <errno.h>
22 #include <stdio.h>
23 
24 #define	BADTYPE(type) \
25 	(strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \
26 	    strcmp(type, FSTAB_RQ))
27 #define	SETTYPE(type) \
28 	(!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ))
29 
30 #define	MTAB	"/etc/mtab"
31 
32 static struct mtab mtab[NMOUNT];
33 static int fake, verbose;
34 
35 main(argc, argv)
36 	int argc;
37 	char **argv;
38 {
39 	extern char *optarg;
40 	extern int optind;
41 	register struct mtab *mp;
42 	register struct fstab *fs;
43 	register int cnt;
44 	int all, ch, fd, rval, sfake;
45 	char *type;
46 
47 	all = 0;
48 	type = NULL;
49 	while ((ch = getopt(argc, argv, "afrwv")) != EOF)
50 		switch((char)ch) {
51 		case 'a':
52 			all = 1;
53 			break;
54 		case 'f':
55 			fake = 1;
56 			break;
57 		case 'r':
58 			type = FSTAB_RO;
59 			break;
60 		case 'v':
61 			verbose = 1;
62 			break;
63 		case 'w':
64 			type = FSTAB_RW;
65 			break;
66 		case '?':
67 		default:
68 			usage();
69 		}
70 	argc -= optind;
71 	argv += optind;
72 
73 	/* NOSTRICT */
74 	if ((fd = open(MTAB, O_RDONLY, 0)) >= 0) {
75 		if (read(fd, (char *)mtab, NMOUNT * sizeof(struct mtab)) < 0)
76 			mtaberr();
77 		(void)close(fd);
78 	}
79 
80 	if (all) {
81 		rval = 0;
82 		for (sfake = fake; fs = getfsent(); fake = sfake) {
83 			if (BADTYPE(fs->fs_type))
84 				continue;
85 			/* `/' is special, it's always mounted */
86 			if (!strcmp(fs->fs_file, "/"))
87 				fake = 1;
88 			rval |= mountfs(fs->fs_spec, fs->fs_file,
89 			    type ? type : fs->fs_type);
90 		}
91 		exit(rval);
92 	}
93 
94 	if (argc == 0) {
95 		if (verbose || fake || type)
96 			usage();
97 		for (mp = mtab, cnt = NMOUNT; cnt--; ++mp)
98 			if (*mp->m_path)
99 				prmtab(mp);
100 		exit(0);
101 	}
102 
103 	if (all)
104 		usage();
105 
106 	if (argc == 1) {
107 		if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) {
108 			fprintf(stderr,
109 			    "mount: unknown special file or file system %s.\n",
110 			    *argv);
111 			exit(1);
112 		}
113 		if (BADTYPE(fs->fs_type)) {
114 			fprintf(stderr,
115 			    "mount: %s has unknown file system type.\n", *argv);
116 			exit(1);
117 		}
118 		exit(mountfs(fs->fs_spec, fs->fs_file,
119 		    type ? type : fs->fs_type));
120 	}
121 
122 	if (argc != 2)
123 		usage();
124 
125 	exit(mountfs(argv[0], argv[1], type ? type : "rw"));
126 }
127 
128 static
129 mountfs(spec, name, type)
130 	char *spec, *name, *type;
131 {
132 	extern int errno;
133 	register struct mtab *mp, *space;
134 	register int cnt;
135 	register char *p;
136 	int fd;
137 	char *index(), *rindex(), *strcpy();
138 
139 	if (!fake) {
140 		if (mount(spec, name, !strcmp(type, FSTAB_RO))) {
141 			fprintf(stderr, "%s on %s: ", spec, name);
142 			switch (errno) {
143 			case EMFILE:
144 				fprintf(stderr, "Mount table full\n");
145 				break;
146 			case EINVAL:
147 				fprintf(stderr, "Bogus super block\n");
148 				break;
149 			default:
150 				perror((char *)NULL);
151 				break;
152 			}
153 			return(1);
154 		}
155 
156 		/* we don't do quotas.... */
157 		if (strcmp(type, FSTAB_RQ) == 0)
158 			type = FSTAB_RW;
159 	}
160 
161 	/* trim trailing /'s and find last component of name */
162 	for (p = index(spec, '\0'); *--p == '/';);
163 	*++p = '\0';
164 	if (p = rindex(spec, '/')) {
165 		*p = '\0';
166 		spec = p + 1;
167 	}
168 
169 	for (mp = mtab, cnt = NMOUNT, space = NULL; cnt--; ++mp) {
170 		if (!strcmp(mp->m_dname, spec))
171 			break;
172 		if (!space && !*mp->m_path)
173 			space = mp;
174 	}
175 	if (cnt == -1) {
176 		if (!space) {
177 			fprintf(stderr, "mount: no more room in %s.\n", MTAB);
178 			exit(1);
179 		}
180 		mp = space;
181 	}
182 
183 #define	DNMAX	(sizeof(mtab[0].m_dname) - 1)
184 #define	PNMAX	(sizeof(mtab[0].m_path) - 1)
185 
186 	(void)strncpy(mp->m_dname, spec, DNMAX);
187 	mp->m_dname[DNMAX] = '\0';
188 	(void)strncpy(mp->m_path, name, PNMAX);
189 	mp->m_path[PNMAX] = '\0';
190 	(void)strcpy(mp->m_type, type);
191 
192 	if (verbose)
193 		prmtab(mp);
194 
195 	for (mp = mtab + NMOUNT - 1; mp > mtab && !*mp->m_path; --mp);
196 	if ((fd = open(MTAB, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0)
197 		mtaberr();
198 	cnt = (mp - mtab + 1) * sizeof(struct mtab);
199 	/* NOSTRICT */
200 	if (write(fd, (char *)mtab, cnt) != cnt)
201 		mtaberr();
202 	(void)close(fd);
203 	return(0);
204 }
205 
206 static
207 prmtab(mp)
208 	register struct mtab *mp;
209 {
210 	printf("%s on %s", mp->m_dname, mp->m_path);
211 	if (!strcmp(mp->m_type, FSTAB_RO))
212 		printf("\t(read-only)");
213 	else if (!strcmp(mp->m_type, FSTAB_RQ))
214 		printf("\t(with quotas)");
215 	printf("\n");
216 }
217 
218 static
219 mtaberr()
220 {
221 	fprintf(stderr, "mount: %s: ", MTAB);
222 	perror((char *)NULL);
223 	exit(1);
224 }
225 
226 static
227 usage()
228 {
229 	fprintf(stderr, "usage: mount [-afrw]\nor mount [-frw] special | node\nor mount [-frw] special node\n");
230 	exit(1);
231 }
232