home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* opendir,readdir,closedir 3
- /* SUMMARY
- /* directory search functions
- /* PROJECT
- /* dos/unix compatibility
- /* PACKAGE
- /* library routines
- /* SYNOPSIS
- /* int opendir(path)
- /* char *path;
- /*
- /* char *readdir(id)
- /* int dir;
- /*
- /* closedir(id)
- /* int id;
- /* DESCRIPTION
- /* This package provides a system-independent interface to the file system
- /* that allows a program to simultaneously scan one or more directories.
- /*
- /* The MS-DOS version accepts both forward and backward slash as
- /* field delimiter in path names.
- /*
- /* opendir() accepts a valid path and returns an id which should be used
- /* in subsequent calls of readdir()....closedir().
- /*
- /* readdir() returns a pointer to a character string with the next file in
- /* the directory associated with id, or a null pointer.
- /*
- /* closedir() terminates the directory search and deallocates
- /* memory used to keep track of `certain important data'.
- /* FUNCTIONS AND MACROS
- /* myalloc()
- /* DIAGNOSTICS
- /* opendir() returns -1 if all slots are in use.
- /* Specifying a wrong id is considered a fatal error condition.
- /* Memory allocation errors cause the program to terminate.
- /* BUGS
- /* readdir() returns a pointer to memory
- /* whose contents is overwritten with each call.
- /*
- /* Despite whatthe names suggest, these functions are not compatible
- /* with the BSD directory access routines.
- /*
- /* Does not work with unix file systems that have variable-length
- /* directory entries (BSD).
- /* AUTHOR(S)
- /* Wietse Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Mon Nov 17 19:38:19 GMT+1:00 1986
- /* LAST MODIFICATION
- /* Mon Apr 4 23:38:43 MET 1988
- /* VERSION/RELEASE
- /* 1.3
- /*--*/
-
- #include "defs.h"
- #include "dir.h"
-
- #ifdef unix
- # include <sys/types.h>
- # include <sys/dir.h>
- #endif
-
- #ifdef MSDOS
- # include <dos.h>
- # include <ctype.h>
-
- hidden void badslot(); /* forward declarations */
- hidden void lowcpy();
-
- /*
- * The Disk Transfer Area as used by MS-DOS when it finds a file name
- * during a wild-card scan.
- */
-
- #define MAXNAME 13 /* max size of MS-DOS file name + null byte */
-
- typedef struct Dta {
- char reserved[21]; /* start of dta buffer */
- char found; /* attribute found */
- short time; /* file's time */
- short date; /* file's date */
- int losize; /* low order file size */
- int hisize; /* high-order file size */
- char name[MAXNAME]; /* name of file terminated by zero byte */
- } Dta;
-
- /* macros for easy access to registers with MS-DOS system calls */
-
- #define AH regs.h.ah /* ah register */
- #define BX regs.x.bx /* bx register */
- #define CX regs.x.cx /* cx register */
- #define DX regs.x.dx /* dx register */
- #define CF regs.x.cflag /* cflag register */
- #define INT intdos(®s,®s) /* dos system call */
- #define WORD (unsigned) /* cast */
-
- #define SET_DTA(d) { AH = 0x1a; DX = WORD d; INT; }
- #define GET_DTA(d) { AH = 0x2f; INT; d = BX; }
- #define GET_1ST(f,n) { AH = 0x4e; CX = 0x10; DX = WORD n; INT; f = CF; }
- #define GET_NXT(f) { AH = 0x4f; CX = 0x10; INT; f = CF; }
-
- /* information about directory accesses is kept in a table with initially */
- /* empty slots */
-
- #define MAXSLOT 20 /* nbr of directories that can be processed */
-
- typedef struct Slot {
- unsigned int dsave; /* temp storage for disk transfer address */
- unsigned int cstat; /* MS-DOS system call return status */
- Dta dta; /* disk transfer area */
- } Slot;
-
- hidden Slot *dirslots[20]; /* slots with pointers */
-
- #endif /* MSDOS */
-
- /* opendir - set up for directory search */
-
- #ifdef MSDOS
-
- public int opendir(name)
- char *name;
- {
- register int id;
- register Slot *q;
- char buf[BUFSIZ];
- union REGS regs; /* cpu registers in system call */
- char lch;
-
- for (id = 0; id < MAXSLOT && dirslots[id]; id++)
- ; /* search first free slot */
- if (id < MAXSLOT) { /* found a free slot */
- dirslots[id] = q = (Slot *) myalloc(sizeof(Slot));
- GET_DTA(q->dsave); /* save dta address */
- SET_DTA(&q->dta); /* set to current dta */
- strcpy(buf,name); /* construct search path */
- if (*name && index("\\/:",name[strlen(name)-1]) == 0)
- strcat(buf,"/");
- strcat(buf,"*.*"); /* append wildest possible file name */
- GET_1ST(q->cstat,buf); /* start search (read one name ahead) */
- SET_DTA(q->dsave); /* restore dta address */
- return(id); /* return offset in slots table */
- } else {
- return(-1); /* no free slot available */
- }
- }
-
- #endif /* MSDOS */
-
- /* readdir - return next file in directory or null string */
-
- #ifdef unix
-
- public char *readdir(id)
- int id;
- {
- static struct direct ent[2];
-
- for (;;) {
- if (read(id,(char *) ent,sizeof(*ent)) != sizeof(*ent))
- return(0);
- if (ent[0].d_ino != 0)
- return(ent[0].d_name);
- }
- }
-
- #endif /* unix */
-
- #ifdef MSDOS
-
- public char *readdir(id)
- int id;
- {
- register Slot *q;
- union REGS regs;
- static char buf[MAXNAME];
-
- if (id < 0 || id >= MAXSLOT || (q = dirslots[id]) == 0) {
- badslot("readdir",id); /* serves you well! */
- /* NOTREACHED */
- } else if (q->cstat) {
- return(0); /* no name found */
- } else {
- lowcpy(buf,q->dta.name); /* keep name (lower case) */
- GET_DTA(q->dsave); /* save dta address */
- SET_DTA(&q->dta); /* setup to search */
- GET_NXT(q->cstat); /* for the next entry */
- SET_DTA(q->dsave); /* in the directory */
- return buf; /* return name */
- }
- }
-
- #endif /* MSDOS */
-
- /* closedir - release directory access slot */
-
- #ifdef MSDOS
-
- public int closedir(id)
- int id;
- {
- register Slot **p;
-
- if (id < 0 || id >= MAXSLOT || *(p = dirslots+id) == 0) {
- badslot("closedir",id);
- /* NOTREACHED */
- } else {
- free((char *)*p); /* deallocate slot */
- *p = 0; /* mark as unused */
- return(0);
- }
- }
-
- #endif /* MSDOS */
-
- #ifdef MSDOS
-
- /* badslot - the program is obviously corrupted. stop it. */
-
- hidden void badslot(name,id)
- char *name;
- int id;
- {
- fatal("%s: bad slot: %d\n",name,id);
- }
-
- /* lowcpy - copy string and map to lower case */
-
- hidden void lowcpy(out,in)
- char *out;
- char *in;
- {
- register char *d = out;
- register char c;
- register char *s = in;
-
- while (c = *s++)
- *d++ = isupper(c) ? tolower(c) : c;
- *d = '\0';
- }
-
- #endif /* MSDOS */
-