savedir.c revision 56230
1/* savedir.c -- save the list of files in a directory in a string 2 Copyright (C) 1990, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2, or (at your option) 7 any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software Foundation, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ 19 20#if HAVE_CONFIG_H 21# include <config.h> 22#endif 23 24#include <sys/types.h> 25 26#if HAVE_UNISTD_H 27# include <unistd.h> 28#endif 29 30#if HAVE_DIRENT_H 31# include <dirent.h> 32# define NAMLEN(dirent) strlen((dirent)->d_name) 33#else 34# define dirent direct 35# define NAMLEN(dirent) (dirent)->d_namlen 36# if HAVE_SYS_NDIR_H 37# include <sys/ndir.h> 38# endif 39# if HAVE_SYS_DIR_H 40# include <sys/dir.h> 41# endif 42# if HAVE_NDIR_H 43# include <ndir.h> 44# endif 45#endif 46 47#ifdef CLOSEDIR_VOID 48/* Fake a return value. */ 49# define CLOSEDIR(d) (closedir (d), 0) 50#else 51# define CLOSEDIR(d) closedir (d) 52#endif 53 54#ifdef STDC_HEADERS 55# include <stdlib.h> 56# include <string.h> 57#else 58char *malloc (); 59char *realloc (); 60#endif 61#ifndef NULL 62# define NULL 0 63#endif 64 65#ifndef stpcpy 66char *stpcpy (); 67#endif 68 69#include "savedir.h" 70 71/* Return a freshly allocated string containing the filenames 72 in directory DIR, separated by '\0' characters; 73 the end is marked by two '\0' characters in a row. 74 NAME_SIZE is the number of bytes to initially allocate 75 for the string; it will be enlarged as needed. 76 Return NULL if DIR cannot be opened or if out of memory. */ 77 78char * 79savedir (dir, name_size) 80 const char *dir; 81 unsigned int name_size; 82{ 83 DIR *dirp; 84 struct dirent *dp; 85 char *name_space; 86 char *namep; 87 88 dirp = opendir (dir); 89 if (dirp == NULL) 90 return NULL; 91 92 /* Be sure name_size is at least `1' so there's room for 93 the final NUL byte. */ 94 name_size += !name_size; 95 96 name_space = (char *) malloc (name_size); 97 if (name_space == NULL) 98 { 99 closedir (dirp); 100 return NULL; 101 } 102 namep = name_space; 103 104 while ((dp = readdir (dirp)) != NULL) 105 { 106 /* Skip "." and ".." (some NFS filesystems' directories lack them). */ 107 if (dp->d_name[0] != '.' 108 || (dp->d_name[1] != '\0' 109 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0'))) 110 { 111 unsigned size_needed = (namep - name_space) + NAMLEN (dp) + 2; 112 113 if (size_needed > name_size) 114 { 115 char *new_name_space; 116 117 while (size_needed > name_size) 118 name_size += 1024; 119 120 new_name_space = realloc (name_space, name_size); 121 if (new_name_space == NULL) 122 { 123 closedir (dirp); 124 return NULL; 125 } 126 namep += new_name_space - name_space; 127 name_space = new_name_space; 128 } 129 namep = stpcpy (namep, dp->d_name) + 1; 130 } 131 } 132 *namep = '\0'; 133 if (CLOSEDIR (dirp)) 134 { 135 free (name_space); 136 return NULL; 137 } 138 return name_space; 139} 140