cat.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Copyright (c) 1992-2007 AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* by AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Bell Laboratories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * cat
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <cmd.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcntl.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const char usage[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[-?\n@(#)$Id: cat (AT&T Research) 2006-05-17 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?cat - concatenate files]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?\bcat\b copies each \afile\a in sequence to the standard"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" output. If no \afile\a is given, or if the \afile\a is \b-\b,"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" \bcat\b copies from standard input starting at the current location.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[b:number-nonblank?Number lines as with \b-n\b but omit line numbers from"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" blank lines.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[d:dos-input?Input files are opened in \atext\amode which removes carriage"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" returns in front of new-lines on some systems.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[e?Equivalent to \b-vE\b.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[n:number?Causes a line number to be inserted at the beginning of each line.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[s?Equivalent to \b-S\b for \aatt\a universe and \b-B\b otherwise.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[t?Equivalent to \b-vT\b.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[u:unbuffer?The output is not delayed by buffering.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[v:show-nonprinting?Causes non-printing characters (whith the exception of"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" tabs, new-lines, and form-feeds) to be output as printable charater"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" sequences. ASCII control characters are printed as \b^\b\an\a,"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" where \an\a is the corresponding ASCII character in the range"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" octal 100-137. The DEL character (octal 0177) is copied"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" as \b^?\b. Other non-printable characters are copied as \bM-\b\ax\a"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" where \ax\a is the ASCII character specified by the low-order seven"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" bits. Multibyte characters in the current locale are treated as"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" printable characters.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[A:show-all?Equivalent to \b-vET\b.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[B:squeeze-blank?Multiple adjacent new-line characters are replace by one"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" new-line.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[D:dos-output?Output files are opened in \atext\amode which inserts carriage"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin" returns in front of new-lines on some systems.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[E:show-ends?Causes a \b$\b to be inserted before each new-line.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[S:silent?\bcat\b is silent about non-existent files.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[T:show-blank?Causes tabs to be copied as \b^I\b and formfeeds as \b^L\b.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n[file ...]\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bcp\b(1), \bgetconf\b(1), \bpr\b(1)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RUBOUT 0177
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* control flags */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define B_FLAG (1<<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define E_FLAG (1<<1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define F_FLAG (1<<2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define N_FLAG (1<<3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define S_FLAG (1<<4)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T_FLAG (1<<5)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define U_FLAG (1<<6)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define V_FLAG (1<<7)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define D_FLAG (1<<8)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define d_FLAG (1<<9)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* character types */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T_ENDBUF 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T_CONTROL 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T_NEWLINE 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T_EIGHTBIT 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T_CNTL8BIT 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define printof(c) ((c)^0100)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called for any special output processing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvcat(register char* states, Sfio_t *fdin, Sfio_t *fdout, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* cpold;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int line = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char* endbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char* inbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int printdefer = (flags&(B_FLAG|N_FLAG));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int lastchar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned char meta[4];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin meta[0] = 'M';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin meta[1] = '-';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* read in a buffer full */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(inbuff = (unsigned char*)sfreserve(fdin, SF_UNBOUND, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return sfvalue(fdin) ? -1 : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((n = sfvalue(fdin)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = inbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lastchar = *(endbuff = cp + --n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *endbuff = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (printdefer)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (states[*cp]!=T_NEWLINE || !(flags&B_FLAG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(fdout,"%6d\t",line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin printdefer = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (endbuff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cpold = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over printable characters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (mbwide())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((n = (m = mbsize(cp)) < 2 ? states[*cp++] : (cp += m, states['a'])) == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((n = states[*cp++]) == 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n==T_ENDBUF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp>endbuff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(n = states[lastchar]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *endbuff = lastchar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (--cp > cpold)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(fdout,(char*)cpold,cp-cpold);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (endbuff==inbuff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *++endbuff = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = cpold = endbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[-1] = lastchar;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n==T_ENDBUF)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = T_CONTROL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endbuff = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else n = T_CONTROL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (--cp>cpold)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(fdout,(char*)cpold,cp-cpold);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_CNTL8BIT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin meta[2] = '^';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (*cp++)&~0200;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin meta[3] = printof(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(fdout,(char*)meta,4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((n=states[*cp])==T_CNTL8BIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_EIGHTBIT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin meta[2] = (*cp++)&~0200;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(fdout,(char*)meta,3);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((n=states[*cp])==T_EIGHTBIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_CONTROL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = *cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fdout,'^');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fdout,printof(n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((n=states[*cp])==T_CONTROL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case T_NEWLINE:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&S_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (states[*++cp]==T_NEWLINE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&E_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fdout,'$');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(fdout,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags&(N_FLAG|B_FLAG)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin line++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp < endbuff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(fdout,"%6d\t",line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else printdefer = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (states[*cp]==T_NEWLINE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinb_cat(int argc, char** argv, void* context)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flags = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t* fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int att;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int dovcat=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char states[UCHAR_MAX+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NoP(argc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin att = !strcmp(astconf("UNIVERSE", NiL, NiL), "att");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = "r";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (optget(argv, usage))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'A':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= T_FLAG|E_FLAG|V_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'B':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= S_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'b':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= B_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'E':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= E_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= E_FLAG|V_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= N_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= att ? F_FLAG : S_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'S':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= F_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'T':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= T_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 't':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= T_FLAG|V_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= U_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= V_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'd':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = "rt";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'D':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= d_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv += opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_info.errors)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_usage(2), "%s", optusage(NiL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(states, 0, sizeof(states));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&V_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(states, T_CONTROL, ' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states[RUBOUT] = T_CONTROL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(states+0200, T_EIGHTBIT, 0200);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(states+0200, T_CNTL8BIT, ' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states[RUBOUT|0200] = T_CNTL8BIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states['\n'] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&T_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states['\t'] = T_CONTROL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states[0] = T_ENDBUF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (att)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&V_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states['\n'|0200] = T_EIGHTBIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags&T_FLAG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states['\t'] = states['\f'] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states['\t'|0200] = states['\f'|0200] = T_EIGHTBIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags&T_FLAG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states['\t'] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&(V_FLAG|T_FLAG|N_FLAG|E_FLAG|B_FLAG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin states['\n'] = T_NEWLINE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dovcat = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&B_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= S_FLAG;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&d_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfopen(sfstdout, NiL, "wt");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp = *argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!cp || streq(cp,"-"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = sfstdin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&D_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfopen(fp, NiL, mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(fp = sfopen(NiL, cp, mode)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags&F_FLAG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: cannot open", cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.errors = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&U_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetbuf(fp, (void*)fp, -1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (dovcat)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = vcat(states, fp, sfstdout, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (sfmove(fp, sfstdout, SF_UNBOUND, -1) >= 0 && sfeof(fp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fp != sfstdin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < 0 && errno != EPIPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "%s: read error", cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "read error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sferror(sfstdout))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (cp = *argv++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sfsync(sfstdout))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(ERROR_system(0), "write error");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (flags&d_FLAG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfopen(sfstdout, NiL, "w");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return error_info.errors;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}