14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1992-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * David Korn <dgk@research.att.com> * 194887Schin * * 204887Schin ***********************************************************************/ 214887Schin #pragma prototyped 224887Schin /* 234887Schin * common support for tail and rev 244887Schin */ 254887Schin 264887Schin #include <cmd.h> 274887Schin #include <rev.h> 284887Schin 294887Schin #define BUFSIZE SF_BUFSIZE 304887Schin #define rounddown(n,size) (((n)-1)&~((size)-1)) 314887Schin 324887Schin /* 334887Schin * copy the lines starting at offset <start> from in <in> to <out> 344887Schin * in reverse order 354887Schin */ 364887Schin int rev_line(Sfio_t *in, Sfio_t *out, off_t start) 374887Schin { 384887Schin register char *cp, *cpold; 394887Schin register int n, nleft=0; 404887Schin char buff[BUFSIZE]; 414887Schin off_t offset; 424887Schin if(sfseek(in,(off_t)0,SEEK_CUR) < 0) 434887Schin { 444887Schin Sfio_t *tmp = sftmp(4*SF_BUFSIZE); 454887Schin if(!tmp) 464887Schin return(-1); 474887Schin if(start>0 && sfmove(in, (Sfio_t*)0, start, -1) != start) 484887Schin return(-1); 494887Schin if(sfmove(in, tmp, SF_UNBOUND, -1) < 0 || !sfeof(in) || sferror(tmp)) 504887Schin return(-1); 514887Schin in = tmp; 524887Schin start=0; 534887Schin } 544887Schin if((offset = sfseek(in,(off_t)0,SEEK_END)) <= start) 554887Schin return(0); 564887Schin offset = rounddown(offset,BUFSIZE); 574887Schin while(1) 584887Schin { 594887Schin n = BUFSIZE; 604887Schin if(offset < start) 614887Schin { 624887Schin n -= (start-offset); 634887Schin offset = start; 644887Schin } 654887Schin sfseek(in, offset, SEEK_SET); 664887Schin if((n=sfread(in, buff, n)) <=0) 674887Schin break; 684887Schin cp = buff+n; 694887Schin n = *buff; 704887Schin *buff = '\n'; 714887Schin while(1) 724887Schin { 734887Schin cpold = cp; 744887Schin if(nleft==0) 754887Schin cp--; 764887Schin if(cp==buff) 774887Schin { 784887Schin nleft= 1; 794887Schin break; 804887Schin } 814887Schin while(*--cp != '\n'); 824887Schin if(cp==buff && n!='\n') 834887Schin { 844887Schin *cp = n; 854887Schin nleft += cpold-cp; 864887Schin break; 874887Schin } 884887Schin else 894887Schin cp++; 904887Schin if(sfwrite(out,cp,cpold-cp) < 0) 914887Schin return(-1); 924887Schin if(nleft) 934887Schin { 944887Schin if(nleft==1) 954887Schin sfputc(out,'\n'); 964887Schin else if(sfmove(in,out,nleft,-1) != nleft) 974887Schin return(-1); 984887Schin nleft = 0; 994887Schin } 1004887Schin } 1014887Schin if(offset <= start) 1024887Schin break; 1034887Schin offset -= BUFSIZE; 1044887Schin } 1054887Schin if(nleft) 1064887Schin { 1074887Schin sfseek(in, start, SEEK_SET); 1084887Schin if(sfmove(in,out,nleft,-1) != nleft) 1094887Schin return(-1); 1104887Schin } 1114887Schin return(0); 1124887Schin } 113