home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
txtutl
/
miscnix.arc
/
TAIL.C
< prev
next >
Wrap
Text File
|
1988-05-28
|
5KB
|
208 lines
#include <stdio.h>
#define ERROR 0
#define MAXINT 32767
#define CPMEOF 26 /* Control Z */
/** TAIL Print last several lines of a file.
Usage: tail [-|+n[lbc][r]] [file ...]
where n is the number of lines (l), 512 byte blocks (b), or
characters (c) from the beginning (+) or end (-) of the file.
The 'r' option causes the lines to be printed in reverse order.
Default is -10 (or -32767 if 'r' is set).
One or more files may be given; also, standard input will be
included in the list if it is a pipe or file. If more than one
file is given, the files will be separated by lines of the form:
==> file.nam <==
Note: If you want to recompile this, make sure your C library allows
you to do fseek() on stdin.
No copyright, dammit: this is PUBLIC DOMAIN!!!
*/
char plus;
long numarg;
char unit ='l';
char revmode;
#define BUFLEN 512
char buf[BUFLEN];
#define BUFLEN2 512
char buf2[BUFLEN2];
char *bufpos,*bufend;
long ftell();
long bgnpos;
long filepos;
usage() {
puts("Usage: tail [-|+#[lbc][r]] [file ...]");
puts("where # is the number of lines from the back (or front) of the file");
puts("and the file is standard input by default.");
exit(1);
}
readback(f)
FILE *f; {
int len;
len=BUFLEN;
if (bgnpos>filepos-len) len=filepos-bgnpos;
filepos-=len;
fseek(f,filepos,0);
fread(buf,1,len,f);
bufpos=bufend= &buf[len];
}
processfile(f,s,b)
FILE *f;
char *s; /* file name */
int b; { /* >0 if we want to print it */
long lastpos;
int nlines;
int len;
if (b>0) {fputs("==> ",stdout); fputs(s,stdout); puts(" <==");}
bgnpos=0;
if (plus) { /* if plus, make use of that information */
bgnpos=numarg;
if (unit!='c') {
bufpos=bufend= &buf;
nlines=numarg;
while (nlines>0) {
bufpos=strnchr(bufpos,bufend-bufpos,'\n');
if (bufpos<bufend) {
--nlines;
++bufpos;
} else {
bufpos= &buf;
bufend= &buf[fread(buf,1,BUFLEN,f)];
if (bufend<=bufpos) break;
}
}
bgnpos=ftell(f) - (int) (bufend-bufpos);
} /* end if unit */
}
else if (unit=='c') {
fseek(f,0L,2);
bgnpos=ftell(f)-numarg;
if (bgnpos<0) bgnpos=0;
}
nlines=0;
if (!plus && unit!='c') nlines=numarg;
else if (revmode) nlines=MAXINT;
/* go reversely through the file */
if (nlines) {
fseek(f,0L,2);
filepos=ftell(f);
readback(f);
if (bufpos > &buf && *(bufpos-1)==CPMEOF) --bufpos;
if (bufpos > &buf && *(bufpos-1)=='\n') --bufpos;
do {
lastpos=filepos + (int) (bufpos-&buf);
for (;;) {
bufpos=strrnchr(&buf,bufpos-&buf,'\n');
if (bufpos>=&buf) break;
readback(f);
if (bufpos<=&buf) {nlines=0; bufpos= &buf-1; break;}
}
if (revmode) {
len = (int) (lastpos-filepos) - (bufend-&buf);
if (len <= 0) {
if (*(bufend+len-1)=='\r') --len;
fwrite(bufpos+1,1,len+bufend-bufpos-1,stdout);
} else {
fwrite(bufpos+1,1,bufend-bufpos-1,stdout);
fseek(f,filepos + (int) (bufend-&buf),0);
while (len>BUFLEN2) {
fread(buf2,1,BUFLEN2,f);
fwrite(buf2,1,BUFLEN2,stdout);
len-=BUFLEN2;
}
fread(buf2,1,len,f);
if (buf2[len-1]=='\r') --len;
fwrite(buf2,1,len,stdout);
}
putchar('\n');
}
} while (--nlines > 0);
bgnpos=filepos + (int) (bufpos-&buf+1);
} /* end if */
if (revmode) return;
/* print the requested number of lines */
fseek(f,bgnpos,0);
for (;;) {
/*fgets(buf,BUFLEN-1,f); len=strlen(buf);*/
len=fgetss(buf,BUFLEN-1,f);
if (len<0) break;
if (len<BUFLEN-2) { /* if end of line found */
buf[len++]='\r';
buf[len++]='\n';
}
fwrite(buf,1,len,stdout); /* faster than puts */
}
}
main(argc,argv)
int argc;
char **argv; {
int arg0 =1;
int arg;
FILE *f;
char c, *s;
/* parse numeric argument */
if (argc>1 && (argv[1][0]=='-' || (argv[1][0]=='+' && ++plus))) {
s=argv[1]+1;
c=*s;
if (isdigit(c)) {
while (isdigit(c)) {
numarg=numarg*10+(c-'0');
c= *++s;
}
unit=c;
if (c=='b') {numarg<<=9; unit='c';}
else if (c!='c' && c!='l') --s;
++s;
}
if (*s == 'r') {++s; ++revmode;}
if (*s) usage();
++arg0;
}
if (numarg==0) {plus=0; numarg=(revmode? MAXINT: 10);}
arg=arg0;
--argc;
if (!isatty(0)) {
--arg0;
processfile(stdin,"Standard input",argc-arg0);
}
if (arg0>argc) usage();
for (; arg <= argc; ++arg) {
if (arg>arg0) putchar('\n');
/* Open file for input */
s=argv[arg];
f=fopen(s,"r");
if (f==ERROR) {
fputs("Cannot open ",stderr);
fputs(s,stderr);
fputs("\n",stderr);
exit(1);
}
processfile(f,s,argc-arg0);
}
}