home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************/
- /* FetchRefs.c - startup, argument parsing and closedown */
- /**************************************************************************/
-
- #include "FetchRefs.h"
-
- /* ReadArgs stuff */
- /* enum Arg { FILES, PORTNAME }; */
-
- const UBYTE Vers_Tag[] = "$VER: FetchRefs " VERSION " " DATE;
- const UBYTE Template[] = "FILES/M,PORTNAME,RUNONCE/S";
- const UBYTE CLI_Help[] = "\n"
- "FetchRefs [FILES <wildcard> [...]] [PORTNAME <name>] [RUNONCE]\n"
- "\n"
- "- FILES are index files generated by GenerateIndex\n"
- "- Default ARexx port name is FETCHREFS\n"
- "- Please read the guide for further information\n"
- "\n";
-
- struct RDArgs *Args;
- STRPTR ToolTypeArgs;
- LONG ParseResult[NO_MORE_ARGUMENTS];
-
- /* Other variables */
- extern struct WBStartup *_WBMsg;
- struct List FileList, LoadedFiles;
-
- /* Main entry point. Clear List's, parse arguments and call the ARexx interface
- * loop. Then clear up.
- */
- __stkargs
- _main(LONG argc, STRPTR argv)
- {
- LONG count;
- STRPTR path;
-
- /* Initialize lists */
- NewList(&FileList);
- NewList(&LoadedFiles);
-
- /* Allocate memory */
- if (Args = AllocDosObject(DOS_RDARGS, NULL))
- {
- LONG retur = 0;
-
- Args->RDA_ExtHelp = CLI_Help; /* Activate extended help */
-
- /* Convert tool types to something that ReadArgs() understands */
- if (_WBMsg)
- {
- struct DiskObject *diskobj;
-
- if (ToolTypeArgs = AllocVec(1024, NULL))
- {
- CurrentDir(_WBMsg->sm_ArgList->wa_Lock);
- if (diskobj = GetDiskObject(_WBMsg->sm_ArgList->wa_Name))
- {
- int err;
- static struct EasyStruct errreq = {
- sizeof(struct EasyStruct),
- 0,
- "FetchRefs " VERSION " by Anders Melchiorsen",
- "There is a problem with this tool type:\n%s\n"
- "The error seems to be: %s (#%ld)",
- "Quit"
- };
-
- if (!(err = ToolTypesToReadArgs(diskobj->do_ToolTypes, Template, ToolTypeArgs, 1)))
- {
- Args->RDA_Source.CS_Buffer = ToolTypeArgs;
- Args->RDA_Source.CS_Length = strlen(ToolTypeArgs);
- Args->RDA_Flags = RDAF_NOPROMPT;
-
- FreeDiskObject(diskobj);
- } else
- {
- UBYTE errortxt[80];
-
- Fault(err & 0xFFFF, NULL, errortxt, 80);
- EasyRequest(NULL, &errreq, NULL, diskobj->do_ToolTypes[err >> 16], errortxt, err & 0xFFFF);
- FreeDiskObject(diskobj);
- CloseAll(err & 0xFFFF);
- }
- }
- } else
- CloseAll(ERROR_NO_FREE_STORE);
- }
-
- if (ReadArgs(Template, ParseResult, Args)) /* Parse arguments */
- {
- STRPTR port = (ParseResult[PORTNAME]) ? ((STRPTR)ParseResult[PORTNAME]) : ((STRPTR)"FETCHREFS");
-
- /* Check if ARexx was opened for us */
- if (!RexxSysBase)
- {
- PutStr("You need rexxsyslib.library (ARexx)!\n");
- CloseAll(0);
- }
-
- /* Try to allocate an ARexx port. If the name is used, append a
- * slot number as suffix - if RUNONCE argument was specified,
- * close both copies of FetchRefs.
- */
- if (CreateGlobalDiceRexxPort(NULL, port) == -1)
- {
- if (CreateDiceRexxPort(NULL, port) == -1)
- CloseAll(ERROR_NO_FREE_STORE);
-
- if (ParseResult[RUNONCE])
- {
- if (PlaceRexxCommandDirect(NULL, port, "FR_QUIT", NULL, NULL) == 0)
- CloseAll(0);
- }
- }
-
- /* Expand each wildcard (which can also be just a file) and read refs */
- if (ParseResult[FILES])
- for (count = 0; path = ((UBYTE **)ParseResult[FILES])[count]; count++)
- ReadWild(path);
-
- /* Activate ARexx handler */
- ARexxLoop();
-
- /* Close everything down */
- CloseAll(retur);
- } else
- CloseAll(IoErr());
- } else
- CloseAll(ERROR_NO_FREE_STORE);
-
- /* Dummy; never actually called */
- _waitwbmsg();
- }
-
- /* Call ReadRefs() for all files matching 'path' */
- void
- ReadWild(STRPTR path)
- {
- struct AnchorPath *fanchor;
-
- if (fanchor = AllocVec(sizeof(struct AnchorPath), MEMF_CLEAR))
- {
- if (MatchFirst(path, fanchor) == 0)
- {
- do
- {
- BPTR olddir;
-
- olddir = CurrentDir(fanchor->ap_Current->an_Lock);
- ReadRefs(fanchor->ap_Info.fib_FileName, fanchor->ap_Info.fib_Size);
- CurrentDir(olddir);
- } while(MatchNext(fanchor) == 0);
- } else if (!_WBMsg)
- Printf("Warning: no match for '%s'\n", (LONG)path);
- MatchEnd(fanchor);
- FreeVec(fanchor);
- }
- }
-
- /* Read all the references in 'filename' (with file lenght 'filesize'). */
- void
- ReadRefs(STRPTR filename, LONG filesize)
- {
- char *buffer;
-
- /* Attemp to load into one big chunk of memory */
- if (buffer = AllocVec(filesize + sizeof(struct Node), MEMF_CLEAR))
- {
- BPTR file;
-
- if (file = Open(filename, MODE_OLDFILE))
- {
- struct FileEntry *fileentry;
- char *gotto;
-
- /* Track the allocated memory */
- AddTail(&LoadedFiles, (struct Node *)buffer);
- buffer += sizeof(struct Node);
-
- Read(file, buffer, filesize);
- Close(file);
-
- gotto = buffer;
- buffer = buffer + filesize;
-
- while (gotto < buffer)
- {
- int size;
-
- size = (LONG)(((struct Node *)gotto)->ln_Succ);
-
- if (((struct Node *)gotto)->ln_Type == 1)
- {
- fileentry = gotto;
- AddTail(&FileList, &fileentry->node);
- NewList(&fileentry->RefsList);
- fileentry->node.ln_Name = fileentry->Name;
- } else if (((struct Node *)gotto)->ln_Type == 2)
- {
- struct RefsEntry *refsentry;
-
- refsentry = gotto;
- AddTail(&fileentry->RefsList, &refsentry->node);
- refsentry->node.ln_Name = fileentry->Name;
- }
- gotto += size;
- }
- } else
- FreeVec(buffer);
- } else
-
- /* Load into fragmented memory. Though this will give more overhead for
- * housekeeping of the memory blocks, it will still stand a much better
- * chance of actually loading the file - however, it is extremely slow!
- */
- {
- BPTR file;
-
- if (file = Open(filename, MODE_OLDFILE))
- {
- struct FileEntry *fileentry;
- struct Node tmpnode;
-
- while (Read(file, &tmpnode, sizeof(struct Node)))
- {
- if (buffer = AllocVec((LONG)tmpnode.ln_Succ + sizeof(struct Node), MEMF_CLEAR))
- {
- /* Track the allocated memory */
- AddTail(&LoadedFiles, (struct Node *)buffer);
- buffer += sizeof(struct Node);
-
- ((struct FileEntry *)buffer)->node = tmpnode;
- Read(file, buffer + sizeof(struct Node), (LONG)tmpnode.ln_Succ - sizeof(struct Node));
-
- if (tmpnode.ln_Type == 1)
- {
- fileentry = ((struct FileEntry *)buffer);
-
- AddTail(&FileList, &fileentry->node);
- NewList(&fileentry->RefsList);
- fileentry->node.ln_Name = fileentry->Name;
- } else if (tmpnode.ln_Type == 2)
- {
- struct RefsEntry *refsentry = ((struct RefsEntry *)buffer);
-
- AddTail(&fileentry->RefsList, &refsentry->node);
- refsentry->node.ln_Name = fileentry->Name;
- }
- } else
- break;
- }
- Close(file);
- }
- }
- }
-
- /* Release all files from memory */
- void
- FreeRefs()
- {
- struct Node *deallocate;
-
- while (deallocate = RemHead(&LoadedFiles))
- FreeVec(deallocate);
- NewList(&FileList);
- }
-
- /* Clean up and possible print an error report */
- void
- CloseAll(LONG error)
- {
- FreeRefs();
-
- if (ToolTypeArgs)
- FreeVec(ToolTypeArgs);
-
- if (Args)
- {
- FreeArgs(Args);
- FreeDosObject(DOS_RDARGS, Args);
- }
-
- if (error && !_WBMsg)
- PrintFault(error, "FetchRefs");
-
- _exit(error ? 5 : 0);
- }
-