diff options
author | James Youngman <jay@gnu.org> | 2005-01-17 08:49:26 +0000 |
---|---|---|
committer | James Youngman <jay@gnu.org> | 2005-01-17 08:49:26 +0000 |
commit | ae831342db0fc6f1ce22a56a78aa01480c1484cf (patch) | |
tree | 193bcb38e66342c84f8adb06b2122790a265aa0d | |
parent | f668774dd7acb44d8327dfe2e9190d52a6851cd5 (diff) | |
download | findutils-ae831342db0fc6f1ce22a56a78aa01480c1484cf.tar.gz |
Initial implementation (temporarily disabled).
-rw-r--r-- | lib/savedirinfo.c | 183 | ||||
-rw-r--r-- | lib/savedirinfo.h | 33 |
2 files changed, 216 insertions, 0 deletions
diff --git a/lib/savedirinfo.c b/lib/savedirinfo.c new file mode 100644 index 00000000..446c9ff9 --- /dev/null +++ b/lib/savedirinfo.c @@ -0,0 +1,183 @@ +/* savedir.c -- save the list of files in a directory in a string + + Copyright 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. */ + +/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#if HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif + +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif + +#include <errno.h> + +#if HAVE_DIRENT_H +# include <dirent.h> +#else +# define dirent direct +# if HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif +# if HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif +# if HAVE_NDIR_H +# include <ndir.h> +# endif +#endif + +#ifdef CLOSEDIR_VOID +/* Fake a return value. */ +# define CLOSEDIR(d) (closedir (d), 0) +#else +# define CLOSEDIR(d) closedir (d) +#endif + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "xalloc.h" +#include "extendbuf.h" +#include "savedirinfo.h" + +#undef HAVE_STRUCT_DIRENT_D_TYPE + + +#if defined HAVE_STRUCT_DIRENT_D_TYPE +static mode_t +type_to_mode(unsigned type) +{ + mode_t result = 0; + + switch (type) + { +#ifdef DT_FIFO + case DT_FIFO: return S_IFIFO; +#endif +#ifdef DT_CHR + case DT_CHR: return S_IFCHR; +#endif +#ifdef DT_DIR + case DT_DIR: return S_IFDIR; +#endif +#ifdef DT_BLK + case DT_BLK: return S_IFBLK; +#endif +#ifdef DT_REG + case DT_REG: return S_IFREG; +#endif +#ifdef DT_LNK + case DT_LNK: return S_IFLNK; +#endif +#ifdef DT_SOCK + case DT_SOCK: return S_IFSOCK; +#endif + default: + return 0; /* Unknown. */ + } +} + +#endif + + +/* Return a freshly allocated string containing the filenames + in directory DIR, separated by '\0' characters; + the end is marked by two '\0' characters in a row. + Return NULL (setting errno) if DIR cannot be opened, read, or closed. */ + +char * +savedirinfo (const char *dir, struct savedir_dirinfo **extra) +{ + DIR *dirp; + struct dirent *dp; + char *name_space; + size_t namebuf_allocated = 0u, namebuf_used = 0u; +#if defined HAVE_STRUCT_DIRENT_D_TYPE + size_t extra_allocated = 0u, extra_used = 0u; + struct savedir_dirinfo *info = NULL; +#endif + int save_errno; + + if (extra) + *extra = NULL; + + dirp = opendir (dir); + if (dirp == NULL) + return NULL; + + errno = 0; + name_space = NULL; + while ((dp = readdir (dirp)) != NULL) + { + /* Skip "", ".", and "..". "" is returned by at least one buggy + implementation: Solaris 2.4 readdir on NFS file systems. */ + char const *entry = dp->d_name; + if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0') + { + /* Remember the name. */ + size_t entry_size = strlen (entry) + 1; + name_space = extendbuf(name_space, namebuf_used+entry_size, &namebuf_allocated); + memcpy (name_space + namebuf_used, entry, entry_size); + namebuf_used += entry_size; + + +#if defined HAVE_STRUCT_DIRENT_D_TYPE + /* Remember the type. */ + if (extra) + { + info = extendbuf(info, + (extra_used+1) * sizeof(struct savedir_dirinfo), + &extra_allocated); + info[extra_used].type_info = type_to_mode(dp->d_type); + } +#endif + } + } + + name_space = extendbuf(name_space, namebuf_used+1, &namebuf_allocated); + name_space[namebuf_used] = '\0'; + + save_errno = errno; + if (CLOSEDIR (dirp) != 0) + save_errno = errno; + if (save_errno != 0) + { + free (name_space); + errno = save_errno; + return NULL; + } + +#if defined HAVE_STRUCT_DIRENT_D_TYPE + if (extra && info) + *extra = info; +#endif + + return name_space; +} diff --git a/lib/savedirinfo.h b/lib/savedirinfo.h new file mode 100644 index 00000000..3b706423 --- /dev/null +++ b/lib/savedirinfo.h @@ -0,0 +1,33 @@ +/* Save the list of files in a directory, with additional information. + + Copyright 1997, 1999, 2001, 2003, 2005 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. */ + +/* Written by James Youngman <jay@gnu.org>. + * Based on savedir.h by David MacKenzie <djm@gnu.org>. + */ + +#if !defined SAVEDIRINFO_H_ +# define SAVEDIRINFO_H_ + +struct savedir_dirinfo +{ + mode_t type_info; +}; + +char *savedirinfo (const char *dir, struct savedir_dirinfo **extra); + +#endif |