static char rcsver[] = "$Id: dir.c,v 1.7 2001/12/20 00:18:38 saadat Exp $"; /** ** $Source: /tes/cvs/vanilla/dir.c,v $ ** ** $Log: dir.c,v $ ** Revision 1.7 2001/12/20 00:18:38 saadat ** File sorting now happens independent of case. ** ** Revision 1.6 2001/12/19 22:42:36 saadat ** The compare function used in qsort was causing vanilla to terminate ** abnormally. It has been fixed as per spec of Visual C++. ** ** Revision 1.5 2001/11/28 20:22:39 saadat ** Merged branch vanilla-3-3-13-key-alias-fix at vanilla-3-3-13-4 with ** vanilla-3-4-6. ** ** Revision 1.4.2.1 2001/05/22 03:58:07 saadat ** Windows 95 stat() fails if the path is suffixed with a "/" (e.g. stat ** on "/vanilla/data/" will yield -1). Windows NT does not complain ** however. ** ** Revision 1.4 2000/07/12 10:34:40 gorelick ** Moves SortFiles out of LoadFilenames ** ** Revision 1.3 2000/07/07 17:15:22 saadat ** Added support for Windows MS Visual C++ memory-mapped file support. ** Removed some unused variables from various files. ** ** Revision 1.2 1999/11/19 21:19:43 gorelick ** Version 3.1, post PDS delivery of 3.0 ** ** Revision 1.1.1.1 1999/10/15 19:30:35 gorelick ** Version 3.0 ** ** Revision 2.1 1999/02/10 04:00:50 gorelick ** *** empty log message *** ** ** Revision 2.0 1998/12/22 22:47:04 gorelick ** release version ** ** Revision 2.0 1998/12/18 01:26:03 gorelick ** release version ** ** Revision 1.3 1998/12/18 01:04:48 gorelick ** *** empty log message *** ** ** Revision 1.2 1998/11/12 22:58:55 gorelick ** first release version ** **/ #ifdef _WINDOWS #include "dos.h" #include #else #include #include #endif /* _WINDOWS */ #include #include #include #include #include "tools.h" #include "system.h" #ifdef _WINDOWS /* Some old Microsoft Visual C compilers need the "__cdecl" */ #define __CDECL __cdecl #else #define __CDECL #endif /* _WINDOWS */ #define qsortptr int (__CDECL *)(const void *, const void *) int mystrcmp(const void *a, const void *b); void SortFiles(LIST *list); int IsDataFile(char *test, char *type); int IsAPhantomLink(const char *fpath); #ifdef _WINDOWS /** ** LoadFilenames() ** Given a directory and table prefix, load the name of all the files ** ** Wed Jul 12 00:16:55 MST 2000 (NsG) ** Removed the SortFiles from here, since it is done again by the ** caller to merge file lists. */ LIST * LoadFilenames(char *path, char *prefix) { LIST *list; char buf[2048]; const char *phantom_link_msg = "Ignoring phantom link named %s.\n"; long fhand; struct _finddata_t finfo; long rc; sprintf(buf, "%s/%s*", path, prefix); fhand = _findfirst(buf, &finfo); if (fhand == -1 && errno == EINVAL){ return NULL; } rc = fhand; list = new_list(); while(rc != -1){ if (IsDataFile(finfo.name, prefix)){ sprintf(buf, "%s/%s", path, finfo.name); if (!IsAPhantomLink(buf)){ /** ** Store the file name **/ list_add(list, strdup(buf)); } else { fprintf(stderr, phantom_link_msg, buf); } } rc = _findnext(fhand, &finfo); } if (fhand != -1) { _findclose(fhand); } return(list); } #else LIST * LoadFilenames(char *path, char *prefix) { LIST *list; char buf[2048]; const char *phantom_link_msg = "Ignoring phantom link named %s.\n"; DIR *d; struct dirent *d_ent; if ((d = opendir(path)) == NULL) return (NULL); list = new_list(); while ((d_ent = readdir(d)) != NULL) { if (IsDataFile(d_ent->d_name, prefix)){ sprintf(buf, "%s/%s", path, d_ent->d_name); if(!IsAPhantomLink(buf)) { /** ** Store the filename **/ list_add(list, strdup(buf)); } else { fprintf(stderr, phantom_link_msg, buf); } } } closedir(d); return(list); } #endif /* _WINDOWS */ int IsAPhantomLink(const char *fpath) { struct stat sbuf; if (stat(fpath, &sbuf) < 0){ if (errno == ENOENT){ return 1; /* Phantom link */ } } /* Not a phantom link or not accessable */ return 0; } int IsDataFile(char *test, char *type) { char *p; if (!strncasecmp(test, type, strlen(type))) { p = strrchr(test, '.'); if (p && (!strcasecmp(p, ".DAT") || !strcasecmp(p, ".TAB"))) return (1); } return (0); } #ifdef _WINDOWS static const char * my_basename(const char *path) { const char *name, *p1, *p2; if (path == NULL){ return NULL; } p1 = strrchr(path, '/'); p2 = strrchr(path, '\\'); /* name follows the last "/" or "\" - if any! */ if (p1 && p2){ name = (p1 > p2)? p1: p2; name ++; } else if (p1) { name = p1 + 1; } else if (p2) { name = p2 + 1; } else { /* name follows the drive letter - if any! */ p1 = strchr(path, ':'); if ((p1 - path) == 2){ name = p1 + 1; } else { name = path; } } return name; } #else /* UNIX */ static const char * my_basename(const char *path) { const char *name; if (path == NULL){ return NULL; } name = strrchr(path, '/'); if (name){ name++; } else { name = path; } return name; } #endif /* _WINDOWS */ static int __CDECL my_filename_cmp(const void *a, const void *b) { return strcasecmp(my_basename(*(char **)a), my_basename(*(char **)b)); } void SortFiles(LIST *list) { if (list->number > 1) qsort(list->ptr, list->number, sizeof(char *), my_filename_cmp); }