1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1992-2012 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * Glenn Fowler <gsf@research.att.com> *
18*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> *
19*b30d1939SAndy Fiddaman * *
20*b30d1939SAndy Fiddaman ***********************************************************************/
21*b30d1939SAndy Fiddaman #pragma prototyped
22*b30d1939SAndy Fiddaman /*
23*b30d1939SAndy Fiddaman * David Korn
24*b30d1939SAndy Fiddaman * Glenn Fowler
25*b30d1939SAndy Fiddaman * AT&T Bell Laboratories
26*b30d1939SAndy Fiddaman *
27*b30d1939SAndy Fiddaman * cat
28*b30d1939SAndy Fiddaman */
29*b30d1939SAndy Fiddaman
30*b30d1939SAndy Fiddaman #include <cmd.h>
31*b30d1939SAndy Fiddaman #include <fcntl.h>
32*b30d1939SAndy Fiddaman
33*b30d1939SAndy Fiddaman static const char usage[] =
34*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: cat (AT&T Research) 2012-05-31 $\n]"
35*b30d1939SAndy Fiddaman USAGE_LICENSE
36*b30d1939SAndy Fiddaman "[+NAME?cat - concatenate files]"
37*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bcat\b copies each \afile\a in sequence to the standard"
38*b30d1939SAndy Fiddaman " output. If no \afile\a is given, or if the \afile\a is \b-\b,"
39*b30d1939SAndy Fiddaman " \bcat\b copies from standard input starting at the current location.]"
40*b30d1939SAndy Fiddaman
41*b30d1939SAndy Fiddaman "[b:number-nonblank?Number lines as with \b-n\b but omit line numbers from"
42*b30d1939SAndy Fiddaman " blank lines.]"
43*b30d1939SAndy Fiddaman "[d:dos-input?Input files are opened in \atext\amode which removes carriage"
44*b30d1939SAndy Fiddaman " returns in front of new-lines on some systems.]"
45*b30d1939SAndy Fiddaman "[e?Equivalent to \b-vE\b.]"
46*b30d1939SAndy Fiddaman "[n:number?Causes a line number to be inserted at the beginning of each line.]"
47*b30d1939SAndy Fiddaman "[s?Equivalent to \b-S\b for \aatt\a universe and \b-B\b otherwise.]"
48*b30d1939SAndy Fiddaman "[t?Equivalent to \b-vT\b.]"
49*b30d1939SAndy Fiddaman "[u:unbuffer?The output is not delayed by buffering.]"
50*b30d1939SAndy Fiddaman "[v:show-nonprinting|print-chars?Print characters as follows: space and "
51*b30d1939SAndy Fiddaman "printable characters as themselves; control characters as \b^\b "
52*b30d1939SAndy Fiddaman "followed by a letter of the alphabet; and characters with the high bit "
53*b30d1939SAndy Fiddaman "set as the lower 7 bit character prefixed by \bM^\b for 7 bit "
54*b30d1939SAndy Fiddaman "non-printable characters and \bM-\b for all other characters. If the 7 "
55*b30d1939SAndy Fiddaman "bit character encoding is not ASCII then the characters are converted "
56*b30d1939SAndy Fiddaman "to ASCII to determine \ahigh bit set\a, and if set it is cleared and "
57*b30d1939SAndy Fiddaman "converted back to the native encoding. Multibyte characters in the "
58*b30d1939SAndy Fiddaman "current locale are treated as printable characters.]"
59*b30d1939SAndy Fiddaman "[A:show-all?Equivalent to \b-vET\b.]"
60*b30d1939SAndy Fiddaman "[B:squeeze-blank?Multiple adjacent new-line characters are replace by one"
61*b30d1939SAndy Fiddaman " new-line.]"
62*b30d1939SAndy Fiddaman "[D:dos-output?Output files are opened in \atext\amode which inserts carriage"
63*b30d1939SAndy Fiddaman " returns in front of new-lines on some systems.]"
64*b30d1939SAndy Fiddaman "[E:show-ends?Causes a \b$\b to be inserted before each new-line.]"
65*b30d1939SAndy Fiddaman "[R:regress?Regression test defaults: \b-v\b buffer size 4.]"
66*b30d1939SAndy Fiddaman "[S:silent?\bcat\b is silent about non-existent files.]"
67*b30d1939SAndy Fiddaman "[T:show-blank?Causes tabs to be copied as \b^I\b and formfeeds as \b^L\b.]"
68*b30d1939SAndy Fiddaman
69*b30d1939SAndy Fiddaman "\n"
70*b30d1939SAndy Fiddaman "\n[file ...]\n"
71*b30d1939SAndy Fiddaman "\n"
72*b30d1939SAndy Fiddaman
73*b30d1939SAndy Fiddaman "[+SEE ALSO?\bcp\b(1), \bgetconf\b(1), \bpr\b(1)]"
74*b30d1939SAndy Fiddaman ;
75*b30d1939SAndy Fiddaman
76*b30d1939SAndy Fiddaman #define RUBOUT 0177
77*b30d1939SAndy Fiddaman
78*b30d1939SAndy Fiddaman /* control flags */
79*b30d1939SAndy Fiddaman #define B_FLAG (1<<0)
80*b30d1939SAndy Fiddaman #define E_FLAG (1<<1)
81*b30d1939SAndy Fiddaman #define F_FLAG (1<<2)
82*b30d1939SAndy Fiddaman #define N_FLAG (1<<3)
83*b30d1939SAndy Fiddaman #define S_FLAG (1<<4)
84*b30d1939SAndy Fiddaman #define T_FLAG (1<<5)
85*b30d1939SAndy Fiddaman #define U_FLAG (1<<6)
86*b30d1939SAndy Fiddaman #define V_FLAG (1<<7)
87*b30d1939SAndy Fiddaman #define D_FLAG (1<<8)
88*b30d1939SAndy Fiddaman #define d_FLAG (1<<9)
89*b30d1939SAndy Fiddaman
90*b30d1939SAndy Fiddaman /* character types */
91*b30d1939SAndy Fiddaman #define T_ERROR 1
92*b30d1939SAndy Fiddaman #define T_EOF 2
93*b30d1939SAndy Fiddaman #define T_ENDBUF 3
94*b30d1939SAndy Fiddaman #define T_NEWLINE 4
95*b30d1939SAndy Fiddaman #define T_CONTROL 5
96*b30d1939SAndy Fiddaman #define T_EIGHTBIT 6
97*b30d1939SAndy Fiddaman #define T_CNTL8BIT 7
98*b30d1939SAndy Fiddaman
99*b30d1939SAndy Fiddaman #define printof(c) ((c)^0100)
100*b30d1939SAndy Fiddaman
101*b30d1939SAndy Fiddaman typedef void* (*Reserve_f)(Sfio_t*, ssize_t, int);
102*b30d1939SAndy Fiddaman
103*b30d1939SAndy Fiddaman #ifndef sfvalue
104*b30d1939SAndy Fiddaman #define sfvalue(f) ((f)->_val)
105*b30d1939SAndy Fiddaman #endif
106*b30d1939SAndy Fiddaman
107*b30d1939SAndy Fiddaman static void*
regress(Sfio_t * sp,ssize_t n,int f)108*b30d1939SAndy Fiddaman regress(Sfio_t* sp, ssize_t n, int f)
109*b30d1939SAndy Fiddaman {
110*b30d1939SAndy Fiddaman void* r;
111*b30d1939SAndy Fiddaman
112*b30d1939SAndy Fiddaman if (!(r = sfreserve(sp, 4, f)))
113*b30d1939SAndy Fiddaman r = sfreserve(sp, n, f);
114*b30d1939SAndy Fiddaman else if (sfvalue(sp) > 4)
115*b30d1939SAndy Fiddaman sfvalue(sp) = 4;
116*b30d1939SAndy Fiddaman return r;
117*b30d1939SAndy Fiddaman }
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy Fiddaman /*
120*b30d1939SAndy Fiddaman * called for any special output processing
121*b30d1939SAndy Fiddaman */
122*b30d1939SAndy Fiddaman
123*b30d1939SAndy Fiddaman static int
vcat(register char * states,Sfio_t * ip,Sfio_t * op,Reserve_f reserve,int flags)124*b30d1939SAndy Fiddaman vcat(register char* states, Sfio_t* ip, Sfio_t* op, Reserve_f reserve, int flags)
125*b30d1939SAndy Fiddaman {
126*b30d1939SAndy Fiddaman register unsigned char* cp;
127*b30d1939SAndy Fiddaman register unsigned char* pp;
128*b30d1939SAndy Fiddaman unsigned char* cur;
129*b30d1939SAndy Fiddaman unsigned char* end;
130*b30d1939SAndy Fiddaman unsigned char* buf;
131*b30d1939SAndy Fiddaman unsigned char* nxt;
132*b30d1939SAndy Fiddaman register int n;
133*b30d1939SAndy Fiddaman register int line;
134*b30d1939SAndy Fiddaman register int raw;
135*b30d1939SAndy Fiddaman int last;
136*b30d1939SAndy Fiddaman int c;
137*b30d1939SAndy Fiddaman int m;
138*b30d1939SAndy Fiddaman int any;
139*b30d1939SAndy Fiddaman int header;
140*b30d1939SAndy Fiddaman
141*b30d1939SAndy Fiddaman unsigned char meta[3];
142*b30d1939SAndy Fiddaman unsigned char tmp[32];
143*b30d1939SAndy Fiddaman
144*b30d1939SAndy Fiddaman meta[0] = 'M';
145*b30d1939SAndy Fiddaman last = -1;
146*b30d1939SAndy Fiddaman *(cp = buf = end = tmp) = 0;
147*b30d1939SAndy Fiddaman any = 0;
148*b30d1939SAndy Fiddaman header = flags & (B_FLAG|N_FLAG);
149*b30d1939SAndy Fiddaman line = 1;
150*b30d1939SAndy Fiddaman states[0] = T_ENDBUF;
151*b30d1939SAndy Fiddaman raw = !mbwide();
152*b30d1939SAndy Fiddaman for (;;)
153*b30d1939SAndy Fiddaman {
154*b30d1939SAndy Fiddaman cur = cp;
155*b30d1939SAndy Fiddaman if (raw)
156*b30d1939SAndy Fiddaman while (!(n = states[*cp++]));
157*b30d1939SAndy Fiddaman else
158*b30d1939SAndy Fiddaman for (;;)
159*b30d1939SAndy Fiddaman {
160*b30d1939SAndy Fiddaman while (!(n = states[*cp++]));
161*b30d1939SAndy Fiddaman if (n < T_CONTROL)
162*b30d1939SAndy Fiddaman break;
163*b30d1939SAndy Fiddaman if ((m = mbsize(pp = cp - 1)) > 1)
164*b30d1939SAndy Fiddaman cp += m - 1;
165*b30d1939SAndy Fiddaman else
166*b30d1939SAndy Fiddaman {
167*b30d1939SAndy Fiddaman if (m <= 0)
168*b30d1939SAndy Fiddaman {
169*b30d1939SAndy Fiddaman if (cur == pp)
170*b30d1939SAndy Fiddaman {
171*b30d1939SAndy Fiddaman if (last > 0)
172*b30d1939SAndy Fiddaman {
173*b30d1939SAndy Fiddaman *end = last;
174*b30d1939SAndy Fiddaman last = -1;
175*b30d1939SAndy Fiddaman c = end - pp + 1;
176*b30d1939SAndy Fiddaman if ((m = mbsize(pp)) == c)
177*b30d1939SAndy Fiddaman {
178*b30d1939SAndy Fiddaman any = 1;
179*b30d1939SAndy Fiddaman if (header)
180*b30d1939SAndy Fiddaman {
181*b30d1939SAndy Fiddaman header = 0;
182*b30d1939SAndy Fiddaman sfprintf(op, "%6d\t", line);
183*b30d1939SAndy Fiddaman }
184*b30d1939SAndy Fiddaman sfwrite(op, cur, m);
185*b30d1939SAndy Fiddaman *(cp = cur = end) = 0;
186*b30d1939SAndy Fiddaman }
187*b30d1939SAndy Fiddaman else
188*b30d1939SAndy Fiddaman {
189*b30d1939SAndy Fiddaman memcpy(tmp, pp, c);
190*b30d1939SAndy Fiddaman if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0)))
191*b30d1939SAndy Fiddaman {
192*b30d1939SAndy Fiddaman states[0] = sfvalue(ip) ? T_ERROR : T_EOF;
193*b30d1939SAndy Fiddaman *(cp = end = tmp + sizeof(tmp) - 1) = 0;
194*b30d1939SAndy Fiddaman last = -1;
195*b30d1939SAndy Fiddaman }
196*b30d1939SAndy Fiddaman else if ((n = sfvalue(ip)) <= 0)
197*b30d1939SAndy Fiddaman {
198*b30d1939SAndy Fiddaman states[0] = n ? T_ERROR : T_EOF;
199*b30d1939SAndy Fiddaman *(cp = end = tmp + sizeof(tmp) - 1) = 0;
200*b30d1939SAndy Fiddaman last = -1;
201*b30d1939SAndy Fiddaman }
202*b30d1939SAndy Fiddaman else
203*b30d1939SAndy Fiddaman {
204*b30d1939SAndy Fiddaman cp = buf = nxt;
205*b30d1939SAndy Fiddaman end = buf + n - 1;
206*b30d1939SAndy Fiddaman last = *end;
207*b30d1939SAndy Fiddaman *end = 0;
208*b30d1939SAndy Fiddaman }
209*b30d1939SAndy Fiddaman mb:
210*b30d1939SAndy Fiddaman if ((n = end - cp + 1) >= (sizeof(tmp) - c))
211*b30d1939SAndy Fiddaman n = sizeof(tmp) - c - 1;
212*b30d1939SAndy Fiddaman memcpy(tmp + c, cp, n);
213*b30d1939SAndy Fiddaman if ((m = mbsize(tmp)) >= c)
214*b30d1939SAndy Fiddaman {
215*b30d1939SAndy Fiddaman any = 1;
216*b30d1939SAndy Fiddaman if (header)
217*b30d1939SAndy Fiddaman {
218*b30d1939SAndy Fiddaman header = 0;
219*b30d1939SAndy Fiddaman sfprintf(op, "%6d\t", line);
220*b30d1939SAndy Fiddaman }
221*b30d1939SAndy Fiddaman sfwrite(op, tmp, m);
222*b30d1939SAndy Fiddaman cur = cp += m - c;
223*b30d1939SAndy Fiddaman }
224*b30d1939SAndy Fiddaman }
225*b30d1939SAndy Fiddaman continue;
226*b30d1939SAndy Fiddaman }
227*b30d1939SAndy Fiddaman }
228*b30d1939SAndy Fiddaman else
229*b30d1939SAndy Fiddaman {
230*b30d1939SAndy Fiddaman cp = pp + 1;
231*b30d1939SAndy Fiddaman n = 0;
232*b30d1939SAndy Fiddaman }
233*b30d1939SAndy Fiddaman }
234*b30d1939SAndy Fiddaman break;
235*b30d1939SAndy Fiddaman }
236*b30d1939SAndy Fiddaman }
237*b30d1939SAndy Fiddaman c = *--cp;
238*b30d1939SAndy Fiddaman if ((m = cp - cur) || n >= T_CONTROL)
239*b30d1939SAndy Fiddaman {
240*b30d1939SAndy Fiddaman flush:
241*b30d1939SAndy Fiddaman any = 1;
242*b30d1939SAndy Fiddaman if (header)
243*b30d1939SAndy Fiddaman {
244*b30d1939SAndy Fiddaman header = 0;
245*b30d1939SAndy Fiddaman sfprintf(op, "%6d\t", line);
246*b30d1939SAndy Fiddaman }
247*b30d1939SAndy Fiddaman if (m)
248*b30d1939SAndy Fiddaman sfwrite(op, cur, m);
249*b30d1939SAndy Fiddaman }
250*b30d1939SAndy Fiddaman special:
251*b30d1939SAndy Fiddaman switch (n)
252*b30d1939SAndy Fiddaman {
253*b30d1939SAndy Fiddaman case T_ERROR:
254*b30d1939SAndy Fiddaman if (cp < end)
255*b30d1939SAndy Fiddaman {
256*b30d1939SAndy Fiddaman n = T_CONTROL;
257*b30d1939SAndy Fiddaman goto flush;
258*b30d1939SAndy Fiddaman }
259*b30d1939SAndy Fiddaman return -1;
260*b30d1939SAndy Fiddaman case T_EOF:
261*b30d1939SAndy Fiddaman if (cp < end)
262*b30d1939SAndy Fiddaman {
263*b30d1939SAndy Fiddaman n = T_CONTROL;
264*b30d1939SAndy Fiddaman goto flush;
265*b30d1939SAndy Fiddaman }
266*b30d1939SAndy Fiddaman return 0;
267*b30d1939SAndy Fiddaman case T_ENDBUF:
268*b30d1939SAndy Fiddaman if (cp < end)
269*b30d1939SAndy Fiddaman {
270*b30d1939SAndy Fiddaman n = T_CONTROL;
271*b30d1939SAndy Fiddaman goto flush;
272*b30d1939SAndy Fiddaman }
273*b30d1939SAndy Fiddaman c = last;
274*b30d1939SAndy Fiddaman if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0)))
275*b30d1939SAndy Fiddaman {
276*b30d1939SAndy Fiddaman *(cp = end = tmp + sizeof(tmp) - 1) = 0;
277*b30d1939SAndy Fiddaman states[0] = (m = sfvalue(ip)) ? T_ERROR : T_EOF;
278*b30d1939SAndy Fiddaman last = -1;
279*b30d1939SAndy Fiddaman }
280*b30d1939SAndy Fiddaman else if ((m = sfvalue(ip)) <= 0)
281*b30d1939SAndy Fiddaman {
282*b30d1939SAndy Fiddaman *(cp = end = tmp + sizeof(tmp) - 1) = 0;
283*b30d1939SAndy Fiddaman states[0] = m ? T_ERROR : T_EOF;
284*b30d1939SAndy Fiddaman last = -1;
285*b30d1939SAndy Fiddaman }
286*b30d1939SAndy Fiddaman else
287*b30d1939SAndy Fiddaman {
288*b30d1939SAndy Fiddaman buf = nxt;
289*b30d1939SAndy Fiddaman end = buf + m - 1;
290*b30d1939SAndy Fiddaman last = *end;
291*b30d1939SAndy Fiddaman *end = 0;
292*b30d1939SAndy Fiddaman cp = buf;
293*b30d1939SAndy Fiddaman }
294*b30d1939SAndy Fiddaman if (c >= 0)
295*b30d1939SAndy Fiddaman {
296*b30d1939SAndy Fiddaman if (!(n = states[c]))
297*b30d1939SAndy Fiddaman {
298*b30d1939SAndy Fiddaman *(cur = tmp) = c;
299*b30d1939SAndy Fiddaman m = 1;
300*b30d1939SAndy Fiddaman goto flush;
301*b30d1939SAndy Fiddaman }
302*b30d1939SAndy Fiddaman if (raw || n < T_CONTROL)
303*b30d1939SAndy Fiddaman {
304*b30d1939SAndy Fiddaman cp--;
305*b30d1939SAndy Fiddaman goto special;
306*b30d1939SAndy Fiddaman }
307*b30d1939SAndy Fiddaman tmp[0] = c;
308*b30d1939SAndy Fiddaman c = 1;
309*b30d1939SAndy Fiddaman goto mb;
310*b30d1939SAndy Fiddaman }
311*b30d1939SAndy Fiddaman break;
312*b30d1939SAndy Fiddaman case T_CONTROL:
313*b30d1939SAndy Fiddaman do
314*b30d1939SAndy Fiddaman {
315*b30d1939SAndy Fiddaman sfputc(op, '^');
316*b30d1939SAndy Fiddaman sfputc(op, printof(c));
317*b30d1939SAndy Fiddaman } while (states[c = *++cp] == T_CONTROL);
318*b30d1939SAndy Fiddaman break;
319*b30d1939SAndy Fiddaman case T_CNTL8BIT:
320*b30d1939SAndy Fiddaman meta[1] = '^';
321*b30d1939SAndy Fiddaman do
322*b30d1939SAndy Fiddaman {
323*b30d1939SAndy Fiddaman n = c & ~0200;
324*b30d1939SAndy Fiddaman meta[2] = printof(n);
325*b30d1939SAndy Fiddaman sfwrite(op, (char*)meta, 3);
326*b30d1939SAndy Fiddaman } while (states[c = *++cp] == T_CNTL8BIT && raw);
327*b30d1939SAndy Fiddaman break;
328*b30d1939SAndy Fiddaman case T_EIGHTBIT:
329*b30d1939SAndy Fiddaman meta[1] = '-';
330*b30d1939SAndy Fiddaman do
331*b30d1939SAndy Fiddaman {
332*b30d1939SAndy Fiddaman meta[2] = c & ~0200;
333*b30d1939SAndy Fiddaman sfwrite(op, (char*)meta, 3);
334*b30d1939SAndy Fiddaman } while (states[c = *++cp] == T_EIGHTBIT && raw);
335*b30d1939SAndy Fiddaman break;
336*b30d1939SAndy Fiddaman case T_NEWLINE:
337*b30d1939SAndy Fiddaman if (header && !(flags & B_FLAG))
338*b30d1939SAndy Fiddaman sfprintf(op, "%6d\t", line);
339*b30d1939SAndy Fiddaman if (flags & E_FLAG)
340*b30d1939SAndy Fiddaman sfputc(op, '$');
341*b30d1939SAndy Fiddaman sfputc(op, '\n');
342*b30d1939SAndy Fiddaman if (!header || !(flags & B_FLAG))
343*b30d1939SAndy Fiddaman line++;
344*b30d1939SAndy Fiddaman header = !(flags & S_FLAG);
345*b30d1939SAndy Fiddaman for (;;)
346*b30d1939SAndy Fiddaman {
347*b30d1939SAndy Fiddaman if ((n = states[*++cp]) == T_ENDBUF)
348*b30d1939SAndy Fiddaman {
349*b30d1939SAndy Fiddaman if (cp < end || last != '\n')
350*b30d1939SAndy Fiddaman break;
351*b30d1939SAndy Fiddaman if (!(nxt = (unsigned char*)(*reserve)(ip, SF_UNBOUND, 0)))
352*b30d1939SAndy Fiddaman {
353*b30d1939SAndy Fiddaman states[0] = sfvalue(ip) ? T_ERROR : T_EOF;
354*b30d1939SAndy Fiddaman cp = end = tmp;
355*b30d1939SAndy Fiddaman *cp-- = 0;
356*b30d1939SAndy Fiddaman last = -1;
357*b30d1939SAndy Fiddaman }
358*b30d1939SAndy Fiddaman else if ((n = sfvalue(ip)) <= 0)
359*b30d1939SAndy Fiddaman {
360*b30d1939SAndy Fiddaman states[0] = n ? T_ERROR : T_EOF;
361*b30d1939SAndy Fiddaman cp = end = tmp;
362*b30d1939SAndy Fiddaman *cp-- = 0;
363*b30d1939SAndy Fiddaman last = -1;
364*b30d1939SAndy Fiddaman }
365*b30d1939SAndy Fiddaman else
366*b30d1939SAndy Fiddaman {
367*b30d1939SAndy Fiddaman buf = nxt;
368*b30d1939SAndy Fiddaman end = buf + n - 1;
369*b30d1939SAndy Fiddaman last = *end;
370*b30d1939SAndy Fiddaman *end = 0;
371*b30d1939SAndy Fiddaman cp = buf - 1;
372*b30d1939SAndy Fiddaman }
373*b30d1939SAndy Fiddaman }
374*b30d1939SAndy Fiddaman else if (n != T_NEWLINE)
375*b30d1939SAndy Fiddaman break;
376*b30d1939SAndy Fiddaman if (!(flags & S_FLAG) || any || header)
377*b30d1939SAndy Fiddaman {
378*b30d1939SAndy Fiddaman any = 0;
379*b30d1939SAndy Fiddaman header = 0;
380*b30d1939SAndy Fiddaman if ((flags & (B_FLAG|N_FLAG)) == N_FLAG)
381*b30d1939SAndy Fiddaman sfprintf(op, "%6d\t", line);
382*b30d1939SAndy Fiddaman if (flags & E_FLAG)
383*b30d1939SAndy Fiddaman sfputc(op, '$');
384*b30d1939SAndy Fiddaman sfputc(op, '\n');
385*b30d1939SAndy Fiddaman }
386*b30d1939SAndy Fiddaman if (!(flags & B_FLAG))
387*b30d1939SAndy Fiddaman line++;
388*b30d1939SAndy Fiddaman }
389*b30d1939SAndy Fiddaman header = flags & (B_FLAG|N_FLAG);
390*b30d1939SAndy Fiddaman break;
391*b30d1939SAndy Fiddaman }
392*b30d1939SAndy Fiddaman }
393*b30d1939SAndy Fiddaman }
394*b30d1939SAndy Fiddaman
395*b30d1939SAndy Fiddaman int
b_cat(int argc,char ** argv,Shbltin_t * context)396*b30d1939SAndy Fiddaman b_cat(int argc, char** argv, Shbltin_t* context)
397*b30d1939SAndy Fiddaman {
398*b30d1939SAndy Fiddaman register int n;
399*b30d1939SAndy Fiddaman register int flags = 0;
400*b30d1939SAndy Fiddaman register char* cp;
401*b30d1939SAndy Fiddaman register Sfio_t* fp;
402*b30d1939SAndy Fiddaman char* mode;
403*b30d1939SAndy Fiddaman Reserve_f reserve = sfreserve;
404*b30d1939SAndy Fiddaman int att;
405*b30d1939SAndy Fiddaman int dovcat = 0;
406*b30d1939SAndy Fiddaman char states[UCHAR_MAX+1];
407*b30d1939SAndy Fiddaman
408*b30d1939SAndy Fiddaman cmdinit(argc, argv, context, ERROR_CATALOG, 0);
409*b30d1939SAndy Fiddaman att = !strcmp(astconf("UNIVERSE", NiL, NiL), "att");
410*b30d1939SAndy Fiddaman mode = "r";
411*b30d1939SAndy Fiddaman for (;;)
412*b30d1939SAndy Fiddaman {
413*b30d1939SAndy Fiddaman n = 0;
414*b30d1939SAndy Fiddaman switch (optget(argv, usage))
415*b30d1939SAndy Fiddaman {
416*b30d1939SAndy Fiddaman case 'A':
417*b30d1939SAndy Fiddaman n = T_FLAG|E_FLAG|V_FLAG;
418*b30d1939SAndy Fiddaman break;
419*b30d1939SAndy Fiddaman case 'B':
420*b30d1939SAndy Fiddaman n = S_FLAG;
421*b30d1939SAndy Fiddaman break;
422*b30d1939SAndy Fiddaman case 'b':
423*b30d1939SAndy Fiddaman n = B_FLAG;
424*b30d1939SAndy Fiddaman break;
425*b30d1939SAndy Fiddaman case 'd':
426*b30d1939SAndy Fiddaman mode = opt_info.num ? "rt" : "r";
427*b30d1939SAndy Fiddaman continue;
428*b30d1939SAndy Fiddaman case 'D':
429*b30d1939SAndy Fiddaman n = d_FLAG;
430*b30d1939SAndy Fiddaman break;
431*b30d1939SAndy Fiddaman case 'E':
432*b30d1939SAndy Fiddaman n = E_FLAG;
433*b30d1939SAndy Fiddaman break;
434*b30d1939SAndy Fiddaman case 'e':
435*b30d1939SAndy Fiddaman n = E_FLAG|V_FLAG;
436*b30d1939SAndy Fiddaman break;
437*b30d1939SAndy Fiddaman case 'n':
438*b30d1939SAndy Fiddaman n = N_FLAG;
439*b30d1939SAndy Fiddaman break;
440*b30d1939SAndy Fiddaman case 'R':
441*b30d1939SAndy Fiddaman reserve = opt_info.num ? regress : sfreserve;
442*b30d1939SAndy Fiddaman continue;
443*b30d1939SAndy Fiddaman case 's':
444*b30d1939SAndy Fiddaman n = att ? F_FLAG : S_FLAG;
445*b30d1939SAndy Fiddaman break;
446*b30d1939SAndy Fiddaman case 'S':
447*b30d1939SAndy Fiddaman n = F_FLAG;
448*b30d1939SAndy Fiddaman break;
449*b30d1939SAndy Fiddaman case 'T':
450*b30d1939SAndy Fiddaman n = T_FLAG;
451*b30d1939SAndy Fiddaman break;
452*b30d1939SAndy Fiddaman case 't':
453*b30d1939SAndy Fiddaman n = T_FLAG|V_FLAG;
454*b30d1939SAndy Fiddaman break;
455*b30d1939SAndy Fiddaman case 'u':
456*b30d1939SAndy Fiddaman n = U_FLAG;
457*b30d1939SAndy Fiddaman break;
458*b30d1939SAndy Fiddaman case 'v':
459*b30d1939SAndy Fiddaman n = V_FLAG;
460*b30d1939SAndy Fiddaman break;
461*b30d1939SAndy Fiddaman case ':':
462*b30d1939SAndy Fiddaman error(2, "%s", opt_info.arg);
463*b30d1939SAndy Fiddaman break;
464*b30d1939SAndy Fiddaman case '?':
465*b30d1939SAndy Fiddaman error(ERROR_usage(2), "%s", opt_info.arg);
466*b30d1939SAndy Fiddaman break;
467*b30d1939SAndy Fiddaman }
468*b30d1939SAndy Fiddaman if (!n)
469*b30d1939SAndy Fiddaman break;
470*b30d1939SAndy Fiddaman if (opt_info.num)
471*b30d1939SAndy Fiddaman flags |= n;
472*b30d1939SAndy Fiddaman else
473*b30d1939SAndy Fiddaman flags &= ~n;
474*b30d1939SAndy Fiddaman }
475*b30d1939SAndy Fiddaman argv += opt_info.index;
476*b30d1939SAndy Fiddaman if (error_info.errors)
477*b30d1939SAndy Fiddaman error(ERROR_usage(2), "%s", optusage(NiL));
478*b30d1939SAndy Fiddaman memset(states, 0, sizeof(states));
479*b30d1939SAndy Fiddaman if (flags&V_FLAG)
480*b30d1939SAndy Fiddaman {
481*b30d1939SAndy Fiddaman memset(states, T_CONTROL, ' ');
482*b30d1939SAndy Fiddaman states[RUBOUT] = T_CONTROL;
483*b30d1939SAndy Fiddaman memset(states+0200, T_EIGHTBIT, 0200);
484*b30d1939SAndy Fiddaman memset(states+0200, T_CNTL8BIT, ' ');
485*b30d1939SAndy Fiddaman states[RUBOUT|0200] = T_CNTL8BIT;
486*b30d1939SAndy Fiddaman states['\n'] = 0;
487*b30d1939SAndy Fiddaman }
488*b30d1939SAndy Fiddaman if (flags&T_FLAG)
489*b30d1939SAndy Fiddaman states['\t'] = T_CONTROL;
490*b30d1939SAndy Fiddaman states[0] = T_ENDBUF;
491*b30d1939SAndy Fiddaman if (att)
492*b30d1939SAndy Fiddaman {
493*b30d1939SAndy Fiddaman if (flags&V_FLAG)
494*b30d1939SAndy Fiddaman {
495*b30d1939SAndy Fiddaman states['\n'|0200] = T_EIGHTBIT;
496*b30d1939SAndy Fiddaman if (!(flags&T_FLAG))
497*b30d1939SAndy Fiddaman {
498*b30d1939SAndy Fiddaman states['\t'] = states['\f'] = 0;
499*b30d1939SAndy Fiddaman states['\t'|0200] = states['\f'|0200] = T_EIGHTBIT;
500*b30d1939SAndy Fiddaman }
501*b30d1939SAndy Fiddaman }
502*b30d1939SAndy Fiddaman }
503*b30d1939SAndy Fiddaman else if (flags)
504*b30d1939SAndy Fiddaman {
505*b30d1939SAndy Fiddaman if (!(flags&T_FLAG))
506*b30d1939SAndy Fiddaman states['\t'] = 0;
507*b30d1939SAndy Fiddaman }
508*b30d1939SAndy Fiddaman if (flags&(V_FLAG|T_FLAG|N_FLAG|E_FLAG|B_FLAG|S_FLAG))
509*b30d1939SAndy Fiddaman {
510*b30d1939SAndy Fiddaman states['\n'] = T_NEWLINE;
511*b30d1939SAndy Fiddaman dovcat = 1;
512*b30d1939SAndy Fiddaman }
513*b30d1939SAndy Fiddaman if (flags&d_FLAG)
514*b30d1939SAndy Fiddaman sfopen(sfstdout, NiL, "wt");
515*b30d1939SAndy Fiddaman if (cp = *argv)
516*b30d1939SAndy Fiddaman argv++;
517*b30d1939SAndy Fiddaman do
518*b30d1939SAndy Fiddaman {
519*b30d1939SAndy Fiddaman if (!cp || streq(cp, "-"))
520*b30d1939SAndy Fiddaman {
521*b30d1939SAndy Fiddaman fp = sfstdin;
522*b30d1939SAndy Fiddaman if (flags&D_FLAG)
523*b30d1939SAndy Fiddaman sfopen(fp, NiL, mode);
524*b30d1939SAndy Fiddaman }
525*b30d1939SAndy Fiddaman else if (!(fp = sfopen(NiL, cp, mode)))
526*b30d1939SAndy Fiddaman {
527*b30d1939SAndy Fiddaman if (!(flags&F_FLAG))
528*b30d1939SAndy Fiddaman error(ERROR_system(0), "%s: cannot open", cp);
529*b30d1939SAndy Fiddaman error_info.errors = 1;
530*b30d1939SAndy Fiddaman continue;
531*b30d1939SAndy Fiddaman }
532*b30d1939SAndy Fiddaman if (flags&U_FLAG)
533*b30d1939SAndy Fiddaman sfsetbuf(fp, (void*)fp, -1);
534*b30d1939SAndy Fiddaman if (dovcat)
535*b30d1939SAndy Fiddaman n = vcat(states, fp, sfstdout, reserve, flags);
536*b30d1939SAndy Fiddaman else if (sfmove(fp, sfstdout, SF_UNBOUND, -1) >= 0 && sfeof(fp))
537*b30d1939SAndy Fiddaman n = 0;
538*b30d1939SAndy Fiddaman else
539*b30d1939SAndy Fiddaman n = -1;
540*b30d1939SAndy Fiddaman if (fp != sfstdin)
541*b30d1939SAndy Fiddaman sfclose(fp);
542*b30d1939SAndy Fiddaman if (n < 0 && !ERROR_PIPE(errno) && errno != EINTR)
543*b30d1939SAndy Fiddaman {
544*b30d1939SAndy Fiddaman if (cp)
545*b30d1939SAndy Fiddaman error(ERROR_system(0), "%s: read error", cp);
546*b30d1939SAndy Fiddaman else
547*b30d1939SAndy Fiddaman error(ERROR_system(0), "read error");
548*b30d1939SAndy Fiddaman }
549*b30d1939SAndy Fiddaman if (sferror(sfstdout))
550*b30d1939SAndy Fiddaman break;
551*b30d1939SAndy Fiddaman } while (cp = *argv++);
552*b30d1939SAndy Fiddaman if (sfsync(sfstdout))
553*b30d1939SAndy Fiddaman error(ERROR_system(0), "write error");
554*b30d1939SAndy Fiddaman if (flags&d_FLAG)
555*b30d1939SAndy Fiddaman sfopen(sfstdout, NiL, "w");
556*b30d1939SAndy Fiddaman return error_info.errors;
557*b30d1939SAndy Fiddaman }
558