~ubuntu-branches/ubuntu/maverick/grafx2/maverick

« back to all changes in this revision

Viewing changes to mountlist.c

  • Committer: Bazaar Package Importer
  • Author(s): Gürkan Sengün
  • Date: 2010-03-22 12:07:47 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100322120747-g0jel6vf6mjkc53s
Tags: 2.2-1
* New upstream version, fixes FTBFS with binutils-gold. (Closes: #554742)
* Bump standards version to 3.8.4.
* debian/control: Add liblua5.1-0-dev and pkg-config to build depends.
* debian/rules: Drop dh_desktop call.
* debian/copyright: Update years.
* Switch to dpkg-source format version 3.0 (quilt).
* debian/watch: Added.
* Added patch to fix spelling errors in source code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* mountlist.c -- return a list of mounted file systems
2
 
 
3
 
   Copyright (C) 1991, 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4
 
   2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5
 
 
6
 
   This program is free software; you can redistribute it and/or modify
7
 
   it under the terms of the GNU General Public License as published by
8
 
   the Free Software Foundation; either version 2, or (at your option)
9
 
   any later version.
10
 
 
11
 
   This program is distributed in the hope that it will be useful,
12
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
   GNU General Public License for more details.
15
 
 
16
 
   You should have received a copy of the GNU General Public License
17
 
   along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
// This file is not used on some platforms, so don't do anything for them
21
 
#if(!defined(__WIN32__))&&(!defined(__amigaos4__))&&(!defined(__AROS__))&&(!defined(__MORPHOS__))&&(!defined(__amigaos__))
22
 
 
23
 
// We don't use autoconf and all that in grafx2, so let's do the config here ...
24
 
#if defined(__macosx__) || defined(__FreeBSD__)                        // MacOS X is POSIX compliant
25
 
    #define MOUNTED_GETMNTINFO
26
 
#elif defined(__BEOS__) || defined(__HAIKU__)
27
 
    #define MOUNTED_FS_STAT_DEV
28
 
#elif defined(__SKYOS__)
29
 
    #warning "Your platform is missing some specific code here ! please check and fix :)"
30
 
#else
31
 
    #define MOUNTED_GETMNTENT1
32
 
#endif
33
 
// --- END GRAFX2 CUSTOM CONFIG ---
34
 
 
35
 
#include "mountlist.h"
36
 
 
37
 
#include <limits.h>
38
 
#include <stdio.h>
39
 
#include <stdlib.h>
40
 
#include <string.h>
41
 
 
42
 
#include <errno.h>
43
 
 
44
 
#include <fcntl.h>
45
 
 
46
 
#include <unistd.h>
47
 
 
48
 
#if HAVE_SYS_PARAM_H
49
 
# include <sys/param.h>
50
 
#endif
51
 
 
52
 
#if defined MOUNTED_GETFSSTAT        /* OSF_1 and Darwin1.3.x */
53
 
# if HAVE_SYS_UCRED_H
54
 
#  include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS,
55
 
                      NGROUPS is used as an array dimension in ucred.h */
56
 
#  include <sys/ucred.h> /* needed by powerpc-apple-darwin1.3.7 */
57
 
# endif
58
 
# if HAVE_SYS_MOUNT_H
59
 
#  include <sys/mount.h>
60
 
# endif
61
 
# if HAVE_SYS_FS_TYPES_H
62
 
#  include <sys/fs_types.h> /* needed by powerpc-apple-darwin1.3.7 */
63
 
# endif
64
 
# if HAVE_STRUCT_FSSTAT_F_FSTYPENAME
65
 
#  define FS_TYPE(Ent) ((Ent).f_fstypename)
66
 
# else
67
 
#  define FS_TYPE(Ent) mnt_names[(Ent).f_type]
68
 
# endif
69
 
#endif /* MOUNTED_GETFSSTAT */
70
 
 
71
 
#ifdef MOUNTED_GETMNTENT1        /* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
72
 
# include <mntent.h>
73
 
# if !defined MOUNTED
74
 
#  if defined _PATH_MOUNTED        /* GNU libc  */
75
 
#   define MOUNTED _PATH_MOUNTED
76
 
#  endif
77
 
#  if defined MNT_MNTTAB        /* HP-UX.  */
78
 
#   define MOUNTED MNT_MNTTAB
79
 
#  endif
80
 
#  if defined MNTTABNAME        /* Dynix.  */
81
 
#   define MOUNTED MNTTABNAME
82
 
#  endif
83
 
# endif
84
 
#endif
85
 
 
86
 
#ifdef MOUNTED_GETMNTINFO        /* 4.4BSD.  */
87
 
# include <sys/mount.h>
88
 
#endif
89
 
 
90
 
#ifdef MOUNTED_GETMNTINFO2        /* NetBSD 3.0.  */
91
 
# include <sys/statvfs.h>
92
 
#endif
93
 
 
94
 
#ifdef MOUNTED_GETMNT                /* Ultrix.  */
95
 
# include <sys/mount.h>
96
 
# include <sys/fs_types.h>
97
 
#endif
98
 
 
99
 
#ifdef MOUNTED_FS_STAT_DEV        /* BeOS.  */
100
 
# include <fs_info.h>
101
 
# include <dirent.h>
102
 
#endif
103
 
 
104
 
#ifdef MOUNTED_FREAD                /* SVR2.  */
105
 
# include <mnttab.h>
106
 
#endif
107
 
 
108
 
#ifdef MOUNTED_FREAD_FSTYP        /* SVR3.  */
109
 
# include <mnttab.h>
110
 
# include <sys/fstyp.h>
111
 
# include <sys/statfs.h>
112
 
#endif
113
 
 
114
 
#ifdef MOUNTED_LISTMNTENT
115
 
# include <mntent.h>
116
 
#endif
117
 
 
118
 
#ifdef MOUNTED_GETMNTENT2        /* SVR4.  */
119
 
# include <sys/mnttab.h>
120
 
#endif
121
 
 
122
 
#ifdef MOUNTED_VMOUNT                /* AIX.  */
123
 
# include <fshelp.h>
124
 
# include <sys/vfs.h>
125
 
#endif
126
 
 
127
 
#ifdef DOLPHIN
128
 
/* So special that it's not worth putting this in autoconf.  */
129
 
# undef MOUNTED_FREAD_FSTYP
130
 
# define MOUNTED_GETMNTTBL
131
 
#endif
132
 
 
133
 
#if HAVE_SYS_MNTENT_H
134
 
/* This is to get MNTOPT_IGNORE on e.g. SVR4.  */
135
 
# include <sys/mntent.h>
136
 
#endif
137
 
 
138
 
#undef MNT_IGNORE
139
 
#if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT
140
 
# define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
141
 
#else
142
 
# define MNT_IGNORE(M) 0
143
 
#endif
144
 
 
145
 
#if USE_UNLOCKED_IO
146
 
# include "unlocked-io.h"
147
 
#endif
148
 
 
149
 
#ifndef SIZE_MAX
150
 
# define SIZE_MAX ((size_t) -1)
151
 
#endif
152
 
 
153
 
/* The results of open() in this file are not used with fchdir,
154
 
   therefore save some unnecessary work in fchdir.c.  */
155
 
#undef open
156
 
#undef close
157
 
 
158
 
/* The results of opendir() in this file are not used with dirfd and fchdir,
159
 
   therefore save some unnecessary work in fchdir.c.  */
160
 
#undef opendir
161
 
#undef closedir
162
 
 
163
 
// gcc2 under haiku and beos don't like these macros for some reason.
164
 
// As they are not used there anyways, we remove them and everyone is happy.
165
 
#if !defined(__HAIKU__) && !defined(__BEOS__)
166
 
#ifndef ME_DUMMY
167
 
# define ME_DUMMY(Fs_name, Fs_type)                \
168
 
    (strcmp (Fs_type, "autofs") == 0            \
169
 
     || strcmp (Fs_type, "none") == 0           \
170
 
     || strcmp (Fs_type, "proc") == 0           \
171
 
     || strcmp (Fs_type, "subfs") == 0          \
172
 
     || strcmp (Fs_type, "sysfs") == 0          \
173
 
     || strcmp (Fs_type, "usbfs") == 0          \
174
 
     || strcmp (Fs_type, "devpts") == 0         \
175
 
     || strcmp (Fs_type, "tmpfs") == 0          \
176
 
     /* for NetBSD 3.0 */                       \
177
 
     || strcmp (Fs_type, "kernfs") == 0         \
178
 
     /* for Irix 6.5 */                         \
179
 
     || strcmp (Fs_type, "ignore") == 0         \
180
 
     /* for MacOSX */                           \
181
 
     || strcmp (Fs_type, "devfs") == 0          \
182
 
     || strcmp (Fs_type, "fdesc") == 0          \
183
 
     || strcmp (Fs_type, "nfs") == 0            \
184
 
     || strcmp (Fs_type, "volfs") == 0)
185
 
#endif
186
 
 
187
 
#ifndef ME_REMOTE
188
 
/* A file system is `remote' if its Fs_name contains a `:'
189
 
   or if (it is of type (smbfs or cifs) and its Fs_name starts with `//').  */
190
 
# define ME_REMOTE(Fs_name, Fs_type)                \
191
 
    (strchr (Fs_name, ':') != NULL                \
192
 
     || ((Fs_name)[0] == '/'                        \
193
 
         && (Fs_name)[1] == '/'                        \
194
 
         && (strcmp (Fs_type, "smbfs") == 0        \
195
 
             || strcmp (Fs_type, "cifs") == 0)))
196
 
#endif
197
 
#endif // HAIKU / BEOS
198
 
 
199
 
#ifdef MOUNTED_GETMNTINFO
200
 
 
201
 
# if ! HAVE_STRUCT_STATFS_F_FSTYPENAME
202
 
static char *
203
 
fstype_to_string (short int t)
204
 
{
205
 
  switch (t)
206
 
    {
207
 
#  ifdef MOUNT_PC
208
 
    case MOUNT_PC:
209
 
      return "pc";
210
 
#  endif
211
 
#  ifdef MOUNT_MFS
212
 
    case MOUNT_MFS:
213
 
      return "mfs";
214
 
#  endif
215
 
#  ifdef MOUNT_LO
216
 
    case MOUNT_LO:
217
 
      return "lo";
218
 
#  endif
219
 
#  ifdef MOUNT_TFS
220
 
    case MOUNT_TFS:
221
 
      return "tfs";
222
 
#  endif
223
 
#  ifdef MOUNT_TMP
224
 
    case MOUNT_TMP:
225
 
      return "tmp";
226
 
#  endif
227
 
#  ifdef MOUNT_UFS
228
 
   case MOUNT_UFS:
229
 
     return "ufs" ;
230
 
#  endif
231
 
#  ifdef MOUNT_NFS
232
 
   case MOUNT_NFS:
233
 
     return "nfs" ;
234
 
#  endif
235
 
#  ifdef MOUNT_MSDOS
236
 
   case MOUNT_MSDOS:
237
 
     return "msdos" ;
238
 
#  endif
239
 
#  ifdef MOUNT_LFS
240
 
   case MOUNT_LFS:
241
 
     return "lfs" ;
242
 
#  endif
243
 
#  ifdef MOUNT_LOFS
244
 
   case MOUNT_LOFS:
245
 
     return "lofs" ;
246
 
#  endif
247
 
#  ifdef MOUNT_FDESC
248
 
   case MOUNT_FDESC:
249
 
     return "fdesc" ;
250
 
#  endif
251
 
#  ifdef MOUNT_PORTAL
252
 
   case MOUNT_PORTAL:
253
 
     return "portal" ;
254
 
#  endif
255
 
#  ifdef MOUNT_NULL
256
 
   case MOUNT_NULL:
257
 
     return "null" ;
258
 
#  endif
259
 
#  ifdef MOUNT_UMAP
260
 
   case MOUNT_UMAP:
261
 
     return "umap" ;
262
 
#  endif
263
 
#  ifdef MOUNT_KERNFS
264
 
   case MOUNT_KERNFS:
265
 
     return "kernfs" ;
266
 
#  endif
267
 
#  ifdef MOUNT_PROCFS
268
 
   case MOUNT_PROCFS:
269
 
     return "procfs" ;
270
 
#  endif
271
 
#  ifdef MOUNT_AFS
272
 
   case MOUNT_AFS:
273
 
     return "afs" ;
274
 
#  endif
275
 
#  ifdef MOUNT_CD9660
276
 
   case MOUNT_CD9660:
277
 
     return "cd9660" ;
278
 
#  endif
279
 
#  ifdef MOUNT_UNION
280
 
   case MOUNT_UNION:
281
 
     return "union" ;
282
 
#  endif
283
 
#  ifdef MOUNT_DEVFS
284
 
   case MOUNT_DEVFS:
285
 
     return "devfs" ;
286
 
#  endif
287
 
#  ifdef MOUNT_EXT2FS
288
 
   case MOUNT_EXT2FS:
289
 
     return "ext2fs" ;
290
 
#  endif
291
 
    default:
292
 
      return "?";
293
 
    }
294
 
}
295
 
# endif
296
 
 
297
 
static char *
298
 
fsp_to_string (const struct statfs *fsp)
299
 
{
300
 
# if HAVE_STRUCT_STATFS_F_FSTYPENAME
301
 
  return (char *) (fsp->f_fstypename);
302
 
# else
303
 
  return fstype_to_string (fsp->f_type);
304
 
# endif
305
 
}
306
 
 
307
 
#endif /* MOUNTED_GETMNTINFO */
308
 
 
309
 
#ifdef MOUNTED_VMOUNT                /* AIX.  */
310
 
static char *
311
 
fstype_to_string (int t)
312
 
{
313
 
  struct vfs_ent *e;
314
 
 
315
 
  e = getvfsbytype (t);
316
 
  if (!e || !e->vfsent_name)
317
 
    return "none";
318
 
  else
319
 
    return e->vfsent_name;
320
 
}
321
 
#endif /* MOUNTED_VMOUNT */
322
 
 
323
 
 
324
 
#if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2
325
 
 
326
 
/* Return the device number from MOUNT_OPTIONS, if possible.
327
 
   Otherwise return (dev_t) -1.  */
328
 
 
329
 
static dev_t
330
 
dev_from_mount_options (char const *mount_options)
331
 
{
332
 
  /* GNU/Linux allows file system implementations to define their own
333
 
     meaning for "dev=" mount options, so don't trust the meaning
334
 
     here.  */
335
 
# ifndef __linux__
336
 
 
337
 
  static char const dev_pattern[] = ",dev=";
338
 
  char const *devopt = strstr (mount_options, dev_pattern);
339
 
 
340
 
  if (devopt)
341
 
    {
342
 
      char const *optval = devopt + sizeof dev_pattern - 1;
343
 
      char *optvalend;
344
 
      unsigned long int dev;
345
 
      errno = 0;
346
 
      dev = strtoul (optval, &optvalend, 16);
347
 
      if (optval != optvalend
348
 
          && (*optvalend == '\0' || *optvalend == ',')
349
 
          && ! (dev == ULONG_MAX && errno == ERANGE)
350
 
          && dev == (dev_t) dev)
351
 
        return dev;
352
 
    }
353
 
 
354
 
# endif
355
 
 
356
 
  return -1;
357
 
}
358
 
 
359
 
#endif
360
 
 
361
 
/* Return a list of the currently mounted file systems, or NULL on error.
362
 
   Add each entry to the tail of the list so that they stay in order.
363
 
   If NEED_FS_TYPE is true, ensure that the file system type fields in
364
 
   the returned list are valid.  Otherwise, they might not be.  */
365
 
 
366
 
struct mount_entry *
367
 
read_file_system_list (bool need_fs_type)
368
 
{
369
 
  struct mount_entry *mount_list;
370
 
  struct mount_entry *me;
371
 
  struct mount_entry **mtail = &mount_list;
372
 
 
373
 
#ifdef MOUNTED_LISTMNTENT
374
 
  {
375
 
    struct tabmntent *mntlist, *p;
376
 
    struct mntent *mnt;
377
 
    struct mount_entry *me;
378
 
 
379
 
    /* the third and fourth arguments could be used to filter mounts,
380
 
       but Crays doesn't seem to have any mounts that we want to
381
 
       remove. Specifically, automount create normal NFS mounts.
382
 
       */
383
 
 
384
 
    if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0)
385
 
      return NULL;
386
 
    for (p = mntlist; p; p = p->next) {
387
 
      mnt = p->ment;
388
 
      me = xmalloc (sizeof *me);
389
 
      me->me_devname = xstrdup (mnt->mnt_fsname);
390
 
      me->me_mountdir = xstrdup (mnt->mnt_dir);
391
 
      me->me_type = xstrdup (mnt->mnt_type);
392
 
      me->me_type_malloced = 1;
393
 
      me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
394
 
      me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
395
 
      me->me_dev = -1;
396
 
      *mtail = me;
397
 
      mtail = &me->me_next;
398
 
    }
399
 
    freemntlist (mntlist);
400
 
  }
401
 
#endif
402
 
 
403
 
#ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
404
 
  {
405
 
    struct mntent *mnt;
406
 
    char *table = MOUNTED;
407
 
    FILE *fp;
408
 
 
409
 
    fp = setmntent (table, "r");
410
 
    if (fp == NULL)
411
 
      return NULL;
412
 
 
413
 
    while ((mnt = getmntent (fp)))
414
 
      {
415
 
        me = malloc (sizeof *me);
416
 
        me->me_devname = strdup (mnt->mnt_fsname);
417
 
        me->me_mountdir = strdup (mnt->mnt_dir);
418
 
        me->me_type = strdup (mnt->mnt_type);
419
 
        me->me_type_malloced = 1;
420
 
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
421
 
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
422
 
        me->me_dev = dev_from_mount_options (mnt->mnt_opts);
423
 
 
424
 
        /* Add to the linked list. */
425
 
        *mtail = me;
426
 
        mtail = &me->me_next;
427
 
      }
428
 
 
429
 
    if (endmntent (fp) == 0)
430
 
      goto free_then_fail;
431
 
  }
432
 
#endif /* MOUNTED_GETMNTENT1. */
433
 
 
434
 
#ifdef MOUNTED_GETMNTINFO        /* 4.4BSD.  */
435
 
  {
436
 
    struct statfs *fsp;
437
 
    int entries;
438
 
 
439
 
    entries = getmntinfo (&fsp, MNT_NOWAIT);
440
 
    if (entries < 0)
441
 
      return NULL;
442
 
    for (; entries-- > 0; fsp++)
443
 
      {
444
 
        me = malloc (sizeof *me);
445
 
        me->me_devname = strdup (fsp->f_mntfromname);
446
 
        me->me_mountdir = strdup (fsp->f_mntonname);
447
 
#if defined(__macosx__)
448
 
        me->me_type = fsp->f_fstypename;
449
 
#else
450
 
        me->me_type = fsp->fs_typename;
451
 
#endif 
452
 
        me->me_type_malloced = 0;
453
 
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
454
 
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
455
 
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
456
 
 
457
 
        /* Add to the linked list. */
458
 
        *mtail = me;
459
 
        mtail = &me->me_next;
460
 
      }
461
 
  }
462
 
#endif /* MOUNTED_GETMNTINFO */
463
 
 
464
 
#ifdef MOUNTED_GETMNTINFO2        /* NetBSD 3.0.  */
465
 
  {
466
 
    struct statvfs *fsp;
467
 
    int entries;
468
 
 
469
 
    entries = getmntinfo (&fsp, MNT_NOWAIT);
470
 
    if (entries < 0)
471
 
      return NULL;
472
 
    for (; entries-- > 0; fsp++)
473
 
      {
474
 
        me = xmalloc (sizeof *me);
475
 
        me->me_devname = xstrdup (fsp->f_mntfromname);
476
 
        me->me_mountdir = xstrdup (fsp->f_mntonname);
477
 
        me->me_type = xstrdup (fsp->f_fstypename);
478
 
        me->me_type_malloced = 1;
479
 
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
480
 
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
481
 
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
482
 
 
483
 
        /* Add to the linked list. */
484
 
        *mtail = me;
485
 
        mtail = &me->me_next;
486
 
      }
487
 
  }
488
 
#endif /* MOUNTED_GETMNTINFO2 */
489
 
 
490
 
#ifdef MOUNTED_GETMNT                /* Ultrix.  */
491
 
  {
492
 
    int offset = 0;
493
 
    int val;
494
 
    struct fs_data fsd;
495
 
 
496
 
    while (errno = 0,
497
 
           0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
498
 
                              (char *) 0)))
499
 
      {
500
 
        me = xmalloc (sizeof *me);
501
 
        me->me_devname = xstrdup (fsd.fd_req.devname);
502
 
        me->me_mountdir = xstrdup (fsd.fd_req.path);
503
 
        me->me_type = gt_names[fsd.fd_req.fstype];
504
 
        me->me_type_malloced = 0;
505
 
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
506
 
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
507
 
        me->me_dev = fsd.fd_req.dev;
508
 
 
509
 
        /* Add to the linked list. */
510
 
        *mtail = me;
511
 
        mtail = &me->me_next;
512
 
      }
513
 
    if (val < 0)
514
 
      goto free_then_fail;
515
 
  }
516
 
#endif /* MOUNTED_GETMNT. */
517
 
 
518
 
#if defined MOUNTED_FS_STAT_DEV /* BeOS */
519
 
  {
520
 
    /* The next_dev() and fs_stat_dev() system calls give the list of
521
 
       all file systems, including the information returned by statvfs()
522
 
       (fs type, total blocks, free blocks etc.), but without the mount
523
 
       point. But on BeOS all file systems except / are mounted in the
524
 
       rootfs, directly under /.
525
 
       The directory name of the mount point is often, but not always,
526
 
       identical to the volume name of the device.
527
 
       We therefore get the list of subdirectories of /, and the list
528
 
       of all file systems, and match the two lists.  */
529
 
 
530
 
    DIR *dirp;
531
 
    struct rootdir_entry
532
 
      {
533
 
        char *name;
534
 
        dev_t dev;
535
 
        ino_t ino;
536
 
        struct rootdir_entry *next;
537
 
      };
538
 
    struct rootdir_entry *rootdir_list;
539
 
    struct rootdir_entry **rootdir_tail;
540
 
    int32 pos;
541
 
    dev_t dev;
542
 
    fs_info fi;
543
 
 
544
 
    /* All volumes are mounted in the rootfs, directly under /. */
545
 
    rootdir_list = NULL;
546
 
    rootdir_tail = &rootdir_list;
547
 
    dirp = opendir ("/");
548
 
    if (dirp)
549
 
      {
550
 
        struct dirent *d;
551
 
 
552
 
        while ((d = readdir (dirp)) != NULL)
553
 
          {
554
 
            char *name;
555
 
            struct stat statbuf;
556
 
 
557
 
            if (strcmp (d->d_name, "..") == 0)
558
 
              continue;
559
 
 
560
 
            if (strcmp (d->d_name, ".") == 0)
561
 
              name = strdup ("/");
562
 
            else
563
 
              {
564
 
                name = malloc (1 + strlen (d->d_name) + 1);
565
 
                name[0] = '/';
566
 
                strcpy (name + 1, d->d_name);
567
 
              }
568
 
 
569
 
            if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
570
 
              {
571
 
                struct rootdir_entry *re = malloc (sizeof *re);
572
 
                re->name = name;
573
 
                re->dev = statbuf.st_dev;
574
 
                re->ino = statbuf.st_ino;
575
 
 
576
 
                /* Add to the linked list.  */
577
 
                *rootdir_tail = re;
578
 
                rootdir_tail = &re->next;
579
 
              }
580
 
            else
581
 
              free (name);
582
 
          }
583
 
        closedir (dirp);
584
 
      }
585
 
    *rootdir_tail = NULL;
586
 
 
587
 
    for (pos = 0; (dev = next_dev (&pos)) >= 0; )
588
 
      if (fs_stat_dev (dev, &fi) >= 0)
589
 
        {
590
 
          /* Note: fi.dev == dev. */
591
 
          struct rootdir_entry *re;
592
 
 
593
 
          for (re = rootdir_list; re; re = re->next)
594
 
            if (re->dev == fi.dev && re->ino == fi.root)
595
 
              break;
596
 
 
597
 
          me = malloc (sizeof *me);
598
 
          me->me_devname = strdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name);
599
 
          me->me_mountdir = strdup (re != NULL ? re->name : fi.fsh_name);
600
 
          me->me_type = strdup (fi.fsh_name);
601
 
          me->me_type_malloced = 1;
602
 
          me->me_dev = fi.dev;
603
 
          me->me_dummy = 0;
604
 
          me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0;
605
 
 
606
 
          /* Add to the linked list. */
607
 
          *mtail = me;
608
 
          mtail = &me->me_next;
609
 
        }
610
 
    *mtail = NULL;
611
 
 
612
 
    while (rootdir_list != NULL)
613
 
      {
614
 
        struct rootdir_entry *re = rootdir_list;
615
 
        rootdir_list = re->next;
616
 
        free (re->name);
617
 
        free (re);
618
 
      }
619
 
  }
620
 
#endif /* MOUNTED_FS_STAT_DEV */
621
 
 
622
 
#if defined MOUNTED_GETFSSTAT        /* __alpha running OSF_1 */
623
 
  {
624
 
    int numsys, counter;
625
 
    size_t bufsize;
626
 
    struct statfs *stats;
627
 
 
628
 
    numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT);
629
 
    if (numsys < 0)
630
 
      return (NULL);
631
 
    if (SIZE_MAX / sizeof *stats <= numsys)
632
 
      xalloc_die ();
633
 
 
634
 
    bufsize = (1 + numsys) * sizeof *stats;
635
 
    stats = xmalloc (bufsize);
636
 
    numsys = getfsstat (stats, bufsize, MNT_NOWAIT);
637
 
 
638
 
    if (numsys < 0)
639
 
      {
640
 
        free (stats);
641
 
        return (NULL);
642
 
      }
643
 
 
644
 
    for (counter = 0; counter < numsys; counter++)
645
 
      {
646
 
        me = xmalloc (sizeof *me);
647
 
        me->me_devname = xstrdup (stats[counter].f_mntfromname);
648
 
        me->me_mountdir = xstrdup (stats[counter].f_mntonname);
649
 
        me->me_type = xstrdup (FS_TYPE (stats[counter]));
650
 
        me->me_type_malloced = 1;
651
 
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
652
 
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
653
 
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
654
 
 
655
 
        /* Add to the linked list. */
656
 
        *mtail = me;
657
 
        mtail = &me->me_next;
658
 
      }
659
 
 
660
 
    free (stats);
661
 
  }
662
 
#endif /* MOUNTED_GETFSSTAT */
663
 
 
664
 
#if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23].  */
665
 
  {
666
 
    struct mnttab mnt;
667
 
    char *table = "/etc/mnttab";
668
 
    FILE *fp;
669
 
 
670
 
    fp = fopen (table, "r");
671
 
    if (fp == NULL)
672
 
      return NULL;
673
 
 
674
 
    while (fread (&mnt, sizeof mnt, 1, fp) > 0)
675
 
      {
676
 
        me = xmalloc (sizeof *me);
677
 
# ifdef GETFSTYP                        /* SVR3.  */
678
 
        me->me_devname = xstrdup (mnt.mt_dev);
679
 
# else
680
 
        me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
681
 
        strcpy (me->me_devname, "/dev/");
682
 
        strcpy (me->me_devname + 5, mnt.mt_dev);
683
 
# endif
684
 
        me->me_mountdir = xstrdup (mnt.mt_filsys);
685
 
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
686
 
        me->me_type = "";
687
 
        me->me_type_malloced = 0;
688
 
# ifdef GETFSTYP                        /* SVR3.  */
689
 
        if (need_fs_type)
690
 
          {
691
 
            struct statfs fsd;
692
 
            char typebuf[FSTYPSZ];
693
 
 
694
 
            if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
695
 
                && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
696
 
              {
697
 
                me->me_type = xstrdup (typebuf);
698
 
                me->me_type_malloced = 1;
699
 
              }
700
 
          }
701
 
# endif
702
 
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
703
 
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
704
 
 
705
 
        /* Add to the linked list. */
706
 
        *mtail = me;
707
 
        mtail = &me->me_next;
708
 
      }
709
 
 
710
 
    if (ferror (fp))
711
 
      {
712
 
        /* The last fread() call must have failed.  */
713
 
        int saved_errno = errno;
714
 
        fclose (fp);
715
 
        errno = saved_errno;
716
 
        goto free_then_fail;
717
 
      }
718
 
 
719
 
    if (fclose (fp) == EOF)
720
 
      goto free_then_fail;
721
 
  }
722
 
#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */
723
 
 
724
 
#ifdef MOUNTED_GETMNTTBL        /* DolphinOS goes its own way.  */
725
 
  {
726
 
    struct mntent **mnttbl = getmnttbl (), **ent;
727
 
    for (ent=mnttbl;*ent;ent++)
728
 
      {
729
 
        me = xmalloc (sizeof *me);
730
 
        me->me_devname = xstrdup ( (*ent)->mt_resource);
731
 
        me->me_mountdir = xstrdup ( (*ent)->mt_directory);
732
 
        me->me_type = xstrdup ((*ent)->mt_fstype);
733
 
        me->me_type_malloced = 1;
734
 
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
735
 
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
736
 
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
737
 
 
738
 
        /* Add to the linked list. */
739
 
        *mtail = me;
740
 
        mtail = &me->me_next;
741
 
      }
742
 
    endmnttbl ();
743
 
  }
744
 
#endif
745
 
 
746
 
#ifdef MOUNTED_GETMNTENT2        /* SVR4.  */
747
 
  {
748
 
    struct mnttab mnt;
749
 
    char *table = MNTTAB;
750
 
    FILE *fp;
751
 
    int ret;
752
 
    int lockfd = -1;
753
 
 
754
 
# if defined F_RDLCK && defined F_SETLKW
755
 
    /* MNTTAB_LOCK is a macro name of our own invention; it's not present in
756
 
       e.g. Solaris 2.6.  If the SVR4 folks ever define a macro
757
 
       for this file name, we should use their macro name instead.
758
 
       (Why not just lock MNTTAB directly?  We don't know.)  */
759
 
#  ifndef MNTTAB_LOCK
760
 
#   define MNTTAB_LOCK "/etc/.mnttab.lock"
761
 
#  endif
762
 
    lockfd = open (MNTTAB_LOCK, O_RDONLY);
763
 
    if (0 <= lockfd)
764
 
      {
765
 
        struct flock flock;
766
 
        flock.l_type = F_RDLCK;
767
 
        flock.l_whence = SEEK_SET;
768
 
        flock.l_start = 0;
769
 
        flock.l_len = 0;
770
 
        while (fcntl (lockfd, F_SETLKW, &flock) == -1)
771
 
          if (errno != EINTR)
772
 
            {
773
 
              int saved_errno = errno;
774
 
              close (lockfd);
775
 
              errno = saved_errno;
776
 
              return NULL;
777
 
            }
778
 
      }
779
 
    else if (errno != ENOENT)
780
 
      return NULL;
781
 
# endif
782
 
 
783
 
    errno = 0;
784
 
    fp = fopen (table, "r");
785
 
    if (fp == NULL)
786
 
      ret = errno;
787
 
    else
788
 
      {
789
 
        while ((ret = getmntent (fp, &mnt)) == 0)
790
 
          {
791
 
            me = xmalloc (sizeof *me);
792
 
            me->me_devname = xstrdup (mnt.mnt_special);
793
 
            me->me_mountdir = xstrdup (mnt.mnt_mountp);
794
 
            me->me_type = xstrdup (mnt.mnt_fstype);
795
 
            me->me_type_malloced = 1;
796
 
            me->me_dummy = MNT_IGNORE (&mnt) != 0;
797
 
            me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
798
 
            me->me_dev = dev_from_mount_options (mnt.mnt_mntopts);
799
 
 
800
 
            /* Add to the linked list. */
801
 
            *mtail = me;
802
 
            mtail = &me->me_next;
803
 
          }
804
 
 
805
 
        ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
806
 
      }
807
 
 
808
 
    if (0 <= lockfd && close (lockfd) != 0)
809
 
      ret = errno;
810
 
 
811
 
    if (0 <= ret)
812
 
      {
813
 
        errno = ret;
814
 
        goto free_then_fail;
815
 
      }
816
 
  }
817
 
#endif /* MOUNTED_GETMNTENT2.  */
818
 
 
819
 
#ifdef MOUNTED_VMOUNT                /* AIX.  */
820
 
  {
821
 
    int bufsize;
822
 
    char *entries, *thisent;
823
 
    struct vmount *vmp;
824
 
    int n_entries;
825
 
    int i;
826
 
 
827
 
    /* Ask how many bytes to allocate for the mounted file system info.  */
828
 
    if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0)
829
 
      return NULL;
830
 
    entries = xmalloc (bufsize);
831
 
 
832
 
    /* Get the list of mounted file systems.  */
833
 
    n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
834
 
    if (n_entries < 0)
835
 
      {
836
 
        int saved_errno = errno;
837
 
        free (entries);
838
 
        errno = saved_errno;
839
 
        return NULL;
840
 
      }
841
 
 
842
 
    for (i = 0, thisent = entries;
843
 
         i < n_entries;
844
 
         i++, thisent += vmp->vmt_length)
845
 
      {
846
 
        char *options, *ignore;
847
 
 
848
 
        vmp = (struct vmount *) thisent;
849
 
        me = xmalloc (sizeof *me);
850
 
        if (vmp->vmt_flags & MNT_REMOTE)
851
 
          {
852
 
            char *host, *dir;
853
 
 
854
 
            me->me_remote = 1;
855
 
            /* Prepend the remote dirname.  */
856
 
            host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
857
 
            dir = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
858
 
            me->me_devname = xmalloc (strlen (host) + strlen (dir) + 2);
859
 
            strcpy (me->me_devname, host);
860
 
            strcat (me->me_devname, ":");
861
 
            strcat (me->me_devname, dir);
862
 
          }
863
 
        else
864
 
          {
865
 
            me->me_remote = 0;
866
 
            me->me_devname = xstrdup (thisent +
867
 
                                      vmp->vmt_data[VMT_OBJECT].vmt_off);
868
 
          }
869
 
        me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
870
 
        me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
871
 
        me->me_type_malloced = 1;
872
 
        options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off;
873
 
        ignore = strstr (options, "ignore");
874
 
        me->me_dummy = (ignore
875
 
                        && (ignore == options || ignore[-1] == ',')
876
 
                        && (ignore[sizeof "ignore" - 1] == ','
877
 
                            || ignore[sizeof "ignore" - 1] == '\0'));
878
 
        me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want.  */
879
 
 
880
 
        /* Add to the linked list. */
881
 
        *mtail = me;
882
 
        mtail = &me->me_next;
883
 
      }
884
 
    free (entries);
885
 
  }
886
 
#endif /* MOUNTED_VMOUNT. */
887
 
 
888
 
  *mtail = NULL;
889
 
  return mount_list;
890
 
 
891
 
 
892
 
 free_then_fail:
893
 
  {
894
 
    int saved_errno = errno;
895
 
    *mtail = NULL;
896
 
 
897
 
    while (mount_list)
898
 
      {
899
 
        me = mount_list->me_next;
900
 
        free (mount_list->me_devname);
901
 
        free (mount_list->me_mountdir);
902
 
        if (mount_list->me_type_malloced)
903
 
          free (mount_list->me_type);
904
 
        free (mount_list);
905
 
        mount_list = me;
906
 
      }
907
 
 
908
 
    errno = saved_errno;
909
 
    return NULL;
910
 
  }
911
 
}
912
 
 
913
 
#endif
914