home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
099
/
SH164AS.ZIP
/
LIB
/
DIRECTOR.C
next >
Wrap
C/C++ Source or Header
|
1992-02-28
|
4KB
|
201 lines
/*
* @(#)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.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <dirent.h>
#include <dos.h>
#define ATTRIBUTES (_A_SUBDIR | _A_HIDDEN | _A_SYSTEM | \
_A_NORMAL | _A_RDONLY | _A_ARCH)
typedef struct _dircontents DIRCONT;
static void free_dircontents (DIRCONT *);
DIR *opendir(name)
char *name;
{
struct stat statb;
DIR *dirp;
char *last;
DIRCONT *dp;
char *nbuf;
struct find_t dtabuf;
int len = strlen (name);
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 */
if (stat (nbuf, &statb) < 0)
{
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, "*.*");
dirp->dd_loc = 0;
dirp->dd_cp = (DIRCONT *) NULL;
dirp->dd_contents = (DIRCONT *) NULL;
if (_dos_findfirst (nbuf, ATTRIBUTES, &dtabuf) != 0)
{
free (nbuf);
return dirp;
}
do
{
if (((dp = (DIRCONT *) malloc (sizeof (DIRCONT))) == (DIRCONT *)NULL) ||
((dp->_d_entry = strdup (dtabuf.name)) == (char *) NULL))
{
if (dp != (char *)NULL)
free ((char *)dp);
free (nbuf);
free_dircontents (dirp->dd_contents);
return (DIR *) NULL;
}
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 (_dos_findnext (&dtabuf) == 0);
dirp->dd_cp = dirp->dd_contents;
free (nbuf);
return dirp;
}
int closedir (dirp)
DIR *dirp;
{
free_dircontents (dirp->dd_contents);
free ((char *)dirp);
return 0;
}
struct dirent *readdir (dirp)
DIR *dirp;
{
static struct dirent dp;
if (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;
strlwr (dp.d_name);
return &dp;
}
void rewinddir (dirp)
DIR *dirp;
{
seekdir (dirp, (off_t)0);
}
void seekdir (dirp, off)
DIR *dirp;
off_t off;
{
long i = off;
DIRCONT *dp;
if (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;
}
off_t telldir(dirp)
DIR *dirp;
{
return dirp->dd_loc;
}
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);
}
}