Category : Files from Magazines
Archive   : VOL9N09.ZIP
Filename : WHEREIS.C

 
Output of file : WHEREIS.C contained in archive : VOL9N09.ZIP
/*
WHEREIS.C for OS/2 version 1.2

A file finder utility that searches the current or specified drive,
starting with the root directory (\), for the specified pathname.
Wildcard characters can be included. Long filenames are supported.
If an extended attribute name and value is also supplied, that
information is also used as a match criterion. Blanks can be
embedded in the EA value by quoting. The current version of
the program only knows how to handle length-preceded ASCII EAs.

This program does not require Microsoft or IBM Programmer's Toolkit
header files, but must be linked using LINK.EXE and DOSCALLS.LIB
from retail OS/2 version 1.2.

Compile: cl -c /Zi whereis.c
link /CO whereis,whereis,,doscalls,whereis.def;

Usage: whereis pathname [EAname=EAvalue]

Examples: whereis *.ico (match filename only)
whereis * .TYPE=Icon (match EA only)
whereis *.ico .TYPE=Icon (match both)
whereis *.txt ".TYPE=Plain Text" (match both)

Copyright (C) 1989 Ziff-Davis Communications
PC Magazine * Ray Duncan
*/

#include
#include
#include
#include

#define API unsigned extern far pascal // OS/2 API function prototypes
API DosChDir(char far *, unsigned long);
API DosFindClose(unsigned);
API DosFindFirst2(char far *, unsigned far *, unsigned, void far *,
unsigned, int far *, int, unsigned long);
API DosFindNext(unsigned, void far *, int, int far *);
API DosQPathInfo(void far *, unsigned, char far *, int, unsigned long);
API DosSelectDisk(int);
API DosWrite(unsigned, void far *, unsigned, unsigned far *);

void showfile(char far *); // local function prototypes
void schdir(char *);
void schfile(void);

#define NORM 0x00 // old file attribute bits
#define RD_ONLY 0x01
#define HIDDEN 0x02
#define SYSTEM 0x04
#define DIR 0x10
#define ARCHIVE 0x20
// EA predefined value types
#define EAT_BINARY 0x0fffe // Length-preceeded binary
#define EAT_ASCII 0x0fffd // Length-preceeded ASCII
#define EAT_BITMAP 0x0fffb // Length-preceeded bitmap
#define EAT_METAFILE 0x0fffa // Metafile
#define EAT_ICON 0x0fff9 // Length-preceeded icon
#define EAT_EA 0x0ffee // ASCIIZ name of associated EA
#define EAT_MVMT 0x0ffdf // Multi-value multi-type
#define EAT_MVST 0x0ffde // Multi-value single-type
#define EAT_ASN1 0x0ffdd // ASN.1 field

// arbitrary buffer sizes
#define SCHBUF_SIZE 4096 // size of search buffer
#define TEAVAL_SIZE 260 // max size of EA target value
#define GEALIST_SIZE 260 // max size of target GEAList
#define MAXPATHNAME 260 // max length of pathname
#define MAXFILENAME 255 // max length of filename

struct _EA { // extended attribute header
unsigned char flags; // critical flag etc.
unsigned char nsize; // length of EA name (without null)
unsigned vsize; // total size of EA value
char name[1]; } ; // EA name and value begin here

struct _EAval { // extended attribute value
unsigned type; // EA value type
unsigned size; // length of EA variable data
char data[1]; } ; // actual data begins here

struct _FEAList { // receives extended attributes
unsigned long size; // total size of structure
char data[1]; } ; // extended attributes begin here

struct _GEA { // extended attribute target name
unsigned char size; // length of name
char name[1]; } ; // actual name begins here

struct _GEAList { // holds names of EAs to get
unsigned long size; // total size of structure
struct _GEA GEA; } ; // name length and name text

struct _EAOP { // used by all EA functions
void far *pGEAList; // pointer to GEAList structure
void far *pFEAList; // pointer to FEAList structure
unsigned long oError; } ; // offset of error, if any

struct _info1 { // result buffer format for
unsigned cdate; // DosFindFirst2 info level 1
unsigned ctime;
unsigned adate;
unsigned atime;
unsigned wdate;
unsigned wtime;
long fsize;
long falloc;
unsigned fattr;
char fcount;
char fname[MAXFILENAME];
} ;

struct _info3 { // result buffer format for
struct _EAOP EAOP; // DosFindFirst2 info level 3
unsigned cdate;
unsigned ctime;
unsigned adate;
unsigned atime;
unsigned wdate;
unsigned wtime;
long fsize;
long falloc;
unsigned fattr;
long easize;
struct _EA EA;
} ;

union _sbuf {
struct _info1 info1;
struct _info3 info3;
} ;

struct _GEAList *GEAList = NULL; // pointer to EA name buffer
union _sbuf *sbuf = NULL; // pointer to search result buffer
struct _EAval *tEAval = NULL; // pointer to EA value buffer
char *tfname = NULL; // pointer to filename buffer
int count = 0; // total files matched


main(int argc, char *argv[])
{
if((argc < 2) || (argc > 3)) // check command line
{
printf("\nUsage: whereis filename [EAname=EAvalue]\n");
printf("\n EA name is case-sensitive, EA value is not.");
printf("\n Use quotes to embed blanks in EA value.\n");
printf("\nExamples: whereis *.ico");
printf("\n whereis * .TYPE=Icon");
printf("\n whereis *.ico .TYPE=Icon");
printf("\n whereis *.txt \".TYPE=Plain Text\"\n");
exit(1);
}

sbuf = malloc(SCHBUF_SIZE); // allocate buffers; note that
GEAList = malloc(GEALIST_SIZE); // these sizes are arbitrary
tEAval = malloc(TEAVAL_SIZE);
tfname = malloc(MAXFILENAME);

if((sbuf==NULL) || (GEAList==NULL) || (tEAval==NULL) || (tfname==NULL))
{
printf("\nwhereis: heap allocation error\n");
exit(1);
}

if(((strlen(argv[1])) >= 2) && ((argv[1])[1] == ':'))
{
if(DosSelectDisk(((argv[1]) [0] | 0x20) - ('a'-1)))
{
printf("\nwhereis: bad drive\n");
exit(1);
}

argv[1] += 2; // advance past drive
}

strncpy(tfname, argv[1], MAXFILENAME); // save target filename

if(argc == 3) // parse EA search target
{ // into name and value strings
strcpy(GEAList->GEA.name, strtok(argv[2], " =\x0a"));
GEAList->GEA.size = strlen(GEAList->GEA.name);
GEAList->size = GEAList->GEA.size + 6;

strcpy(tEAval->data, strtok(NULL, "\x0a"));
tEAval->size = strlen(tEAval->data);
}
else // if no EA search target
{ // supplied, force length
GEAList->GEA.size = 0; // of name and value to 0
tEAval->size = 0;
GEAList->size = sizeof(GEAList->size);
}

schdir("\\"); // start search with root

if(count == 0) // advise if no matches
printf("\nwhereis: no files\n");
}

/*
SCHDIR: search specified directory for matching files and
any other directories which can be searched recursively.
*/
void schdir(char *dirname)
{
unsigned shandle = -1; // search handle
int scount = 1; // max search matches

DosChDir(dirname, 0L); // select new directory

schfile(); // find and list files

// search for directories
if(!DosFindFirst2("*.*", // match any name
&shandle, // receives search handle
NORM|DIR, // match normal files & dirs
sbuf, // buffer receives match info
SCHBUF_SIZE, // size of search buffer
&scount, // receives match count
1, // info level 1 = no EAs
0L)) // reserved
{
do // recurse to search directories
{ // other than . and .. aliases
if((sbuf->info1.fattr & DIR) && (sbuf->info1.fname[0] != '.'))
{
schdir(sbuf->info1.fname);
DosChDir("..", 0L); // restore previous directory
}
// look for more directories
} while(DosFindNext(shandle, sbuf, SCHBUF_SIZE, &scount) == 0);
}

DosFindClose(shandle); // close search handle
}

/*
SCHFILE: search current directory for files matching supplied
filename, also matching extended attribute name and value if any.
*/
void schfile(void)
{
struct _EAval *pEAval; // pointer to EA value in sbuf
char far *pfname; // pointer to filename

unsigned shandle = -1; // search handle
int scount = 1; // max search matches

sbuf->info3.EAOP.oError = 0L; // initialize EAOP pointers
sbuf->info3.EAOP.pGEAList = GEAList;
sbuf->info3.EAOP.pFEAList = NULL;

if(!DosFindFirst2(tfname, // target filename for search
&shandle, // receives search handle
NORM, // match normal files only
sbuf, // buffer receives match info
SCHBUF_SIZE, // size of search buffer
&scount, // receives match count
3, // info level 3 = get EAs too
0L)) // reserved
{
do
{
pfname = (char far *) // calc address of filename
&sbuf->info3.easize + sbuf->info3.easize + 1;

if(tEAval->size) // if EA entered, does it match?
{
(char *) pEAval = // calc address of EA value
sbuf->info3.EA.name + sbuf->info3.EA.nsize + 1;

if((sbuf->info3.EA.vsize) &&
(pEAval->size == tEAval->size) &&
(pEAval->type == EAT_ASCII) &&
(! memicmp(pEAval->data, tEAval->data, tEAval->size)))
showfile(pfname); // EA matches, display filename
}
else showfile(pfname); // no EA entered, display filename

} while(DosFindNext(shandle, sbuf, SCHBUF_SIZE, &scount) == 0);
}

DosFindClose(shandle); // close search handle
}

/*
SHOWFILE: called with filename, displays fully qualified pathname.
*/
void showfile(char far *pfname)
{
char pathname[MAXPATHNAME]; // receives full pathname

count++; // count matched files
// qualify the filename
DosQPathInfo(pfname, 5, pathname, sizeof(pathname), 0L);
printf("%s\n", strlwr(pathname)); // and display it
}



  3 Responses to “Category : Files from Magazines
Archive   : VOL9N09.ZIP
Filename : WHEREIS.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/