1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1992-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * Glenn Fowler <gsf@research.att.com> * 18*4887Schin * David Korn <dgk@research.att.com> * 19*4887Schin * * 20*4887Schin ***********************************************************************/ 21*4887Schin #pragma prototyped 22*4887Schin /* 23*4887Schin * common support for tail and rev 24*4887Schin */ 25*4887Schin 26*4887Schin #include <cmd.h> 27*4887Schin #include <rev.h> 28*4887Schin 29*4887Schin #define BUFSIZE SF_BUFSIZE 30*4887Schin #define rounddown(n,size) (((n)-1)&~((size)-1)) 31*4887Schin 32*4887Schin /* 33*4887Schin * copy the lines starting at offset <start> from in <in> to <out> 34*4887Schin * in reverse order 35*4887Schin */ 36*4887Schin int rev_line(Sfio_t *in, Sfio_t *out, off_t start) 37*4887Schin { 38*4887Schin register char *cp, *cpold; 39*4887Schin register int n, nleft=0; 40*4887Schin char buff[BUFSIZE]; 41*4887Schin off_t offset; 42*4887Schin if(sfseek(in,(off_t)0,SEEK_CUR) < 0) 43*4887Schin { 44*4887Schin Sfio_t *tmp = sftmp(4*SF_BUFSIZE); 45*4887Schin if(!tmp) 46*4887Schin return(-1); 47*4887Schin if(start>0 && sfmove(in, (Sfio_t*)0, start, -1) != start) 48*4887Schin return(-1); 49*4887Schin if(sfmove(in, tmp, SF_UNBOUND, -1) < 0 || !sfeof(in) || sferror(tmp)) 50*4887Schin return(-1); 51*4887Schin in = tmp; 52*4887Schin start=0; 53*4887Schin } 54*4887Schin if((offset = sfseek(in,(off_t)0,SEEK_END)) <= start) 55*4887Schin return(0); 56*4887Schin offset = rounddown(offset,BUFSIZE); 57*4887Schin while(1) 58*4887Schin { 59*4887Schin n = BUFSIZE; 60*4887Schin if(offset < start) 61*4887Schin { 62*4887Schin n -= (start-offset); 63*4887Schin offset = start; 64*4887Schin } 65*4887Schin sfseek(in, offset, SEEK_SET); 66*4887Schin if((n=sfread(in, buff, n)) <=0) 67*4887Schin break; 68*4887Schin cp = buff+n; 69*4887Schin n = *buff; 70*4887Schin *buff = '\n'; 71*4887Schin while(1) 72*4887Schin { 73*4887Schin cpold = cp; 74*4887Schin if(nleft==0) 75*4887Schin cp--; 76*4887Schin if(cp==buff) 77*4887Schin { 78*4887Schin nleft= 1; 79*4887Schin break; 80*4887Schin } 81*4887Schin while(*--cp != '\n'); 82*4887Schin if(cp==buff && n!='\n') 83*4887Schin { 84*4887Schin *cp = n; 85*4887Schin nleft += cpold-cp; 86*4887Schin break; 87*4887Schin } 88*4887Schin else 89*4887Schin cp++; 90*4887Schin if(sfwrite(out,cp,cpold-cp) < 0) 91*4887Schin return(-1); 92*4887Schin if(nleft) 93*4887Schin { 94*4887Schin if(nleft==1) 95*4887Schin sfputc(out,'\n'); 96*4887Schin else if(sfmove(in,out,nleft,-1) != nleft) 97*4887Schin return(-1); 98*4887Schin nleft = 0; 99*4887Schin } 100*4887Schin } 101*4887Schin if(offset <= start) 102*4887Schin break; 103*4887Schin offset -= BUFSIZE; 104*4887Schin } 105*4887Schin if(nleft) 106*4887Schin { 107*4887Schin sfseek(in, start, SEEK_SET); 108*4887Schin if(sfmove(in,out,nleft,-1) != nleft) 109*4887Schin return(-1); 110*4887Schin } 111*4887Schin return(0); 112*4887Schin } 113