home *** CD-ROM | disk | FTP | other *** search
- /*
- 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);
- }
-