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