home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
375.lha
/
ARPTools_v1.0
/
src
/
Sf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-02
|
7KB
|
336 lines
/*
Sf - Search files in volumes or directories.
Strictly based on the SF program by Andrea Suatoni published
in MC-Microcomputer 86, June 1989. Little enhancements by
Fabio Rossetti: resident support, NOCOL option.
(c) 1989 by Fabio Rossetti
To compile under Lattice C v5.0x use:
lc -O -v -cus sf
blink lib:cres.o sf.o to sf lib lib:a.lib lib:lc.lib lib:amiga.lib sc sd nd
*/
#include <exec/types.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <arpfunctions.h>
#include <string.h>
#include <libraries/arpbase.h>
#include <libraries/dosextens.h>
#include <proto/dos.h>
#include <proto/exec.h>
#define NO_ERROR 0
#define ERROR_NO_MEM -101
typedef
struct
{
struct MinNode dir_Node;
LONG PathLen;
STRPTR PathName;
}
DIR_ENTRY;
GLOBAL VOID (*_ONBREAK)();
UBYTE DateFormat = FORMAT_DOS;
struct Process *Pr;
struct ArpBase *ArpBase;
struct MinList DirList;
VOID Cleanup(r1,r2,msg)
LONG r1,r2;
STRPTR msg;
{
if (msg) Puts(msg);
if (ArpBase) CloseLibrary((struct Library *)ArpBase);
Pr->pr_Result2 = r2;
exit(r1);
}
STRPTR StrUpper(Str)
REGISTER STRPTR Str;
{
REGISTER STRPTR r = Str;
do
{
*Str = Toupper(*Str);
}
while (*(++Str));
return(r);
}
LONG AddDirEntry(PathNode,Dir)
REGISTER STRPTR PathNode,
Dir;
{
REGISTER DIR_ENTRY *Entry;
if ((Entry =
(DIR_ENTRY*) AllocMem(sizeof(DIR_ENTRY), MEMF_CLEAR)) == NULL)
return(ERROR_NO_MEM);
Entry->PathLen = strlen(PathNode) + strlen(Dir) + 2;
if((Entry->PathName =
(STRPTR) AllocMem(Entry->PathLen, MEMF_CLEAR)) == NULL)
{
FreeMem(Entry, sizeof(DIR_ENTRY));
return(ERROR_NO_MEM);
}
strcpy(Entry->PathName, PathNode);
TackOn(Entry->PathName, Dir);
AddTail((struct List *) &DirList, (struct Node *) Entry);
return(0);
}
VOID RemDirEntry()
{
REGISTER DIR_ENTRY *Entry;
Entry = (DIR_ENTRY *) RemHead((struct List *) &DirList);
FreeMem(Entry->PathName, Entry->PathLen);
FreeMem((STRPTR) Entry, sizeof(DIR_ENTRY));
}
VOID FreeDirList()
{
while (DirList.mlh_Head->mln_Succ)
RemDirEntry();
}
VOID FindFile(ArgV)
STRPTR ArgV[];
#define PATTERN ArgV[0]
#define FILES ArgV[1]
#define DIRS ArgV[2]
#define QUICK ArgV[3]
#define NOROOT ArgV[4]
#define NOCOL ArgV[5]
{
REGISTER struct FileLock *DirLock;
REGISTER struct FileInfoBlock *FileInfo;
REGISTER STRPTR CurrentPath;
REGISTER LONG Error;
REGISTER BOOL Found = FALSE,
First,
Dir;
TEXT Day [12],
Time [10],
Date [10],
StrToken[120],
Path [120];
WORD Tabs = 0;
struct DateTime DateTime;
if ((FileInfo = (struct FileInfoBlock *)
AllocMem(sizeof(struct FileInfoBlock), MEMF_CLEAR)) != NULL)
{
DateTime.dat_Format = DateFormat;
DateTime.dat_Flags = DTF_FUTURE;
DateTime.dat_StrDay = Day;
DateTime.dat_StrDate = Date;
DateTime.dat_StrTime = Time;
NewList((struct List *) &DirList);
*Path = '\0';
if (NOROOT == NULL)
if (strchr(PATTERN, ':') == NULL)
strcpy(Path, ":");
strcat(Path, PATTERN);
PreParse((CurrentPath = StrUpper(BaseName(Path))), StrToken);
*CurrentPath = '\0';
if ((DirLock = (struct FileLock *) Lock(Path, ACCESS_READ)) == NULL)
Error = ERROR_INVALID_LOCK;
else
{
PathName((BPTR) DirLock, Path, 10);
UnLock((BPTR) DirLock);
Error = AddDirEntry(Path,"");
}
while (DirList.mlh_Head->mln_Succ)
{
CurrentPath = ((DIR_ENTRY *) DirList.mlh_Head)->PathName;
if ((DirLock = (struct FileLock *) Lock(CurrentPath, ACCESS_READ)) ==
(struct FileLock *) 0)
{
Error = ERROR_INVALID_LOCK;
break;
}
First = TRUE;
if (Examine((BPTR) DirLock, FileInfo))
{
while (ExNext((BPTR) DirLock, FileInfo))
{
if (Dir = (FileInfo->fib_DirEntryType >= 0))
if ((Error = AddDirEntry(CurrentPath,
FileInfo->fib_FileName)) != NO_ERROR)
break;
if (PatternMatch(StrToken,
StrUpper(strcpy(Path, FileInfo->fib_FileName))) == TRUE)
if (!(DIRS || FILES) ||
(DIRS && Dir) ||
(FILES && !Dir))
{
Found = TRUE;
if (First)
{
if(Tabs)
{
Puts("");
Tabs = 0;
}
if(NOCOL) Printf("\n\"%s\"\n",CurrentPath);
else Printf("\n\033[33m\"%s\"\033[31m\n",
CurrentPath);
First = FALSE;
}
if (QUICK)
{
if (Dir)
if (NOCOL) Printf("%s%-18s",(Tabs) ? "": " ",
FileInfo->fib_FileName);
else Printf("\033[33m%s%-18s\033[31m",(Tabs) ? "": " ",
FileInfo->fib_FileName);
else
Printf("%s%-18s",(Tabs) ? "": " ",
FileInfo->fib_FileName);
if (++Tabs == 4)
{
Tabs = 0;
Puts("");
}
}
else
{
DateTime.dat_Stamp.ds_Days = FileInfo->fib_Date.ds_Days;
DateTime.dat_Stamp.ds_Minute= FileInfo->fib_Date.ds_Minute;
DateTime.dat_Stamp.ds_Tick = FileInfo->fib_Date.ds_Tick;
StamptoStr(&DateTime);
Printf(" %-30s ", FileInfo->fib_FileName);
if (Dir)
Printf(" (dir)");
else
Printf("%7ld", FileInfo->fib_Size);
Printf(" %-9s %9s %8s\n", Day, Date, Time);
}
}
if (CheckBreak(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D,NULL))
{
Error = ERROR_BREAK;
break;
}
}
if (Error == NO_ERROR)
Error = IoErr();
}
RemDirEntry();
UnLock((BPTR) DirLock);
if (Error != ERROR_NO_MORE_ENTRIES)
break;
}
if (Tabs)
Puts("");
if (Error == ERROR_NO_MORE_ENTRIES && Found == TRUE)
Error = NO_ERROR;
FreeDirList();
FreeMem((STRPTR) FileInfo, sizeof(struct FileInfoBlock));
}
else
Error = ERROR_NO_MEM;
switch(Error)
{
case NO_ERROR:
break;
case ERROR_INVALID_LOCK:
Puts("Invalid pattern or path name");
break;
case ERROR_NO_MEM:
Puts("No memory");
break;
case ERROR_NO_MORE_ENTRIES:
Puts("Search failed");
break;
case ERROR_OBJECT_NOT_FOUND:
Puts("Object not found");
break;
case ERROR_BREAK:
Puts("***Break");
break;
default:
Printf("Error %ld\n", Error);
}
}
VOID MemCleanup()
{
}
VOID Break()
{
Cleanup(RETURN_WARN,NULL,"***Break");
}
VOID _main(Line)
REGISTER STRPTR Line;
#define MAX_ARG 6
{
REGISTER LONG ArgC;
STRPTR Arg[MAX_ARG];
TEXT EnvBuf[2];
_ONBREAK = Break;
Pr = (struct Process*)FindTask(NULL);
if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion)))
Cleanup(RETURN_FAIL,ERROR_INVALID_RESIDENT_LIBRARY,NULL);
for (ArgC = 0; ArgC < MAX_ARG; ++ArgC)
Arg[ArgC] = (STRPTR)NULL;
while (*Line > ' ') ++Line;
if ((ArgC = GADS(++Line,
strlen(Line),
"Usage: Sf PAT <PathName|Pattern> [FILES=F] [DIRS=D] [QUICK=Q] [NOROOT=NR] [NOCOL=NC]",
Arg,
"PAT/A,FILES=F/S,DIRS=D/S,QUICK=Q/S,NOROOT=NR/S,NOCOL=NC/S"))<= 0)
Cleanup(RETURN_FAIL,ERROR_LINE_TOO_LONG,Arg[0]);
if(Getenv("dateformat",EnvBuf,2))
switch (EnvBuf[0]) {
case '1':
DateFormat = FORMAT_INT;
break;
case '2':
DateFormat = FORMAT_USA;
break;
case '3':
DateFormat = FORMAT_CDN;
break;
};
if (ArgC > 0)
FindFile(Arg);
Cleanup(NULL,NULL,NULL);
}