fix include file case
[reactos.git] / rosapps / mc / src / mountlist.c
1 /* mountlist.c -- return a list of mounted filesystems
2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21 #ifndef NO_INFOMOUNT
22
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include "mountlist.h"
26
27 #ifdef STDC_HEADERS
28 #include <stdlib.h>
29 #else
30 void free (void *ptr);
31 #endif
32 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
33 #include <string.h>
34 #else
35 #include <strings.h>
36 #endif
37
38 #ifdef HAVE_SYS_PARAM_H
39 #include <sys/param.h>
40 #endif
41
42 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
43 #include <sys/mount.h>
44 #include <sys/fs_types.h>
45 #endif /* MOUNTED_GETFSSTAT */
46
47 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
48 #include <mntent.h>
49 #if !defined(MOUNTED)
50 #if defined(MNT_MNTTAB) /* HP-UX. */
51 #define MOUNTED MNT_MNTTAB
52 #endif
53 #if defined(MNTTABNAME) /* Dynix. */
54 #define MOUNTED MNTTABNAME
55 #endif
56 #endif
57 #endif
58
59 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
60 #include <sys/mount.h>
61 #endif
62
63 #ifdef MOUNTED_GETMNT /* Ultrix. */
64 #include <sys/mount.h>
65 #include <sys/fs_types.h>
66 #endif
67
68 #ifdef MOUNTED_FREAD /* SVR2. */
69 #include <mnttab.h>
70 #endif
71
72 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
73 #include <mnttab.h>
74 #include <sys/fstyp.h>
75 #include <sys/statfs.h>
76 #endif
77
78 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
79 #include <sys/mnttab.h>
80 #endif
81
82 #ifdef MOUNTED_VMOUNT /* AIX. */
83 #include <fshelp.h>
84 #include <sys/vfs.h>
85 #endif
86
87 #ifdef __bsdi__
88 # ifndef MOUNT_UFS
89 # define xBSD
90 # endif
91 #endif
92
93 #ifdef __NetBSD__
94 # define xBSD
95 #endif
96
97 #ifdef __OpenBSD__
98 # define xBSD
99 #endif
100
101 #if defined(SCO_FLAVOR) && defined(__GNUC__)
102 extern char* strdup(const char*);
103 #endif
104
105 char *strstr (const char *haystack, const char *needle);
106 /* void error (void); FIXME -- needed? */
107
108 #ifdef DOLPHIN
109 /* So special that it's not worth putting this in autoconf. */
110 #undef MOUNTED_FREAD_FSTYP
111 #define MOUNTED_GETMNTTBL
112 #endif
113
114 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
115 /* Return the value of the hexadecimal number represented by CP.
116 No prefix (like '0x') or suffix (like 'h') is expected to be
117 part of CP. */
118
119 static int xatoi (char *cp)
120 {
121 int val;
122
123 val = 0;
124 while (*cp) {
125 if (*cp >= 'a' && *cp <= 'f')
126 val = val * 16 + *cp - 'a' + 10;
127 else if (*cp >= 'A' && *cp <= 'F')
128 val = val * 16 + *cp - 'A' + 10;
129 else if (*cp >= '0' && *cp <= '9')
130 val = val * 16 + *cp - '0';
131 else
132 break;
133 cp++;
134 }
135 return val;
136 }
137 #endif /* MOUNTED_GETMNTENT1. */
138
139 #if defined (MOUNTED_GETMNTINFO) && !defined (xBSD)
140 static char *fstype_to_string (short t)
141 {
142 switch (t) {
143 case MOUNT_UFS:
144 return "ufs";
145 case MOUNT_NFS:
146 return "nfs";
147 #ifdef MOUNT_PC
148 case MOUNT_PC:
149 return "pc";
150 #endif
151 #ifdef MOUNT_MFS
152 case MOUNT_MFS:
153 return "mfs";
154 #endif
155 #ifdef MOUNT_LO
156 case MOUNT_LO:
157 return "lo";
158 #endif
159 #ifdef MOUNT_TFS
160 case MOUNT_TFS:
161 return "tfs";
162 #endif
163 #ifdef MOUNT_TMP
164 case MOUNT_TMP:
165 return "tmp";
166 #endif
167 default:
168 return "?";
169 }
170 }
171 #endif /* MOUNTED_GETMNTINFO */
172
173 #ifdef MOUNTED_VMOUNT /* AIX. */
174 static char *fstype_to_string (int t)
175 {
176 struct vfs_ent *e;
177
178 e = getvfsbytype (t);
179 if (!e || !e->vfsent_name)
180 return "none";
181 else
182 return e->vfsent_name;
183 }
184 #endif /* MOUNTED_VMOUNT */
185
186 /* Return a list of the currently mounted filesystems, or NULL on error.
187 Add each entry to the tail of the list so that they stay in order.
188 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
189 the returned list are valid. Otherwise, they might not be.
190 If ALL_FS is zero, do not return entries for filesystems that
191 are automounter (dummy) entries. */
192
193 struct mount_entry *read_filesystem_list (int need_fs_type, int all_fs)
194 {
195 struct mount_entry *mount_list;
196 struct mount_entry *me;
197 struct mount_entry *mtail;
198
199 /* Start the list off with a dummy entry. */
200 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
201 me->me_next = NULL;
202 mount_list = mtail = me;
203
204 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
205 {
206 struct mntent *mnt;
207 char *table = MOUNTED;
208 FILE *fp;
209 char *devopt;
210
211 fp = setmntent (table, "r");
212 if (fp == NULL)
213 return NULL;
214
215 while ((mnt = getmntent (fp))) {
216 if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
217 || !strcmp (mnt->mnt_type, "auto")))
218 continue;
219
220 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
221 me->me_devname = strdup (mnt->mnt_fsname);
222 me->me_mountdir = strdup (mnt->mnt_dir);
223 me->me_type = strdup (mnt->mnt_type);
224 devopt = strstr (mnt->mnt_opts, "dev=");
225 if (devopt) {
226 if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
227 me->me_dev = xatoi (devopt + 6);
228 else
229 me->me_dev = xatoi (devopt + 4);
230 } else
231 me->me_dev = -1; /* Magic; means not known yet. */
232 me->me_next = NULL;
233
234 /* Add to the linked list. */
235 mtail->me_next = me;
236 mtail = me;
237 }
238
239 if (endmntent (fp) == 0)
240 return NULL;
241 }
242 #endif /* MOUNTED_GETMNTENT1. */
243
244 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
245 {
246 struct statfs *fsp;
247 int entries;
248
249 entries = getmntinfo (&fsp, MNT_NOWAIT);
250 if (entries < 0)
251 return NULL;
252 while (entries-- > 0) {
253 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
254 me->me_devname = strdup (fsp->f_mntfromname);
255 me->me_mountdir = strdup (fsp->f_mntonname);
256 #ifdef xBSD
257 me->me_type = strdup (fsp->f_fstypename);
258 #else
259 me->me_type = fstype_to_string (fsp->f_type);
260 #endif
261 me->me_dev = -1; /* Magic; means not known yet. */
262 me->me_next = NULL;
263
264 /* Add to the linked list. */
265 mtail->me_next = me;
266 mtail = me;
267 fsp++;
268 }
269 }
270 #endif /* MOUNTED_GETMNTINFO */
271
272 #ifdef MOUNTED_GETMNT /* Ultrix. */
273 {
274 int offset = 0;
275 int val;
276 struct fs_data fsd;
277
278 while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
279 (char *) 0)) > 0) {
280 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
281 me->me_devname = strdup (fsd.fd_req.devname);
282 me->me_mountdir = strdup (fsd.fd_req.path);
283 me->me_type = gt_names[fsd.fd_req.fstype];
284 me->me_dev = fsd.fd_req.dev;
285 me->me_next = NULL;
286
287 /* Add to the linked list. */
288 mtail->me_next = me;
289 mtail = me;
290 }
291 if (val < 0)
292 return NULL;
293 }
294 #endif /* MOUNTED_GETMNT. */
295
296 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
297 {
298 int numsys, counter, bufsize;
299 struct statfs *stats;
300
301 numsys = getfsstat ((struct statfs *) 0, 0L, MNT_WAIT);
302 if (numsys < 0)
303 return (NULL);
304
305 bufsize = (1 + numsys) * sizeof (struct statfs);
306 stats = (struct statfs *) malloc (bufsize);
307 numsys = getfsstat (stats, bufsize, MNT_WAIT);
308
309 if (numsys < 0) {
310 free (stats);
311 return (NULL);
312 }
313 for (counter = 0; counter < numsys; counter++) {
314 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
315 me->me_devname = strdup (stats[counter].f_mntfromname);
316 me->me_mountdir = strdup (stats[counter].f_mntonname);
317 me->me_type = mnt_names[stats[counter].f_type];
318 me->me_dev = -1; /* Magic; means not known yet. */
319 me->me_next = NULL;
320
321 /* Add to the linked list. */
322 mtail->me_next = me;
323 mtail = me;
324 }
325
326 free (stats);
327 }
328 #endif /* MOUNTED_GETFSSTAT */
329
330 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
331 {
332 struct mnttab mnt;
333 char *table = "/etc/mnttab";
334 FILE *fp;
335
336 fp = fopen (table, "r");
337 if (fp == NULL)
338 return NULL;
339
340 while (fread (&mnt, sizeof mnt, 1, fp) > 0) {
341 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
342 #ifdef GETFSTYP /* SVR3. */
343 me->me_devname = strdup (mnt.mt_dev);
344 #else
345 me->me_devname = malloc (strlen (mnt.mt_dev) + 6);
346 strcpy (me->me_devname, "/dev/");
347 strcpy (me->me_devname + 5, mnt.mt_dev);
348 #endif
349 me->me_mountdir = strdup (mnt.mt_filsys);
350 me->me_dev = -1; /* Magic; means not known yet. */
351 me->me_type = "";
352 #ifdef GETFSTYP /* SVR3. */
353 if (need_fs_type) {
354 struct statfs fsd;
355 char typebuf[FSTYPSZ];
356
357 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
358 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
359 me->me_type = strdup (typebuf);
360 }
361 #endif
362 me->me_next = NULL;
363
364 /* Add to the linked list. */
365 mtail->me_next = me;
366 mtail = me;
367 }
368
369 if (fclose (fp) == EOF)
370 return NULL;
371 }
372 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
373
374 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
375 {
376 struct mntent **mnttbl = getmnttbl (), **ent;
377 for (ent = mnttbl; *ent; ent++) {
378 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
379 me->me_devname = strdup ((*ent)->mt_resource);
380 me->me_mountdir = strdup ((*ent)->mt_directory);
381 me->me_type = strdup ((*ent)->mt_fstype);
382 me->me_dev = -1; /* Magic; means not known yet. */
383 me->me_next = NULL;
384
385 /* Add to the linked list. */
386 mtail->me_next = me;
387 mtail = me;
388 }
389 endmnttbl ();
390 }
391 #endif
392
393 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
394 {
395 struct mnttab mnt;
396 char *table = MNTTAB;
397 FILE *fp;
398 int ret;
399
400 fp = fopen (table, "r");
401 if (fp == NULL)
402 return NULL;
403
404 while ((ret = getmntent (fp, &mnt)) == 0) {
405 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
406 me->me_devname = strdup (mnt.mnt_special);
407 me->me_mountdir = strdup (mnt.mnt_mountp);
408 me->me_type = strdup (mnt.mnt_fstype);
409 me->me_dev = -1; /* Magic; means not known yet. */
410 me->me_next = NULL;
411
412 /* Add to the linked list. */
413 mtail->me_next = me;
414 mtail = me;
415 }
416
417 if (ret > 0)
418 return NULL;
419 if (fclose (fp) == EOF)
420 return NULL;
421 }
422 #endif /* MOUNTED_GETMNTENT2. */
423
424 #ifdef MOUNTED_VMOUNT /* AIX. */
425 {
426 int bufsize;
427 char *entries, *thisent;
428 struct vmount *vmp;
429
430 /* Ask how many bytes to allocate for the mounted filesystem info. */
431 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
432 entries = malloc (bufsize);
433
434 /* Get the list of mounted filesystems. */
435 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
436
437 for (thisent = entries; thisent < entries + bufsize;
438 thisent += vmp->vmt_length) {
439 vmp = (struct vmount *) thisent;
440 me = (struct mount_entry *) malloc (sizeof (struct mount_entry));
441 if (vmp->vmt_flags & MNT_REMOTE) {
442 char *host, *path;
443
444 /* Prepend the remote pathname. */
445 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
446 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
447 me->me_devname = malloc (strlen (host) + strlen (path) + 2);
448 strcpy (me->me_devname, host);
449 strcat (me->me_devname, ":");
450 strcat (me->me_devname, path);
451 } else {
452 me->me_devname = strdup (thisent +
453 vmp->vmt_data[VMT_OBJECT].vmt_off);
454 }
455 me->me_mountdir = strdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
456 me->me_type = strdup (fstype_to_string (vmp->vmt_gfstype));
457 me->me_dev = -1; /* vmt_fsid might be the info we want. */
458 me->me_next = NULL;
459
460 /* Add to the linked list. */
461 mtail->me_next = me;
462 mtail = me;
463 }
464 free (entries);
465 }
466 #endif /* MOUNTED_VMOUNT. */
467
468 /* Free the dummy head. */
469 me = mount_list;
470 mount_list = mount_list->me_next;
471 free (me);
472 return mount_list;
473 }
474 #endif /* NO_INFOMOUNT */
475
476 #if defined(NO_INFOMOUNT) && defined(__QNX__)
477 /*
478 ** QNX has no [gs]etmnt*(), [gs]etfs*(), or /etc/mnttab, but can do
479 ** this via the following code.
480 ** Note that, as this is based on CWD, it only fills one mount_entry
481 ** structure. See my_statfs() in utilunix.c for the "other side" of
482 ** this hack.
483 */
484
485 #include <fcntl.h>
486 #include <stdio.h>
487 #include <stdlib.h>
488 #include <string.h>
489 #ifdef HAVE_UNISTD_H
490 # include <unistd.h>
491 #endif
492 #include <sys/disk.h>
493 #include <sys/fsys.h>
494 #include <sys/statfs.h>
495
496 #include "mountlist.h"
497
498 struct mount_entry *read_filesystem_list(int need_fs_type, int all_fs)
499 {
500 struct _disk_entry de;
501 struct statfs fs;
502 int i, fd;
503 char *tp, dev[_POSIX_NAME_MAX], dir[_POSIX_PATH_MAX];
504
505 static struct mount_entry *me = NULL;
506
507 if (me)
508 {
509 if (me->me_devname) free(me->me_devname);
510 if (me->me_mountdir) free(me->me_mountdir);
511 if (me->me_type) free(me->me_type);
512 }
513 else
514 me = (struct mount_entry *)malloc(sizeof(struct mount_entry));
515
516 if (!getcwd(dir, _POSIX_PATH_MAX)) return (NULL);
517
518 if ((fd = open(dir, O_RDONLY)) == -1) return (NULL);
519
520 i = disk_get_entry(fd, &de);
521
522 close(fd);
523
524 if (i == -1) return (NULL);
525
526 switch (de.disk_type)
527 {
528 case _UNMOUNTED: tp = "unmounted"; break;
529 case _FLOPPY: tp = "Floppy"; break;
530 case _HARD: tp = "Hard"; break;
531 case _RAMDISK: tp = "Ram"; break;
532 case _REMOVABLE: tp = "Removable"; break;
533 case _TAPE: tp = "Tape"; break;
534 case _CDROM: tp = "CDROM"; break;
535 default: tp = "unknown";
536 }
537
538 if (fsys_get_mount_dev(dir, &dev) == -1) return (NULL);
539
540 if (fsys_get_mount_pt(dev, &dir) == -1) return (NULL);
541
542 me->me_devname = strdup(dev);
543 me->me_mountdir = strdup(dir);
544 me->me_type = strdup(tp);
545 me->me_dev = de.disk_type;
546
547 #ifdef DEBUG
548 fprintf(stderr, "disk_get_entry():\n\tdisk_type=%d (%s)\n\tdriver_name='%-*.*s'\n\tdisk_drv=%d\n",
549 de.disk_type, tp, _DRIVER_NAME_LEN, _DRIVER_NAME_LEN, de.driver_name, de.disk_drv);
550 fprintf(stderr, "fsys_get_mount_dev():\n\tdevice='%s'\n", dev);
551 fprintf(stderr, "fsys_get_mount_pt():\n\tmount point='%s'\n", dir);
552 #endif
553
554 return (me);
555 }
556 #endif /* __QNX__ */
557