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