From ae5d181b854d3ccb373b6bc01b4869e44ff4d87a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 18:37:15 +0200 Subject: Adding upstream version 2.9.0dev.12. Signed-off-by: Daniel Baumann --- lib/dirent.c | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/dirent.h | 53 +++++++++++ 2 files changed, 346 insertions(+) create mode 100644 lib/dirent.c create mode 100644 lib/dirent.h (limited to 'lib') diff --git a/lib/dirent.c b/lib/dirent.c new file mode 100644 index 0000000..373ba31 --- /dev/null +++ b/lib/dirent.c @@ -0,0 +1,293 @@ +/* + * $LynxId: dirent.c,v 1.7 2018/02/17 17:52:45 tom Exp $ + * + * dir.c for MS-DOS by Samuel Lam , June/87 + */ + +/* #ifdef WIN32 */ +/* + * @(#)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 + * Ported to OS/2 by Kai Uwe Rommel + * December 1989, February 1990 + * Ported to Windows NT 22 May 91 + * other mods Summer '92 brianmo@microsoft.com + * opendirx() was horribly written, very inefficient, and did not take care + * of all cases. It is still not too clean, but it is far more efficient. + * Changes made by Gordon Chaffee (chaffee@bugs-bunny.cs.berkeley.edu) + */ + +/*Includes: + * crt + */ +#ifdef HAVE_CONFIG_H +#include "lynx_cfg.h" +#endif + +#ifndef __GNUC__ +#pragma warning (disable : 4100) /* unreferenced formal parameter */ +#pragma warning (disable : 4127) /* conditional expression is constant */ +#pragma warning (disable : 4201) /* nameless struct/union */ +#pragma warning (disable : 4214) /* bit field types other than int */ +#pragma warning (disable : 4310) /* cast truncates constant value */ +#pragma warning (disable : 4514) /* unreferenced inline function has been removed */ +#pragma warning (disable : 4996) /* This function or variable may be unsafe. ... */ +#endif + +#include +#include +#include +#include +#include + +#include "dirent.h" + +#define stat _stat + +/* + * NT specific + */ +#include + +/* + * random typedefs + */ +#define HDIR HANDLE +#define HFILE HANDLE +#define PHFILE PHANDLE + +#ifndef INVALID_HANDLE_VALUE +#define INVALID_HANDLE_VALUE ((HDIR) 0xffffffff) +#endif + +/* + * local functions + */ +static char *getdirent(char *); +static void free_dircontents(struct _dircontents *); + +static HDIR FindHandle; +static WIN32_FIND_DATA FileFindData; + +static struct dirent dp; + +DIR *opendirx(char *name, char *pattern) +{ + struct stat statb; + DIR *dirp; + char c; + char *s; + struct _dircontents *dp; + int len; + int unc; + char path[OFS_MAXPATHNAME]; + register char *ip, *op; + + for (ip = name, op = path;; op++, ip++) { + *op = *ip; + if (*ip == '\0') { + break; + } + } + len = (int) (ip - name); + if (len > 0) { + unc = ((path[0] == '\\' || path[0] == '/') && + (path[1] == '\\' || path[1] == '/')); + c = path[len - 1]; + if (unc) { + if (c != '\\' && c != '/') { + path[len] = '/'; + len++; + path[len] = '\0'; + } + } else { + if ((c == '\\' || c == '/') && (len > 1)) { + len--; + path[len] = '\0'; + + if (path[len - 1] == ':') { + path[len] = '/'; + len++; + path[len] = '.'; + len++; + path[len] = '\0'; + } + } else if (c == ':') { + path[len] = '.'; + len++; + path[len] = '\0'; + } + } + } else { + unc = 0; + path[0] = '.'; + path[1] = '\0'; + len = 1; + } + + if (stat(path, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) { + return NULL; + } + dirp = malloc(sizeof(DIR)); + + if (dirp == NULL) { + return dirp; + } + c = path[len - 1]; + if (c == '.') { + if (len == 1) { + len--; + } else { + c = path[len - 2]; + if (c == '\\' || c == ':') { + len--; + } else { + path[len] = '/'; + len++; + } + } + } else if (!unc && ((len != 1) || (c != '\\' && c != '/'))) { + path[len] = '/'; + len++; + } + strcpy(path + len, pattern); + + dirp->dd_loc = 0; + dirp->dd_contents = dirp->dd_cp = NULL; + + if ((s = getdirent(path)) == NULL) { + return dirp; + } + do { + if (((dp = malloc(sizeof(struct _dircontents))) == NULL) || + ((dp->_d_entry = malloc(strlen(s) + 1)) == NULL)) { + if (dp) + free(dp); + free_dircontents(dirp->dd_contents); + + return NULL; + } + if (dirp->dd_contents) + dirp->dd_cp = dirp->dd_cp->_d_next = dp; + else + dirp->dd_contents = dirp->dd_cp = dp; + + strcpy(dp->_d_entry, s); + dp->_d_next = NULL; + + } + while ((s = getdirent(NULL)) != NULL); + + dirp->dd_cp = dirp->dd_contents; + return dirp; +} + +DIR *opendir(char *name) +{ + return opendirx(name, "*"); +} + +void closedir(DIR *dirp) +{ + free_dircontents(dirp->dd_contents); + free(dirp); +} + +struct dirent *readdir(DIR *dirp) +{ + /* static struct dirent dp; */ + if (dirp->dd_cp == NULL) + return NULL; + + /*strcpy(dp.d_name,dirp->dd_cp->_d_entry); */ + + dp.d_name = dirp->dd_cp->_d_entry; + + dp.d_namlen = dp.d_reclen = + (int) strlen(dp.d_name); + + dp.d_ino = (ino_t) (dirp->dd_loc + 1); /* fake the inode */ + + dirp->dd_cp = dirp->dd_cp->_d_next; + dirp->dd_loc++; + + return &dp; +} + +void seekdir(DIR *dirp, long off) +{ + long i = off; + struct _dircontents *dp; + + if (off >= 0) { + for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next) ; + + dirp->dd_loc = off - (i + 1); + dirp->dd_cp = dp; + } +} + +long telldir(DIR *dirp) +{ + return dirp->dd_loc; +} + +static void free_dircontents(struct _dircontents *dp) +{ + struct _dircontents *odp; + + while (dp) { + if (dp->_d_entry) + free(dp->_d_entry); + + dp = (odp = dp)->_d_next; + free(odp); + } +} +/* end of "free_dircontents" */ + +static char *getdirent(char *dir) +{ + int got_dirent; + + if (dir != NULL) { /* get first entry */ + if ((FindHandle = FindFirstFile(dir, &FileFindData)) + == INVALID_HANDLE_VALUE) { + return NULL; + } + got_dirent = 1; + } else /* get next entry */ + got_dirent = FindNextFile(FindHandle, &FileFindData); + + if (got_dirent) + return FileFindData.cFileName; + else { + FindClose(FindHandle); + return NULL; + } +} +/* end of getdirent() */ + +struct passwd *_cdecl getpwnam(char *name) +{ + return NULL; +} + +struct passwd *_cdecl getpwuid(int uid) +{ + return NULL; +} + +int getuid() +{ + return 0; +} + +void _cdecl endpwent(void) +{ +} + +/* #endif */ diff --git a/lib/dirent.h b/lib/dirent.h new file mode 100644 index 0000000..db59849 --- /dev/null +++ b/lib/dirent.h @@ -0,0 +1,53 @@ +/* + * @(#) dirent.h 2.0 17 Jun 91 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1987 + * + * Enhanced and ported to OS/2 by Kai Uwe Rommel; added scandir() prototype + * December 1989, February 1990 + * Change of MAXPATHLEN for HPFS, October 1990 + * + * Unenhanced and ported to Windows NT by Bill Gallagher + * 17 Jun 91 + * changed d_name to char * instead of array, removed non-std extensions + * + * Cleanup, other hackery, Summer '92, Brian Moran , brianmo@microsoft.com + */ + +#ifndef _DIRENT +#define _DIRENT + +#include + +struct dirent { + ino_t d_ino; /* a bit of a farce */ + short d_reclen; /* more farce */ + short d_namlen; /* length of d_name */ + char *d_name; +}; + +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 */ + struct _dircontents *dd_contents; /* pointer to contents of dir */ + struct _dircontents *dd_cp; /* pointer to current position */ +} DIR; + +extern DIR *opendir(char *); +extern struct dirent *readdir(DIR *); +extern void seekdir(DIR *, long); +extern long telldir(DIR *); +extern void closedir(DIR *); + +#define rewinddir(dirp) seekdir(dirp, 0L) + +#endif /* _DIRENT */ + +/* end of dirent.h */ -- cgit v1.2.3