/* 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 #include #include #include #include #include #include #include #include #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 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); }