home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
326.lha
/
ARPTools
/
src
/
For.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-27
|
6KB
|
322 lines
/*
For - Use wildcards with commands not supporting them.
Original effort by Fabio Rossetti.
(c) 1989 by Fabio Rossetti
To compile under Lattice C v5.0x use:
lc -O -v -cus for
blink lib:cres.o for.o to for lib lib:a.lib lib:lc.lib sd nd
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/arpbase.h>
#include <arpfunctions.h>
#include <proto/exec.h>
#include <proto/dos.h>
#define MAXARG 20
#define PAT 0
#define MOD 1
#define DO 2
#define ARGS 3
#define DIRECTORY 0
#define FILE 1
#define DALIST TRUE
#define ANCHOR TRUE
#define BREAKS (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)
struct Process *Pr;
struct ArpBase *ArpBase;
BPTR DoSeg;
struct ResidentProgramNode *DoNode;
struct UserAnchor {
struct AnchorPath ua_AP;
BYTE moremem[255]; /* extension */
};
struct UserAnchor *Anchor = NULL;
struct DirectoryEntry *FileList = NULL; /* Head of DAList */
struct {
unsigned Sort : 1;
unsigned Verbose : 1;
unsigned Res : 1;
unsigned Dirs : 1;
unsigned Files : 1;
} Mod;
TEXT Arguments[256];
LONG argc,Pat;
STRPTR argv[MAXARG];
/* shutdown */
VOID Cleanup(code,retcode,msg)
LONG code,retcode;
STRPTR msg;
{
if (FileList) FreeDAList( FileList );
if (Anchor) {
FreeAnchorChain( (struct AnchorPath *) Anchor );
FreeMem(Anchor, sizeof( *Anchor));
}
CloseLibrary( (struct Library *) ArpBase);
Pr->pr_Result2 = retcode;
if (msg) Puts(msg);
if (Mod.Res) RemResidentPrg(argv[DO]);
exit(code);
}
/* concatenate strings with interleaved blanks */
VOID sstrcat(to,from)
TEXT *to;
TEXT *from;
{
strcat(to,from);
strcat(to," ");
}
VOID SyncIt(Pt)
TEXT *Pt;
{
LONG Rc;
REGISTER LONG i;
if(Pat==DO) for (i=ARGS; i <argc; ++i)
sstrcat(&Arguments,argv[i]);
else {
for(i=ARGS;i < Pat; ++i)
sstrcat(&Arguments,argv[i]);
strcat(&Arguments,"\"");
strcat(&Arguments,Pt);
sstrcat(&Arguments,"\"");
for(i=Pat+1; i <argc; ++i)
sstrcat(&Arguments,argv[i]);
}
if (Mod.Verbose) Printf("*** Executing: %s %s ***\n\n",
argv[DO],Arguments);
/* problem with resident: checksum invalid or lowmem */
if (Mod.Res)
if (!(DoNode = ObtainResidentPrg(argv[DO]))) {
Puts("***Warn: problem with resident, releasing segs");
/*ReleaseResidentPrg(DoSeg);*/
RemResidentPrg(argv[DO]);
/* not to do this anymore */
Mod.Res = 0;
}
else ReleaseResidentPrg(DoSeg);
if((Rc = SyncRun(argv[DO],Arguments,NULL,NULL)) < 0)
Cleanup(RETURN_ERROR,NULL,"Error:can't load/execute program");
if (Mod.Verbose) Printf("\n*** Return Code = %ld ; Error Code = %ld ***\n",
Rc,
Pr->pr_Result2);
*Arguments = '\0';
}
VOID _main(Line)
STRPTR Line;
{
LONG Result,key;
REGISTER struct DirectoryEntry *de;
Pr = (struct Process*)FindTask(NULL);
if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion))){
Pr->pr_Result2=ERROR_INVALID_RESIDENT_LIBRARY;
exit(RETURN_FAIL);
}
/* parse command line */
for (argc=0;argc < MAXARG;++argc)
argv[argc] = (STRPTR) NULL;
while(*Line > ' ')
++Line;
/* I couldn't get /.. (and any other tracked fucntion) to work
in conjunction with SyncRun() in a way to prevent ARP not to
release resources.. There HAS to be a bug. SDB are you listening ? */
if((argc = GADS(++Line,
strlen(Line),
"\nUsage: For Pattern [MODE S|V|R|F|D] DO Command [Arguments]\n %% will be replaced with pattern\n",
argv,
"PAT/A,MODE/K,DO/A,,,,,,,,,,,,,,,")) <= 0)
Cleanup(RETURN_ERROR,NULL,argv[0]);
argc += (argv[MOD]) ? 0 : 1;
Mod.Sort=Mod.Verbose=Mod.Res=0;
Mod.Dirs=Mod.Files=1;
/* set options */
do {
switch (Toupper((TEXT)*argv[MOD])) {
case 'S':
Mod.Sort = 1;
break;
case 'V':
Mod.Verbose = 1;
break;
case 'R':
Mod.Res = 1;
break;
case 'F':
Mod.Dirs = 0;
break;
case 'D':
Mod.Files = 0;
break;
}
}
while (*argv[MOD]++ != '\0') ;
/* Just in case...*/
if (!(Mod.Files || Mod.Dirs)) Mod.Files=Mod.Dirs=1;
/* Find argument where pattern is to be expanded, if any.
Only one allowed...Oh how much I love all the C-ism down here.*/
for(Pat=argc; (Strcmp(argv[Pat],"%%") && (Pat > DO)); Pat--);
/* Check if resident mode is req'd and proceed if prog ain't
resident either */
if (Mod.Res)
{
if (!(DoNode = ObtainResidentPrg(argv[DO]))) {
if(!(DoSeg = LoadPrg(argv[DO]))) {
Mod.Res = 0;
Cleanup(RETURN_ERROR,NULL,"Error: can't load program");
}
if(!(DoNode = AddResidentPrg(DoSeg,argv[DO]))) Mod.Res = 0;
}
else {
ReleaseResidentPrg(DoNode->rpn_Segment);
Mod.Res = 0;
}
}
/* Allocate space for anchorpath */
if ( Anchor = (struct UserAnchor *)AllocMem( (ULONG)sizeof( *Anchor ),MEMF_PUBLIC|MEMF_CLEAR) )
{
Anchor->ua_AP.ap_Length = 255; /* path */
}
else Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error:No memory");
Result = FindFirst( argv[PAT], (struct AnchorPath *)Anchor);
while ( Result == 0 )
{
if (Mod.Sort) {
if (Anchor->ua_AP.ap_Info.fib_DirEntryType >= 0)
{
key = DIRECTORY;
}
else
{
key = FILE;
}
if ( !AddDANode(Anchor->ua_AP.ap_Buf, &FileList, 0L, key))
Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error: no memory");
}
else
{
if ((Anchor->ua_AP.ap_Info.fib_DirEntryType >= 0) && Mod.Dirs)
SyncIt(&Anchor->ua_AP.ap_Buf);
if ((Anchor->ua_AP.ap_Info.fib_DirEntryType < 0) && Mod.Files)
SyncIt(&Anchor->ua_AP.ap_Buf);
}
/* check for ^D */
if (SetSignal(0,0) & BREAKS)
Cleanup(RETURN_WARN,NULL,"***Break");
Result = FindNext((struct AnchorPath*) Anchor );
}
/* Free the Anchor chain built by the above functions */
if ((Result == ERROR_OBJECT_NOT_FOUND) ||
(Result != ERROR_NO_MORE_ENTRIES))
Cleanup(RETURN_ERROR,Result,"Error");
if (Mod.Sort) {
de = FileList;
if (de->de_Type == DIRECTORY)
{
for ( ; de ; de = de->de_Next)
{
/* check for ^D */
if (SetSignal(0,0) & BREAKS)
Cleanup(RETURN_WARN,NULL,"***Break");
if (de->de_Type != DIRECTORY)
break;
if (Mod.Dirs) SyncIt(de->de_Name);
}
}
if ( de && Mod.Files )
{
for ( ; de ; de = de->de_Next) {
/* check for ^D */
if (SetSignal(0,0) & BREAKS)
Cleanup(RETURN_WARN,NULL,"***Break");
SyncIt(de->de_Name);
}
}
}
Cleanup(RETURN_OK,NULL,NULL);
}