From 0019abd66bcf6193911b23abd198135492c18c6a Mon Sep 17 00:00:00 2001 From: jay Date: Sun, 21 Nov 2004 21:04:16 +0000 Subject: [PATCH] Enable the 'Warning: filesystem XXX has recently been mounted' check on Solaris, which prevents it exiting fatally when traversing an automount mount point --- NEWS | 2 +- configure.in | 72 ++++++++++++++++++++++++++++++++- find/find.c | 4 +- find/fstype.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 185 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 9d850e7..114a1cf 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout) -* Major changes in release 4.2.7 +* Major changes in release 4.2.7-CVS ** Functionality Changes *** xargs can now read a list of arguments from a named file, allowing the invoked program to use the same stdin as xargs started with diff --git a/configure.in b/configure.in index b19a789..c1cc1d1 100644 --- a/configure.in +++ b/configure.in @@ -54,7 +54,7 @@ dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h string.h limits.h unistd.h errno.h stdlib.h stddef.h) AC_CHECK_HEADERS(unistd.h inttypes.h fcntl.h locale.h stdint.h) -AC_CHECK_HEADERS(sys/param.h mntent.h) +AC_CHECK_HEADERS(sys/param.h mntent.h sys/mnttab.h) AC_HEADER_MAJOR AC_HEADER_DIRENT AC_HEADER_STAT @@ -112,6 +112,76 @@ dnl will try to use -lsun on platforms which have getmntent() in the dnl C library, for example UNICOS. AC_CHECK_FUNC(getmntent, [], [AC_FUNC_GETMNTENT]) AC_CHECK_FUNCS(getmntent) +AC_CHECK_FUNCS(setmntent endmntent) + +dnl Linux, 4.3BSD, etc. +AC_CHECK_TYPE([struct mntent], +[AC_DEFINE([HAVE_STRUCT_MNTENT],1,[Set if you have struct mntent]) +AC_CHECK_MEMBERS([struct mntent.mnt_type, struct mntent.mnt_dir],,,[#include ])],, +[#include ]) + +dnl Solaris +AC_CHECK_TYPE([struct mnttab], +[AC_DEFINE([HAVE_STRUCT_MNTTAB],1,[Set if you have struct mnttab]) +AC_CHECK_MEMBERS([struct mnttab.mnt_fstype,struct mnttab.mnt_mountp],,, +[ +#include +#include ])],, +[ +#include +#include ]) + +AC_DEFUN([jy_FUNC_GETMNTENT_ARGTYPES], +AC_MSG_CHECKING([how to call getmntent()]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( +[AC_INCLUDES_DEFAULT +#if HAVE_MNTENT_H +# include +#endif + +#if HAVE_SYS_MNTTAB_H +# include +# include +#endif +#if HAVE_STRUCT_MNTTAB + typedef struct mnttab MMM; +#elif HAVE_STRUCT_MNTENT + typedef struct mntent MMM; +#endif +], +[extern int getmntent(FILE*,MMM *);])], +AC_DEFINE([GETMNTENT_RETURNS_INT],1,[Set if getmntent() returns int]) +AC_DEFINE([GETMNTENT_REQUIRES_STRUCT_PTR],1,[Set if the second argument to getmntent() is a pointer to struct]) +AC_MSG_RESULT([takes two arguments and returns int]) +, +dnl First try failed. +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( +[AC_INCLUDES_DEFAULT +#if HAVE_MNTENT_H +# include +#endif + +#if HAVE_SYS_MNTTAB_H +# include +# include +#endif +#if HAVE_STRUCT_MNTTAB + typedef struct mnttab MMM; +#elif HAVE_STRUCT_MNTENT + typedef struct mntent MMM; +#endif +], +[extern MMM* getmntent(FILE *);])], +AC_DEFINE([GETMNTENT_RETURNS_STRUCT],1,[Set if getmntent() returns a struct pointer]) +AC_MSG_RESULT([takes just one argument and returns a struct pointer]), +AC_MSG_ERROR([I can't figure out how to use your getmntent() function.])))) + + +jy_FUNC_GETMNTENT_ARGTYPES + +sleep 2 dnl Checks for library functions that are provided by findlib. FINDLIB_REPLACE_FUNCS(waitpid strspn) diff --git a/find/find.c b/find/find.c index 4e864a9..137febf 100644 --- a/find/find.c +++ b/find/find.c @@ -691,14 +691,14 @@ wd_sanity_check(const char *thing_to_stat, case MountPointRecentlyUnmounted: isfatal = 0; error (0, 0, - _("Filesystem %s has recently been unmounted."), + _("Warning: filesystem %s has recently been unmounted."), specific_what); break; case MountPointRecentlyMounted: isfatal = 0; error (0, 0, - _("Filesystem %s has recently been mounted."), + _("Warning: filesystem %s has recently been mounted."), specific_what); break; diff --git a/find/fstype.c b/find/fstype.c index 9fc822f..db1cc60 100644 --- a/find/fstype.c +++ b/find/fstype.c @@ -52,12 +52,22 @@ extern int errno; static char *filesystem_type_uncached PARAMS((const char *path, const char *relpath, const struct stat *statp)); -#if defined(FSTYPE_MNTENT) || defined(HAVE_GETMNTENT) /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ +#if defined(FSTYPE_MNTENT) || defined(HAVE_GETMNTENT) || defined(HAVE_SYS_MNTTAB_H) /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ #if HAVE_MNTENT_H # include #endif +#if HAVE_SYS_MNTTAB_H +# include +# include +#endif + +#if HAVE_STRUCT_MNTTAB_MNT_MOUNTP +#define mnt_dir mnt_mountp +#endif + + #if !defined(MOUNTED) # if defined(MNT_MNTTAB) /* HP-UX. */ # define MOUNTED MNT_MNTTAB @@ -65,12 +75,27 @@ static char *filesystem_type_uncached PARAMS((const char *path, const char *relp # if defined(MNTTABNAME) /* Dynix. */ # define MOUNTED MNTTABNAME # endif +# if defined(MNTTAB) /* Solaris. */ +# define MOUNTED MNTTAB +# endif #endif #if !defined(MOUNTED) /* last resort. */ # define MOUNTED "/etc/mtab" #endif + +#if HAVE_SETMNTENT +#define SETMNTENT(name,mode) setmntent(name,mode) +#else +#define SETMNTENT(name,mode) fopen(name,mode) +#endif + +#if HAVE_ENDMNTENT +#define ENDMNTENT(fp) (0 != endmntent(fp)) +#else +#define ENDMNTENT(fp) (0 == fclose(fp)) +#endif #endif #ifdef FSTYPE_GETMNT /* Ultrix. */ @@ -256,7 +281,7 @@ filesystem_type_uncached (const char *path, const char *relpath, const struct st (void) &path; (void) &relpath; - mfp = setmntent (table, "r"); + mfp = SETMNTENT (table, "r"); if (mfp == NULL) error (1, errno, "%s", table); @@ -295,11 +320,11 @@ filesystem_type_uncached (const char *path, const char *relpath, const struct st else #endif /* not hpux */ { - if (stat (mnt->mnt_dir, &disk_stats) == -1) { + if (stat (mnt-> mnt_dir, &disk_stats) == -1) { if (errno == EACCES) continue; else - error (1, errno, _("error in %s: %s"), table, mnt->mnt_dir); + error (1, errno, _("error in %s: %s"), table, mnt-> mnt_dir); } dev = disk_stats.st_dev; } @@ -308,7 +333,7 @@ filesystem_type_uncached (const char *path, const char *relpath, const struct st type = mnt->mnt_type; } - if (endmntent (mfp) == 0) + if (ENDMNTENT (mfp) == 0) error (0, errno, "%s", table); #endif @@ -395,23 +420,92 @@ filesystem_type_uncached (const char *path, const char *relpath, const struct st +#ifdef HAVE_GETMNTENT + +#if HAVE_STRUCT_MNTTAB + typedef struct mnttab MountPointEntry; +#elif HAVE_STRUCT_MNTENT + typedef struct mntent MountPointEntry; +#endif + +#if GETMNTENT_RETURNS_STRUCT +static MountPointEntry* +next_mount_point(FILE *fp) +{ + return getmntent(fp); + +} +#elif GETMNTENT_RETURNS_INT && GETMNTENT_REQUIRES_STRUCT_PTR +static MountPointEntry current_mount_point; + +static MountPointEntry* +next_mount_point(FILE *fp) +{ + int rv = getmntent(fp, ¤t_mount_point); + + switch (rv) + { + case 0: + return ¤t_mount_point; /* success */ + + case -1: /* EOF - this is normal.*/ + return NULL; + + case MNT_TOOLONG: + error(0, 0, _("Line too long in `%s'"), MOUNTED); + return NULL; + + case MNT_TOOMANY: + error(0, 0, + _("One of the lines in `%s' has too many fields"), + MOUNTED); + return NULL; + + case MNT_TOOFEW: + error(0, 0, + _("One of the lines in `%s' has too few fields"), + MOUNTED); + return NULL; + + default: + error(0, 0, + _("Failed to parse an entry in `%s'"), + MOUNTED); + return NULL; + } +} +#else +static MountPointEntry* +next_mount_point(FILE *fp) +{ + if (warnings) + { + error(0, 0, _("Don't know how to use getmntent() to read `%s'. This is a bug.")); + } + return NULL; +} + +#endif + char * get_mounted_filesystems (void) { -#ifdef HAVE_GETMNTENT char *table = MOUNTED; FILE *mfp; +#if HAVE_STRUCT_MNTTAB + struct mnttab *mnt; +#elif HAVE_STRUCT_MNTENT struct mntent *mnt; +#endif char *result = NULL; size_t alloc_size = 0u; size_t used = 0u; - - mfp = setmntent (table, "r"); + mfp = SETMNTENT(table, "r"); if (mfp == NULL) error (1, errno, "%s", table); - while (NULL != (mnt = getmntent (mfp))) + while (NULL != (mnt = next_mount_point (mfp))) { size_t len; @@ -420,12 +514,12 @@ get_mounted_filesystems (void) continue; #endif - len = strlen(mnt->mnt_dir) + 1; + len = strlen(mnt-> mnt_dir) + 1; result = extendbuf(result, used+len, &alloc_size); strcpy(&result[used], mnt->mnt_dir); used += len; /* len already includes one for the \0 */ } - if (endmntent (mfp) == 0) + if (ENDMNTENT(mfp) == 0) error (0, errno, "%s", table); if (used) @@ -439,10 +533,11 @@ get_mounted_filesystems (void) assert(NULL == result); /* Postcondition. */ } return result; - +} #else - /* No getmntent(). */ - return NULL; -#endif +char * +get_mounted_filesystems (void) +{ + return NULL; /* No getmntent(). */ } - +#endif -- 2.11.4.GIT