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 |
499c04f5 | 14 | static char sccsid[] = "@(#)mount.c 5.6 (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]; |
a15efba1 | 33 | static int fake, 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; | |
499c04f5 | 44 | int all, ch, fd, rval, sfake; |
f8836a3c KB |
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) { |
a15efba1 | 81 | rval = 0; |
499c04f5 KB |
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 | } | |
5ad3e76c | 91 | exit(rval); |
9dc9fb3d | 92 | } |
f8836a3c KB |
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); | |
7a6d69cb SL |
100 | exit(0); |
101 | } | |
f8836a3c KB |
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 | } | |
a15efba1 KB |
118 | exit(mountfs(fs->fs_spec, fs->fs_file, |
119 | type ? type : fs->fs_type)); | |
df611cb9 | 120 | } |
9dc9fb3d | 121 | |
f8836a3c KB |
122 | if (argc != 2) |
123 | usage(); | |
7a6d69cb | 124 | |
a15efba1 | 125 | exit(mountfs(argv[0], argv[1], type ? type : "rw")); |
7a6d69cb SL |
126 | } |
127 | ||
f8836a3c | 128 | static |
7a6d69cb SL |
129 | mountfs(spec, name, type) |
130 | char *spec, *name, *type; | |
9dc9fb3d | 131 | { |
f8836a3c KB |
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(); | |
9dc9fb3d | 138 | |
7a6d69cb | 139 | if (!fake) { |
a15efba1 | 140 | if (mount(spec, name, !strcmp(type, FSTAB_RO))) { |
f8836a3c | 141 | fprintf(stderr, "%s on %s: ", spec, name); |
78b57350 | 142 | switch (errno) { |
78b57350 | 143 | case EMFILE: |
f8836a3c | 144 | fprintf(stderr, "Mount table full\n"); |
78b57350 | 145 | break; |
78b57350 | 146 | case EINVAL: |
f8836a3c | 147 | fprintf(stderr, "Bogus super block\n"); |
78b57350 | 148 | break; |
78b57350 | 149 | default: |
f8836a3c KB |
150 | perror((char *)NULL); |
151 | break; | |
78b57350 | 152 | } |
a15efba1 | 153 | return(1); |
df611cb9 | 154 | } |
f8836a3c | 155 | |
7a6d69cb SL |
156 | /* we don't do quotas.... */ |
157 | if (strcmp(type, FSTAB_RQ) == 0) | |
158 | type = FSTAB_RW; | |
df611cb9 | 159 | } |
f8836a3c KB |
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; | |
7a6d69cb | 167 | } |
f8836a3c KB |
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); | |
7a6d69cb | 187 | mp->m_dname[DNMAX] = '\0'; |
f8836a3c | 188 | (void)strncpy(mp->m_path, name, PNMAX); |
7a6d69cb | 189 | mp->m_path[PNMAX] = '\0'; |
f8836a3c KB |
190 | (void)strcpy(mp->m_type, type); |
191 | ||
7a6d69cb SL |
192 | if (verbose) |
193 | prmtab(mp); | |
f8836a3c KB |
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); | |
a15efba1 | 203 | return(0); |
f8836a3c KB |
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 | { | |
a15efba1 | 229 | fprintf(stderr, "usage: mount [-afrw]\nor mount [-frw] special | node\nor mount [-frw] special node\n"); |
f8836a3c | 230 | exit(1); |
9dc9fb3d | 231 | } |