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