Readdir, Opendir,...
David MacKenzie
edf at rocky2.rockefeller.edu
Mon Dec 26 15:16:48 AEST 1988
My last message should have specified that the GNU tar contains a
public domain *MS-DOS* implementation of readdir, etc. Matter of fact,
they're not that long, so here they are . . .
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by rocky2.rockefeller.edu!edf on Mon Dec 26 00:15:21 EST 1988
# Contents: msd_dir.c msd_dir.h
echo x - msd_dir.c
sed 's/^@//' > "msd_dir.c" <<'@//E*O*F msd_dir.c//'
/*
* @(#)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 at garfield),
* August 1897
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <malloc.h>
#include <string.h>
#include <dos.h>
#ifndef NULL
# define NULL 0
#endif /* NULL */
#ifndef MAXPATHLEN
# define MAXPATHLEN 255
#endif /* MAXPATHLEN */
/* attribute stuff */
#define A_RONLY 0x01
#define A_HIDDEN 0x02
#define A_SYSTEM 0x04
#define A_LABEL 0x08
#define A_DIR 0x10
#define A_ARCHIVE 0x20
/* dos call values */
#define DOSI_FINDF 0x4e
#define DOSI_FINDN 0x4f
#define DOSI_SDTA 0x1a
#define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
/* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */
#define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR)
/* what find first/next calls look use */
typedef struct {
char d_buf[21];
char d_attribute;
unsigned short d_time;
unsigned short d_date;
long d_size;
char d_name[13];
} Dta_buf;
static char *getdirent();
static void setdta();
static void free_dircontents();
static Dta_buf dtabuf;
static Dta_buf *dtapnt = &dtabuf;
static union REGS reg, nreg;
#if defined(M_I86LM)
static struct SREGS sreg;
#endif
DIR *
opendir(name)
char *name;
{
struct stat statb;
DIR *dirp;
char c;
char *s;
struct _dircontents *dp;
char nbuf[MAXPATHLEN + 1];
if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
return (DIR *) NULL;
if (Newisnull(dirp, DIR))
return (DIR *) NULL;
if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
(void) strcat(strcpy(nbuf, name), "\\*.*");
else
(void) strcat(strcpy(nbuf, name), "*.*");
dirp->dd_loc = 0;
setdta();
dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
if ((s = getdirent(nbuf)) == (char *) NULL)
return dirp;
do {
if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
{
if (dp)
free((char *) dp);
free_dircontents(dirp->dd_contents);
return (DIR *) NULL;
}
if (dirp->dd_contents)
dirp->dd_cp = dirp->dd_cp->_d_next = dp;
else
dirp->dd_contents = dirp->dd_cp = dp;
(void) strcpy(dp->_d_entry, s);
dp->_d_next = (struct _dircontents *) NULL;
} while ((s = getdirent((char *) NULL)) != (char *) NULL);
dirp->dd_cp = dirp->dd_contents;
return dirp;
}
void
closedir(dirp)
DIR *dirp;
{
free_dircontents(dirp->dd_contents);
free((char *) dirp);
}
struct direct *
readdir(dirp)
DIR *dirp;
{
static struct direct dp;
if (dirp->dd_cp == (struct _dircontents *) NULL)
return (struct direct *) 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;
dirp->dd_cp = dirp->dd_cp->_d_next;
dirp->dd_loc++;
return &dp;
}
void
seekdir(dirp, off)
DIR *dirp;
long off;
{
long i = off;
struct _dircontents *dp;
if (off < 0)
return;
for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
;
dirp->dd_loc = off - (i + 1);
dirp->dd_cp = dp;
}
long
telldir(dirp)
DIR *dirp;
{
return dirp->dd_loc;
}
static void
free_dircontents(dp)
struct _dircontents *dp;
{
struct _dircontents *odp;
while (dp) {
if (dp->_d_entry)
free(dp->_d_entry);
dp = (odp = dp)->_d_next;
free((char *) odp);
}
}
static char *
getdirent(dir)
char *dir;
{
if (dir != (char *) NULL) { /* get first entry */
reg.h.ah = DOSI_FINDF;
reg.h.cl = ATTRIBUTES;
#if defined(M_I86LM)
reg.x.dx = FP_OFF(dir);
sreg.ds = FP_SEG(dir);
#else
reg.x.dx = (unsigned) dir;
#endif
} else { /* get next entry */
reg.h.ah = DOSI_FINDN;
#if defined(M_I86LM)
reg.x.dx = FP_OFF(dtapnt);
sreg.ds = FP_SEG(dtapnt);
#else
reg.x.dx = (unsigned) dtapnt;
#endif
}
#if defined(M_I86LM)
intdosx(®, &nreg, &sreg);
#else
intdos(®, &nreg);
#endif
if (nreg.x.cflag)
return (char *) NULL;
return dtabuf.d_name;
}
static void
setdta()
{
reg.h.ah = DOSI_SDTA;
#if defined(M_I86LM)
reg.x.dx = FP_OFF(dtapnt);
sreg.ds = FP_SEG(dtapnt);
intdosx(®, &nreg, &sreg);
#else
reg.x.dx = (int) dtapnt;
intdos(®, &nreg);
#endif
}
@//E*O*F msd_dir.c//
chmod u=rw,g=r,o=r msd_dir.c
echo x - msd_dir.h
sed 's/^@//' > "msd_dir.h" <<'@//E*O*F msd_dir.h//'
/*
* @(#)msd_dir.h 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 at garfield),
* August 1897
*/
#define rewinddir(dirp) seekdir(dirp, 0L)
#define MAXNAMLEN 12
struct direct {
ino_t d_ino; /* a bit of a farce */
int d_reclen; /* more farce */
int d_namlen; /* length of d_name */
char d_name[MAXNAMLEN + 1]; /* garentee null termination */
};
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;
extern DIR *opendir();
extern struct direct *readdir();
extern void seekdir();
extern long telldir();
extern void closedir();
@//E*O*F msd_dir.h//
chmod u=rw,g=r,o=r msd_dir.h
exit 0
-----
David MacKenzie
Environmental Defense Fund
edf at rocky2.rockefeller.edu (...rutgers!cmcl2!rocky2!edf)
More information about the Comp.lang.c
mailing list