From: <dan...@ya...> - 2001-08-22 23:39:19
|
In gcc-2.95.3 source there are public domain dirent.c /dirent.h source for winnt (in gcc/config/winnt). This source fixes the trailing slash problems reported recently in user list. (_stat accepts "c:\\" as a valid directory and "c:tmp" and "c:\\tmp" and (on NT) c:/tmp/, but not "c:\\tmp\\"). I have tested the gcc dirent on NT and works on all the various combinations of slashes and backslashes I can think of (oops no I just thought of some back-slashed mixed up UNC names and some device names llke "\\\\.\\PhysicalDrive0" that I haven't tested). The gcc/winnt dirent also supports HPFS conventions, but I can't test. Anyone here have that filesystem? I can patch up the existing dirent.c easily enough to handle the DOS filename bug that was was reported, or we could replace with the attached PD files. Comments. Danny _____________________________________________________________________________ http://shopping.yahoo.com.au - Father's Day Shopping - Find the perfect gift for your Dad for Father's Day |
From: Earnie B. <ear...@ya...> - 2001-08-23 11:41:59
|
HPFS is dead. Which ever you feel best with. Earnie. Danny Smith wrote: > > > > In gcc-2.95.3 source there are public domain dirent.c /dirent.h source > for winnt (in gcc/config/winnt). This source fixes the trailing slash > problems reported recently in user list. (_stat accepts "c:\\" as a > valid directory and "c:tmp" and "c:\\tmp" and (on NT) c:/tmp/, but not > "c:\\tmp\\"). I have tested the gcc dirent on NT and works on all the > various combinations of slashes and backslashes I can think of (oops no > I just thought of some back-slashed mixed up UNC names and some device > names llke "\\\\.\\PhysicalDrive0" that I haven't tested). > > The gcc/winnt dirent also supports HPFS conventions, but I can't test. > Anyone here have that filesystem? > > I can patch up the existing dirent.c easily enough to handle the DOS > filename bug that was was reported, or we could replace with the > attached PD files. Comments. > > Danny > > _____________________________________________________________________________ > http://shopping.yahoo.com.au - Father's Day Shopping > - Find the perfect gift for your Dad for Father's Day > > ------------------------------------------------------------------------ > /* > * @(#)msd_dir.c 1.4 87/11/06 Public Domain. > * > * A public domain implementation of BSD directory routines for > * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), > * August 1897 > * > * Modified by Ian Stewartson, Data Logic (ist...@da...). > * > * Updates: 1. To support OS/2 1.x > * 2. To support HPFS long filenames > * 3. To support OS/2 2.x > * 4. To support TurboC > * 5. To support Windows NT > */ > > #include <sys/types.h> > #include <sys/stat.h> > #include <stdio.h> > #include <stdlib.h> > > #include <malloc.h> > > #include <string.h> > #include <limits.h> > #include <ctype.h> > #include <errno.h> > #include <dirent.h> > > #define WIN32_LEAN_AND_MEAN > #include <windows.h> > > #define FILE_NAME_E cFileName > #define OS_CloseFH(a) FindClose (a) > #define FIND_BUFFER WIN32_FIND_DATA > #define DISABLE_HARD_ERRORS SetErrorMode (0) > #define ENABLE_HARD_ERRORS SetErrorMode (SEM_FAILCRITICALERRORS | \ > SEM_NOOPENFILEERRORBOX); > > # define ERROR_EMPTY_DIR ERROR_FILE_NOT_FOUND > > # define ATTRIBUTES (_A_SUBDIR | _A_HIDDEN | _A_SYSTEM | \ > _A_NORMAL | _A_RDONLY | _A_ARCH) > > /* > * missing ?? > */ > > #ifndef ENOTDIR > # define ENOTDIR 120 /* Not a directory */ > #endif > > #ifndef S_IFMT > # define S_IFMT 0xf000 /* type of file */ > #endif > > #ifndef S_ISDIR > # define S_ISDIR(m) ((((m) & S_IFMT) == S_IFDIR)) > #endif > > /* > * Internals > */ > > typedef struct _dircontents DIRCONT; > static void free_dircontents (DIRCONT *); > > /* > * Open the directory stream > */ > > DIR * > opendir (name) > const char *name; > { > struct stat statb; > DIR *dirp; > char *last; > DIRCONT *dp; > char *nbuf; > int len = strlen (name); > unsigned long rc; > FIND_BUFFER dtabuf; > HANDLE d_handle; > bool HPFS = FALSE; > > if (!len) > { > errno = ENOTDIR; > return (DIR *)NULL; > } > > if ((nbuf = malloc (len + 5)) == (char *)NULL) > return (DIR *) NULL; > > strcpy (nbuf, name); > last = &nbuf[len - 1]; > > /* Ok, DOS is very picky about its directory names. The following are > * valid. > * > * c:/ > * c:. > * c:name/name1 > * > * c:name/ is not valid > */ > > if (((*last == '\\') || (*last == '/')) && (len > 1) && > (!((len == 3) && (name[1] == ':')))) > *(last--) = 0; > > /* Check its a directory */ > > DISABLE_HARD_ERRORS; > rc = stat (nbuf, &statb); > ENABLE_HARD_ERRORS; > > if (rc) > { > free (nbuf); > return (DIR *) NULL; > } > > if (!S_ISDIR (statb.st_mode)) > { > free (nbuf); > errno = ENOTDIR; > return (DIR *)NULL; > } > > if ((dirp = (DIR *) malloc (sizeof (DIR))) == (DIR *) NULL) > { > free (nbuf); > return (DIR *) NULL; > } > > /* Set up to find everything */ > > if ((*last != '\\') && (*last != '/')) > strcat (last, "/"); > > strcat (last, "*.*"); > > /* Find the file system type */ > > HPFS = IsHPFSFileSystem (nbuf); > > dirp->dd_loc = 0; > dirp->dd_cp = (DIRCONT *) NULL; > dirp->dd_contents = (DIRCONT *) NULL; > > DISABLE_HARD_ERRORS; > > d_handle = FindFirstFile (nbuf, &dtabuf); > rc = (d_handle == INVALID_HANDLE_VALUE) ? GetLastError () : 0; > > ENABLE_HARD_ERRORS; > > /* Check for errors */ > > if (rc) > { > free (nbuf); > > /* Empty directory */ > > #if defined (ERROR_EMPTY_DIR) > if (rc == ERROR_EMPTY_DIR) > return dirp; > #endif > > free (dirp); > return (DIR *) NULL; > } > > /* Process the directory */ > > do > { > if (((dp = (DIRCONT *) malloc (sizeof (DIRCONT))) == (DIRCONT *)NULL) || > ((dp->_d_entry = strdup (dtabuf.FILE_NAME_E)) == (char *) NULL)) > { > if (dp->_d_entry != (char *)NULL) > free ((char *)dp); > > free (nbuf); > free_dircontents (dirp->dd_contents); > > OS_CloseFH (d_handle); > return (DIR *) NULL; > } > > if (!HPFS) > strlwr (dp->_d_entry); > > if (dirp->dd_contents != (DIRCONT *) NULL) > dirp->dd_cp = dirp->dd_cp->_d_next = dp; > > else > dirp->dd_contents = dirp->dd_cp = dp; > > dp->_d_next = (DIRCONT *) NULL; > > } while (FindNextFile (d_handle, &dtabuf)); > > dirp->dd_cp = dirp->dd_contents; > free (nbuf); > > OS_CloseFH (d_handle); > return dirp; > } > > /* > * Close the directory stream > */ > > int > closedir (dirp) > DIR *dirp; > { > if (dirp != (DIR *)NULL) > { > free_dircontents (dirp->dd_contents); > free ((char *)dirp); > } > > return 0; > } > > /* > * Read the next record from the stream > */ > > struct dirent * > readdir (dirp) > DIR *dirp; > { > static struct dirent dp; > > if ((dirp == (DIR *)NULL) || (dirp->dd_cp == (DIRCONT *) NULL)) > return (struct dirent *) NULL; > > dp.d_reclen = strlen (strcpy (dp.d_name, dirp->dd_cp->_d_entry)); > dp.d_off = dirp->dd_loc * 32; > dp.d_ino = (ino_t)++dirp->dd_loc; > dirp->dd_cp = dirp->dd_cp->_d_next; > > return &dp; > } > > /* > * Restart the directory stream > */ > > void > rewinddir (dirp) > DIR *dirp; > { > seekdir (dirp, (off_t)0); > } > > /* > * Move to a know position in the stream > */ > > void > seekdir (dirp, off) > DIR *dirp; > off_t off; > { > long i = off; > DIRCONT *dp; > > if ((dirp == (DIR *)NULL) || (off < 0L)) > return; > > for (dp = dirp->dd_contents; (--i >= 0) && (dp != (DIRCONT *)NULL); > dp = dp->_d_next) > ; > > dirp->dd_loc = off - (i + 1); > dirp->dd_cp = dp; > } > > /* > * Get the current position > */ > > off_t > telldir(dirp) > DIR *dirp; > { > return (dirp == (DIR *)NULL) ? (off_t) -1 : dirp->dd_loc; > } > > /* > * Release the internal structure > */ > > static void > free_dircontents (dp) > DIRCONT *dp; > { > DIRCONT *odp; > > while ((odp = dp) != (DIRCONT *)NULL) > { > if (dp->_d_entry != (char *)NULL) > free (dp->_d_entry); > > dp = dp->_d_next; > free ((char *)odp); > } > } > > /* > * Windows NT version > */ > > bool > IsHPFSFileSystem (directory) > char *directory; > { > char bName[4]; > DWORD flags; > DWORD maxname; > BOOL rc; > unsigned int nDrive; > char szCurDir [MAX_PATH]; > > if (isalpha (directory[0]) && (directory[1] == ':')) > nDrive = toupper (directory[0]) - '@'; > > else > { > GetCurrentDirectory (MAX_PATH, szCurDir); > nDrive = szCurDir[0] - 'A' + 1; > } > > /* Set up the drive name */ > > strcpy (bName, "x:\\"); > bName[0] = (char) (nDrive + '@'); > > /* Read the volume info, if we fail - assume non-HPFS */ > > DISABLE_HARD_ERRORS; > > rc = GetVolumeInformation (bName, (LPTSTR)NULL, 0, (LPDWORD)NULL, > &maxname, &flags, (LPTSTR)NULL, 0); > ENABLE_HARD_ERRORS; > > return ((rc) && (flags & (FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED))) > ? TRUE : FALSE; > } > > ------------------------------------------------------------------------ > /* > * dirent.h > */ > > #ifndef _DIRENT_H > # define _DIRENT_H > > # include <sys/types.h> > # include <limits.h> > > #define MAXNAMLEN 255 /* maximum filename length */ > > #ifndef NAME_MAX > #define NAME_MAX (MAXNAMLEN - 1) > #endif > > struct dirent /* data from getdents()/readdir() */ > { > ino_t d_ino; /* inode number of entry */ > off_t d_off; /* offset of disk directory entry */ > wchar_t d_reclen; /* length of this record */ > char d_name[MAXNAMLEN + 1]; > }; > > /* The following nonportable ugliness could have been avoided by defining > * DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments. > * There shouldn't be any problem if you avoid using the DIRENTSIZ() macro. > */ > > #define DIRENTBASESIZ (((struct dirent *)0)->d_name \ > - (char *)&((struct dirent *)0)->d_ino) > > #define DIRENTSIZ(namlen) ((DIRENTBASESIZ + sizeof(long) + (namlen)) \ > / sizeof(long) * sizeof(long)) > > # ifndef _BOOL_T_DEFINED > typedef unsigned char bool; > # define _BOOL_T_DEFINED > # endif > > # define DIRBUF 8192 /* buffer size for fs-indep. dirs */ > /* must in general be larger than the */ > /* filesystem buffer size */ > > struct _dircontents { > char *_d_entry; > struct _dircontents *_d_next; > }; > > typedef struct _dirdesc { > int dd_id; /* uniquely identify each open directory */ > long dd_loc; /* where we are in directory entry is this */ > struct _dircontents *dd_contents; /* pointer to contents of dir */ > struct _dircontents *dd_cp; /* pointer to current position */ > } DIR; > > #if defined (__STDC__) > # define _PROTO(p) p > #else > # define _PROTO(p) () > # undef const > # undef volatile > #endif > > /* Functions */ > > extern DIR * opendir _PROTO ((const char *)); > extern struct dirent * readdir _PROTO ((DIR *)); > extern void rewinddir _PROTO ((DIR *)); > > extern int closedir _PROTO ((DIR *)); > extern void seekdir _PROTO ((DIR *, off_t)); > extern off_t telldir _PROTO ((DIR *)); > > extern int chdir _PROTO ((const char *)); > extern char * getcwd _PROTO ((char *, size_t)); > > extern int mkdir _PROTO ((const char *)); > > extern int rmdir _PROTO ((const char *)); > extern int scandir _PROTO ((char *, > struct dirent ***, > int (*)(const void *, const void *), > int (*)(const void *, const void *))); > > extern int _chdrive _PROTO ((int)); > extern int _getdrive _PROTO ((void)); > extern char * _getdcwd _PROTO ((int, char *, int)); > > extern bool IsHPFSFileSystem _PROTO ((char *)); > > #endif _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com |
From: <dan...@ya...> - 2001-08-23 21:16:41
|
--- Earnie Boyd <ear...@ya...> wrote: > HPFS is dead. Which ever you feel best with. > > Yes, I did some googling after last message. In fact, the alternative dirent.c doesn't really support HPFS. It just checks for case-senitive or case-preserving file system, and if not it lower-cases everthing. It's not worth it. What I've done in the end: taken some bits out of the alternative dirent and incorporated in current one. This has the main advantage of keeping the public interface (dirent.h) constant. The alternative dirent.h had some ugly bits. I've also silenced opendir() and readdir() when it tries to access an empty removeable drive. That behaviour can be changed by a macro definition at compile time. The other alternative is to have a runtime switch: enable SEM dialogs if in GUI mode, disable if stderr is the console. I will submit patch to SF in a few minutes. Danny _____________________________________________________________________________ http://shopping.yahoo.com.au - Father's Day Shopping - Find the perfect gift for your Dad for Father's Day |