home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
375.lha
/
ARPTools_v1.0
/
src
/
tail.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-02
|
5KB
|
236 lines
/*
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);
}