home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / dev / fetchrefs-1.1.lha / FetchRefs / Source / FetchRefs / FetchRefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-11  |  8.9 KB  |  288 lines

  1. /**************************************************************************/
  2. /* FetchRefs.c - startup, argument parsing and closedown                  */
  3. /**************************************************************************/
  4.  
  5. #include "FetchRefs.h"
  6.  
  7. /* ReadArgs stuff */
  8. /* enum Arg { FILES, PORTNAME }; */
  9.  
  10. const UBYTE Vers_Tag[] = "$VER: FetchRefs " VERSION " " DATE;
  11. const UBYTE Template[] = "FILES/M,PORTNAME,RUNONCE/S";
  12. const UBYTE CLI_Help[] = "\n"
  13.                          "FetchRefs [FILES <wildcard> [...]] [PORTNAME <name>] [RUNONCE]\n"
  14.                          "\n"
  15.                          "- FILES are index files generated by GenerateIndex\n"
  16.                          "- Default ARexx port name is FETCHREFS\n"
  17.                          "- Please read the guide for further information\n"
  18.                          "\n";
  19.  
  20. struct RDArgs *Args;
  21. STRPTR ToolTypeArgs;
  22. LONG ParseResult[NO_MORE_ARGUMENTS];
  23.  
  24. /* Other variables */
  25. extern struct WBStartup *_WBMsg;
  26. struct List FileList, LoadedFiles;
  27.  
  28. /* Main entry point. Clear List's, parse arguments and call the ARexx interface
  29.  * loop. Then clear up.
  30.  */
  31. __stkargs
  32. _main(LONG argc, STRPTR argv)
  33. {
  34.     LONG count;
  35.     STRPTR path;
  36.  
  37.     /* Initialize lists */
  38.     NewList(&FileList);
  39.     NewList(&LoadedFiles);
  40.  
  41.     /* Allocate memory */
  42.     if (Args = AllocDosObject(DOS_RDARGS, NULL))
  43.     {
  44.         LONG retur = 0;
  45.  
  46.         Args->RDA_ExtHelp = CLI_Help; /* Activate extended help */
  47.  
  48.         /* Convert tool types to something that ReadArgs() understands */
  49.         if (_WBMsg)
  50.         {
  51.             struct DiskObject *diskobj;
  52.  
  53.             if (ToolTypeArgs = AllocVec(1024, NULL))
  54.             {
  55.                 CurrentDir(_WBMsg->sm_ArgList->wa_Lock);
  56.                 if (diskobj = GetDiskObject(_WBMsg->sm_ArgList->wa_Name))
  57.                 {
  58.                     int err;
  59.                     static struct EasyStruct errreq = {
  60.                         sizeof(struct EasyStruct),
  61.                         0,
  62.                         "FetchRefs " VERSION " by Anders Melchiorsen",
  63.                         "There is a problem with this tool type:\n%s\n"
  64.                         "The error seems to be: %s (#%ld)",
  65.                         "Quit"
  66.                     };
  67.  
  68.                     if (!(err = ToolTypesToReadArgs(diskobj->do_ToolTypes, Template, ToolTypeArgs, 1)))
  69.                     {
  70.                         Args->RDA_Source.CS_Buffer = ToolTypeArgs;
  71.                         Args->RDA_Source.CS_Length = strlen(ToolTypeArgs);
  72.                         Args->RDA_Flags = RDAF_NOPROMPT;
  73.  
  74.                         FreeDiskObject(diskobj);
  75.                     } else
  76.                     {
  77.                         UBYTE errortxt[80];
  78.  
  79.                         Fault(err & 0xFFFF, NULL, errortxt, 80);
  80.                         EasyRequest(NULL, &errreq, NULL, diskobj->do_ToolTypes[err >> 16], errortxt, err & 0xFFFF);
  81.                         FreeDiskObject(diskobj);
  82.                         CloseAll(err & 0xFFFF);
  83.                     }
  84.                 }
  85.             } else
  86.                 CloseAll(ERROR_NO_FREE_STORE);
  87.         }
  88.  
  89.         if (ReadArgs(Template, ParseResult, Args)) /* Parse arguments */
  90.         {
  91.             STRPTR port = (ParseResult[PORTNAME]) ? ((STRPTR)ParseResult[PORTNAME]) : ((STRPTR)"FETCHREFS");
  92.  
  93.             /* Check if ARexx was opened for us */
  94.             if (!RexxSysBase)
  95.             {
  96.                 PutStr("You need rexxsyslib.library (ARexx)!\n");
  97.                 CloseAll(0);
  98.             }
  99.  
  100.             /* Try to allocate an ARexx port. If the name is used, append a
  101.              * slot number as suffix - if RUNONCE argument was specified, 
  102.              * close both copies of FetchRefs.
  103.              */
  104.             if (CreateGlobalDiceRexxPort(NULL, port) == -1)
  105.             {
  106.                 if (CreateDiceRexxPort(NULL, port) == -1)
  107.                     CloseAll(ERROR_NO_FREE_STORE);
  108.  
  109.                 if (ParseResult[RUNONCE])
  110.                 {
  111.                     if (PlaceRexxCommandDirect(NULL, port, "FR_QUIT", NULL, NULL) == 0)
  112.                         CloseAll(0);
  113.                 }
  114.             }
  115.  
  116.             /* Expand each wildcard (which can also be just a file) and read refs */
  117.             if (ParseResult[FILES])
  118.                 for (count = 0; path = ((UBYTE **)ParseResult[FILES])[count]; count++)
  119.                     ReadWild(path);
  120.  
  121.             /* Activate ARexx handler */
  122.             ARexxLoop();
  123.  
  124.             /* Close everything down */
  125.             CloseAll(retur);
  126.         } else
  127.             CloseAll(IoErr());
  128.     } else
  129.         CloseAll(ERROR_NO_FREE_STORE);
  130.  
  131.      /* Dummy; never actually called */
  132.     _waitwbmsg();
  133. }
  134.  
  135. /* Call ReadRefs() for all files matching 'path' */
  136. void
  137. ReadWild(STRPTR path)
  138. {
  139.     struct AnchorPath *fanchor;
  140.  
  141.     if (fanchor = AllocVec(sizeof(struct AnchorPath), MEMF_CLEAR))
  142.     {
  143.         if (MatchFirst(path, fanchor) == 0)
  144.         {
  145.             do
  146.             {
  147.                 BPTR olddir;
  148.  
  149.                 olddir = CurrentDir(fanchor->ap_Current->an_Lock);
  150.                 ReadRefs(fanchor->ap_Info.fib_FileName, fanchor->ap_Info.fib_Size);
  151.                 CurrentDir(olddir);
  152.             } while(MatchNext(fanchor) == 0);
  153.         } else if (!_WBMsg)
  154.             Printf("Warning: no match for '%s'\n", (LONG)path);
  155.         MatchEnd(fanchor);
  156.         FreeVec(fanchor);
  157.     }
  158. }
  159.  
  160. /* Read all the references in 'filename' (with file lenght 'filesize'). */
  161. void
  162. ReadRefs(STRPTR filename, LONG filesize)
  163. {
  164.     char *buffer;
  165.  
  166.     /* Attemp to load into one big chunk of memory */
  167.     if (buffer = AllocVec(filesize + sizeof(struct Node), MEMF_CLEAR))
  168.     {
  169.         BPTR file;
  170.  
  171.         if (file = Open(filename, MODE_OLDFILE))
  172.         {
  173.             struct FileEntry *fileentry;
  174.             char *gotto;
  175.  
  176.             /* Track the allocated memory */
  177.             AddTail(&LoadedFiles, (struct Node *)buffer);
  178.             buffer += sizeof(struct Node);
  179.  
  180.             Read(file, buffer, filesize);
  181.             Close(file);
  182.  
  183.             gotto = buffer;
  184.             buffer = buffer + filesize;
  185.  
  186.             while (gotto < buffer)
  187.             {
  188.                 int size;
  189.  
  190.                 size = (LONG)(((struct Node *)gotto)->ln_Succ);
  191.  
  192.                 if (((struct Node *)gotto)->ln_Type == 1)
  193.                 {
  194.                     fileentry = gotto;
  195.                     AddTail(&FileList, &fileentry->node);
  196.                     NewList(&fileentry->RefsList);
  197.                     fileentry->node.ln_Name = fileentry->Name;
  198.                 } else if (((struct Node *)gotto)->ln_Type == 2)
  199.                 {
  200.                     struct RefsEntry *refsentry;
  201.  
  202.                     refsentry = gotto;
  203.                     AddTail(&fileentry->RefsList, &refsentry->node);
  204.                     refsentry->node.ln_Name = fileentry->Name;
  205.                 }
  206.                 gotto += size;
  207.             }
  208.         } else
  209.             FreeVec(buffer);
  210.     } else 
  211.  
  212.     /* Load into fragmented memory. Though this will give more overhead for
  213.      * housekeeping of the memory blocks, it will still stand a much better
  214.      * chance of actually loading the file - however, it is extremely slow!
  215.      */
  216.     {
  217.         BPTR file;
  218.  
  219.         if (file = Open(filename, MODE_OLDFILE))
  220.         {
  221.             struct FileEntry *fileentry;
  222.             struct Node tmpnode;
  223.  
  224.             while (Read(file, &tmpnode, sizeof(struct Node)))
  225.             {
  226.                 if (buffer = AllocVec((LONG)tmpnode.ln_Succ + sizeof(struct Node), MEMF_CLEAR))
  227.                 {
  228.                     /* Track the allocated memory */
  229.                     AddTail(&LoadedFiles, (struct Node *)buffer);
  230.                     buffer += sizeof(struct Node);
  231.                     
  232.                     ((struct FileEntry *)buffer)->node = tmpnode;
  233.                     Read(file, buffer + sizeof(struct Node), (LONG)tmpnode.ln_Succ - sizeof(struct Node));
  234.  
  235.                     if (tmpnode.ln_Type == 1)
  236.                     {
  237.                         fileentry = ((struct FileEntry *)buffer);
  238.  
  239.                         AddTail(&FileList, &fileentry->node);
  240.                         NewList(&fileentry->RefsList);
  241.                         fileentry->node.ln_Name = fileentry->Name;
  242.                     } else if (tmpnode.ln_Type == 2)
  243.                     {
  244.                         struct RefsEntry *refsentry = ((struct RefsEntry *)buffer);
  245.  
  246.                         AddTail(&fileentry->RefsList, &refsentry->node);
  247.                         refsentry->node.ln_Name = fileentry->Name;
  248.                     }
  249.                 } else
  250.                     break;
  251.             }
  252.             Close(file);
  253.         }
  254.     }
  255. }
  256.  
  257. /* Release all files from memory */
  258. void
  259. FreeRefs()
  260. {
  261.     struct Node *deallocate;
  262.  
  263.     while (deallocate = RemHead(&LoadedFiles))
  264.         FreeVec(deallocate);
  265.     NewList(&FileList);
  266. }
  267.  
  268. /* Clean up and possible print an error report */
  269. void
  270. CloseAll(LONG error)
  271. {
  272.     FreeRefs();
  273.  
  274.     if (ToolTypeArgs)
  275.         FreeVec(ToolTypeArgs);
  276.  
  277.     if (Args)
  278.     {
  279.         FreeArgs(Args);
  280.         FreeDosObject(DOS_RDARGS, Args);
  281.     }
  282.  
  283.     if (error && !_WBMsg)
  284.         PrintFault(error, "FetchRefs");
  285.  
  286.     _exit(error ? 5 : 0);
  287. }
  288.