1a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Directory hashing for GNU Make. 2a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerCopyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software 4a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation, Inc. 5a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerThis file is part of GNU Make. 6a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 7a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make is free software; you can redistribute it and/or modify it under the 8a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerterms of the GNU General Public License as published by the Free Software 9a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation; either version 2, or (at your option) any later version. 10a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 11a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make is distributed in the hope that it will be useful, but WITHOUT ANY 12a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 13a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerA PARTICULAR PURPOSE. See the GNU General Public License for more details. 14a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 15a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerYou should have received a copy of the GNU General Public License along with 16a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerGNU Make; see the file COPYING. If not, write to the Free Software 17a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' TurnerFoundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ 18a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 19a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "make.h" 20a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "hash.h" 21a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 22a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_DIRENT_H 23a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# include <dirent.h> 24a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define NAMLEN(dirent) strlen((dirent)->d_name) 25a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef VMS 26a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerextern char *vmsify PARAMS ((char *name, int type)); 27a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 28a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 29a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define dirent direct 30a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define NAMLEN(dirent) (dirent)->d_namlen 31a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef HAVE_SYS_NDIR_H 32a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# include <sys/ndir.h> 33a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 34a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef HAVE_SYS_DIR_H 35a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# include <sys/dir.h> 36a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 37a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef HAVE_NDIR_H 38a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# include <ndir.h> 39a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 40a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef HAVE_VMSDIR_H 41a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# include "vmsdir.h" 42a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif /* HAVE_VMSDIR_H */ 43a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 44a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 45a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* In GNU systems, <dirent.h> defines this macro for us. */ 46a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef _D_NAMLEN 47a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# undef NAMLEN 48a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define NAMLEN(d) _D_NAMLEN(d) 49a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 50a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 51a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#if (defined (POSIX) || defined (VMS) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__) 52a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Posix does not require that the d_ino field be present, and some 53a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner systems do not provide it. */ 54a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define REAL_DIR_ENTRY(dp) 1 55a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define FAKE_DIR_ENTRY(dp) 56a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 57a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) 58a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1) 59a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* POSIX */ 60a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 61a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef __MSDOS__ 62a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <ctype.h> 63a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <fcntl.h> 64a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 65a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* If it's MSDOS that doesn't have _USE_LFN, disable LFN support. */ 66a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef _USE_LFN 67a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define _USE_LFN 0 68a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 69a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 70a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic char * 71a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdosify (char *filename) 72a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 73a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static char dos_filename[14]; 74a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *df; 75a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int i; 76a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 77a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (filename == 0 || _USE_LFN) 78a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return filename; 79a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 80a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* FIXME: what about filenames which violate 81a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 8+3 constraints, like "config.h.in", or ".emacs"? */ 82a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0) 83a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return filename; 84a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 85a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner df = dos_filename; 86a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 87a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* First, transform the name part. */ 88a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i) 89a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *df++ = tolower ((unsigned char)*filename++); 90a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 91a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Now skip to the next dot. */ 92a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (*filename != '\0' && *filename != '.') 93a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++filename; 94a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*filename != '\0') 95a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 96a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *df++ = *filename++; 97a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i) 98a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *df++ = tolower ((unsigned char)*filename++); 99a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 100a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 101a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Look for more dots. */ 102a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (*filename != '\0' && *filename != '.') 103a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++filename; 104a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*filename == '.') 105a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return filename; 106a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *df = 0; 107a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dos_filename; 108a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 109a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* __MSDOS__ */ 110a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 111a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 112a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include "pathstuff.h" 113a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 114a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 115a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef _AMIGA 116a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <ctype.h> 117a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 118a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 119a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_CASE_INSENSITIVE_FS 120a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic char * 121a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdowncase (char *filename) 122a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 123a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static PATH_VAR (new_filename); 124a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *df; 125a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int i; 126a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 127a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (filename == 0) 128a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 129a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 130a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner df = new_filename; 131a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 132a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* First, transform the name part. */ 133a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for (i = 0; *filename != '\0'; ++i) 134a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 135a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *df++ = tolower ((unsigned char)*filename); 136a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++filename; 137a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 138a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 139a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *df = 0; 140a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 141a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return new_filename; 142a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 143a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* HAVE_CASE_INSENSITIVE_FS */ 144a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 145a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 146a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 147a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 148a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervms_hash (char *name) 149a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 150a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int h = 0; 151a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int g; 152a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 153a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (*name) 154a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 155a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned char uc = *name; 156a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_CASE_INSENSITIVE_FS 157a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner h = (h << 4) + (isupper (uc) ? tolower (uc) : uc); 158a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 159a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner h = (h << 4) + uc; 160a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 161a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner name++; 162a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner g = h & 0xf0000000; 163a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (g) 164a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 165a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner h = h ^ (g >> 24); 166a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner h = h ^ g; 167a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 168a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 169a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return h; 170a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 171a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 172a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* fake stat entry for a directory */ 173a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 174a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervmsstat_dir (char *name, struct stat *st) 175a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 176a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *s; 177a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int h; 178a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DIR *dir; 179a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 180a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = opendir (name); 181a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir == 0) 182a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return -1; 183a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner closedir (dir); 184a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner s = strchr (name, ':'); /* find device */ 185a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (s) 186a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 187a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *s++ = 0; 188a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner st->st_dev = (char *)vms_hash (name); 189a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner h = vms_hash (s); 190a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *(s-1) = ':'; 191a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 192a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 193a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 194a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner st->st_dev = 0; 195a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner s = name; 196a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner h = vms_hash (s); 197a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 198a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 199a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner st->st_ino[0] = h & 0xff; 200a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner st->st_ino[1] = h & 0xff00; 201a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner st->st_ino[2] = h >> 16; 202a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 203a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 204a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 205a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* VMS */ 206a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 207a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Hash table of directories. */ 208a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 209a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef DIRECTORY_BUCKETS 210a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define DIRECTORY_BUCKETS 199 211a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 212a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 213a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct directory_contents 214a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 215a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dev_t dev; /* Device and inode numbers of this dir. */ 216a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 217a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* 218a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * Inode means nothing on WINDOWS32. Even file key information is 219a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * unreliable because it is random per file open and undefined 220a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * for remote filesystems. The most unique attribute I can 221a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * come up with is the fully qualified name of the directory. Beware 222a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * though, this is also unreliable. I'm open to suggestion on a better 223a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * way to emulate inode. 224a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 225a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *path_key; 226a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int ctime; 227a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int mtime; /* controls check for stale directory cache */ 228a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int fs_flags; /* FS_FAT, FS_NTFS, ... */ 229a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define FS_FAT 0x1 230a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define FS_NTFS 0x2 231a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define FS_UNKNOWN 0x4 232a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 233a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 234a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ino_t ino[3]; 235a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 236a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ino_t ino; 237a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 238a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* WINDOWS32 */ 239a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct hash_table dirfiles; /* Files in this directory. */ 240a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DIR *dirstream; /* Stream reading this directory. */ 241a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner }; 242a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 243a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 244a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirectory_contents_hash_1 (const void *key_0) 245a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 246a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents const *key = (struct directory_contents const *) key_0; 247a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long hash; 248a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 249a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 250a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash = 0; 251a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ISTRING_HASH_1 (key->path_key, hash); 252a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime; 253a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 254a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef VMS 255a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash = (((unsigned int) key->dev << 4) 256a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ^ ((unsigned int) key->ino[0] 257a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner + (unsigned int) key->ino[1] 258a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner + (unsigned int) key->ino[2])); 259a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# else 260a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash = ((unsigned int) key->dev << 4) ^ (unsigned int) key->ino; 261a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 262a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* WINDOWS32 */ 263a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return hash; 264a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 265a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 266a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 267a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirectory_contents_hash_2 (const void *key_0) 268a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 269a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents const *key = (struct directory_contents const *) key_0; 270a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long hash; 271a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 272a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 273a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash = 0; 274a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ISTRING_HASH_2 (key->path_key, hash); 275a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime; 276a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 277a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef VMS 278a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash = (((unsigned int) key->dev << 4) 279a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ^ ~((unsigned int) key->ino[0] 280a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner + (unsigned int) key->ino[1] 281a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner + (unsigned int) key->ino[2])); 282a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# else 283a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash = ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ino; 284a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 285a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* WINDOWS32 */ 286a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 287a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return hash; 288a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 289a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 290a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Sometimes it's OK to use subtraction to get this value: 291a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner result = X - Y; 292a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner But, if we're not sure of the type of X and Y they may be too large for an 293a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int (on a 64-bit system for example). So, use ?: instead. 294a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner See Savannah bug #15534. 295a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 296a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner NOTE! This macro has side-effects! 297a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner*/ 298a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 299a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define MAKECMP(_x,_y) ((_x)<(_y)?-1:((_x)==(_y)?0:1)) 300a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 301a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 302a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirectory_contents_hash_cmp (const void *xv, const void *yv) 303a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 304a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents const *x = (struct directory_contents const *) xv; 305a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents const *y = (struct directory_contents const *) yv; 306a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int result; 307a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 308a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 309a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ISTRING_COMPARE (x->path_key, y->path_key, result); 310a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 311a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 312a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner result = MAKECMP(x->ctime, y->ctime); 313a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 314a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 315a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 316a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef VMS 317a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner result = MAKECMP(x->ino[0], y->ino[0]); 318a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 319a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 320a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner result = MAKECMP(x->ino[1], y->ino[1]); 321a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 322a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 323a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner result = MAKECMP(x->ino[2], y->ino[2]); 324a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 325a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 326a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# else 327a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner result = MAKECMP(x->ino, y->ino); 328a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 329a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 330a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 331a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* WINDOWS32 */ 332a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 333a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return MAKECMP(x->dev, y->dev); 334a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 335a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 336a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Table of directory contents hashed by device and inode number. */ 337a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct hash_table directory_contents; 338a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 339a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct directory 340a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 341a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *name; /* Name of the directory. */ 342a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 343a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The directory's contents. This data may be shared by several 344a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner entries in the hash table, which refer to the same directory 345a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (identified uniquely by `dev' and `ino') under different names. */ 346a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents *contents; 347a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner }; 348a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 349a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 350a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirectory_hash_1 (const void *key) 351a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 352a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_ISTRING_HASH_1 (((struct directory const *) key)->name); 353a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 354a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 355a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 356a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirectory_hash_2 (const void *key) 357a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 358a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_ISTRING_HASH_2 (((struct directory const *) key)->name); 359a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 360a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 361a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 362a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirectory_hash_cmp (const void *x, const void *y) 363a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 364a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_ISTRING_COMPARE (((struct directory const *) x)->name, 365a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ((struct directory const *) y)->name); 366a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 367a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 368a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Table of directories hashed by name. */ 369a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct hash_table directories; 370a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 371a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Never have more than this many directories open at once. */ 372a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 373a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define MAX_OPEN_DIRECTORIES 10 374a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 375a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned int open_directories = 0; 376a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 377a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 378a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Hash table of files in each directory. */ 379a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 380a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct dirfile 381a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 382a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *name; /* Name of the file. */ 383a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner short length; 384a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner short impossible; /* This file is impossible. */ 385a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner }; 386a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 387a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 388a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirfile_hash_1 (const void *key) 389a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 390a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_ISTRING_HASH_1 (((struct dirfile const *) key)->name); 391a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 392a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 393a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic unsigned long 394a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirfile_hash_2 (const void *key) 395a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 396a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_ISTRING_HASH_2 (((struct dirfile const *) key)->name); 397a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 398a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 399a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 400a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdirfile_hash_cmp (const void *xv, const void *yv) 401a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 402a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile const *x = ((struct dirfile const *) xv); 403a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile const *y = ((struct dirfile const *) yv); 404a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int result = x->length - y->length; 405a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (result) 406a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return result; 407a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return_ISTRING_COMPARE (x->name, y->name); 408a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 409a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 410a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef DIRFILE_BUCKETS 411a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#define DIRFILE_BUCKETS 107 412a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 413a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 414a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int dir_contents_file_exists_p PARAMS ((struct directory_contents *dir, char *filename)); 415a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct directory *find_directory PARAMS ((char *name)); 416a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 417a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Find the directory named NAME and return its `struct directory'. */ 418a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 419a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct directory * 420a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerfind_directory (char *name) 421a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 422a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register char *p; 423a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct directory *dir; 424a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct directory **dir_slot; 425a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory dir_key; 426a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int r; 427a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 428a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char* w32_path; 429a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char fs_label[BUFSIZ]; 430a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char fs_type[BUFSIZ]; 431a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long fs_serno; 432a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long fs_flags; 433a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned long fs_len; 434a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 435a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 436a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if ((*name == '.') && (*(name+1) == 0)) 437a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner name = "[]"; 438a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 439a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner name = vmsify (name,1); 440a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 441a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 442a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir_key.name = name; 443a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key); 444a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = *dir_slot; 445a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 446a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (HASH_VACANT (dir)) 447a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 448a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct stat st; 449a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 450a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The directory was not found. Create a new entry for it. */ 451a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 452a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = name + strlen (name); 453a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = (struct directory *) xmalloc (sizeof (struct directory)); 454a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->name = savestring (name, p - name); 455a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_insert_at (&directories, dir, dir_slot); 456a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The directory is not in the name hash table. 457a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Find its device and inode numbers, and look it up by them. */ 458a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 459a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 460a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Remove any trailing '\'. Windows32 stat fails even on valid 461a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner directories if they end in '\'. */ 462a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p[-1] == '\\') 463a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p[-1] = '\0'; 464a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 465a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 466a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 467a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner r = vmsstat_dir (name, &st); 468a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 469a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner EINTRLOOP (r, stat (name, &st)); 470a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 471a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 472a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 473a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Put back the trailing '\'. If we don't, we're permanently 474a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner truncating the value! */ 475a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p[-1] == '\0') 476a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p[-1] = '\\'; 477a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 478a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 479a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (r < 0) 480a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 481a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Couldn't stat the directory. Mark this by 482a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setting the `contents' member to a nil pointer. */ 483a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->contents = 0; 484a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 485a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 486a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 487a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Search the contents hash table; device and inode are the key. */ 488a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 489a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents *dc; 490a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents **dc_slot; 491a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents dc_key; 492a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 493a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_key.dev = st.st_dev; 494a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 495a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_key.path_key = w32_path = w32ify (name, 1); 496a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_key.ctime = st.st_ctime; 497a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 498a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef VMS 499a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_key.ino[0] = st.st_ino[0]; 500a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_key.ino[1] = st.st_ino[1]; 501a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_key.ino[2] = st.st_ino[2]; 502a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# else 503a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_key.ino = st.st_ino; 504a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 505a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 506a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key); 507a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc = *dc_slot; 508a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 509a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (HASH_VACANT (dc)) 510a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 511a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Nope; this really is a directory we haven't seen before. */ 512a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 513a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc = (struct directory_contents *) 514a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner xmalloc (sizeof (struct directory_contents)); 515a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 516a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Enter it in the contents hash table. */ 517a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->dev = st.st_dev; 518a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 519a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->path_key = xstrdup (w32_path); 520a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->ctime = st.st_ctime; 521a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->mtime = st.st_mtime; 522a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 523a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* 524a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * NTFS is the only WINDOWS32 filesystem that bumps mtime 525a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * on a directory when files are added/deleted from 526a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * a directory. 527a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 528a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner w32_path[3] = '\0'; 529a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (GetVolumeInformation(w32_path, 530a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fs_label, sizeof (fs_label), 531a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &fs_serno, &fs_len, 532a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner &fs_flags, fs_type, sizeof (fs_type)) == FALSE) 533a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->fs_flags = FS_UNKNOWN; 534a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (!strcmp(fs_type, "FAT")) 535a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->fs_flags = FS_FAT; 536a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (!strcmp(fs_type, "NTFS")) 537a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->fs_flags = FS_NTFS; 538a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 539a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->fs_flags = FS_UNKNOWN; 540a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 541a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef VMS 542a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->ino[0] = st.st_ino[0]; 543a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->ino[1] = st.st_ino[1]; 544a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->ino[2] = st.st_ino[2]; 545a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# else 546a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->ino = st.st_ino; 547a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 548a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* WINDOWS32 */ 549a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_insert_at (&directory_contents, dc, dc_slot); 550a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ENULLLOOP (dc->dirstream, opendir (name)); 551a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dc->dirstream == 0) 552a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Couldn't open the directory. Mark this by 553a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner setting the `files' member to a nil pointer. */ 554a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dc->dirfiles.ht_vec = 0; 555a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 556a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 557a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&dc->dirfiles, DIRFILE_BUCKETS, 558a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp); 559a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Keep track of how many directories are open. */ 560a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++open_directories; 561a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (open_directories == MAX_OPEN_DIRECTORIES) 562a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* We have too many directories open already. 563a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Read the entire directory and then close it. */ 564a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) dir_contents_file_exists_p (dc, (char *) 0); 565a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 566a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 567a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 568a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Point the name-hashed entry for DIR at its contents data. */ 569a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->contents = dc; 570a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 571a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 572a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 573a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dir; 574a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 575a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 576a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Return 1 if the name FILENAME is entered in DIR's hash table. 577a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner FILENAME must contain no slashes. */ 578a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 579a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 580a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdir_contents_file_exists_p (struct directory_contents *dir, char *filename) 581a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 582a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned int hash; 583a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile *df; 584a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirent *d; 585a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 586a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct stat st; 587a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int rehash = 0; 588a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 589a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 590a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir == 0 || dir->dirfiles.ht_vec == 0) 591a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 592a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The directory could not be stat'd or opened. */ 593a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 594a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 595a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef __MSDOS__ 596a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename = dosify (filename); 597a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 598a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 599a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_CASE_INSENSITIVE_FS 600a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename = downcase (filename); 601a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 602a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 603a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef __EMX__ 604a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (filename != 0) 605a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner _fnlwr (filename); /* lower case for FAT drives */ 606a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 607a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 608a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 609a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename = vmsify (filename,0); 610a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 611a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 612a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash = 0; 613a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (filename != 0) 614a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 615a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile dirfile_key; 616a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 617a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (*filename == '\0') 618a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 619a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Checking if the directory exists. */ 620a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 1; 621a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 622a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_key.name = filename; 623a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_key.length = strlen (filename); 624a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner df = (struct dirfile *) hash_find_item (&dir->dirfiles, &dirfile_key); 625a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (df) 626a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 627a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return !df->impossible; 628a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 629a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 630a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 631a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The file was not found in the hashed list. 632a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner Try to read the directory further. */ 633a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 634a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir->dirstream == 0) 635a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 636a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 637a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* 638a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * Check to see if directory has changed since last read. FAT 639a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * filesystems force a rehash always as mtime does not change 640a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * on directories (ugh!). 641a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 642a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir->path_key) 643a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 644a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if ((dir->fs_flags & FS_FAT) != 0) 645a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 646a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->mtime = time ((time_t *) 0); 647a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner rehash = 1; 648a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 649a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (stat(dir->path_key, &st) == 0 && st.st_mtime > dir->mtime) 650a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 651a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* reset date stamp to show most recent re-process. */ 652a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->mtime = st.st_mtime; 653a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner rehash = 1; 654a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 655a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 656a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If it has been already read in, all done. */ 657a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!rehash) 658a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 659a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 660a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* make sure directory can still be opened; if not return. */ 661a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->dirstream = opendir(dir->path_key); 662a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!dir->dirstream) 663a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 664a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 665a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 666a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 667a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The directory has been all read in. */ 668a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 669a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 670a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 671a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (1) 672a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 673a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Enter the file in the hash table. */ 674a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned int len; 675a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile dirfile_key; 676a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile **dirfile_slot; 677a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 678a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ENULLLOOP (d, readdir (dir->dirstream)); 679a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (d == 0) 680a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner break; 681a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 682a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#if defined(VMS) && defined(HAVE_DIRENT_H) 683a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* In VMS we get file versions too, which have to be stripped off */ 684a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 685a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *p = strrchr (d->d_name, ';'); 686a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p) 687a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner *p = '\0'; 688a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 689a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 690a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!REAL_DIR_ENTRY (d)) 691a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner continue; 692a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 693a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner len = NAMLEN (d); 694a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_key.name = d->d_name; 695a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_key.length = len; 696a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_slot = (struct dirfile **) hash_find_slot (&dir->dirfiles, &dirfile_key); 697a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 698a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* 699a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * If re-reading a directory, don't cache files that have 700a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * already been discovered. 701a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 702a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! rehash || HASH_VACANT (*dirfile_slot)) 703a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 704a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 705a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner df = (struct dirfile *) xmalloc (sizeof (struct dirfile)); 706a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner df->name = savestring (d->d_name, len); 707a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner df->length = len; 708a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner df->impossible = 0; 709a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_insert_at (&dir->dirfiles, df, dirfile_slot); 710a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 711a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Check if the name matches the one we're searching for. */ 712a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (filename != 0 && strieq (d->d_name, filename)) 713a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 714a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 1; 715a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 716a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 717a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 718a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* If the directory has been completely read in, 719a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner close the stream and reset the pointer to nil. */ 720a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (d == 0) 721a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 722a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner --open_directories; 723a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner closedir (dir->dirstream); 724a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->dirstream = 0; 725a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 726a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 727a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 728a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 729a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Return 1 if the name FILENAME in directory DIRNAME 730a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner is entered in the dir hash table. 731a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner FILENAME must contain no slashes. */ 732a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 733a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerint 734a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdir_file_exists_p (char *dirname, char *filename) 735a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 736a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dir_contents_file_exists_p (find_directory (dirname)->contents, 737a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename); 738a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 739a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 740a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Return 1 if the file named NAME exists. */ 741a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 742a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerint 743a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerfile_exists_p (char *name) 744a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 745a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *dirend; 746a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *dirname; 747a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *slash; 748a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 749a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef NO_ARCHIVES 750a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (ar_name (name)) 751a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return ar_member_date (name) != (time_t) -1; 752a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 753a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 754a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 755a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (name, ']'); 756a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == 0) 757a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (name, ':'); 758a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == (char *)0) 759a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dir_file_exists_p ("[]", name); 760a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else /* !VMS */ 761a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (name, '/'); 762a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_DOS_PATHS 763a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Forward and backslashes might be mixed. We need the rightmost one. */ 764a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 765a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *bslash = strrchr(name, '\\'); 766a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!dirend || bslash > dirend) 767a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = bslash; 768a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The case of "d:file". */ 769a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!dirend && name[0] && name[1] == ':') 770a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = name + 1; 771a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 772a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* HAVE_DOS_PATHS */ 773a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == 0) 774a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef _AMIGA 775a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dir_file_exists_p (".", name); 776a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else /* !VMS && !AMIGA */ 777a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dir_file_exists_p ("", name); 778a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* AMIGA */ 779a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* VMS */ 780a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 781a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner slash = dirend; 782a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == name) 783a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname = "/"; 784a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 785a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 786a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_DOS_PATHS 787a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* d:/ and d: are *very* different... */ 788a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend < name + 3 && name[1] == ':' && 789a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (*dirend == '/' || *dirend == '\\' || *dirend == ':')) 790a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend++; 791a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 792a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname = (char *) alloca (dirend - name + 1); 793a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bcopy (name, dirname, dirend - name); 794a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname[dirend - name] = '\0'; 795a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 796a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dir_file_exists_p (dirname, slash + 1); 797a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 798a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 799a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Mark FILENAME as `impossible' for `file_impossible_p'. 800a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner This means an attempt has been made to search for FILENAME 801a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner as an intermediate file, and it has failed. */ 802a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 803a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 804a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerfile_impossible (char *filename) 805a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 806a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *dirend; 807a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register char *p = filename; 808a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct directory *dir; 809a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct dirfile *new; 810a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 811a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 812a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (p, ']'); 813a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == 0) 814a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (p, ':'); 815a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend++; 816a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == (char *)1) 817a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory ("[]"); 818a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 819a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (p, '/'); 820a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef HAVE_DOS_PATHS 821a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Forward and backslashes might be mixed. We need the rightmost one. */ 822a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 823a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *bslash = strrchr(p, '\\'); 824a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!dirend || bslash > dirend) 825a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = bslash; 826a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The case of "d:file". */ 827a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!dirend && p[0] && p[1] == ':') 828a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = p + 1; 829a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 830a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif /* HAVE_DOS_PATHS */ 831a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == 0) 832a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifdef _AMIGA 833a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory (""); 834a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# else /* !VMS && !AMIGA */ 835a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory ("."); 836a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif /* AMIGA */ 837a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* VMS */ 838a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 839a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 840a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *dirname; 841a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *slash = dirend; 842a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == p) 843a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname = "/"; 844a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 845a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 846a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_DOS_PATHS 847a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* d:/ and d: are *very* different... */ 848a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend < p + 3 && p[1] == ':' && 849a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (*dirend == '/' || *dirend == '\\' || *dirend == ':')) 850a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend++; 851a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 852a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname = (char *) alloca (dirend - p + 1); 853a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bcopy (p, dirname, dirend - p); 854a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname[dirend - p] = '\0'; 855a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 856a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory (dirname); 857a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename = p = slash + 1; 858a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 859a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 860a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir->contents == 0) 861a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 862a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The directory could not be stat'd. We allocate a contents 863a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner structure for it, but leave it out of the contents hash table. */ 864a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->contents = (struct directory_contents *) 865a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner xmalloc (sizeof (struct directory_contents)); 866a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bzero ((char *) dir->contents, sizeof (struct directory_contents)); 867a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 868a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 869a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir->contents->dirfiles.ht_vec == 0) 870a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 871a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&dir->contents->dirfiles, DIRFILE_BUCKETS, 872a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp); 873a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 874a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 875a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Make a new entry and put it in the table. */ 876a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 877a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new = (struct dirfile *) xmalloc (sizeof (struct dirfile)); 878a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new->name = xstrdup (filename); 879a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new->length = strlen (filename); 880a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new->impossible = 1; 881a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_insert (&dir->contents->dirfiles, new); 882a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 883a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 884a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Return nonzero if FILENAME has been marked impossible. */ 885a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 886a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerint 887a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerfile_impossible_p (char *filename) 888a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 889a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *dirend; 890a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register char *p = filename; 891a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct directory_contents *dir; 892a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct dirfile *dirfile; 893a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile dirfile_key; 894a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 895a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 896a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (filename, ']'); 897a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == 0) 898a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory ("[]")->contents; 899a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 900a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = strrchr (filename, '/'); 901a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_DOS_PATHS 902a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Forward and backslashes might be mixed. We need the rightmost one. */ 903a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 904a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *bslash = strrchr(filename, '\\'); 905a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!dirend || bslash > dirend) 906a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = bslash; 907a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The case of "d:file". */ 908a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (!dirend && filename[0] && filename[1] == ':') 909a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend = filename + 1; 910a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 911a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* HAVE_DOS_PATHS */ 912a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == 0) 913a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef _AMIGA 914a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory ("")->contents; 915a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else /* !VMS && !AMIGA */ 916a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory (".")->contents; 917a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* AMIGA */ 918a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* VMS */ 919a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 920a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 921a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *dirname; 922a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner char *slash = dirend; 923a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend == filename) 924a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname = "/"; 925a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 926a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 927a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_DOS_PATHS 928a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* d:/ and d: are *very* different... */ 929a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirend < filename + 3 && filename[1] == ':' && 930a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (*dirend == '/' || *dirend == '\\' || *dirend == ':')) 931a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirend++; 932a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 933a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname = (char *) alloca (dirend - filename + 1); 934a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bcopy (p, dirname, dirend - p); 935a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirname[dirend - p] = '\0'; 936a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 937a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir = find_directory (dirname)->contents; 938a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner p = filename = slash + 1; 939a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 940a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 941a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir == 0 || dir->dirfiles.ht_vec == 0) 942a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* There are no files entered for this directory. */ 943a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 944a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 945a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef __MSDOS__ 946a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename = dosify (p); 947a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 948a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef HAVE_CASE_INSENSITIVE_FS 949a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename = downcase (p); 950a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 951a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 952a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner filename = vmsify (p, 1); 953a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 954a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 955a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_key.name = filename; 956a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile_key.length = strlen (filename); 957a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dirfile = (struct dirfile *) hash_find_item (&dir->dirfiles, &dirfile_key); 958a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dirfile) 959a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return dirfile->impossible; 960a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 961a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 962a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 963a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 964a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Return the already allocated name in the 965a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner directory hash table that matches DIR. */ 966a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 967a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerchar * 968a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdir_name (char *dir) 969a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 970a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return find_directory (dir)->name; 971a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 972a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 973a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Print the data base of directories. */ 974a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 975a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 976a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerprint_dir_data_base (void) 977a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 978a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register unsigned int files; 979a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register unsigned int impossible; 980a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct directory **dir_slot; 981a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct directory **dir_end; 982a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 983a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner puts (_("\n# Directories\n")); 984a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 985a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner files = impossible = 0; 986a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 987a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir_slot = (struct directory **) directories.ht_vec; 988a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir_end = dir_slot + directories.ht_size; 989a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for ( ; dir_slot < dir_end; dir_slot++) 990a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 991a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct directory *dir = *dir_slot; 992a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! HASH_VACANT (dir)) 993a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 994a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir->contents == 0) 995a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("# %s: could not be stat'd.\n"), dir->name); 996a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else if (dir->contents->dirfiles.ht_vec == 0) 997a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 998a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 999a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("# %s (key %s, mtime %d): could not be opened.\n"), 1000a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->name, dir->contents->path_key,dir->contents->mtime); 1001a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else /* WINDOWS32 */ 1002a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 1003a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"), 1004a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->name, dir->contents->dev, 1005a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->contents->ino[0], dir->contents->ino[1], 1006a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->contents->ino[2]); 1007a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 1008a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("# %s (device %ld, inode %ld): could not be opened.\n"), 1009a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->name, (long int) dir->contents->dev, 1010a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (long int) dir->contents->ino); 1011a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1012a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* WINDOWS32 */ 1013a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1014a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1015a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1016a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register unsigned int f = 0; 1017a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register unsigned int im = 0; 1018a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct dirfile **files_slot; 1019a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct dirfile **files_end; 1020a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1021a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner files_slot = (struct dirfile **) dir->contents->dirfiles.ht_vec; 1022a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner files_end = files_slot + dir->contents->dirfiles.ht_size; 1023a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner for ( ; files_slot < files_end; files_slot++) 1024a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1025a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct dirfile *df = *files_slot; 1026a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! HASH_VACANT (df)) 1027a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1028a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (df->impossible) 1029a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++im; 1030a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1031a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner ++f; 1032a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1033a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1034a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef WINDOWS32 1035a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("# %s (key %s, mtime %d): "), 1036a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->name, dir->contents->path_key, dir->contents->mtime); 1037a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else /* WINDOWS32 */ 1038a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef VMS 1039a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("# %s (device %d, inode [%d,%d,%d]): "), 1040a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->name, dir->contents->dev, 1041a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->contents->ino[0], dir->contents->ino[1], 1042a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->contents->ino[2]); 1043a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 1044a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_("# %s (device %ld, inode %ld): "), 1045a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner dir->name, 1046a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (long)dir->contents->dev, (long)dir->contents->ino); 1047a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1048a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif /* WINDOWS32 */ 1049a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (f == 0) 1050a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_("No"), stdout); 1051a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1052a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("%u", f); 1053a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_(" files, "), stdout); 1054a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (im == 0) 1055a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_("no"), stdout); 1056a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1057a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("%u", im); 1058a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_(" impossibilities"), stdout); 1059a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir->contents->dirstream == 0) 1060a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner puts ("."); 1061a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1062a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner puts (_(" so far.")); 1063a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner files += f; 1064a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner impossible += im; 1065a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1066a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1067a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1068a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1069a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs ("\n# ", stdout); 1070a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (files == 0) 1071a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_("No"), stdout); 1072a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1073a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("%u", files); 1074a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_(" files, "), stdout); 1075a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (impossible == 0) 1076a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner fputs (_("no"), stdout); 1077a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner else 1078a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf ("%u", impossible); 1079a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner printf (_(" impossibilities in %lu directories.\n"), directories.ht_fill); 1080a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1081a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1082a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Hooks for globbing. */ 1083a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1084a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#include <glob.h> 1085a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1086a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Structure describing state of iterating through a directory hash table. */ 1087a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1088a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstruct dirstream 1089a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1090a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents *contents; /* The directory being read. */ 1091a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile **dirfile_slot; /* Current slot in table. */ 1092a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner }; 1093a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1094a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* Forward declarations. */ 1095a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic __ptr_t open_dirstream PARAMS ((const char *)); 1096a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct dirent *read_dirstream PARAMS ((__ptr_t)); 1097a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1098a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic __ptr_t 1099a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turneropen_dirstream (const char *directory) 1100a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1101a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirstream *new; 1102a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory *dir = find_directory ((char *)directory); 1103a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1104a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (dir->contents == 0 || dir->contents->dirfiles.ht_vec == 0) 1105a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* DIR->contents is nil if the directory could not be stat'd. 1106a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner DIR->contents->dirfiles is nil if it could not be opened. */ 1107a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 1108a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1109a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Read all the contents of the directory now. There is no benefit 1110a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner in being lazy, since glob will want to see every file anyway. */ 1111a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1112a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner (void) dir_contents_file_exists_p (dir->contents, (char *) 0); 1113a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1114a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new = (struct dirstream *) xmalloc (sizeof (struct dirstream)); 1115a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new->contents = dir->contents; 1116a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner new->dirfile_slot = (struct dirfile **) new->contents->dirfiles.ht_vec; 1117a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1118a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return (__ptr_t) new; 1119a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1120a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1121a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic struct dirent * 1122a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerread_dirstream (__ptr_t stream) 1123a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1124a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirstream *const ds = (struct dirstream *) stream; 1125a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct directory_contents *dc = ds->contents; 1126a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirfile **dirfile_end = (struct dirfile **) dc->dirfiles.ht_vec + dc->dirfiles.ht_size; 1127a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static char *buf; 1128a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner static unsigned int bufsz; 1129a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1130a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner while (ds->dirfile_slot < dirfile_end) 1131a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1132a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner register struct dirfile *df = *ds->dirfile_slot++; 1133a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (! HASH_VACANT (df) && !df->impossible) 1134a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1135a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* The glob interface wants a `struct dirent', 1136a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner so mock one up. */ 1137a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner struct dirent *d; 1138a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner unsigned int len = df->length + 1; 1139a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (sizeof *d - sizeof d->d_name + len > bufsz) 1140a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner { 1141a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (buf != 0) 1142a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free (buf); 1143a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bufsz *= 2; 1144a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (sizeof *d - sizeof d->d_name + len > bufsz) 1145a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner bufsz = sizeof *d - sizeof d->d_name + len; 1146a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner buf = xmalloc (bufsz); 1147a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1148a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner d = (struct dirent *) buf; 1149a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef __MINGW32__ 1150a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# if __MINGW32_MAJOR_VERSION < 3 || (__MINGW32_MAJOR_VERSION == 3 && \ 1151a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner __MINGW32_MINOR_VERSION == 0) 1152a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner d->d_name = xmalloc(len); 1153a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 1154a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1155a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner FAKE_DIR_ENTRY (d); 1156a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef _DIRENT_HAVE_D_NAMLEN 1157a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner d->d_namlen = len - 1; 1158a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1159a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifdef _DIRENT_HAVE_D_TYPE 1160a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner d->d_type = DT_UNKNOWN; 1161a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1162a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner memcpy (d->d_name, df->name, len); 1163a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return d; 1164a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1165a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner } 1166a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1167a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return 0; 1168a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1169a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1170a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic void 1171a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turneransi_free (void *p) 1172a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1173a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner if (p) 1174a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner free(p); 1175a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1176a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1177a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a 1178a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * macro for stat64(). If stat is a macro, make a local wrapper function to 1179a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner * invoke it. 1180a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner */ 1181a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#ifndef stat 1182a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# ifndef VMS 1183a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerextern int stat PARAMS ((const char *path, struct stat *sbuf)); 1184a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# endif 1185a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner# define local_stat stat 1186a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#else 1187a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerstatic int 1188a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerlocal_stat (const char *path, struct stat *buf) 1189a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1190a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner int e; 1191a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1192a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner EINTRLOOP (e, stat (path, buf)); 1193a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner return e; 1194a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1195a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner#endif 1196a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1197a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 1198a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerdir_setup_glob (glob_t *gl) 1199a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1200a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* Bogus sunos4 compiler complains (!) about & before functions. */ 1201a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner gl->gl_opendir = open_dirstream; 1202a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner gl->gl_readdir = read_dirstream; 1203a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner gl->gl_closedir = ansi_free; 1204a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner gl->gl_stat = local_stat; 1205a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner /* We don't bother setting gl_lstat, since glob never calls it. 1206a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner The slot is only there for compatibility with 4.4 BSD. */ 1207a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1208a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner 1209a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnervoid 1210a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turnerhash_init_directories (void) 1211a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner{ 1212a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&directories, DIRECTORY_BUCKETS, 1213a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner directory_hash_1, directory_hash_2, directory_hash_cmp); 1214a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner hash_init (&directory_contents, DIRECTORY_BUCKETS, 1215a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner directory_contents_hash_1, directory_contents_hash_2, directory_contents_hash_cmp); 1216a86d4c1bde70365cbbe874ad9ddb3f06916d2085David 'Digit' Turner} 1217