home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
graf
/
macpnt1.zip
/
WILDCARD.C
< prev
next >
Wrap
Text File
|
1987-01-16
|
7KB
|
250 lines
/*
******************************************************************
* WILDCARD.C - routine to handle expansion of paths that may include
* wildcards in the filename. This routine was developed for MACPAINT
* in Jan 1987 by Joan Riff, but is self-contained and can be included
* in other packages relatively easily. Like MACPAINT.C, it is written
* for Microsoft C, version 3.0.
*
*
* (c) Copyright 1987 by:
*
* Computerwise Consulting Services
* P.O. Box 813
* McLean, VA 22101
* (703) 280-2809
*
* All rights reserved.
*
* Permission is granted for personal use of this program, with the
* exception that the following potential users ARE EXPLICITLY DENIED
* PERMISSION TO RECEIVE, USE, OR TRANSFER THIS PROGRAM IN SOURCE OR
* OBJECT OR EXECUTABLE OR ANY OTHER FORM:
*
* 1) Lotus Development Corporation, and any employee thereof
* or consultant thereto;
*
* 2) ADAPSO, and any firm which is a member thereof, or any
* employee of such a firm.
*
* These two organizations have - in the opinion of CCS - acted as
* "software pirates" by continually and intentionally violating
* U.S. Copyright law, specifically by first "copy-protecting" software
* disks and then zealously prosecuting innocent users who exercised
* their rights under the law to make copies of their own property.
*
* Further, permission is granted to transfer this program only if
* it is transferred absolutely unmodified in any form.
*
******************************************************************
*/
/*
* Handle wildcard paths.
*
* Use of this routine is a two-part process.
*
* In the first part, you call this routine with a func of 0, a path, and
* an attribute byte. The func of zero says "init yourself for subsequent
* calls". The path is the plain old path as a user may have typed it in.
* It may or may not contain wildcards "*" and "?", but if they are present
* then they had better reside ONLY in the filename part of the path. The
* attribute byte allows the caller to specify exactly what he's looking
* for:
*
* Bit 0: Include Read-only files
* Bit 1: Include Hidden files
* Bit 2: Include System files
* Bit 3: Search for the Volume Label. To use this, no other bits may
* be set, and the path must identify some root directory.
* Bit 4: Include directories
* Bit 5: Include Archiveable files
*
* This routine then remembers all of this for later use, and returns NULL.
*
* In the second part, you call this routine with a func of 1 and dummy values
* for the path and attribute. It then returns the complete pathname of a
* file that matches your original pattern, or NULL of no more matches are
* found. If the name being returned is the name of a directory, then this
* routine appends a "\" character to the name.
*
* This second part is repeated until this routine returns a NULL. After each
* call you may do whatever you want to do with the returned filename before
* calling this routine again.
*
*/
BYTE *wildcard( func, path, attrib )
int func; /* 0 (seed things) or 1 (return a name) */
BYTE *path; /* Raw input pathname (only if func = 0) */
BYTE attrib; /* Attribute bits (only if func = 0) */
{
static struct
{
BYTE reserved[21];
BYTE attribute;
unsigned time;
unsigned date;
unsigned long size;
BYTE filename[13];
BYTE filler[85];
}
dta;
static BYTE directory[65];
static BYTE filename[15];
static BYTE result[90];
BYTE *p;
static unsigned user_attrib; /* Saved attrib */
static int first = -1; /* Need "find first" ? */
static union REGS inregs, outregs; /* For intdosx() */
static struct SREGS segregs;
static int seeded = 0; /* Are we seeded for another search? */
if (func == 0)
{
/*
* Seed things for subsequent searches
*/
memcpy(directory, path, 64); /* Save raw path */
directory[64] = '\0'; /* Truncate to be safe */
/*
* Look for a divider between directory and filename
*/
p = strrchr(directory, '\\'); /* Try '\' first */
if ( p == NULL )
{
p = strrchr( directory, ':' ); /* No '\', so try for ':' */
}
if ( p == NULL ) /* Any delimiter? */
{
/*
* No delimiter found. Assume that path was just
* a filename.
*/
memcpy( filename, directory, 13 );
directory[0] = '\0';
filename[12] = '\0';
}
else
{
/*
* We found a delimiter. Keep everything up to it
* so that we can prepend this to found filenames,
* but copy everything after it as the prototype
* filename pattern.
*/
memcpy(filename, ++p, 13);
filename[12] = '\0';
*p = '\0';
}
/*
* Set flags for later use
*/
seeded = -1; /* Enable search */
first = -1; /* Need "find first" */
user_attrib = attrib; /* Save his attribute byte */
return(NULL);
}
/*
* Not a "seed things" call, so get set to return a matching filename.
*/
if ( !seeded )
{
/*
* Last try failed, so why even try again
*/
return(NULL);
}
/*
* Point DOS's opinion of the current DTA to our own DTA
*/
p = (BYTE *) &dta; /* So that we can use FP_SEG() and FP_OFF() */
segregs.ds = FP_SEG(p);
inregs.x.dx = FP_OFF(p);
inregs.h.ah = 0x1a;
intdosx( &inregs, &outregs, &segregs);
/*
* Set up regs for either a "find first" or a "find next"
*/
if ( first )
{
first = 0;
/*
* We need to do a "find first". Construct original pathname
* from directory and filename. This is what DOS uses as a
* starting point. From then on, it uses info in the DTA.
*/
sprintf( result, "%s%s", directory, filename );
p = result; /* So that we can use FP_SEG() and FP_OFF() */
segregs.ds = FP_SEG(p);
inregs.x.dx = FP_OFF(p);
inregs.x.cx = user_attrib;
inregs.h.ah = 0x4e;
}
else
{
/*
* We are to do a "find next". All info is in the DTA.
*/
inregs.h.ah = 0x4f;
}
/*
* Now ask DOS for the first or next matching file.
*/
intdosx( &inregs, &outregs, &segregs );
if ( outregs.x.cflag ) /* Error? */
{
seeded = 0; /* Yes, remember this */
return(NULL);
}
/*
* Put the filename returned by DOS together with our original
* directory, to give the user something that he can call OPEN with.
*/
sprintf( result, "%s%s", directory, dta.filename );
if ( dta.attribute & 0x10 ) /* Directory? */
{
strcat( result, "\\"); /* Yes, add '\' to end */
}
return( result );
}