Commit | Line | Data |
---|---|---|
4ba29bcc DF |
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 | ||
a3c5c1bf | 13 | #ifndef lint |
5ad3e76c | 14 | static char sccsid[] = "@(#)mount.c 5.4 (Berkeley) %G%"; |
4ba29bcc | 15 | #endif not lint |
9dc9fb3d | 16 | |
7a6d69cb | 17 | #include <sys/param.h> |
f8836a3c | 18 | #include <sys/file.h> |
a3c5c1bf | 19 | #include <fstab.h> |
7a6d69cb | 20 | #include <mtab.h> |
78b57350 | 21 | #include <errno.h> |
f8836a3c | 22 | #include <stdio.h> |
9dc9fb3d | 23 | |
f8836a3c KB |
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)) | |
9dc9fb3d | 29 | |
f8836a3c | 30 | #define MTAB "/etc/mtab" |
9dc9fb3d | 31 | |
f8836a3c | 32 | static struct mtab mtab[NMOUNT]; |
5ad3e76c | 33 | static int fake, rval, verbose; |
62c2bd36 | 34 | |
9dc9fb3d | 35 | main(argc, argv) |
62c2bd36 BJ |
36 | int argc; |
37 | char **argv; | |
9dc9fb3d | 38 | { |
f8836a3c KB |
39 | extern char *optarg; |
40 | extern int optind; | |
9dc9fb3d | 41 | register struct mtab *mp; |
f8836a3c KB |
42 | register struct fstab *fs; |
43 | register int cnt; | |
44 | int all, ch, fd; | |
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': | |
7a6d69cb | 58 | type = FSTAB_RO; |
f8836a3c KB |
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(); | |
df611cb9 | 69 | } |
f8836a3c KB |
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); | |
df611cb9 | 78 | } |
f8836a3c | 79 | |
df611cb9 | 80 | if (all) { |
f8836a3c KB |
81 | while ((fs = getfsent())) |
82 | if (strcmp(fs->fs_file, "/") && !BADTYPE(fs->fs_type)) | |
83 | mountfs(fs->fs_spec, fs->fs_file, | |
84 | type ? type : fs->fs_type); | |
5ad3e76c | 85 | exit(rval); |
9dc9fb3d | 86 | } |
f8836a3c KB |
87 | |
88 | if (argc == 0) { | |
89 | if (verbose || fake || type) | |
90 | usage(); | |
91 | for (mp = mtab, cnt = NMOUNT; cnt--; ++mp) | |
92 | if (*mp->m_path) | |
93 | prmtab(mp); | |
7a6d69cb SL |
94 | exit(0); |
95 | } | |
f8836a3c KB |
96 | |
97 | if (all) | |
98 | usage(); | |
99 | ||
100 | if (argc == 1) { | |
101 | if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { | |
102 | fprintf(stderr, | |
103 | "mount: unknown special file or file system %s.\n", | |
104 | *argv); | |
105 | exit(1); | |
106 | } | |
107 | if (BADTYPE(fs->fs_type)) { | |
108 | fprintf(stderr, | |
109 | "mount: %s has unknown file system type.\n", *argv); | |
110 | exit(1); | |
111 | } | |
112 | mountfs(fs->fs_spec, fs->fs_file, type ? type : fs->fs_type); | |
5ad3e76c | 113 | exit(rval); |
df611cb9 | 114 | } |
9dc9fb3d | 115 | |
f8836a3c KB |
116 | if (argc != 2) |
117 | usage(); | |
7a6d69cb | 118 | |
f8836a3c | 119 | mountfs(argv[0], argv[1], type ? type : "rw"); |
5ad3e76c | 120 | exit(rval); |
7a6d69cb SL |
121 | } |
122 | ||
f8836a3c | 123 | static |
7a6d69cb SL |
124 | mountfs(spec, name, type) |
125 | char *spec, *name, *type; | |
9dc9fb3d | 126 | { |
f8836a3c KB |
127 | extern int errno; |
128 | register struct mtab *mp, *space; | |
129 | register int cnt; | |
130 | register char *p; | |
131 | int fd; | |
132 | char *index(), *rindex(), *strcpy(); | |
9dc9fb3d | 133 | |
7a6d69cb | 134 | if (!fake) { |
f8836a3c | 135 | if (mount(spec, name, type)) { |
5ad3e76c | 136 | rval = 1; |
f8836a3c | 137 | fprintf(stderr, "%s on %s: ", spec, name); |
78b57350 | 138 | switch (errno) { |
78b57350 | 139 | case EMFILE: |
f8836a3c | 140 | fprintf(stderr, "Mount table full\n"); |
78b57350 | 141 | break; |
78b57350 | 142 | case EINVAL: |
f8836a3c | 143 | fprintf(stderr, "Bogus super block\n"); |
78b57350 | 144 | break; |
78b57350 | 145 | default: |
f8836a3c KB |
146 | perror((char *)NULL); |
147 | break; | |
78b57350 | 148 | } |
df611cb9 BJ |
149 | return; |
150 | } | |
f8836a3c | 151 | |
7a6d69cb SL |
152 | /* we don't do quotas.... */ |
153 | if (strcmp(type, FSTAB_RQ) == 0) | |
154 | type = FSTAB_RW; | |
df611cb9 | 155 | } |
f8836a3c KB |
156 | |
157 | /* trim trailing /'s and find last component of name */ | |
158 | for (p = index(spec, '\0'); *--p == '/';); | |
159 | *++p = '\0'; | |
160 | if (p = rindex(spec, '/')) { | |
161 | *p = '\0'; | |
162 | spec = p + 1; | |
7a6d69cb | 163 | } |
f8836a3c KB |
164 | |
165 | for (mp = mtab, cnt = NMOUNT, space = NULL; cnt--; ++mp) { | |
166 | if (!strcmp(mp->m_dname, spec)) | |
167 | break; | |
168 | if (!space && !*mp->m_path) | |
169 | space = mp; | |
170 | } | |
171 | if (cnt == -1) { | |
172 | if (!space) { | |
173 | fprintf(stderr, "mount: no more room in %s.\n", MTAB); | |
174 | exit(1); | |
175 | } | |
176 | mp = space; | |
177 | } | |
178 | ||
179 | #define DNMAX (sizeof(mtab[0].m_dname) - 1) | |
180 | #define PNMAX (sizeof(mtab[0].m_path) - 1) | |
181 | ||
182 | (void)strncpy(mp->m_dname, spec, DNMAX); | |
7a6d69cb | 183 | mp->m_dname[DNMAX] = '\0'; |
f8836a3c | 184 | (void)strncpy(mp->m_path, name, PNMAX); |
7a6d69cb | 185 | mp->m_path[PNMAX] = '\0'; |
f8836a3c KB |
186 | (void)strcpy(mp->m_type, type); |
187 | ||
7a6d69cb SL |
188 | if (verbose) |
189 | prmtab(mp); | |
f8836a3c KB |
190 | |
191 | for (mp = mtab + NMOUNT - 1; mp > mtab && !*mp->m_path; --mp); | |
192 | if ((fd = open(MTAB, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) | |
193 | mtaberr(); | |
194 | cnt = (mp - mtab + 1) * sizeof(struct mtab); | |
195 | /* NOSTRICT */ | |
196 | if (write(fd, (char *)mtab, cnt) != cnt) | |
197 | mtaberr(); | |
198 | (void)close(fd); | |
199 | } | |
200 | ||
201 | static | |
202 | prmtab(mp) | |
203 | register struct mtab *mp; | |
204 | { | |
205 | printf("%s on %s", mp->m_dname, mp->m_path); | |
206 | if (!strcmp(mp->m_type, FSTAB_RO)) | |
207 | printf("\t(read-only)"); | |
208 | else if (!strcmp(mp->m_type, FSTAB_RQ)) | |
209 | printf("\t(with quotas)"); | |
210 | printf("\n"); | |
211 | } | |
212 | ||
213 | static | |
214 | mtaberr() | |
215 | { | |
216 | fprintf(stderr, "mount: %s: ", MTAB); | |
217 | perror((char *)NULL); | |
218 | exit(1); | |
219 | } | |
220 | ||
221 | static | |
222 | usage() | |
223 | { | |
224 | fprintf(stderr, "usage: mount [-arw]\nor mount [-rw] special | node\nor mount [-rw] special node\n"); | |
225 | exit(1); | |
9dc9fb3d | 226 | } |