home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
ddjmag
/
ddj8710.arc
/
BOWLST.OCT
next >
Wrap
Text File
|
1987-09-14
|
16KB
|
518 lines
Listing 1
/*
*
* FINDCMD
*
* MODULE: MAIN.C
*
* COPYRIGHT (C) 1987 by Charles F. Bowman
* All Rights Reserved.
*
*/
/*
* This module contains the driving loop of the program.
*/
#include <stdio.h>
#include "findcmd.h"
struct attribs atts[] = { /* For display */
DIRECT, 'd',
RDONLY, 'r',
HIDDEN, 'h',
SYSTEM, 's',
ARCHIV, 'a'
};
char *month[] = {
"Jan", "Feb", "Mar",
"Apr", "May", "Jun",
"Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"
};
main( ac, av )
int ac;
char *av[];
{
int i, len;
char dir[ MAXPATH ];
char path[ MAXPATH ];
char *tptr, tpath[ MAXPATH ];
struct dirent dfile;
if( ac == 1 ){
fprintf( stderr, "usage: fc pat1 pat2 ... patn\n" );
exit( 1 );
}
printf( "FINDCMD - COPYRIGHT (C) 1987, Charles F. Bowman. " );
printf( "All Rights Reserved.\n\n" );
sprintf( path, ".;%s", getenv("PATH") ); /* Get path */
for( i = 1; i < ac; i++ ){
/*
* For each supplied pattern argument
*/
strcpy( tpath, path );
tptr = tpath;
inits( av[i] ); /* set-up transition table */
while( (len = nextdir(tptr)) > 0 ){
/*
* For each directory component
*/
tptr[ len ] = NIL;
if( tptr[len-1] == '\\' ){
/*
* No double backslashes!
*/
sprintf( dir, "%s*.*", tptr );
} else {
sprintf( dir, "%s\\*.*", tptr );
}
/*
* Compare each entry in directory
*/
if( firstf(dir, &dfile) ){ /* Get first */
/*
* Error - bad dir in path
*/
fprintf( stderr,
"BAD DIRECTORY SEGMENT: [%s]\n",
dir );
break;
}
do{
if( state(slcase(dfile.dname)) ){
/*
* Print if a match is found!
*/
putfile( &dfile, tptr );
}
} while( nextf(&dfile) ); /* Get next */
tptr += len + 1;
}
}
exit( 0 );
}
/*
* NEXTDIR: return the next directory component of 'PATH'
*/
nextdir( cp )
char *cp;
{
register count;
count = 0;
if( *cp == NIL ){ /* End of list */
return( -1 );
}
while( *cp != NIL && *cp != FLDSEP ){
cp++;
count++;
}
return( count );
}
/*
* SLCASE: convert a string to lower case
*/
char *
slcase( cp )
char *cp;
{
register char *ptr;
ptr = cp;
while( *ptr ){
*ptr = tolower( *ptr );
ptr++;
}
return( cp );
}
/*
* PUTFILE: display directory info for each matched file
*/
putfile( dfile, dir )
struct dirent *dfile;
char *dir;
{
int i;
char datestr[ 50 ];
/*
* Print attribute chatacters
*/
for( i = 0; i < SA_SIZE(atts); i++ ){
if( atts[i].val & dfile->dattr ){
putchar( atts[i].chr );
} else {
putchar( '-' );
}
}
fdosdte( datestr, &dfile->ddate ); /* DOS -> ASCII */
if( dir[strlen(dir)-1] == '\\' ){
/*
* No double backslashes!
*/
printf( " %8D %s %s%s\n",
dfile->dsize,
datestr,
slcase(dir),
dfile->dname
);
} else {
printf( " %8D %s %s\\%s\n",
dfile->dsize,
datestr,
slcase(dir),
dfile->dname
);
}
return( 0 );
}
/*
* FDOSDATE: convert a DOS format date to an ASCII string
*/
fdosdte( where, dptr )
char *where;
struct dosdate *dptr;
{
sprintf( where, "%s %2d %02d:%02d:%02d %4d",
month[ dptr->month-1 ],
dptr->day,
dptr->hour,
dptr->min,
dptr->sec * 2,
dptr->year + 1980
);
return( 0 );
}
Listing 2
/*
*
* FINDCMD
*
* MODULE: DOS.C
*
* COPYRIGHT (C) 1987 by Charles F. Bowman
* All Rights Reserved.
*
*/
/*
* This module contains the DOS dependent functions to
* access file names in directories. This is non-portable code.
*/
#include <dos.h>
#include <stdio.h>
#include "findcmd.h"
struct reg regs; /* set & retrieve regs */
static struct dirent lfile; /* DOS disk trans addr */
/*
* FIRSTF: initiate DOS environment and return first file name
*/
firstf( dirpath, dfile )
char *dirpath;
struct dirent *dfile;
{
/*
* Set disk transfer address
*/
regs.r_ax = SETDTA;
ptoreg( dsreg, regs.r_dx, regs.r_ds, &lfile );
intcall( ®s, ®s, DOSINT );
/*
* Find first
*/
regs.r_ax = NFFIRST;
regs.r_cx = HIDDEN | SYSTEM | DIRECT | RDONLY | ARCHIV; /* All! */
ptoreg( dsreg, regs.r_dx, regs.r_ds, dirpath );
intcall( ®s, ®s, DOSINT );
if( regs.r_flags & F_CF ){
/*
* Error!
*/
return( 1 );
}
*dfile = lfile;
return( 0 );
}
/*
* NEXTF: return all subsequent files in directory
*/
nextf( dfile )
struct dirent *dfile;
{
/*
* Call DOS: find next
*/
regs.r_ax = NFNEXT;
regs.r_cx = HIDDEN | SYSTEM | DIRECT | RDONLY | ARCHIV;
intcall( ®s, ®s, DOSINT );
if( regs.r_flags & F_CF ){
/*
* Error!
*/
return( 0 );
}
*dfile = lfile;
return( 1 );
}
Listing 3
/*
*
* FINDCMD
*
* MODULE: STATE.C
*
* COPYRIGHT (C) 1987 by Charles F. Bowman
* All Rights Reserved.
*
*/
/*
* This module contains the routines nesessary
* to implement the state machine
*/
#include <stdio.h>
#include "findcmd.h"
static int tos = -1;
static int pat[ 100 ];
static struct stk stk[ 100 ];
/*
* INITS: initialize the state machine (transition table)
*/
inits( p )
char *p;
{
register int i;
i = 1;
pat[0] = PATBEG;
while( *p != NIL ){
/*
* Add each char in pattern to state array
*/
switch( *p ){
case '?':
pat[i] = QUEST;
break;
case '*':
pat[i] = ASTER;
break;
default:
pat[i] = *p;
break;
}
p++;
i++;
}
pat[i] = PATEND;
return( 0 );
}
/*
* STATE: driving routine for the state machine;
* performs the actual pattern matching.
*/
state( n )
char *n;
{
register int state;
char *ptr;
ptr = n;
tos = -1;
state = 0;
for(;;){ /* Forever */
switch( pat[state] ){
case PATBEG: /* Begin state */
break;
case ASTER: /* Wild card */
if( *(ptr+1) != NIL ){
/*
* Save machine state
*/
PUSH( state-1, ptr+1 );
}
while( (*ptr != pat[state+1]) && (*ptr != NIL) ){
/*
* Skip non-matching chars
* up to end of string
*/
ptr++;
}
break;
case PATEND: /* End state */
if( *ptr == NIL ){
/*
* Match!
*/
return( 1 );
} else if( TOS ){
/*
* No match - restore saved state
*/
POP( state, ptr );
} else {
/*
* No match!
*/
return( 0 );
}
break;
case QUEST: /* Any 1 character */
ptr++;
break;
default:
if( *ptr != pat[state] ){
if( TOS ){
/*
* Restore saved state
*/
POP( state, ptr );
} else {
/*
* Fail - no match!
*/
return( 0 );
}
} else {
/*
* Equal - move on
*/
ptr++;
}
break;
}
state++; /* Next state */
}
}
Listing 4
/*
*
* FINDCMD
*
* MODULE: FINDCMD.H
*
* COPYRIGHT (C) 1987 by Charles F. Bowman
* All Rights Reserved.
*
*/
/*
* Header file for FINDCMD.C
*/
#define NIL '\0'
#define FLDSEP ';' /* dir separator in path */
#define MAXPATH 250
/*
* Machine states
*/
#define ASTER 128
#define QUEST 129
#define PATBEG 130
#define PATEND 131
/*
* DOS file attribute bits
*/
#define RDONLY 0x01 /* Read only file */
#define HIDDEN 0x02 /* Hidden file */
#define SYSTEM 0x04 /* System file */
#define DIRECT 0x10 /* Directory file */
#define ARCHIV 0x20 /* Archive bit */
#define SA_SIZE(foo) (sizeof(foo)/sizeof(foo[0]))
/*
* Macros for stack manipulation
*/
#define TOS (tos == -1 ? 0 : 1)
#define POP(x,y) {x = stk[tos].state; y = stk[tos].ptr; tos--; }
#define PUSH(x,y) { tos++; stk[tos].state = (x); stk[tos].ptr = (y); }
char *slcase();
/*
* Internal DOS date structure
*/
struct dosdate {
unsigned sec : 5; /* Second (intervals of 2) */
unsigned min : 6; /* Minutes */
unsigned hour : 5; /* Hours */
unsigned day : 5; /* Day of month */
unsigned month : 4; /* Month of year */
unsigned year : 7; /* Year since 1980 */
};
/*
* DOS FCB / DIR ENTRY - Set to DTA
*/
struct dirent {
char dinfo[ 21 ];
char dattr;
struct dosdate ddate;
long dsize;
char dname[ 13 ];
};
/*
* Used to print attribute bits of files
*/
struct attribs {
int val;
int chr;
};
/*
* Used to save an restore machine state
*/
struct stk {
int state;
char *ptr;
};