home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright © 1992-94 by S.R. & P.C.
- *
- * Created: 30 Mar 1992 18:26:36
- * Modified: 09 Nov 1994 23:11:45
- *
- * Make>> rx BumpRev For 3 8
- * Make>> sc <file>.c
- * Make>> slink LIB:cs.o <file>.o SC SD BATCH NOICONS TO <file> LIB LIB:c.lib
- * Make>> protect <file> P ADD
- *
- *
- * 30/03/1992: V1.0 (Pierre Carrette)
- * Simple version with template: "Args/M,ALL/S,DONTFAIL/S,DO/K/A/F"
- * 4/07/1994: V2.2 (Sylvain Rougier)
- * No longer add the name of the object if no '%%' present
- * 5/07/1994: V3.0
- * Add the 'Quiet' option not to print hierarchy (but still print FileType if asked)
- * Now work as it should always work: don't scan all the directory if no pattern
- * but scan all subdir if 'All' option specified.
- * Add the 'GivePathName' option to provide a Full Path arguments to the command.
- * No longuer add '"' around the file name. User can type '"%%"' if he need it.
- * 7/07/1994 V3.1
- * If a full pathname file entry was specified, For don't find it type. fixed
- * 15/07/1994 V3.2
- * Guru if a single file was suplied. fixed
- * Now FullPathArgs realy work
- * Don't put optimize or it guru ! (see note)
- * 31/07/1994 V3.3
- * Check the stack size because it need at least 8192 (probably !...)
- * put optimize again. just to see.
- * 07/08/1994 V3.4
- * Remove optimize because the sasc bug still here
- * correct some error int the doc ( the '*' was incorrectly used instead of the '"')
- * 21/08/1994 V3.5
- * Now use StackSwap() to avoid stack pb
- * 22/09/1994 V3.6 (Pierre Carrette is back :-)
- * Major code cleanup. No more need StackSwap(). Bug fixes in template. whatis.library now Optional.
- * Inverted 'Quiet' to 'Verbose'. Changed 'VNFileType' to more comprehensive 'FileTypeVar' keyword.
- * Changed 'GivePathName' to 'FullPathArgs'.
- * FileTypeVar was not set if Showbytes was off.
- * Showbytes/ShowFileType is now off if no Cmd supplied.
- * 'Type' argument syntax simplified. now: "#text,!source c"
- * MatchFileType() bug fix. "#text,!source c" was not working!!
- * SAS Optimisation now works!!!
- * 22/09/1994 V3.7
- * Recompiled with new version of c.lib which had a bug for 'ENV:' var parsing
- * 09/11/1994 V3.8
- * Bug fix. File UnLock()ed before processed so that command can open it for writing.
- */
-
- #include <clib.h>
- #include <libraries/WhatIsBase.h>
- #include <proto/WhatIs.h>
- #include "For_rev.h"
-
- // Startup Modules...
- CliArgs; ReadEnvArgs("For");
-
- static char Version[] = VERSTAG;
-
- STRPTR Template = "\
- Pattern/A/M,Files/K,Dirs/K,Since/K,Before/K,MinSize/K/N,MaxSize/K/N,\
- PosProtect/K,NegProtect/K,Type/K,All/S,ASync/S,ReadSize/K/N,ShowBytes/K/N,\
- D=Deep/K/N,SFT=ShowFileType/S,FTV=FileTypeVar/K,FPA=FullPathArgs/S,Verbose/S,Do/K/F";
-
- STRPTR CliHelp = VERS" ("DATE") © Sylvain Rougier & Pierre Carrette.\n\
- Usage: For <Pattern> [Files <MATCH|YES|NO>] [Dirs <MATCH|YES|NO>]\n\
- [Since <Date>] [Before <Date>] [MinSize <Number>] [MaxSize <Number>]\n\
- [PosProtect <L|C|H|S|P|A|R|W|E|D>] [NegProtect <L|C|H|S|P|A|R|W|E|D>]\n\
- [Type <[#=SUB,~=EXLC]FileType0,,,FileType15>] [All] [ASync] [ReadSize]\n\
- [ShowBytes] [Deep] [ShowFileType] [FileTypeVar <var name>] [FullPathArgs]\n\
- [DO <Command [args] [,Command [args] [,...]]>]\n";
-
- #define ARG_Template 0
- #define ARG_Files 1
- #define ARG_Dirs 2
- #define ARG_Since 3
- #define ARG_Before 4
- #define ARG_MinSize 5
- #define ARG_MaxSize 6
- #define ARG_PosProtect 7
- #define ARG_NegProtect 8
- #define ARG_Type 9
- #define ARG_ALL 10
- #define ARG_ASYNC 11
- #define ARG_READSIZE 12
- #define ARG_SHOWBYTES 13
- #define ARG_DEEPWHATIS 14
- #define ARG_SHOWFILETYPE 15
- #define ARG_FileTypeVar 16
- #define ARG_FullPathArgs 17
- #define ARG_Verbose 18
- #define ARG_CMD 19
- #define ARG_ENDARG 20
-
-
- struct Library *WhatIsBase;
-
-
- #define MAX_PATHLEN 256
- #define MAX_CMDLEN 512
-
- /* char used in the filetype spec string */
- #define NOTFileType '~'
- #define WITHSubTypes '#'
-
- /*******************************************************/
- /* not in dos.h !! */
- #define FIBB_HOLD 7
- #define FIBF_HOLD (1<<FIBB_HOLD)
-
- /* it is my own definition: not standard */
- #define FIBB_COMMENT 8
- #define FIBF_COMMENT (1<<FIBB_COMMENT)
- #define FIBB_LINK 9
- #define FIBF_LINK (1<<FIBB_LINK)
-
-
- #define PATTERN_BUF_SIZE 40
- #define MAX_FTS 16 /* Max FileTypeSpec in SelectInfo */
-
- struct FileTypeSpec {
- FileType fs_FileType;
- UWORD fs_Flags;
- };
-
- /* FileTypeSpec flags */
- #define FTSF_EXCLUDETYPE 0x0001 /* Exclude this type (otherwise include) */
- #define FTSF_WITHSUBTYPES 0x0002 /* Affect Include/Exclude to subtypes */
-
-
- struct SelectInfo {
- UBYTE si_PatTok[PATTERN_BUF_SIZE]; /* PreParsed pattern */
- LONG si_MinSize; /* Show files bigger than that */
- LONG si_MaxSize; /* and smaller than that */
- struct DateStamp si_SinceDate; /* Show files newer than that */
- struct DateStamp si_BeforeDate; /* and older than that */
- UWORD si_PosProtect; /* Show files that have these bits set */
- UWORD si_NegProtect; /* Show files that have these bits clear */
- struct FileTypeSpec si_FileTypes[MAX_FTS]; /* Include and Exclude file types */
- UWORD si_NumFts; /* Number of FileTypeSpec in previous array */
- UWORD si_Flags; /* Flags. See below */
- };
-
- /* SelectInfo flags */
-
- #define SI_ALL_FILES 0x0001
- #define SI_MATCH_FILES 0x0002
- #define SI_ALL_DIRS 0x0004
- #define SI_MATCH_DIRS 0x0008
- #define SI_AFFECT_SUBDIRS 0x0010
- #define SI_NAME 0x0020
- #define SI_SIZE 0x0040
- #define SI_SINCEDATE 0x0080
- #define SI_BEFOREDATE 0x0100
- #define SI_POSPROTECTION 0x0200
- #define SI_NEGPROTECTION 0x0400
- #define SI_POSFILETYPE 0x0800
- #define SI_NEGFILETYPE 0x1000
-
- #define SI_FILETYPE (SI_POSFILETYPE|SI_NEGFILETYPE)
- #define SI_MATCHBITS (SI_NAME|SI_SIZE|SI_SINCEDATE|SI_BEFOREDATE|SI_POSPROTECTION|SI_NEGPROTECTION|SI_FILETYPE)
-
-
- struct Opt {
- BOOL Verbose; /* Print some information */
- BOOL Async; /* Run commands Asynchronously */
- BOOL FullPathArgs; /* Give Full PathName in Fmt ? */
- BOOL ShowFileType; /* Show FileType ? */
- LONG ReadSize; /* Size to read to find filetype */
- ULONG Deep; /* deep level to find FileType */
- UWORD Showbytes; /* number of bytes to show */
- STRPTR FileTypeVar; /* Name of FileType var. no var if null */
- };
-
-
- /* return pointer to the first non blank char in a string, or to the '\0' if the string is empty */
-
- static char *FirstNonBlank(char *buf)
- {
- while (*buf && *buf == ' ')
- buf++;
- return buf;
- }
-
-
- /* check if buffer is empty or not */
-
- static BOOL IsEmpty(char *buf)
- {
- return (BOOL) ((*FirstNonBlank(buf)) ? FALSE : TRUE);
- }
-
-
- static BOOL String2Date(char *src, struct DateStamp *ds)
- {
- struct DateTime *dt;
- BOOL Ok = TRUE;
- char *s1, *s2;
- char buf[60];
-
- if (!(dt = AllocMem(sizeof(struct DateTime), MEMF_PUBLIC | MEMF_CLEAR)))
- return FALSE;
-
- strcpy(buf, src);
- s1 = s2 = FirstNonBlank(buf);
- if (*s1) {
- dt->dat_StrDate = s1;
- while (*s2 && *s2 != ' ')
- s2++;
- if (*s2) {
- *s2++ = '\0';
- s2 = FirstNonBlank(s2);
- }
- if (*s2) {
- dt->dat_StrTime = s2;
- if (!StrToDate(dt))
- Ok = FALSE;
- }
- else if (!StrToDate(dt)) {
- dt->dat_StrDate = NULL;
- dt->dat_StrTime = s1;
- if (!StrToDate(dt))
- Ok = FALSE;
- }
- if (Ok)
- *ds = dt->dat_Stamp;
- }
- FreeMem(dt, sizeof(struct DateTime));
-
- return Ok;
- }
-
-
- static void PrintByte(UBYTE Buffer[], LONG BufLen, UBYTE Num)
- {
- register short i;
-
- if (BufLen > 0) {
- for (i = 0; i < Num && i < BufLen; i++)
- Printf("%02lx", Buffer[i]);
- }
- }
-
-
- /*
- * Parse a line that may contain comas. Backslash ('\') is the override char.
- */
-
- static UWORD ProtectBit(char P[])
- {
- UWORD PB = 0;
-
- while (*P) {
- switch (*P) {
- case 'L':
- case 'l':
- PB |= FIBF_LINK; /* another magic bit! */
- break;
- case 'C':
- case 'c':
- PB |= FIBF_COMMENT; /* our magic bit! */
- break;
- case 'H':
- case 'h':
- PB |= FIBF_HOLD;
- break;
- case 'S':
- case 's':
- PB |= FIBF_SCRIPT;
- break;
- case 'P':
- case 'p':
- PB |= FIBF_PURE;
- break;
- case 'A':
- case 'a':
- PB |= FIBF_ARCHIVE;
- break;
- case 'R':
- case 'r':
- PB |= FIBF_READ;
- break;
- case 'W':
- case 'w':
- PB |= FIBF_WRITE;
- break;
- case 'E':
- case 'e':
- PB |= FIBF_EXECUTE;
- break;
- case 'D':
- case 'd':
- PB |= FIBF_DELETE;
- break;
- }
- P++;
- }
- return PB;
- }
-
-
- static UWORD __inline EasyProtect(LONG Protection)
- {
- return (UWORD) ((Protection ^ 0x0F) & 0x00FF); /* Complement 4 lower bits so all work the same way */
- }
-
-
- static BOOL Match(struct SelectInfo * SelectInfo, struct FileInfoBlock *fib)
- {
- if (fib->fib_DirEntryType < 0) { /* this is a file */
- if (SelectInfo->si_Flags & SI_ALL_FILES)
- return TRUE;
- else if (!(SelectInfo->si_Flags & SI_MATCH_FILES))
- return FALSE;
- }
- else { /* Dir */
- if (SelectInfo->si_Flags & SI_ALL_DIRS)
- return TRUE;
- else if (!(SelectInfo->si_Flags & SI_MATCH_DIRS))
- return FALSE;
- }
- if (SelectInfo->si_Flags & SI_NAME) {
- if (!MatchPatternNoCase(SelectInfo->si_PatTok, fib->fib_FileName))
- return FALSE;
- }
- if (SelectInfo->si_Flags & SI_SINCEDATE) {
- if (CompareDates(&SelectInfo->si_SinceDate, &fib->fib_Date) < 0)
- return FALSE;
- }
- if (SelectInfo->si_Flags & SI_BEFOREDATE) {
- if (CompareDates(&SelectInfo->si_BeforeDate, &fib->fib_Date) > 0)
- return FALSE;
- }
- if (fib->fib_Size < SelectInfo->si_MinSize)
- return FALSE;
- if (SelectInfo->si_MaxSize && (fib->fib_Size > SelectInfo->si_MaxSize))
- return FALSE;
- {
- UWORD Protection = EasyProtect(fib->fib_Protection);
-
- if (SelectInfo->si_Flags & SI_POSPROTECTION) {
- if (!(Protection & SelectInfo->si_PosProtect))
- return FALSE;
- }
- if (SelectInfo->si_Flags & SI_NEGPROTECTION) {
- if ((Protection & SelectInfo->si_NegProtect))
- return FALSE;
- }
- }
- return TRUE;
- }
-
-
- static BOOL MatchFileType(struct SelectInfo *SelectInfo, struct FileInfoBlock *fib, FileType Type)
- {
- if (WhatIsBase && (SelectInfo->si_Flags & SI_FILETYPE)) {
- BOOL Sub = FALSE;
- UWORD Flags, i;
-
- do {
- for( i=0 ; i<SelectInfo->si_NumFts ; i++ ) {
- Flags = SelectInfo->si_FileTypes[i].fs_Flags;
- if ((!Sub || (Flags & FTSF_WITHSUBTYPES)) && !CmpFileType(SelectInfo->si_FileTypes[i].fs_FileType, Type))
- return (BOOL)((Flags & FTSF_EXCLUDETYPE) ? FALSE : TRUE);
- }
- Sub = TRUE;
- } while (Type = ParentFileType(Type));
- if (SelectInfo->si_Flags & SI_POSFILETYPE)
- return FALSE; /* no match within include FileTypes, exclude file */
- else
- return TRUE; /* Only exclude types, and not found in them, include file */
- }
- return TRUE;
- }
-
-
- /*
- * Parse a line that may contain comas ','. Backslash ('\') is the override
- * char. This function replace comas by cariage returns so that SystemTags()
- * takes them as different command lines, just like a script file.
- */
-
- static void ParseCmdLine(char *cmd)
- {
- char *s, *d, c;
-
- s = d = cmd;
- while (c = *d++ = *s++) {
- if (c == '\\')
- *(d - 1) = *s++;
- else if (c == ',')
- *(d - 1) = '\n';
- }
- }
-
-
- /* Replaces %% by %s, suitable for SPrintf() */
-
- static void MakeFmt(char *CmdFmt, char *Cmd)
- {
- char *s;
-
- strcpy(CmdFmt, Cmd);
- ParseCmdLine(CmdFmt); /* Replace , by \n to separate commands */
- s = CmdFmt;
- while (*s) {
- if (*s == '%' && *(s + 1) == '%')
- *(s + 1) = 's';
- s++;
- }
- }
-
-
- static LONG ExecuteCmd(char *Cmd, STRPTR StartPath, char *Name, struct Opt *Opt)
- {
- char *CmdBuf, *CmdFmt, *NameBuf;
- LONG rc = 20;
- BOOL NoMem = TRUE;
-
- if (CmdBuf = AllocVec(MAX_CMDLEN, MEMF_ANY)) {
- if (NameBuf = AllocVec(MAX_CMDLEN, MEMF_ANY)) {
- if (CmdFmt = AllocVec(MAX_CMDLEN, MEMF_ANY)) {
- MakeFmt(CmdFmt, Cmd);
- if (Opt->FullPathArgs) {
- strcpy(NameBuf, StartPath);
- AddPart(NameBuf, Name, MAX_CMDLEN);
- }
- else
- strcpy(NameBuf, Name);
- /* Allow 5 %% in cmd */
- SPrintf(CmdBuf, CmdFmt, NameBuf, NameBuf, NameBuf, NameBuf, NameBuf); /* build command line */
- if (Opt->Async) {
- SystemTags(CmdBuf, SYS_Input, Open("*", MODE_OLDFILE),
- SYS_Output, NULL, // System() will open it
- SYS_Asynch, TRUE,
- SYS_UserShell, TRUE,
- TAG_DONE);
- rc = 0;
- }
- else
- rc = SystemTags(CmdBuf, SYS_UserShell, TRUE, TAG_DONE);
- NoMem = FALSE;
- FreeVec(CmdFmt);
- }
- FreeVec(NameBuf);
- }
- FreeVec(CmdBuf);
- }
- if (NoMem)
- PrintFault(ERROR_NO_FREE_STORE, "For");
- else if (rc)
- PrintFault(IoErr(), "For");
- return rc;
- }
-
-
- static LONG ProcessEntry(struct SelectInfo *SelectInfo, struct FileInfoBlock *fib, STRPTR StartPath,
- STRPTR Name, UBYTE *FileData, struct Opt *Opt, STRPTR Cmd)
- {
- LONG RC = 0, BytesRead = 0;
- FileType Type = TYPE_UNSCANNED;
-
- if (WhatIsBase) {
- if (Opt->Deep && fib->fib_DirEntryType <= 0) {
- BPTR FH;
-
- if (FH = Open(Name, MODE_OLDFILE)) {
- BytesRead = Read(FH, FileData, Opt->ReadSize);
- FileData[BytesRead] = '\0'; /* whatis.library need that */
- Type = WhatIsTags(Name, WI_Deep, Opt->Deep, WI_FIB, fib, WI_Buffer, FileData, WI_BufLen, BytesRead, TAG_DONE);
- Close(FH);
- }
- }
- else
- Type = WhatIsTags(Name, WI_Deep, LIGHTTYPE, WI_FIB, fib, TAG_DONE);
- }
- if (MatchFileType(SelectInfo, fib, Type)) {
- if (WhatIsBase) {
- STRPTR IDString;
- BOOL CR = FALSE;
-
- IDString = GetIDString(Type);
- if (Opt->ShowFileType) {
- Printf("%-12s %-32s", IDString, (Opt->Verbose) ? fib->fib_FileName : Name);
- CR = TRUE;
- }
- if (Opt->Showbytes && fib->fib_DirEntryType <= 0) {
- PrintByte(FileData, BytesRead, Opt->Showbytes);
- CR = TRUE;
- }
- if (CR)
- PutStr("\n");
- if (Opt->FileTypeVar)
- SetVar(Opt->FileTypeVar, IDString, -1L, GVF_LOCAL_ONLY);
- }
- if (Cmd)
- RC = ExecuteCmd(Cmd, StartPath, Name, Opt);
- }
- return RC;
- }
-
-
- static LONG ProcessEntryPattern(struct AnchorPath *AP, struct SelectInfo *SelectInfo, struct Opt *Opt,
- STRPTR StartPath, STRPTR Pattern, UBYTE *FileData, STRPTR Cmd)
- {
- BOOL DoIt = TRUE;
- LONG RC=0, MatchErr;
-
- for (MatchErr = MatchFirst(Pattern, AP); RC == 0 && MatchErr == 0; MatchErr = MatchNext(AP)) {
- if (AP->ap_Flags & APF_DIDDIR) {
- if (Opt->Verbose)
- Printf("%s\n", AP->ap_Buf);
- DoIt = FALSE; /* Dir processed before entering it, don't process it twice */
- AP->ap_Flags &= ~APF_DIDDIR; /* clear the completed directory flag */
- }
- else if (AP->ap_Info.fib_DirEntryType > 0) {
- if (SelectInfo->si_Flags & SI_AFFECT_SUBDIRS) {
- if (Opt->Verbose)
- Printf("%s\n", AP->ap_Buf);
- AP->ap_Flags |= APF_DODIR; /* make Matchext() enter the directory */
- }
- else
- AP->ap_Flags &= ~APF_DODIR; /* RESET this bit after MatchFirst/MatchNext to AVOID entering a dir. */
- }
-
- /* Here is code for handling each particular file */
- if (DoIt && Match(SelectInfo, &AP->ap_Info))
- RC = ProcessEntry(SelectInfo, &AP->ap_Info, StartPath, AP->ap_Buf, FileData, Opt, Cmd);
- DoIt = TRUE;
- }
- MatchEnd(AP);
- if (MatchErr != ERROR_NO_MORE_ENTRIES)
- PrintFault(MatchErr, "For");
- return RC;
- }
-
-
- LONG Main(char *ArgV[], struct WBStartup *WBenchMsg)
- {
- LONG rc = RETURN_OK;
- char *StartPath = NULL, *Buffer = NULL;
- struct FileInfoBlock *fib = NULL;
- struct SelectInfo SelectInfo;
- struct Opt Opt;
- UBYTE *FileData;
-
- WhatIsBase = OpenLibrary("whatis.library", 3L);
- memset(&SelectInfo, 0, sizeof(SelectInfo));
- memset(&Opt, 0, sizeof(struct Opt));
-
- if (ArgV[ARG_Files]) {
- if (!Stricmp(ArgV[ARG_Files], "MATCH"))
- SelectInfo.si_Flags |= SI_MATCH_FILES;
- else if (!Stricmp(ArgV[ARG_Files], "YES"))
- SelectInfo.si_Flags |= SI_ALL_FILES;
- }
- else /* set default */
- SelectInfo.si_Flags |= SI_MATCH_FILES;
- if (ArgV[ARG_Dirs]) {
- if (!Stricmp(ArgV[ARG_Dirs], "MATCH"))
- SelectInfo.si_Flags |= SI_MATCH_DIRS;
- else if (!Stricmp(ArgV[ARG_Dirs], "YES"))
- SelectInfo.si_Flags |= SI_ALL_DIRS;
- }
- else /* set default */
- SelectInfo.si_Flags |= SI_MATCH_DIRS;
- if (ArgV[ARG_Since]) {
- struct DateStamp DateStamp;
-
- String2Date(ArgV[ARG_Since], &DateStamp);
- SelectInfo.si_SinceDate = DateStamp;
- SelectInfo.si_Flags |= SI_SINCEDATE;
- }
- if (ArgV[ARG_Before]) {
- struct DateStamp DateStamp;
-
- String2Date(ArgV[ARG_Before], &DateStamp);
- SelectInfo.si_BeforeDate = DateStamp;
- SelectInfo.si_Flags |= SI_BEFOREDATE;
- }
- if (ArgV[ARG_MinSize])
- SelectInfo.si_MinSize = *(ULONG *) ArgV[ARG_MinSize];
- if (ArgV[ARG_MaxSize])
- SelectInfo.si_MaxSize = *(ULONG *) ArgV[ARG_MaxSize];
- if (ArgV[ARG_PosProtect]) {
- SelectInfo.si_Flags |= SI_POSPROTECTION;
- SelectInfo.si_PosProtect = ProtectBit(ArgV[ARG_PosProtect]);
- }
- if (ArgV[ARG_NegProtect]) {
- SelectInfo.si_Flags |= SI_NEGPROTECTION;
- SelectInfo.si_NegProtect = ProtectBit(ArgV[ARG_NegProtect]);
- }
- if (ArgV[ARG_Type] && WhatIsBase) {
- char IDType[100];
- UBYTE NumFT = 0;
- char *c, *i;
-
- for (c = ArgV[ARG_Type]; *c && NumFT < MAX_FTS && rc == 0;) {
- switch (*c) {
- case NOTFileType: // ~
- SelectInfo.si_FileTypes[NumFT].fs_Flags |= FTSF_EXCLUDETYPE;
- break;
- case WITHSubTypes: // #
- SelectInfo.si_FileTypes[NumFT].fs_Flags |= FTSF_WITHSUBTYPES;
- break;
- default:
- i = IDType;
- while (*c && *c != ',' && i < IDType+100-1)
- *i++ = *c++; // copy until ',' or end of string
- *i = '\0'; // nul terminate the string
- if (SelectInfo.si_FileTypes[NumFT].fs_Flags & FTSF_EXCLUDETYPE)
- SelectInfo.si_Flags |= SI_NEGFILETYPE;
- else
- SelectInfo.si_Flags |= SI_POSFILETYPE;
- SelectInfo.si_FileTypes[NumFT].fs_FileType = GetIDType(IDType);
- if (TYPE_UNKNOWNIDSTRING == SelectInfo.si_FileTypes[NumFT].fs_FileType) {
- Printf("Unknown FileType: %s\n", IDType);
- rc = 21; // Hack to prevent PrintFault('no memory')
- }
- NumFT++;
- }
- if (*c)
- c++;
- }
- SelectInfo.si_NumFts = NumFT;
- }
- if (ArgV[ARG_ALL])
- SelectInfo.si_Flags |= SI_AFFECT_SUBDIRS;
-
- Opt.Async = (BOOL) ArgV[ARG_ASYNC];
- Opt.ReadSize = (ArgV[ARG_READSIZE]) ? *(LONG *) ArgV[ARG_READSIZE] : 488;
- Opt.Deep = (ArgV[ARG_DEEPWHATIS]) ? *(LONG *) ArgV[ARG_DEEPWHATIS] : LIGHTTYPE;
- if (ArgV[ARG_SHOWBYTES]) {
- Opt.Showbytes = (UBYTE) (*(LONG *) ArgV[ARG_SHOWBYTES]);
- Opt.Deep = DEEPTYPE;
- }
- Opt.ShowFileType = (BOOL) ArgV[ARG_SHOWFILETYPE];
- Opt.FileTypeVar = (STRPTR) ArgV[ARG_FileTypeVar];
- Opt.FullPathArgs = (BOOL) ArgV[ARG_FullPathArgs];
- Opt.Verbose = (BOOL) ArgV[ARG_Verbose];
-
- if (rc == 0 && !(Buffer = AllocVec(MAX_PATHLEN, MEMF_ANY)))
- rc = RETURN_FAIL;
-
- if (rc == 0 && !(StartPath = AllocVec(MAX_PATHLEN, MEMF_ANY)))
- rc = RETURN_FAIL;
-
- if (rc == 0 && !(fib = AllocVec(sizeof(struct FileInfoBlock), MEMF_ANY)))
- rc = RETURN_FAIL;
-
- if (rc == 0 && (FileData = AllocVec(Opt.ReadSize + 1, MEMF_ANY))) {
- struct AnchorPath *AP;
-
- if (AP = AllocVec(sizeof(struct AnchorPath) + MAX_PATHLEN, MEMF_ANY)) {
- LONG IsWild;
- STRPTR Elmt;
- UBYTE i;
-
- if (Opt.FullPathArgs)
- NameFromLock(((struct Process *)SysBase->ThisTask)->pr_CurrentDir, StartPath, MAX_PATHLEN);
- else
- StartPath[0] = '\0';
-
- for (i = 0; rc == 0 && (Elmt = ((char **) ArgV[ARG_Template])[i]); i++) {
- memset(AP, 0, sizeof(struct AnchorPath) + MAX_PATHLEN);
- AP->ap_BreakBits = SIGBREAKF_CTRL_C; /* Break on these bits */
- AP->ap_Strlen = MAX_PATHLEN;
- /*
- * For wildcard matching with ALL flag set, two situations are handled differently
- * 1. foo#?/bar
- * 2. foobar#?
- * In the first case, a standard MatchFirst()/MatchNext() is used.
- * For the second one, if 'ALL' option is on, the pattern is replaced with "#?"
- * so that all directories are parsed, and then files filtered out by the more
- * powerfull function Match()
- */
- IsWild = ParsePatternNoCase(Elmt, Buffer, MAX_PATHLEN);
- if (ArgV[ARG_ALL] && IsWild == 1 && FilePart(Elmt) == Elmt) {
- SelectInfo.si_Flags |= SI_NAME;
- strcpy(SelectInfo.si_PatTok, Buffer);
- rc = ProcessEntryPattern(AP, &SelectInfo, &Opt, StartPath, "#?", FileData, ArgV[ARG_CMD]);
- }
- else {
- BPTR L;
-
- switch (IsWild) {
- case 1:
- /*
- * Pattern
- * Dir1/Dir2/Pattern
- * Vol:Dir1/Dir2/Pattern
- */
- rc = ProcessEntryPattern(AP, &SelectInfo, &Opt, StartPath, Elmt, FileData, ArgV[ARG_CMD]);
- break;
- case 0:
- if (L = Lock(Elmt, SHARED_LOCK)) {
- long ok;
-
- ok = Examine(L, fib);
- UnLock(L); // UnLock so that command can open file for writing
- if (ok) {
- if (ArgV[ARG_ALL] && fib->fib_DirEntryType >= 0) { // This is a dir
- strcpy(Buffer, Elmt);
- AddPart(Buffer, "#?", MAX_PATHLEN);
- rc = ProcessEntryPattern(AP, &SelectInfo, &Opt, StartPath, Buffer, FileData, ArgV[ARG_CMD]);
- }
- else
- rc = ProcessEntry(&SelectInfo, fib, StartPath, Elmt, FileData, &Opt, ArgV[ARG_CMD]);
- }
- else {
- PrintFault(IoErr(), Elmt);
- rc = RETURN_FAIL;
- }
- }
- else if (ArgV[ARG_CMD]) // Arg does not exists, allow: For 1 2 3 DO Echo %%
- rc = ExecuteCmd(ArgV[ARG_CMD], StartPath, Elmt, &Opt);
- else
- rc = RETURN_WARN;
- break;
- default:
- PrintFault(IoErr(), Elmt);
- rc = RETURN_FAIL;
- }
- }
- }
- FreeVec(AP);
- }
- FreeVec(FileData);
- }
- else if (rc == 21)
- rc = RETURN_FAIL;
- else
- PrintFault(ERROR_NO_FREE_STORE, "For");
- if (fib)
- FreeVec(fib);
- if (Buffer)
- FreeVec(Buffer);
- if (StartPath)
- FreeVec(StartPath);
- if (WhatIsBase)
- CloseLibrary(WhatIsBase);
- return rc;
- }
-
-