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