diff options
Diffstat (limited to 'os2/director.c')
-rw-r--r-- | os2/director.c | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/os2/director.c b/os2/director.c new file mode 100644 index 0000000000..a360af712b --- /dev/null +++ b/os2/director.c @@ -0,0 +1,200 @@ +/* + * @(#)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 + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/dir.h> + +#include <stdio.h> +#include <malloc.h> +#include <string.h> + +#define INCL_NOPM +#include <os2.h> + + +int attributes = A_DIR | A_HIDDEN; + + +static char *getdirent(char *); +static void free_dircontents(struct _dircontents *); + +static HDIR hdir; +static USHORT count; +static FILEFINDBUF find; + + +DIR *opendir(char *name) +{ + struct stat statb; + DIR *dirp; + char c; + char *s; + struct _dircontents *dp; + char nbuf[MAXPATHLEN + 1]; + + strcpy(nbuf, name); + + if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') && + (strlen(nbuf) > 1) ) + { + nbuf[strlen(nbuf) - 1] = 0; + + if ( nbuf[strlen(nbuf) - 1] == ':' ) + strcat(nbuf, "\\."); + } + else + if ( nbuf[strlen(nbuf) - 1] == ':' ) + strcat(nbuf, "."); + + if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) + return NULL; + + if ( (dirp = malloc(sizeof(DIR))) == NULL ) + return NULL; + + if ( nbuf[strlen(nbuf) - 1] == '.' ) + strcpy(nbuf + strlen(nbuf) - 1, "*.*"); + else + if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') && + (strlen(nbuf) == 1) ) + strcat(nbuf, "*.*"); + else + strcat(nbuf, "\\*.*"); + + dirp -> dd_loc = 0; + dirp -> dd_contents = dirp -> dd_cp = NULL; + + if ((s = getdirent(nbuf)) == 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; + + dp -> _d_size = find.cbFile; + dp -> _d_mode = find.attrFile; + dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite); + dp -> _d_date = *(unsigned *) &(find.fdateLastWrite); + } + while ((s = getdirent(NULL)) != NULL); + + dirp -> dd_cp = dirp -> dd_contents; + + return dirp; +} + + +void closedir(DIR * dirp) +{ + free_dircontents(dirp -> dd_contents); + free(dirp); +} + + +struct direct *readdir(DIR * dirp) +{ + static struct direct dp; + + if (dirp -> dd_cp == NULL) + return NULL; + + dp.d_namlen = dp.d_reclen = + strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry)); + + strlwr(dp.d_name); /* JF */ + dp.d_ino = 0; + + dp.d_size = dirp -> dd_cp -> _d_size; + dp.d_mode = dirp -> dd_cp -> _d_mode; + dp.d_time = dirp -> dd_cp -> _d_time; + dp.d_date = dirp -> dd_cp -> _d_date; + + 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); + } +} + + +static char *getdirent(char *dir) +{ + int done; + + if (dir != NULL) + { /* get first entry */ + hdir = HDIR_CREATE; + count = 1; + done = DosFindFirst(dir, &hdir, attributes, + &find, sizeof(find), &count, 0L); + } + else /* get next entry */ + done = DosFindNext(hdir, &find, sizeof(find), &count); + + if (done == 0) + return find.achName; + else + { + DosFindClose(hdir); + return NULL; + } +} |