]> git.saurik.com Git - apple/libinfo.git/blob - gen.subproj/fstab.c
Libinfo-278.0.3.tar.gz
[apple/libinfo.git] / gen.subproj / fstab.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
26 *
27 * Copyright (c) 1980, 1988, 1993
28 * The Regents of the University of California. All rights reserved.
29 *
30 * @(#)fstab.c 8.1 (Berkeley) 6/4/93
31 */
32
33 #include <errno.h>
34 #include <fstab.h>
35 #include <paths.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <dirent.h>
41 #include <sys/param.h>
42 #include <sys/stat.h>
43 #include <sys/mount.h>
44
45 static FILE *_fs_fp = NULL;
46 static struct fstab _fs_fstab;
47 static struct fstab _root_fstab;
48 static char _root_fstype[MFSNAMELEN];
49 static int firstTime = 1;
50 static int returnedRoot = 0;
51 static void error __P((int));
52 static int fstabscan __P((void));
53 static const char *slash = "/";
54 static const char *remountedroot = "/root";
55
56 /* We don't want to depend on fstab for the root filesystem entry,
57 ** since that can change when disks are added or removed from the system.
58 ** So, we stat "/" and find the _PATH_DEV entry that matches. The devname()
59 ** function can be used as a shortcut if _PATH_DEVDB exists. This returns a
60 ** string like "sd1a", so we need to prepend _PATH_DEV to it.
61 */
62
63 static char *getDevPath(dev_t target_dev) {
64 static char *dev = NULL;
65 char *name;
66
67 if (dev == NULL) {
68 dev = malloc(MAXPATHLEN);
69 if (dev == NULL)
70 return NULL;
71 }
72
73 strcpy(dev, _PATH_DEV);
74
75 /* The root device in fstab should always be a block special device */
76 name = devname(target_dev, S_IFBLK);
77 if (name == NULL) {
78 /* No _PATH_DEVDB. We have to search for it the slow way */
79 DIR *dirp;
80 struct dirent *ent;
81 dirp = opendir(_PATH_DEV);
82 if (dirp == NULL) {
83 perror("opendir");
84 return NULL;
85 }
86 while ((ent = readdir(dirp)) != NULL) {
87 /* Look for a block special device */
88 if (ent->d_type == DT_BLK) {
89 struct stat devst;
90 strcat(dev, ent->d_name);
91 if (stat(dev, &devst) >= 0) {
92 if (devst.st_rdev == target_dev) {
93 return dev;
94 }
95 }
96 }
97 /* set dev to _PATH_DEV and try again */
98 dev[sizeof(_PATH_DEV) - 1] = '\0';
99 }
100 } else {
101 /* We found the _PATH_DEVDB entry */
102 strcat(dev, name);
103 return dev;
104 }
105 return NULL;
106 }
107
108 static int initrootentry(struct fstab *rootentry)
109 {
110 char *rootpath = (char *)slash;
111 struct stat rootstat;
112 struct statfs rootfsinfo;
113
114 if (stat(rootpath, &rootstat) < 0) {
115 perror("stat");
116 return -1;
117 };
118 if (statfs(rootpath, &rootfsinfo) < 0) {
119 perror("statfs");
120 return -1;
121 };
122
123 /* Check to make sure we're not looking at a synthetic root: */
124 if (strcmp(rootfsinfo.f_fstypename, "synthfs") == 0) {
125 rootpath = (char *)remountedroot;
126 if (stat(rootpath, &rootstat) < 0) {
127 perror("stat");
128 return -1;
129 };
130 if (statfs(rootpath, &rootfsinfo) < 0) {
131 perror("statfs");
132 return -1;
133 };
134 };
135
136 /* Copy the type name before returning a pointer a pointer to it */
137 strncpy(_root_fstype, rootfsinfo.f_fstypename, MFSNAMELEN);
138
139 rootentry->fs_spec = getDevPath(rootstat.st_dev);
140 rootentry->fs_file = rootpath;
141 rootentry->fs_vfstype = _root_fstype;
142 rootentry->fs_mntops = FSTAB_RW;
143 rootentry->fs_type = FSTAB_RW;
144 rootentry->fs_freq = 0;
145 rootentry->fs_passno = 1;
146
147 return 0;
148 }
149
150 static int fstabscan()
151 {
152 register char *cp;
153 #define MAXLINELENGTH 1024
154 static char *line = NULL;
155 char subline[MAXLINELENGTH];
156 int typexx;
157
158 if (!returnedRoot) {
159 returnedRoot = 1;
160 if (firstTime) {
161 firstTime = 0;
162 if (initrootentry(&_root_fstab) != 0) {
163 return 0;
164 };
165 }
166 _fs_fstab = _root_fstab;
167 return 1;
168 }
169 if (!_fs_fp) {
170 return(0);
171 }
172
173 if (line == NULL) {
174 line = malloc(MAXLINELENGTH);
175 if (line == NULL)
176 return 0;
177 }
178
179 for (;;) {
180 if (!(cp = fgets(line, MAXLINELENGTH, _fs_fp)))
181 return(0);
182 /* OLD_STYLE_FSTAB */
183 if (!strpbrk(cp, " \t")) {
184 _fs_fstab.fs_spec = strtok(cp, ":\n");
185 #if defined(__APPLE__)
186 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
187 continue;
188 #endif
189 _fs_fstab.fs_file = strtok((char *)NULL, ":\n");
190 /* Only list the root filesystem once */
191 if (!_fs_fstab.fs_file || !(strcmp(_fs_fstab.fs_file, "/"))) {
192 continue;
193 }
194 _fs_fstab.fs_type = strtok((char *)NULL, ":\n");
195 if (_fs_fstab.fs_type) {
196 if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
197 continue;
198 _fs_fstab.fs_mntops = _fs_fstab.fs_type;
199 _fs_fstab.fs_vfstype =
200 strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
201 "ufs" : "swap";
202 if ((cp = strtok((char *)NULL, ":\n"))) {
203 _fs_fstab.fs_freq = atoi(cp);
204 if ((cp = strtok((char *)NULL, ":\n"))) {
205 _fs_fstab.fs_passno = atoi(cp);
206 return(1);
207 }
208 }
209 }
210 goto bad;
211 }
212 /* OLD_STYLE_FSTAB */
213 _fs_fstab.fs_spec = strtok(cp, " \t\n");
214 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
215 continue;
216 _fs_fstab.fs_file = strtok((char *)NULL, " \t\n");
217 /* Only list the root filesystem once */
218 if (!(strcmp(_fs_fstab.fs_file, "/"))) {
219 continue;
220 }
221 _fs_fstab.fs_vfstype = strtok((char *)NULL, " \t\n");
222 _fs_fstab.fs_mntops = strtok((char *)NULL, " \t\n");
223 if (_fs_fstab.fs_mntops == NULL)
224 goto bad;
225 _fs_fstab.fs_freq = 0;
226 _fs_fstab.fs_passno = 0;
227 if ((cp = strtok((char *)NULL, " \t\n")) != NULL) {
228 _fs_fstab.fs_freq = atoi(cp);
229 if ((cp = strtok((char *)NULL, " \t\n")) != NULL)
230 _fs_fstab.fs_passno = atoi(cp);
231 }
232 strcpy(subline, _fs_fstab.fs_mntops);
233 for (typexx = 0, cp = strtok(subline, ","); cp;
234 cp = strtok((char *)NULL, ",")) {
235 if (strlen(cp) != 2)
236 continue;
237 if (!strcmp(cp, FSTAB_RW)) {
238 _fs_fstab.fs_type = FSTAB_RW;
239 break;
240 }
241 if (!strcmp(cp, FSTAB_RQ)) {
242 _fs_fstab.fs_type = FSTAB_RQ;
243 break;
244 }
245 if (!strcmp(cp, FSTAB_RO)) {
246 _fs_fstab.fs_type = FSTAB_RO;
247 break;
248 }
249 if (!strcmp(cp, FSTAB_SW)) {
250 _fs_fstab.fs_type = FSTAB_SW;
251 break;
252 }
253 if (!strcmp(cp, FSTAB_XX)) {
254 _fs_fstab.fs_type = FSTAB_XX;
255 typexx++;
256 break;
257 }
258 }
259 if (typexx)
260 continue;
261 if (cp != NULL)
262 return(1);
263
264 bad: /* no way to distinguish between EOF and syntax error */
265 error(EFTYPE);
266 }
267 /* NOTREACHED */
268 }
269
270 struct fstab *
271 getfsent()
272 {
273 if (!returnedRoot) {
274 setfsent();
275 }
276 if (!fstabscan()) {
277 return((struct fstab *)NULL);
278 }
279 return(&_fs_fstab);
280 }
281
282 struct fstab *
283 getfsspec(name)
284 register const char *name;
285 {
286 if (setfsent())
287 while (fstabscan())
288 if (!strcmp(_fs_fstab.fs_spec, name))
289 return(&_fs_fstab);
290 return((struct fstab *)NULL);
291 }
292
293 struct fstab *
294 getfsfile(name)
295 register const char *name;
296 {
297 if (setfsent())
298 while (fstabscan())
299 if (!strcmp(_fs_fstab.fs_file, name))
300 return(&_fs_fstab);
301 return((struct fstab *)NULL);
302 }
303
304 int
305 setfsent()
306 {
307 returnedRoot = 0;
308 if (_fs_fp) {
309 rewind(_fs_fp);
310 } else {
311 _fs_fp = fopen(_PATH_FSTAB, "r");
312 }
313 return(1);
314 }
315
316 void
317 endfsent()
318 {
319 returnedRoot = 0;
320 if (_fs_fp) {
321 (void)fclose(_fs_fp);
322 _fs_fp = NULL;
323 }
324 }
325
326 static void error(err)
327 int err;
328 {
329 char *p;
330
331 (void)write(STDERR_FILENO, "fstab: ", 7);
332 (void)write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1);
333 (void)write(STDERR_FILENO, ": ", 1);
334 p = strerror(err);
335 (void)write(STDERR_FILENO, p, strlen(p));
336 (void)write(STDERR_FILENO, "\n", 1);
337 }