diff options
Diffstat (limited to 'lib/savedir.c')
-rw-r--r-- | lib/savedir.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/lib/savedir.c b/lib/savedir.c new file mode 100644 index 000000000..fce61da0d --- /dev/null +++ b/lib/savedir.c @@ -0,0 +1,125 @@ +/* savedir.c -- save the list of files in a directory in a string + Copyright (C) 1990 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by David MacKenzie <djm@ai.mit.edu>. */ + +#include <sys/types.h> +#ifdef DIRENT +#include <dirent.h> +#ifdef direct +#undef direct +#endif +#define direct dirent +#define NLENGTH(direct) (strlen((direct)->d_name)) +#else +#define NLENGTH(direct) ((direct)->d_namlen) +#ifdef USG +#ifdef SYSNDIR +#include <sys/ndir.h> +#else +#include <ndir.h> +#endif +#else +#include <sys/dir.h> +#endif +#endif + +#ifdef VOID_CLOSEDIR +/* Fake a return value. */ +#define CLOSEDIR(d) (closedir (d), 0) +#else +#define CLOSEDIR(d) closedir (d) +#endif + +#ifdef STDC_HEADERS +#include <stdlib.h> +#include <string.h> +#else +char *malloc (); +char *realloc (); +#ifndef NULL +#define NULL 0 +#endif +#endif + +char *stpcpy (); + +/* 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. + NAME_SIZE is the number of bytes to initially allocate + for the string; it will be enlarged as needed. + Return NULL if DIR cannot be opened or if out of memory. */ + +char * +savedir (dir, name_size) + char *dir; + unsigned name_size; +{ + DIR *dirp; + struct direct *dp; + char *name_space; + char *namep; + + dirp = opendir (dir); + if (dirp == NULL) + return NULL; + + name_space = (char *) malloc (name_size); + if (name_space == NULL) + { + closedir (dirp); + return NULL; + } + namep = name_space; + + while ((dp = readdir (dirp)) != NULL) + { + /* Skip "." and ".." (some NFS filesystems' directories lack them). */ + if (dp->d_name[0] != '.' + || (dp->d_name[1] != '\0' + && (dp->d_name[1] != '.' || dp->d_name[2] != '\0'))) + { + unsigned size_needed = (namep - name_space) + NLENGTH (dp) + 2; + + if (size_needed > name_size) + { + char *new_name_space; + + while (size_needed > name_size) + name_size += 1024; + + new_name_space = realloc (name_space, name_size); + if (new_name_space == NULL) + { + closedir (dirp); + return NULL; + } + namep += new_name_space - name_space; + name_space = new_name_space; + } + namep = stpcpy (namep, dp->d_name) + 1; + } + } + *namep = '\0'; + if (CLOSEDIR (dirp)) + { + free (name_space); + return NULL; + } + return name_space; +} |