293 lines
5.6 KiB
C
293 lines
5.6 KiB
C
/*
|
|
* $LynxId: dirent.c,v 1.7 2018/02/17 17:52:45 tom Exp $
|
|
*
|
|
* dir.c for MS-DOS by Samuel Lam <skl@van-bc.UUCP>, 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 <windows.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys\types.h>
|
|
#include <sys\stat.h>
|
|
|
|
#include "dirent.h"
|
|
|
|
#define stat _stat
|
|
|
|
/*
|
|
* NT specific
|
|
*/
|
|
#include <stdio.h>
|
|
|
|
/*
|
|
* 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 */
|