home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------------------------------*/
- /* FFF.COM - Fast-File-Find, a fully public domain program to search
- * for files on one or more disks (functionally similar to
- * the familiar "WHERE" program. FFF will also search inside
- * of ZIP, ARC, PKA, and ZOO archives to the first level.
- *
- * Version: 3.2.0
- * Date: January 12, 1990
- * Author: Don A. Williams
- *
- ********************* NOTICE ************************
- * Contrary to the current trend in MS-DOS software *
- * this program, for whatever it is worth, is NOT *
- * copyrighted (with the exception of the runtime *
- * library from the C compiler)! The program, in *
- * whole or in part, may be used freely in any *
- * fashion or environment desired. If you find this *
- * program to be useful to you, do NOT send any *
- * contribution to the author; in the words of Rick *
- * Conn, 'Enjoy!' However, if you make any *
- * improvements, I would enjoy receiving a copy of *
- * the modified source. I can be reached, usually *
- * within 24 hours, by messages on any of the *
- * following Phoenix, AZ systems: *
- * *
- * The Tool Shop BBS [PCBOARD] [PC-Pursuit] *
- * (602) 279-2673 1200/2400/9600 bps *
- * Technoids Anonymous [PCBOARD] *
- * (602) 899-4876 300/1200/2400 bps *
- * (602) 899-5233 *
- * (602) 786-9131 *
- * Inn On The Park [PCBOARD] *
- * (602) 957-0631 1200/2400/9600 bps *
- * Pascalaholics Anonymous [WBBS] *
- * (602) 484-9356 1200/2400 bps *
- * *
- * or: *
- * GEnie, mail address: DON-WILL *
- * CompuServ: 75410,543 *
- * *
- * Every effort has been made to avoid error and *
- * moderately extensive testing has been performed *
- * on this program, however, the author does not *
- * warrant it to be fit for any purpose or to be *
- * free from error and disclaims any liability for *
- * actual or any other damage arising from the use *
- * of this program. *
- *******************************************************
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <dos.h>
- #include <dir.h>
- #include <io.h>
-
- #define MAIN
-
- #define ON 1
- #define OFF 0
-
- #define VERSION "Version 3.2.0"
- #define VER_DATE "January 12, 1990"
-
- #include "fff.h"
- #include "queue.h"
- #include "arc.h"
- #include "zip.h"
- #include "zoo.h"
-
- void WalkTree (QUE_DEF *Q);
- int SearchQ (char *Str, QUE_DEF *Q);
- int Match (char *Str, char *Pat);
- void GetPath (QUE_DEF *Q, char *Arg);
- void PrtVerbose (char *Path, char *Name, DOS_FILE_TIME Time, DOS_FILE_DATE Date,
- long Size);
- void Usage (void);
- void ChkPage (void);
-
- void GetCurrentDisk (int *CurDisk);
- int GetCurrentDirectory (int Disk, char *CurDir);
- void ErrorExit (char *Format, ...);
- void GetProgName (char *Name, char *argv);
-
- char Path[65];
- char Temp[66];
- char Pattern[66];
- char CurDir[65];
- unsigned long Position;
- char ProgName[9];
-
- int Spaced = 0;
- int Lnno = 1;
- int TotalFiles = 0;
- int TotalMatch = 0;
-
- ARC_TYPE ArcType;
-
- struct Archives {
- char Ext[4];
- ARC_TYPE Type;
- } Arcs[6] = {
- {"ARC", arc},
- {"LZH", lzh},
- {"PAK", arc},
- {"ZIP", zip},
- {"ZOO", zoo},
- {"", none}
- };
-
- int S[6][3] = {
- {0, 0, 0}, /* Dummy */
- {0, 0, 0}, /* Arc File Stats */
- {0, 0, 0}, /* Zip File Stats */
- {0, 0, 0}, /* Zoo File Stats */
- {0, 0, 0}, /* Pak File Stats */
- {0, 0, 0} /* Lzh File Stats */
- };
-
- /*--- Option Switches --- */
-
- int ArcSwt = 1; /* Search inside of archives - default ON */
- int PageSwt = 0; /* Paginate output - default OFF */
- int VerboseSwt = 0; /* Verbose out put - default OFF */
- int QuietSwt = 0; /* Supress stats - default OFF */
- int DateSwt = 0; /* Change date formaat - default OFF */
-
-
- /*--- End Option Switches --- */
-
- char *Legend[] = {
- "NONE", "ARC", "ZIP", "ZOO", "PAK", "LZH", ""
- };
-
- char Devices[16] = "";
-
- void
- main (int argc, char *argv[]) {
- QUE_DEF Paths, PatQue;
- QUE_ENTRY *t;
- int CurDisk, i, j;
- char *p;
-
- GetProgName(ProgName, argv[0]);
- fprintf(stderr, "%s: FastFileFind - %s: %s\n", ProgName, VERSION, VER_DATE);
- InitQueue(&Paths); InitQueue(&PatQue);
- GetCurrentDisk(&CurDisk);
- CurDir[0] = (char) (CurDisk + 'A'); CurDir[1] = ':'; CurDir[2] = '\\';
- GetCurrentDirectory(0, CurDir+3);
- strupr(CurDir);
- strcpy(Path, "C:\\");
- p = getenv("FFF");
- if (p != NULL) {
- while (*p != '\0') {
- if (*p == ' ' || *p == '\t') ++p;
- else if (*p == '-') switch(tolower(*(++p))) {
- case 'a':
- ArcSwt ^= ON;
- ++p;
- break;
- case 'v':
- VerboseSwt ^= ON;
- ++p;
- break;
- case 'p':
- PageSwt ^= ON;
- ++p;
- break;
- case 'q':
- QuietSwt ^= ON;
- break;
- case 'f':
- DateSwt ^= ON;
- break;
- }
- else {
- i = strcspn(p, " :-");
- strncpy(Devices, p, i); Devices[i] = '\0';
- p += i;
- }
- }
- }
-
- if (Devices[0] == '\0') {
- Devices[0] = CurDisk + 'A';
- Devices[1] = '\0';
- }
- if (argc < 2) Usage();
- for (i=1; i < argc; ++i) {
- if (argv[i][0] == '-') {
- switch( tolower(argv[i][1]) ) {
- case 'a':
- ArcSwt ^= ON;
- break;
- case 'v':
- VerboseSwt ^= ON;
- break;
- case 'p':
- PageSwt ^= ON;
- break;
- case 'q':
- QuietSwt ^= ON;
- break;
- case 'f':
- DateSwt ^= ON;
- break;
- default:
- fprintf(stderr, "Invalid argument: %c\n", argv[i][1]);
- Usage();
- break;
- }
- continue;
- }
- else if ( (p = strrchr(argv[i], '\\')) != NULL ) {
- strcpy(Pattern, p+1);
- strupr(Pattern);
- Enque(&PatQue, Pattern);
- *(p+1) = '\0';
- }
- else if ( (p = strchr(argv[i], ':')) != NULL ) {
- strcpy(Pattern , p+1);
- strupr(Pattern);
- Enque(&PatQue, Pattern);
- *(p+1) = '\0';
- }
- else {
- strcpy(Pattern, argv[i]);
- strupr(Pattern);
- Enque(&PatQue, Pattern);
- if ( (p = Devices) != NULL) {
- while ( (*p != '\0') && (*p != ':') ) {
- Path[0] = toupper(*p++); Path[1] = ':';
- Path[2] = '\\'; Path[3] = '\0';
- Enque(&Paths, Path);
- }
- }
- else {
- Path[0] = (char) (CurDisk + 'A'); Path[1] = ':'; Path[2] = '\\';
- Path[3] = '\0';
- Enque(&Paths, Path);
- }
- continue;
- }
- GetPath(&Paths, argv[i]);
- }
- for (t = Paths.Head; t != NULL; t = t->Next) {
- strcpy(Path, t->Body);
- WalkTree(&PatQue);
- }
- if (!QuietSwt) {
- if (!Spaced) printf("\n");
- printf("Total Files = %6d Total Matched Files = %d\n", TotalFiles, TotalMatch);
- for (i=0; Legend[i][0] != '\0'; ++i) {
- if (S[i][0] != 0) {
- printf("\n%s Files = %6d ", Legend[i], S[i][0]);
- if (ArcSwt) printf("%sed Files = %6d %s Matches = %4d",
- Legend[i], S[i][1], Legend[i],
- S[i][2]);
- }
- }
- printf("\n");
- }
- }
-
- void
- WalkTree (QUE_DEF *Q) {
- extern int VerboseSwt, Spaced;
- extern struct Archives Arcs[6];
-
- int Status, Reply, i;
- QUE_DEF Direc;
- QUE_ENTRY *t, *u;
- char *p;
- struct ffblk DirBlk;
- DOS_FILE_TIME Time;
- DOS_FILE_DATE Date;
-
- InitQueue(&Direc);
- strcat(Path, "*.*");
- Status = findfirst(Path, &DirBlk, 0xFF);
- *(strrchr(Path, '\\')+1) = '\0';
- while (!Status) {
- if ( (DirBlk.ff_attrib & FA_LABEL) != 0) {
- Status = findnext(&DirBlk);
- continue;
- }
- if ( (DirBlk.ff_attrib & FA_DIREC) != 0) {
- if (DirBlk.ff_name[0] != '.') {
- Enque(&Direc, DirBlk.ff_name);
- }
- }
- else {
- ++TotalFiles;
- if ( SearchQ(DirBlk.ff_name, Q) ) {
- ++TotalMatch;
- if (PageSwt) ChkPage();
- if (VerboseSwt) {
- fputs(" ", stdout);
- Time.u = DirBlk.ff_ftime;
- Date.u = DirBlk.ff_fdate;
- PrtVerbose(Path, DirBlk.ff_name, Time, Date,
- DirBlk.ff_fsize);
- }
- else {
- fputs(Path, stdout);
- puts(DirBlk.ff_name);
- }
- ++Lnno;
- Spaced = 0;
- }
- if ( (p = strchr(DirBlk.ff_name, '.')) != NULL ) {
- for (i=0; Arcs[i].Ext[0] != '\0' && stricmp(p+1, Arcs[i].Ext); ++i);
- ArcType = Arcs[i].Type;
- switch (ArcType) {
- case arc:
- case pak:
- ++S[ArcType][0];
- if (ArcSwt) {
- strcat(Path, DirBlk.ff_name);
- DoArc(Path);
- *(strrchr(Path, '\\') + 1) = '\0';
- }
- break;
- case zip:
- ++S[ArcType][0];
- if (ArcSwt) {
- strcat(Path, DirBlk.ff_name);
- DoZip(Path);
- *(strrchr(Path, '\\') + 1) = '\0';
- }
- break;
- case zoo:
- ++S[ArcType][0];
- if (ArcSwt) {
- strcat(Path, DirBlk.ff_name);
- DoZOO(Path);
- *(strrchr(Path, '\\') + 1) = '\0';
- }
- break;
- case lzh:
- ++S[ArcType][0];
- if (ArcSwt) {
- strcat(Path, DirBlk.ff_name);
- DoLzh(Path);
- *(strrchr(Path, '\\') + 1) = '\0';
- }
- break;
- }
- }
- }
- Status = findnext(&DirBlk);
- }
- p = strrchr(Path,'\\') + 1;
- for (t=Direc.Head; t != NULL; ) {
- *p = '\0';
- strcat(Path, t->Body); strcat(Path, "\\");
- WalkTree(Q);
- u = t->Next;
- free(t->Body);
- free(t);
- t = u;
- }
- }
-
- int
- SearchQ (char *Str, QUE_DEF *Q) {
- QUE_ENTRY *t;
- int Result;
-
- for (t=Q->Head; t != NULL; t = t->Next) {
- if ( (Result = Match(Str, t->Body)) != 0) return(Result);
- }
- return(0);
- }
-
- int
- Match (char *Str, char *Pat) {
-
- while (*Str != '\0') {
- if (*Pat == '*') {
- if ( *(++Pat) == '\0') return(1);
- else {
- while (*Str != *Pat && *Str != '\0') ++Str;
- if (*Str == '\0') {
- if (*Pat == '.' && ( *(Pat+1) == '\0' || *(Pat+1) == '*') ) return(1);
- else return(0);
- }
- }
- }
- if (*Pat == '?') {
- ++Pat; ++Str;
- }
- if (*Str != *Pat) return(0);
- ++Pat; ++Str;
- }
- if ( (*Pat == '\0') || !strcmp(Pat, ".*") || !strcmp(Pat, "*") ) return(1);
- else return(0);
- }
-
-
- void
- GetPath (QUE_DEF *Q, char *Arg) {
- char *p, Temp[65];
- int i, j;
-
- if ( (p = strchr(Arg, ':')) != NULL) {
- if ( (i = p - Arg) > 1) {
- for (j=0; j < i; ++j) {
- Temp[0] = Arg[j];
- Temp[1] = '\0';
- strcat(Temp, p);
- if (Temp[strlen(Temp)-1] != '\\') strcat(Temp, "\\");
- strupr(Temp);
- if (Enque(Q, Temp) == NULL)
- ErrorExit("Insufficient memory for Path List.\n");
- }
- }
- else {
- strcpy(Temp, Arg);
- if (Temp[strlen(Temp)-1] != '\\') strcat(Temp, "\\");
- strupr(Temp);
- if (Enque(Q, Temp) == NULL)
- ErrorExit("Insufficient memory for Path List.\n");
- }
- }
- else {
- Temp[0] = CurDir[0]; Temp[1] = ':'; Temp[2] = '\0';
- strcat(Temp, Arg);
- if (Temp[strlen(Temp)-1] != '\\') strcat(Temp, "\\");
- strupr(Temp);
- if (Enque(Q, Temp) == NULL)
- ErrorExit("Insufficient memory for Path List.\n");
- }
- }
-
- void
- ErrorExit (char *Format, ...) {
- va_list ArgPtr;
- extern char ProgName[];
- extern int errno;
-
- fprintf(stderr, "%s: ", ProgName);
- va_start(ArgPtr, Format);
- vfprintf(stderr, Format, ArgPtr);
- va_end(ArgPtr);
- if (errno) perror(" ");
- fprintf(stderr, "\n");
- exit(1);
- }
-
- void
- GetProgName (char *Name, char *argv) {
- char *p, *p1;
-
- if ( (p = strrchr(argv, '\\')) != NULL) ++p;
- else p = argv;
- if ( (p1 = strchr(p, '.')) != NULL) *p1 = '\0';
- strcpy(Name, p);
- }
-
- void
- PrtVerbose (char *Path, char *Name, DOS_FILE_TIME Time, DOS_FILE_DATE Date,
- long Size) {
- extern int DateSwt;
- static char *MonTab[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
- "Oct", "Nov", "Dec"
- };
-
- if (DateSwt) {
- printf("%-13s %02d/%02d/%02d %02u:%02u %8ld %s\n", Name,
- Date.b.Year + 80, Date.b.Month, Date.b.Day, Time.b.Hour,
- Time.b.Minute, Size, Path);
- }
- else {
- printf("%-13s %02u %s %02u %02u:%02u %8ld %s\n", Name, Date.b.Day,
- MonTab[Date.b.Month - 1], Date.b.Year + 80, Time.b.Hour,
- Time.b.Minute, Size, Path);
- }
- }
-
- void
- Usage (void) {
- fprintf(stderr, "USAGE: %s [device(s):[path]pattern [options]\n", ProgName);
- fprintf(stderr, "\nOptions:\n\n");
- fprintf(stderr, " -a Suppress searching inside of archive files.\n");
- fprintf(stderr, " -v Display Date/Time and File Size as well as name\n");
- fprintf(stderr, " and path for all matched files.\n");
- fprintf(stderr, " -f Modify the date in the Verbose output for sorting\n");
- fprintf(stderr, " YY/MM/DD form\n");
- fprintf(stderr, " -p Paginate output every 23 lines\n");
- fprintf(stderr, " -q Supress the printing of the statistics on files\n");
- fprintf(stderr, " searched and matched\n");
- exit(1);
- }
-
-
- void
- ChkPage (void) {
- int Reply;
-
- if (Lnno >= 24) {
- clreol();
- printf("More?...");
- Reply = tolower( getche() );
- if ( (Reply == 'n') || (Reply == 0x03) ) exit(1);
- printf("\r"); clreol();
- Lnno = 1;
- }
- }