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