home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Tail - Display the last lines of a file.
-
- Original effort by Fabio Rossetti. Inspired by the tail program
- by Gary Brant found on <>< 179.
-
- (c) 1989 by Fabio Rossetti
-
- To compile under Lattice C v5.0x use:
-
- lc -O -v -cus tail
- blink lib:cres.o tail.o to tail 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>
-
- struct ArpBase *ArpBase=NULL;
- struct Process *Pr;
- LONG argc;
-
- #define NARGS 4
- #define BFSIZE 256
- #define FROM argv[0]
- #define TO argv[1]
- #define LIN argv[2]
- #define BAN argv[3]
- STRPTR argv[NARGS];
- #define MAXLIN 256
- TEXT *Lin[256];
-
-
- TEXT *Buf,*OBuf;
- TEXT Banner[256];
-
- struct UserAnchor {
- struct AnchorPath ua_AP;
- BYTE moremem[255]; /* extension */
- };
- struct UserAnchor *Anchor=NULL;
-
- /* Trick to keep code down to size */
- VOID MemCleanup()
- {
- }
-
- /* shutdown routine */
- VOID Cleanup(r1,r2,msg)
- LONG r1,r2;
- STRPTR msg;
- {
- if (msg) Puts(msg);
- if (ArpBase) CloseLibrary((struct Library *)ArpBase);
- Pr->pr_Result2 = r2;
- exit(r1);
- }
-
- VOID Tail(Inp,Out,lines)
- BPTR Inp,Out;
- ULONG lines;
-
- {
-
- REGISTER TEXT *il = Lin[0];
- REGISTER LONG count, obp=0,p=0,i,fl=0;
-
- /* enqueue the last lines read */
- for(;;) {
- /* read until eof */
- if (!obp) if (!(count = Read(Inp,Buf,BFSIZE))) {
- /* the last line */
- if(fl) {
- *il = '\0';
- p++;}
- break;
- }
- fl = 1;
- if (*(Buf + obp) == '\n') {
- fl = 0;
- ++obp;
- *il = '\0';
- p++;
- il = Lin[p%lines];
-
- if (SetSignal(0,0) & SIGBREAKF_CTRL_C)
- Cleanup(RETURN_WARN,NULL,"***Break");
- }
- else
- {
- if (((TEXT *)il - (TEXT *)Lin[p%lines]) > MAXLIN)
- Cleanup(RETURN_FAIL,NULL,"Buffer overflow");
- *il++ = *(Buf + obp++);
- }
-
- if (obp == count) obp = 0;
-
- }
-
- /* display queue */
- if (p <= lines) for(i=0; i < p; i++) FPrintf(Out,"%s\n",Lin[i]);
- else {
- for(i=(p%lines); i < lines; i++) {
- if (SetSignal(0,0) & SIGBREAKF_CTRL_C)
- Cleanup(RETURN_WARN,NULL,"***Break");
- FPrintf(Out,"%s\n",Lin[i]);
- }
-
- if ((lines != 1) && ((p%lines) != 0))
- for(i=0; i <= (p%lines)-1 ; i++) {
- FPrintf(Out,"%s\n",Lin[i]);
- if (SetSignal(0,0) & SIGBREAKF_CTRL_C)
- Cleanup(RETURN_WARN,NULL,"***Break");
- }
- }
- }
-
- VOID _main(Line)
- STRPTR Line;
- {
-
-
-
- BPTR infh,outfh;
- LONG Lines,Result,i=0,j;
- char **ArV;
- Pr = (struct Process*)FindTask(NULL);
-
-
- if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion)))
- Cleanup(RETURN_FAIL,ERROR_INVALID_RESIDENT_LIBRARY,NULL);
-
- /* parse command line */
- for (argc=0;argc < NARGS ;++argc)
- argv[argc] = (STRPTR) NULL;
-
- while(*Line > ' ')
- ++Line;
-
- if((argc = GADS(++Line,
- strlen(Line),
- "Usage: Tail [Files file1 file2 ...] [TO filename] [LIN linenumber] [BAN]",
- argv,
- "Files/...,TO/K,LIN/K,BAN/S" )) < 0)
- Cleanup(RETURN_WARN,NULL,FROM);
-
- if (!(Buf = ArpAllocMem(BFSIZE,MEMF_CLEAR)))
- Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error: no memory");
-
- if ( Anchor = (struct UserAnchor *)ArpAlloc( (ULONG)sizeof( *Anchor )) )
- {
- Anchor->ua_AP.ap_Length = 255; /* Want full path built */
-
- }
- else Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error:No memory");
-
-
- if (LIN) {
- Lines = Atol(LIN);
- if((Errno == ERRBADINT) || (Lines <=0)) Cleanup(RETURN_ERROR,NULL,"Bad args");
- if(Lines > 255) Cleanup(RETURN_WARN,NULL,"Too many lines");
- }
- else Lines = 10;
-
- /* set up queue */
- for (j = 0; j < Lines; j++) {
- if (!(Lin[j]=ArpAllocMem(MAXLIN,MEMF_CLEAR)))
- Cleanup(RETURN_ERROR,ERROR_NO_FREE_STORE,"Error: no memory!");
- }
- if(TO) {
- if(!(outfh=ArpOpen(TO,MODE_NEWFILE))) {
- Printf("Can't open %s\n",TO);
- Cleanup(RETURN_ERROR,ERROR_OBJECT_NOT_FOUND,NULL);
- }
- }
- else outfh = Output();
-
-
- ArV = (char **)FROM;
- if (ArV[0]) {
-
- if ( Anchor = (struct UserAnchor *)ArpAlloc( (ULONG)sizeof( *Anchor )) )
- {
- Anchor->ua_AP.ap_Length = 255; /* Want full path built */
-
- }
- else
- Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"Error: no memory");
-
- while (ArV[i] != NULL) {
-
- Result = FindFirst(ArV[i],(struct AnchorPath*) Anchor);
-
- while (Result == 0) {
-
- if (Anchor->ua_AP.ap_Info.fib_DirEntryType < 0) {
- if(!(infh=ArpOpen(Anchor->ua_AP.ap_Buf,MODE_OLDFILE))) {
- Printf("Can't open %s\n",FROM);
- Cleanup(RETURN_ERROR,ERROR_OBJECT_NOT_FOUND,NULL);
- }
- else {
- if (BAN) {
- PathName(ArpLock(Anchor->ua_AP.ap_Buf,
- ACCESS_READ),Banner,255);
- FPrintf(outfh,"*** File %s ***\n",
- Banner);
- }
- Tail(infh,outfh,Lines);
- }
- }
- else {
- Printf("%s is a directory !\n",ArV[i]);
- Cleanup(RETURN_ERROR,ERROR_OBJECT_WRONG_TYPE,NULL);
- }
-
- Result = FindNext((struct AnchorPath*) Anchor );
- }
- i++;
- }
- }
-
- else Tail(Input(),outfh,Lines);
-
- Cleanup(NULL,NULL,NULL);
-
-
- }
-