home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
xdir1.exe
/
DIR.C
next >
Wrap
Text File
|
1995-08-29
|
13KB
|
556 lines
/****************************************************************************
** File: DIR.C
**
** Desc: Sample code showing how to do a recursive subdirectory search.
**
** Disclaimer:
**
** Novell, Inc. makes no representations or warranties with respect to
** any NetWare software, and specifically disclaims any express or
** implied warranties of merchantability, title, or fitness for a
** particular purpose.
**
** Distribution of any NetWare software is forbidden without the
** express written consent of Novell, Inc. Further, Novell reserves
** the right to discontinue distribution of any NetWare software.
**
** Novell is not responsible for lost profits or revenue, loss of use
** of the software, loss of data, costs of re-creating lost data, the
** cost of any substitute equipment or program, or claims by any party
** other than you. Novell strongly recommends a backup be made before
** any software is installed. Developer support for this software
** may be provided at the discretion of Novell.
**
** QMK386 options used:
**
** None
**
** Programmers:
**
** Ini Who Firm
** -----------------------------------------------------------------------
** ABJ Adam B. Jerome Novell Developer Support.
**
** History:
**
** When Who What
** -----------------------------------------------------------------------
** 08-28-95 ABJ First code.
*/
/****************************************************************************
** Compiler setup
*/
/*------------------------------------------------------------------------
** ANSI
*/
#include <stdlib.h> /* malloc() free() */
#include <stdio.h> /* stdout, vfprintf(), printf() */
#include <string.h> /* strrchr(), strupr(), strlen(), strcat(), strcpy() */
#include <errno.h> /* ESUCCESS, ENOMEM, EFAILURE, errno */
#include <stdarg.h> /* va_list */
#include <conio.h> /* kbhit(), getch() */
#include <signal.h> /* signal(), SIGTERM, SIGINT */
/*------------------------------------------------------------------------
** NetWare
*/
#include <nwdir.h> /* opendir(), readdir(), closedir(), DIR, _A_NORMAL, ...*/
#include <niterror.h> /* NetWareErrno */
#include <process.h> /* ThreadSwitchWithDelay() */
/****************************************************************************
** Globals
*/
int NLM_exiting = FALSE;
int NLM_threadCnt = 0;
int NLM_pause = FALSE;
int NLM_subSearch = FALSE;
/****************************************************************************
** Paste two path fragments into a malloced buffer.
*/
char *NLM_PastePath(char *frag1, char *frag2)
{
char *cp;
char *fullPath;
fullPath=malloc(strlen(frag1) + 1 + strlen(frag2) + 1);
if(fullPath == NULL) return(NULL);
strcpy(fullPath, frag1);
/*------------------------------------------------------------------------
** Locate the last character of the string.
*/
cp=fullPath;
while(*cp) ++cp;
if(cp > fullPath) --cp;
if((*cp != '\\') && (*cp != '/') && (*cp != ':') && (*fullPath != '\0'))
strcat(fullPath, "\\");
strcat(fullPath, frag2);
return(fullPath);
}
/****************************************************************************
** Parse the specified path into drive:path and wildcard.
*/
int NLM_ParsePath(char *fullPath, char **path, char **wild)
{
int cCode=ESUCCESS;
char *cp;
char ch;
cp=strrchr(fullPath, '\\');
if(cp==NULL) cp=strrchr(fullPath, '/');
if(cp==NULL) cp=strrchr(fullPath, ':');
/*-----------------------------------------------------------------------
** No path, just a wild.
*/
if(cp == NULL)
{
*path=malloc(1);
if(*path == NULL)
{
cCode=ENOMEM;
goto END;
}
**path='\0';
*wild=malloc(strlen(fullPath)+1);
if(*wild == NULL)
{
free(*path);
cCode=ENOMEM;
goto END;
}
strcpy(*wild, fullPath);
goto END;
}
*wild=malloc(strlen(&cp[1]) +1);
if(*wild == NULL)
{
cCode=ENOMEM;
goto END;
}
strcpy(*wild, &cp[1]);
if((*cp == '\\') || (*cp == '/'))
if(cp > fullPath)
{
--cp;
if(*cp == ':') cp += 2;
else ++cp;
}
ch = *cp;
*cp = '\0';
*path=malloc(strlen(fullPath) + 1 + 1);
if(*path == NULL)
{
free(*wild);
cCode=ENOMEM;
goto END;
}
strcpy(*path, fullPath);
*cp=ch;
END:
if(cCode == ESUCCESS)
{
strupr(*path);
strupr(*wild);
}
return(cCode);
}
/****************************************************************************
** Print a line on the screen, printf() compatable.
*/
int NLM_PrintLine(char *format, ...)
{
int charCnt;
int ch;
va_list argList;
static lineCnt = 0;
va_start(argList, format);
charCnt=vfprintf(stdout, format, argList);
va_end(argList);
printf("\n");
++lineCnt;
if((lineCnt == 24) && (NLM_pause))
{
lineCnt = 0;
printf(">>> C=Continuous ESC=Quit AnyOtherKey=More <<<");
while((!kbhit()) && (!NLM_exiting))
ThreadSwitchWithDelay();
while(kbhit())
ch=getch();
/*---------------------------------------------------------------------
** Handle special keys:
*/
switch(ch)
{
case 27: /* ESCAPE */
NLM_exiting=TRUE;
break;
case 'C': /* Continuous */
case 'c':
NLM_pause = FALSE;
break;
}
printf("\r");
printf(" ");
printf("\r");
}
return(charCnt);
}
/****************************************************************************
** Recursive Directory listing.
*/
int NLM_Dir(char *path, char *wild, unsigned long searchAttributes)
{
int cCode=ESUCCESS;
char *tempPath;
struct dirent *de;
DIR *dir;
/*------------------------------------------------------------------------
** Scan for non-directories.
*/
tempPath=NLM_PastePath(path, wild);
if(tempPath == NULL)
{
printf("ERROR: NLM_PastePath() reports NULL return value.\n");
return(EFAILURE);
}
if((searchAttributes & _A_SUBDIR) != _A_SUBDIR)
{
NLM_PrintLine("");
NLM_PrintLine("%s", tempPath);
}
else
NLM_PrintLine("%s", path);
dir=opendir(tempPath);
if(dir == NULL)
{
/*---------------------------------------------------------------------
** Error recovery.
*/
if((errno == 1) && (NetWareErrno == 255))
/* This simply indicates that the directory was empty */;
else
{
printf("ERROR: opendir(\"%s\") reports NULL return value.\n", tempPath);
printf("\"\"\"\"\": errno=%d NetWareErrno= %d\n", errno, NetWareErrno);
free(tempPath);
return(EFAILURE);
}
}
free(tempPath);
cCode=SetReaddirAttribute(
/* I- dirP */ dir,
/* I- newAttribute */ searchAttributes
);
if(cCode != ESUCCESS)
{
printf("ERROR: SetReaddirAttribute() reports %d.\n", cCode);
goto END_ERR;
}
de=readdir(dir);
while((de != NULL) && (!NLM_exiting))
{
if(!(de->d_attr & _A_SUBDIR))
{
NLM_PrintLine("%-12.12s %10lu %02d-%02d-%02d %2d:%02d",
de->d_name,
de->d_size,
(de->d_date & 0x01E0) >> 5, /* Month */
de->d_date & 0x001F, /* Day */
(de->d_date >> 9) + 80, /* Year */
de->d_time >> 11, /* Hour */
(de->d_time & 0x07E0) >> 5 /* Minute*/
);
}
de=readdir(dir);
}
closedir(dir);
if(!NLM_subSearch)
return(ESUCCESS);
/*------------------------------------------------------------------------
** Scan for directories.
*/
tempPath=NLM_PastePath(path, "*.*");
if(tempPath == NULL)
{
printf("ERROR: NLM_PastePath() reports NULL return value.\n");
return(EFAILURE);
}
dir=opendir(tempPath);
if(dir == NULL)
{
/*---------------------------------------------------------------------
** Error recovery.
*/
if((errno == 1) && (NetWareErrno == 255))
/* This simply indicates that the directory was empty */;
else
{
printf("ERROR: opendir(\"%s\") reports NULL return value.\n", tempPath);
printf("\"\"\"\"\": errno=%d NetWareErrno= %d\n", errno, NetWareErrno);
free(tempPath);
return(EFAILURE);
}
}
free(tempPath);
cCode=SetReaddirAttribute(
/* I- dirP */ dir,
/* I- newAttribute */ searchAttributes
);
if(cCode != ESUCCESS)
{
printf("ERROR: SetReaddirAttribute() reports %d.\n", cCode);
goto END_ERR;
}
de=readdir(dir);
while((de != NULL) && (!NLM_exiting))
{
if(de->d_attr & _A_SUBDIR)
{
tempPath=NLM_PastePath(path, de->d_name);
NLM_Dir(tempPath, wild, searchAttributes);
free(tempPath);
}
de=readdir(dir);
}
closedir(dir);
END_ERR:
return(cCode);
}
/****************************************************************************
** Signal handler.
*/
void NLM_SignalHandler(int sig)
{
switch(sig)
{
case SIGTERM:
NLM_exiting = TRUE;
while(NLM_threadCnt)
ThreadSwitchWithDelay();
break;
case SIGINT:
NLM_exiting = TRUE;
signal(SIGINT, NLM_SignalHandler);
break;
default:
break;
}
return;
}
/****************************************************************************
** Program help
*/
void NLM_Help(void)
{
printf("\n");
printf("Usage: LOAD DIR {path}wildcard {:[parameters]}\n");
printf("\n");
printf("Parameters:\n");
printf("\n");
printf(" :P Pause display.\n");
printf(" :S Search Sub-directories.\n");
printf(" :R Search Read-Only files.\n");
printf(" :H Search Hidden files.\n");
printf(" :B Search System files.\n");
printf(" :V Search Volume ID entry.\n");
printf(" :A Search Archive files.\n");
printf(" :X List only directories.\n");
printf("\n");
printf("Example: LOAD DIR sys:system\\*.*\n");
printf("\n");
return;
}
/****************************************************************************
** Program start
*/
void main(int argC, char *argV[])
{
char *wild = NULL;
char *path = NULL;
unsigned long searchAttributes = _A_NORMAL;
unsigned rVal;
int nCnt;
++NLM_threadCnt;
/*------------------------------------------------------------------------
** Register signal handlers.
*/
signal(SIGTERM, NLM_SignalHandler);
signal(SIGINT, NLM_SignalHandler);
/*------------------------------------------------------------------------
** Parse command line.
**
** Discourse:
**
** ABJ 8-29-95 You may be wondering why I chose the ':' character to
** prefix each parameter on the (user) command line. It
** is perhaps more common to use other characters such as
** '/', '\', or '-'. Those more commonly used characters
** are all legal characters for a path specification.
** Although the ':' character is also a legal character,
** it never appears as the first character of a path.
** Therefore the ':'is perfect as a parameter prefix. As
** the logic below shows, it makes parsing a user command
** line very easy, and allows the parameters (including
** the path) to be specified in any order.
*/
for(nCnt=1; nCnt < argC; ++nCnt)
{
if(argV[nCnt][0] != ':')
{
if(path != NULL) /* Path already specified? */
{
NLM_Help();
goto END_ERR;
}
rVal=NLM_ParsePath(argV[1], &path, &wild);
if(rVal != ESUCCESS)
{
printf("ERROR: NLM_ParsePath() indicates %d\n", rVal);
goto END_ERR;
}
continue;
}
switch(argV[nCnt][1])
{
case 'P':
case 'p':
NLM_pause=TRUE;
break;
case 'S':
case 's':
NLM_subSearch=TRUE;
break;
case 'X':
case 'x':
NLM_subSearch=TRUE;
searchAttributes |= _A_SUBDIR;
break;
case 'R':
case 'r':
searchAttributes |= _A_RDONLY;
break;
case 'H':
case 'h':
searchAttributes |= _A_HIDDEN;
break;
case 'B':
case 'b':
searchAttributes |= _A_SYSTEM;
break;
case 'V':
case 'v':
searchAttributes |= _A_VOLID;
break;
case 'A':
case 'a':
searchAttributes |= _A_ARCH;
break;
default:
NLM_Help();
goto END_ERR;
}
}
/*------------------------------------------------------------------------
** Validate parameters.
*/
if(path == NULL)
{
NLM_Help();
goto END_ERR;
}
/*------------------------------------------------------------------------
** Perform directory search.
*/
NLM_Dir(path, wild, searchAttributes);
NLM_PrintLine("");
END_ERR:
/*------------------------------------------------------------------------
** Free up resources.
*/
if(path != NULL)
free(path);
if(wild != NULL)
free(wild);
--NLM_threadCnt;
return;
}