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 >
C/C++ Source or Header  |  1989-12-27  |  6KB  |  322 lines

  1. /*
  2.           For - Use wildcards with commands not supporting them.
  3.  
  4.           Original effort by Fabio Rossetti.
  5.  
  6.           (c) 1989 by Fabio Rossetti
  7.  
  8.           To compile under Lattice C v5.0x use:
  9.  
  10.         lc -O -v -cus for
  11.         blink lib:cres.o for.o to for lib lib:a.lib lib:lc.lib sd nd
  12.  
  13. */
  14.     
  15.  
  16. #include <exec/types.h>
  17. #include <exec/memory.h>
  18. #include <exec/libraries.h>
  19. #include <libraries/dos.h>
  20. #include <libraries/dosextens.h>
  21. #include <libraries/arpbase.h>
  22. #include <arpfunctions.h>
  23. #include <proto/exec.h>
  24. #include <proto/dos.h>
  25.  
  26. #define MAXARG 20
  27. #define PAT 0
  28. #define MOD 1
  29. #define DO 2
  30. #define ARGS 3
  31. #define DIRECTORY    0
  32. #define FILE        1
  33. #define DALIST TRUE
  34. #define ANCHOR TRUE
  35. #define BREAKS (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)
  36.  
  37. struct Process *Pr;
  38. struct ArpBase *ArpBase;
  39. BPTR DoSeg;
  40. struct ResidentProgramNode *DoNode;
  41. struct UserAnchor {
  42.     struct    AnchorPath    ua_AP;
  43.     BYTE    moremem[255];    /* extension */
  44. };
  45.  
  46. struct    UserAnchor *Anchor = NULL;
  47.  
  48. struct DirectoryEntry *FileList = NULL;    /* Head of DAList */
  49.  
  50. struct {
  51.     unsigned Sort : 1;
  52.     unsigned Verbose : 1;
  53.     unsigned Res : 1;
  54.     unsigned Dirs : 1;
  55.     unsigned Files : 1;
  56.     } Mod;
  57.  
  58. TEXT Arguments[256];
  59.  
  60. LONG argc,Pat;
  61. STRPTR argv[MAXARG];
  62.  
  63. /* shutdown */
  64. VOID Cleanup(code,retcode,msg)
  65. LONG code,retcode;
  66. STRPTR msg;
  67. {
  68.     if (FileList) FreeDAList( FileList );
  69.     if (Anchor) {
  70.             FreeAnchorChain( (struct AnchorPath *) Anchor );
  71.             FreeMem(Anchor, sizeof( *Anchor));
  72.              }
  73.  
  74.     CloseLibrary( (struct Library *) ArpBase);
  75.  
  76.     Pr->pr_Result2 = retcode;
  77.     if (msg) Puts(msg);
  78.     if (Mod.Res) RemResidentPrg(argv[DO]);
  79.     exit(code);
  80. }
  81.  
  82. /* concatenate strings with interleaved blanks */
  83. VOID sstrcat(to,from)
  84. TEXT *to;
  85. TEXT *from;
  86. {
  87.     strcat(to,from);
  88.     strcat(to," ");
  89. }
  90.  
  91. VOID SyncIt(Pt)
  92. TEXT *Pt;
  93.  
  94. {
  95.     LONG Rc;
  96.     REGISTER LONG i;
  97.  
  98.     if(Pat==DO) for (i=ARGS; i <argc; ++i)
  99.                  sstrcat(&Arguments,argv[i]);
  100.         else {
  101.             for(i=ARGS;i < Pat; ++i)
  102.                  sstrcat(&Arguments,argv[i]);
  103.             strcat(&Arguments,"\"");
  104.             strcat(&Arguments,Pt);
  105.             sstrcat(&Arguments,"\"");
  106.             for(i=Pat+1; i <argc; ++i)
  107.                  sstrcat(&Arguments,argv[i]); 
  108.             }
  109.  
  110.     if (Mod.Verbose) Printf("*** Executing: %s %s ***\n\n",
  111.                     argv[DO],Arguments);
  112.  
  113.     /* problem with resident: checksum invalid or lowmem */
  114.     if (Mod.Res) 
  115.         if (!(DoNode = ObtainResidentPrg(argv[DO]))) {
  116.         Puts("***Warn: problem with resident, releasing segs");
  117.         /*ReleaseResidentPrg(DoSeg);*/
  118.         RemResidentPrg(argv[DO]);
  119.         /* not to do this anymore */
  120.         Mod.Res = 0;
  121.         }
  122.         else ReleaseResidentPrg(DoSeg);
  123.  
  124.     if((Rc = SyncRun(argv[DO],Arguments,NULL,NULL)) < 0) 
  125.         Cleanup(RETURN_ERROR,NULL,"Error:can't load/execute program");
  126.         
  127.     
  128.     if (Mod.Verbose) Printf("\n*** Return Code = %ld ; Error Code = %ld ***\n",
  129.                             Rc,
  130.                             Pr->pr_Result2);
  131.  
  132.     
  133.                     
  134.     *Arguments = '\0';
  135.  
  136. }
  137.  
  138. VOID _main(Line)
  139.  
  140. STRPTR Line;
  141.  
  142. {
  143.  
  144.     LONG Result,key;
  145.  
  146.     REGISTER struct DirectoryEntry    *de;
  147.         
  148.     Pr = (struct Process*)FindTask(NULL);
  149.  
  150.     if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion))){
  151.             Pr->pr_Result2=ERROR_INVALID_RESIDENT_LIBRARY;
  152.             exit(RETURN_FAIL);
  153.             }
  154.  
  155.     /* parse command line */
  156.     for (argc=0;argc < MAXARG;++argc)
  157.         argv[argc] = (STRPTR) NULL;
  158.  
  159.     while(*Line > ' ')
  160.         ++Line;
  161.  
  162.     /* I couldn't get /.. (and any other tracked fucntion) to work
  163.        in conjunction with SyncRun() in a way to prevent ARP not to
  164.        release resources.. There HAS to be a bug. SDB are you listening ? */
  165.     if((argc = GADS(++Line,
  166.             strlen(Line),
  167.             "\nUsage: For Pattern [MODE S|V|R|F|D] DO Command [Arguments]\n       %% will be replaced with pattern\n",
  168.             argv,
  169.             "PAT/A,MODE/K,DO/A,,,,,,,,,,,,,,,")) <= 0)
  170.                 Cleanup(RETURN_ERROR,NULL,argv[0]);
  171.     
  172.  
  173.     argc += (argv[MOD]) ? 0 : 1;
  174.  
  175.     Mod.Sort=Mod.Verbose=Mod.Res=0;
  176.     Mod.Dirs=Mod.Files=1;
  177.  
  178.     /* set options */
  179.     do {
  180.     switch (Toupper((TEXT)*argv[MOD])) {
  181.  
  182.         case 'S':
  183.             Mod.Sort = 1;
  184.             break;
  185.         case 'V':
  186.             Mod.Verbose = 1;
  187.             break;
  188.         case 'R':
  189.             Mod.Res = 1;
  190.             break;
  191.         case 'F':
  192.             Mod.Dirs = 0;
  193.             break;
  194.         case 'D':
  195.             Mod.Files = 0;
  196.             break;
  197.         }
  198.     }    
  199.     while (*argv[MOD]++ != '\0') ;
  200.  
  201.     /* Just in case...*/
  202.     if (!(Mod.Files || Mod.Dirs)) Mod.Files=Mod.Dirs=1;
  203.  
  204.     /* Find argument where pattern is to be expanded, if any.
  205.     Only one allowed...Oh how much I love all the C-ism down here.*/
  206.     for(Pat=argc; (Strcmp(argv[Pat],"%%") && (Pat > DO)); Pat--);
  207.  
  208.     /* Check if resident mode is req'd and proceed if prog ain't
  209.        resident either */
  210.  
  211.     if (Mod.Res)
  212.     {
  213.     if (!(DoNode = ObtainResidentPrg(argv[DO]))) {
  214.         
  215.         if(!(DoSeg = LoadPrg(argv[DO]))) {
  216.             Mod.Res = 0;
  217.             Cleanup(RETURN_ERROR,NULL,"Error: can't load program");
  218.             }
  219.         if(!(DoNode  = AddResidentPrg(DoSeg,argv[DO]))) Mod.Res = 0;
  220.     }
  221.     else {
  222.         ReleaseResidentPrg(DoNode->rpn_Segment);
  223.         Mod.Res = 0;    
  224.         }    
  225.     }
  226.  
  227.     /* Allocate space for anchorpath */     
  228.     if ( Anchor = (struct UserAnchor *)AllocMem( (ULONG)sizeof( *Anchor ),MEMF_PUBLIC|MEMF_CLEAR) )
  229.     {
  230.         Anchor->ua_AP.ap_Length = 255;    /* path */
  231.         
  232.     }
  233.     else Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error:No memory");
  234.     
  235.  
  236.     Result = FindFirst( argv[PAT], (struct AnchorPath *)Anchor);
  237.  
  238. while ( Result == 0 )
  239. {
  240.  
  241.  
  242.  
  243.     if (Mod.Sort) {
  244.  
  245.  
  246.         if (Anchor->ua_AP.ap_Info.fib_DirEntryType >= 0)
  247.         {
  248.             key = DIRECTORY;
  249.         }
  250.         else
  251.         {
  252.             key = FILE;
  253.         }
  254.  
  255.         if ( !AddDANode(Anchor->ua_AP.ap_Buf, &FileList, 0L, key))
  256.             Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error: no memory");
  257.         
  258.  
  259.     }
  260.  
  261.     else
  262.     {
  263.  
  264.  
  265.  
  266.         if ((Anchor->ua_AP.ap_Info.fib_DirEntryType >= 0) && Mod.Dirs)
  267.             SyncIt(&Anchor->ua_AP.ap_Buf);
  268.  
  269.         if ((Anchor->ua_AP.ap_Info.fib_DirEntryType < 0) && Mod.Files)
  270.             SyncIt(&Anchor->ua_AP.ap_Buf);
  271.  
  272.  
  273.     }
  274.  
  275.     /* check for ^D */
  276.     if (SetSignal(0,0) & BREAKS)
  277.         Cleanup(RETURN_WARN,NULL,"***Break");
  278.  
  279.         Result = FindNext((struct AnchorPath*) Anchor );
  280. }
  281.  
  282.  
  283.     /* Free the Anchor chain built by the above functions */
  284.  
  285.     if ((Result == ERROR_OBJECT_NOT_FOUND) ||
  286.         (Result != ERROR_NO_MORE_ENTRIES))
  287.             Cleanup(RETURN_ERROR,Result,"Error");
  288.  
  289.     if (Mod.Sort) {
  290.  
  291.     de = FileList;
  292.     if (de->de_Type == DIRECTORY)
  293.     {
  294.         for ( ; de ; de = de->de_Next)
  295.         {
  296.         /* check for ^D */
  297.         if (SetSignal(0,0) & BREAKS)
  298.             Cleanup(RETURN_WARN,NULL,"***Break");
  299.     
  300.         if (de->de_Type != DIRECTORY)
  301.                 break;
  302.             if (Mod.Dirs) SyncIt(de->de_Name);
  303.         }
  304.     }
  305.  
  306.     if ( de && Mod.Files )
  307.     {
  308.         for ( ; de ; de = de->de_Next) {
  309.         /* check for ^D */
  310.         if (SetSignal(0,0) & BREAKS)
  311.             Cleanup(RETURN_WARN,NULL,"***Break");
  312.             
  313.     
  314.         SyncIt(de->de_Name);
  315.         }
  316.     }
  317.  
  318. }
  319.  
  320.     Cleanup(RETURN_OK,NULL,NULL);
  321. }
  322.