1*a967d739SClaudio Martella /* $NetBSD: read.c,v 1.17 2011/09/03 10:59:10 christos Exp $ */
2*a967d739SClaudio Martella
3*a967d739SClaudio Martella /*-
4*a967d739SClaudio Martella * Copyright (c) 1991, 1993
5*a967d739SClaudio Martella * The Regents of the University of California. All rights reserved.
6*a967d739SClaudio Martella *
7*a967d739SClaudio Martella * This code is derived from software contributed to Berkeley by
8*a967d739SClaudio Martella * Edward Sze-Tyan Wang.
9*a967d739SClaudio Martella *
10*a967d739SClaudio Martella * Redistribution and use in source and binary forms, with or without
11*a967d739SClaudio Martella * modification, are permitted provided that the following conditions
12*a967d739SClaudio Martella * are met:
13*a967d739SClaudio Martella * 1. Redistributions of source code must retain the above copyright
14*a967d739SClaudio Martella * notice, this list of conditions and the following disclaimer.
15*a967d739SClaudio Martella * 2. Redistributions in binary form must reproduce the above copyright
16*a967d739SClaudio Martella * notice, this list of conditions and the following disclaimer in the
17*a967d739SClaudio Martella * documentation and/or other materials provided with the distribution.
18*a967d739SClaudio Martella * 3. Neither the name of the University nor the names of its contributors
19*a967d739SClaudio Martella * may be used to endorse or promote products derived from this software
20*a967d739SClaudio Martella * without specific prior written permission.
21*a967d739SClaudio Martella *
22*a967d739SClaudio Martella * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*a967d739SClaudio Martella * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*a967d739SClaudio Martella * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*a967d739SClaudio Martella * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*a967d739SClaudio Martella * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*a967d739SClaudio Martella * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*a967d739SClaudio Martella * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*a967d739SClaudio Martella * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*a967d739SClaudio Martella * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*a967d739SClaudio Martella * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*a967d739SClaudio Martella * SUCH DAMAGE.
33*a967d739SClaudio Martella */
34*a967d739SClaudio Martella
35*a967d739SClaudio Martella #include <sys/cdefs.h>
36*a967d739SClaudio Martella #ifndef lint
37*a967d739SClaudio Martella #if 0
38*a967d739SClaudio Martella static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/6/93";
39*a967d739SClaudio Martella #endif
40*a967d739SClaudio Martella __RCSID("$NetBSD: read.c,v 1.17 2011/09/03 10:59:10 christos Exp $");
41*a967d739SClaudio Martella #endif /* not lint */
42*a967d739SClaudio Martella
43*a967d739SClaudio Martella #include <sys/types.h>
44*a967d739SClaudio Martella #include <sys/stat.h>
45*a967d739SClaudio Martella #include <fcntl.h>
46*a967d739SClaudio Martella #include <errno.h>
47*a967d739SClaudio Martella #include <unistd.h>
48*a967d739SClaudio Martella #include <stdio.h>
49*a967d739SClaudio Martella #include <stdlib.h>
50*a967d739SClaudio Martella #include <string.h>
51*a967d739SClaudio Martella #include "extern.h"
52*a967d739SClaudio Martella
53*a967d739SClaudio Martella /*
54*a967d739SClaudio Martella * displaybytes -- read bytes to an offset from the end and display.
55*a967d739SClaudio Martella *
56*a967d739SClaudio Martella * This is the function that reads to a byte offset from the end of the input,
57*a967d739SClaudio Martella * storing the data in a wrap-around buffer which is then displayed. If the
58*a967d739SClaudio Martella * rflag is set, the data is displayed in lines in reverse order, and this
59*a967d739SClaudio Martella * routine has the usual nastiness of trying to find the newlines. Otherwise,
60*a967d739SClaudio Martella * it is displayed from the character closest to the beginning of the input to
61*a967d739SClaudio Martella * the end.
62*a967d739SClaudio Martella *
63*a967d739SClaudio Martella * Non-zero return means than a (non-fatal) error occurred.
64*a967d739SClaudio Martella */
65*a967d739SClaudio Martella int
displaybytes(FILE * fp,off_t off)66*a967d739SClaudio Martella displaybytes(FILE *fp, off_t off)
67*a967d739SClaudio Martella {
68*a967d739SClaudio Martella int ch, len, tlen;
69*a967d739SClaudio Martella char *ep, *p, *t;
70*a967d739SClaudio Martella int wrap;
71*a967d739SClaudio Martella char *sp;
72*a967d739SClaudio Martella
73*a967d739SClaudio Martella if ((sp = p = malloc(off)) == NULL)
74*a967d739SClaudio Martella xerr(1, "malloc");
75*a967d739SClaudio Martella
76*a967d739SClaudio Martella for (wrap = 0, ep = p + off; (ch = getc(fp)) != EOF;) {
77*a967d739SClaudio Martella *p = ch;
78*a967d739SClaudio Martella if (++p == ep) {
79*a967d739SClaudio Martella wrap = 1;
80*a967d739SClaudio Martella p = sp;
81*a967d739SClaudio Martella }
82*a967d739SClaudio Martella }
83*a967d739SClaudio Martella if (ferror(fp)) {
84*a967d739SClaudio Martella ierr();
85*a967d739SClaudio Martella return 1;
86*a967d739SClaudio Martella }
87*a967d739SClaudio Martella
88*a967d739SClaudio Martella if (rflag) {
89*a967d739SClaudio Martella for (t = p - 1, len = 0; t >= sp; --t, ++len)
90*a967d739SClaudio Martella if (*t == '\n' && len) {
91*a967d739SClaudio Martella WR(t + 1, len);
92*a967d739SClaudio Martella len = 0;
93*a967d739SClaudio Martella }
94*a967d739SClaudio Martella if (wrap) {
95*a967d739SClaudio Martella tlen = len;
96*a967d739SClaudio Martella for (t = ep - 1, len = 0; t >= p; --t, ++len)
97*a967d739SClaudio Martella if (*t == '\n') {
98*a967d739SClaudio Martella if (len) {
99*a967d739SClaudio Martella WR(t + 1, len);
100*a967d739SClaudio Martella len = 0;
101*a967d739SClaudio Martella }
102*a967d739SClaudio Martella if (tlen) {
103*a967d739SClaudio Martella WR(sp, tlen);
104*a967d739SClaudio Martella tlen = 0;
105*a967d739SClaudio Martella }
106*a967d739SClaudio Martella }
107*a967d739SClaudio Martella if (len)
108*a967d739SClaudio Martella WR(t + 1, len);
109*a967d739SClaudio Martella if (tlen)
110*a967d739SClaudio Martella WR(sp, tlen);
111*a967d739SClaudio Martella }
112*a967d739SClaudio Martella } else {
113*a967d739SClaudio Martella if (wrap && (len = ep - p))
114*a967d739SClaudio Martella WR(p, len);
115*a967d739SClaudio Martella if ((len = p - sp) != 0)
116*a967d739SClaudio Martella WR(sp, len);
117*a967d739SClaudio Martella }
118*a967d739SClaudio Martella return 0;
119*a967d739SClaudio Martella }
120*a967d739SClaudio Martella
121*a967d739SClaudio Martella /*
122*a967d739SClaudio Martella * displaylines -- read lines to an offset from the end and display.
123*a967d739SClaudio Martella *
124*a967d739SClaudio Martella * This is the function that reads to a line offset from the end of the input,
125*a967d739SClaudio Martella * storing the data in an array of buffers which is then displayed. If the
126*a967d739SClaudio Martella * rflag is set, the data is displayed in lines in reverse order, and this
127*a967d739SClaudio Martella * routine has the usual nastiness of trying to find the newlines. Otherwise,
128*a967d739SClaudio Martella * it is displayed from the line closest to the beginning of the input to
129*a967d739SClaudio Martella * the end.
130*a967d739SClaudio Martella *
131*a967d739SClaudio Martella * Non-zero return means than a (non-fatal) error occurred.
132*a967d739SClaudio Martella */
133*a967d739SClaudio Martella int
displaylines(FILE * fp,off_t off)134*a967d739SClaudio Martella displaylines(FILE *fp, off_t off)
135*a967d739SClaudio Martella {
136*a967d739SClaudio Martella struct {
137*a967d739SClaudio Martella int blen;
138*a967d739SClaudio Martella int len;
139*a967d739SClaudio Martella char *l;
140*a967d739SClaudio Martella } *lines;
141*a967d739SClaudio Martella int ch;
142*a967d739SClaudio Martella char *p;
143*a967d739SClaudio Martella int blen, cnt, recno, wrap;
144*a967d739SClaudio Martella char *sp, *n;
145*a967d739SClaudio Martella
146*a967d739SClaudio Martella p = NULL;
147*a967d739SClaudio Martella if ((lines = malloc(off * sizeof(*lines))) == NULL)
148*a967d739SClaudio Martella xerr(1, "malloc");
149*a967d739SClaudio Martella
150*a967d739SClaudio Martella memset(lines, 0, sizeof(*lines) * off);
151*a967d739SClaudio Martella
152*a967d739SClaudio Martella sp = NULL;
153*a967d739SClaudio Martella blen = cnt = recno = wrap = 0;
154*a967d739SClaudio Martella
155*a967d739SClaudio Martella while ((ch = getc(fp)) != EOF) {
156*a967d739SClaudio Martella if (++cnt > blen) {
157*a967d739SClaudio Martella if ((n = realloc(sp, blen + 1024)) == NULL)
158*a967d739SClaudio Martella xerr(1, "realloc");
159*a967d739SClaudio Martella sp = n;
160*a967d739SClaudio Martella blen += 1024;
161*a967d739SClaudio Martella p = sp + cnt - 1;
162*a967d739SClaudio Martella }
163*a967d739SClaudio Martella *p++ = ch;
164*a967d739SClaudio Martella if (ch == '\n') {
165*a967d739SClaudio Martella if (lines[recno].blen < cnt) {
166*a967d739SClaudio Martella if ((n = realloc(lines[recno].l,
167*a967d739SClaudio Martella cnt + 256)) == NULL)
168*a967d739SClaudio Martella xerr(1, "realloc");
169*a967d739SClaudio Martella lines[recno].l = n;
170*a967d739SClaudio Martella lines[recno].blen = cnt + 256;
171*a967d739SClaudio Martella }
172*a967d739SClaudio Martella memmove(lines[recno].l, sp, lines[recno].len = cnt);
173*a967d739SClaudio Martella cnt = 0;
174*a967d739SClaudio Martella p = sp;
175*a967d739SClaudio Martella if (++recno == off) {
176*a967d739SClaudio Martella wrap = 1;
177*a967d739SClaudio Martella recno = 0;
178*a967d739SClaudio Martella }
179*a967d739SClaudio Martella }
180*a967d739SClaudio Martella }
181*a967d739SClaudio Martella if (ferror(fp)) {
182*a967d739SClaudio Martella free(lines);
183*a967d739SClaudio Martella ierr();
184*a967d739SClaudio Martella return 1;
185*a967d739SClaudio Martella }
186*a967d739SClaudio Martella if (cnt) {
187*a967d739SClaudio Martella lines[recno].l = sp;
188*a967d739SClaudio Martella lines[recno].len = cnt;
189*a967d739SClaudio Martella if (++recno == off) {
190*a967d739SClaudio Martella wrap = 1;
191*a967d739SClaudio Martella recno = 0;
192*a967d739SClaudio Martella }
193*a967d739SClaudio Martella }
194*a967d739SClaudio Martella
195*a967d739SClaudio Martella if (rflag) {
196*a967d739SClaudio Martella for (cnt = recno - 1; cnt >= 0; --cnt)
197*a967d739SClaudio Martella WR(lines[cnt].l, lines[cnt].len);
198*a967d739SClaudio Martella if (wrap)
199*a967d739SClaudio Martella for (cnt = off - 1; cnt >= recno; --cnt)
200*a967d739SClaudio Martella WR(lines[cnt].l, lines[cnt].len);
201*a967d739SClaudio Martella } else {
202*a967d739SClaudio Martella if (wrap)
203*a967d739SClaudio Martella for (cnt = recno; cnt < off; ++cnt)
204*a967d739SClaudio Martella WR(lines[cnt].l, lines[cnt].len);
205*a967d739SClaudio Martella for (cnt = 0; cnt < recno; ++cnt)
206*a967d739SClaudio Martella WR(lines[cnt].l, lines[cnt].len);
207*a967d739SClaudio Martella }
208*a967d739SClaudio Martella free(lines);
209*a967d739SClaudio Martella return 0;
210*a967d739SClaudio Martella }
211