X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fmountlist.c;h=50e90eed473253e4be76068808ba7161bbd67c67;hb=cdfe647f8d29540cdfe90cef0fa568c5d2fd4481;hp=55071c3fc80fe44003a6c2cf7a61f0cf6ce38d73;hpb=917752adb19961999cd68c6c961efffe33c85141;p=gnulib.git diff --git a/lib/mountlist.c b/lib/mountlist.c index 55071c3fc..50e90eed4 100644 --- a/lib/mountlist.c +++ b/lib/mountlist.c @@ -1,10 +1,11 @@ /* mountlist.c -- return a list of mounted file systems - Copyright (C) 1991, 1992, 1997-2004 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + Copyright (C) 1991, 1992, 1997-2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,33 +13,25 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ -#if HAVE_CONFIG_H -# include -#endif +#include + +#include "mountlist.h" +#include #include -#include #include #include +#include #include "xalloc.h" -#ifndef strstr -char *strstr (); -#endif - #include -#ifdef HAVE_FCNTL_H -# include -#endif +#include -#ifdef HAVE_UNISTD_H -# include -#endif +#include #if HAVE_SYS_PARAM_H # include @@ -82,6 +75,10 @@ char *strstr (); # include #endif +#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ +# include +#endif + #ifdef MOUNTED_GETMNT /* Ultrix. */ # include # include @@ -133,19 +130,46 @@ char *strstr (); # define MNT_IGNORE(M) 0 #endif -#include "mountlist.h" - #if USE_UNLOCKED_IO # include "unlocked-io.h" #endif -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + +/* The results of opendir() in this file are not used with dirfd and fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef opendir +#undef closedir + +#ifndef ME_DUMMY +# define ME_DUMMY(Fs_name, Fs_type) \ + (strcmp (Fs_type, "autofs") == 0 \ + || strcmp (Fs_type, "none") == 0 \ + || strcmp (Fs_type, "proc") == 0 \ + || strcmp (Fs_type, "subfs") == 0 \ + /* for NetBSD 3.0 */ \ + || strcmp (Fs_type, "kernfs") == 0 \ + /* for Irix 6.5 */ \ + || strcmp (Fs_type, "ignore") == 0) +#endif + +#ifndef ME_REMOTE +/* A file system is `remote' if its Fs_name contains a `:' + or if (it is of type (smbfs or cifs) and its Fs_name starts with `//'). */ +# define ME_REMOTE(Fs_name, Fs_type) \ + (strchr (Fs_name, ':') != NULL \ + || ((Fs_name)[0] == '/' \ + && (Fs_name)[1] == '/' \ + && (strcmp (Fs_type, "smbfs") == 0 \ + || strcmp (Fs_type, "cifs") == 0))) #endif #if MOUNTED_GETMNTINFO -# if ! HAVE_F_FSTYPENAME_IN_STATFS +# if ! HAVE_STRUCT_STATFS_F_FSTYPENAME static char * fstype_to_string (short int t) { @@ -239,13 +263,12 @@ fstype_to_string (short int t) return "?"; } } -# endif /* ! HAVE_F_FSTYPENAME_IN_STATFS */ +# endif -/* __NetBSD__ || BSD_NET2 || __OpenBSD__ */ static char * fsp_to_string (const struct statfs *fsp) { -# if defined HAVE_F_FSTYPENAME_IN_STATFS +# if HAVE_STRUCT_STATFS_F_FSTYPENAME return (char *) (fsp->f_fstypename); # else return fstype_to_string (fsp->f_type); @@ -268,6 +291,43 @@ fstype_to_string (int t) } #endif /* MOUNTED_VMOUNT */ + +#if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2 + +/* Return the device number from MOUNT_OPTIONS, if possible. + Otherwise return (dev_t) -1. */ +static dev_t +dev_from_mount_options (char const *mount_options) +{ + /* GNU/Linux allows file system implementations to define their own + meaning for "dev=" mount options, so don't trust the meaning + here. */ +# ifndef __linux__ + + static char const dev_pattern[] = ",dev="; + char const *devopt = strstr (mount_options, dev_pattern); + + if (devopt) + { + char const *optval = devopt + sizeof dev_pattern - 1; + char *optvalend; + unsigned long int dev; + errno = 0; + dev = strtoul (optval, &optvalend, 16); + if (optval != optvalend + && (*optvalend == '\0' || *optvalend == ',') + && ! (dev == ULONG_MAX && errno == ERANGE) + && dev == (dev_t) dev) + return dev; + } + +# endif + (void) mount_options; + return -1; +} + +#endif + /* Return a list of the currently mounted file systems, or NULL on error. Add each entry to the tail of the list so that they stay in order. If NEED_FS_TYPE is true, ensure that the file system type fields in @@ -279,6 +339,7 @@ read_file_system_list (bool need_fs_type) struct mount_entry *mount_list; struct mount_entry *me; struct mount_entry **mtail = &mount_list; + (void) need_fs_type; #ifdef MOUNTED_LISTMNTENT { @@ -310,12 +371,11 @@ read_file_system_list (bool need_fs_type) } #endif -#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ +#ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ { struct mntent *mnt; - char *table = MOUNTED; + char const *table = MOUNTED; FILE *fp; - char *devopt; fp = setmntent (table, "r"); if (fp == NULL) @@ -330,11 +390,7 @@ read_file_system_list (bool need_fs_type) me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - devopt = strstr (mnt->mnt_opts, "dev="); - if (devopt) - me->me_dev = strtoul (devopt + 4, NULL, 16); - else - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + me->me_dev = dev_from_mount_options (mnt->mnt_opts); /* Add to the linked list. */ *mtail = me; @@ -374,6 +430,32 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_GETMNTINFO */ +#ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ + { + struct statvfs *fsp; + int entries; + + entries = getmntinfo (&fsp, MNT_NOWAIT); + if (entries < 0) + return NULL; + for (; entries-- > 0; fsp++) + { + me = xmalloc (sizeof *me); + me->me_devname = xstrdup (fsp->f_mntfromname); + me->me_mountdir = xstrdup (fsp->f_mntonname); + me->me_type = xstrdup (fsp->f_fstypename); + me->me_type_malloced = 1; + me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); + me->me_remote = ME_REMOTE (me->me_devname, me->me_type); + me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + + /* Add to the linked list. */ + *mtail = me; + mtail = &me->me_next; + } + } +#endif /* MOUNTED_GETMNTINFO2 */ + #ifdef MOUNTED_GETMNT /* Ultrix. */ { int offset = 0; @@ -608,7 +690,7 @@ read_file_system_list (bool need_fs_type) } #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ -#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */ +#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */ { struct mntent **mnttbl = getmnttbl (), **ent; for (ent=mnttbl;*ent;ent++) @@ -682,7 +764,7 @@ read_file_system_list (bool need_fs_type) me->me_type_malloced = 1; me->me_dummy = MNT_IGNORE (&mnt) != 0; me->me_remote = ME_REMOTE (me->me_devname, me->me_type); - me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ + me->me_dev = dev_from_mount_options (mnt.mnt_mntopts); /* Add to the linked list. */ *mtail = me; @@ -736,16 +818,16 @@ read_file_system_list (bool need_fs_type) me = xmalloc (sizeof *me); if (vmp->vmt_flags & MNT_REMOTE) { - char *host, *path; + char *host, *dir; me->me_remote = 1; - /* Prepend the remote pathname. */ + /* Prepend the remote dirname. */ host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off; - path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; - me->me_devname = xmalloc (strlen (host) + strlen (path) + 2); + dir = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; + me->me_devname = xmalloc (strlen (host) + strlen (dir) + 2); strcpy (me->me_devname, host); strcat (me->me_devname, ":"); - strcat (me->me_devname, path); + strcat (me->me_devname, dir); } else {