only executable by group dialer
[unix-history] / usr / src / sbin / mount / mount.c
CommitLineData
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
8char 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 14static 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 32static struct mtab mtab[NMOUNT];
a15efba1 33static int fake, verbose;
62c2bd36 34
9dc9fb3d 35main(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 128static
7a6d69cb
SL
129mountfs(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
206static
207prmtab(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
218static
219mtaberr()
220{
221 fprintf(stderr, "mount: %s: ", MTAB);
222 perror((char *)NULL);
223 exit(1);
224}
225
226static
227usage()
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}