lpf.c revision 8857
117680Spst/* 239297Sfenner * Copyright (c) 1983, 1993 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that the following conditions 717680Spst * are met: 817680Spst * 1. Redistributions of source code must retain the above copyright 917680Spst * notice, this list of conditions and the following disclaimer. 1017680Spst * 2. Redistributions in binary form must reproduce the above copyright 1117680Spst * notice, this list of conditions and the following disclaimer in the 1217680Spst * documentation and/or other materials provided with the distribution. 1317680Spst * 3. All advertising materials mentioning features or use of this software 1417680Spst * must display the following acknowledgement: 1517680Spst * This product includes software developed by the University of 1617680Spst * California, Berkeley and its contributors. 1717680Spst * 4. Neither the name of the University nor the names of its contributors 1817680Spst * may be used to endorse or promote products derived from this software 1917680Spst * without specific prior written permission. 2017680Spst * 2117680Spst * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2217680Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2317680Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2417680Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25127668Sbms * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26214478Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2717680Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2817680Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2956893Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3056893Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3156893Sfenner * SUCH DAMAGE. 3256893Sfenner */ 33127668Sbms 3417680Spst#ifndef lint 3539297Sfennerstatic char copyright[] = 3639297Sfenner"@(#) Copyright (c) 1983, 1993\n\ 3739297Sfenner The Regents of the University of California. All rights reserved.\n"; 3817680Spst#endif /* not lint */ 3917680Spst 4017680Spst#ifndef lint 4117680Spststatic char sccsid[] = "@(#)lpf.c 8.1 (Berkeley) 6/6/93"; 4217680Spst#endif /* not lint */ 4317680Spst 44127668Sbms/* 45172683Smlaier * filter which reads the output of nroff and converts lines 4617680Spst * with ^H's to overwritten lines. Thus this works like 'ul' 4717680Spst * but is much better: it can handle more than 2 overwrites 4817680Spst * and it is written with some style. 4917680Spst * modified by kls to use register references instead of arrays 5017680Spst * to try to gain a little speed. 5117680Spst */ 5217680Spst 53190207Srpaulo#include <signal.h> 54172683Smlaier#include <unistd.h> 5517680Spst#include <stdlib.h> 5617680Spst#include <stdio.h> 5717680Spst 5817680Spst#define MAXWIDTH 132 5917680Spst#define MAXREP 10 6017680Spst 6117680Spstchar buf[MAXREP][MAXWIDTH]; 6217680Spstint maxcol[MAXREP] = {-1}; 6317680Spstint lineno; 6417680Spstint width = 132; /* default line length */ 6517680Spstint length = 66; /* page length */ 6617680Spstint indent; /* indentation length */ 6717680Spstint npages = 1; 6817680Spstint literal; /* print control characters */ 6917680Spstchar *name; /* user's login name */ 7017680Spstchar *host; /* user's machine name */ 7117680Spstchar *acctfile; /* accounting information file */ 7217680Spst 7317680Spstint 7417680Spstmain(argc, argv) 7517680Spst int argc; 7617680Spst char *argv[]; 7717680Spst{ 7817680Spst register FILE *p = stdin, *o = stdout; 7917680Spst register int i, col; 8017680Spst register char *cp; 8117680Spst int done, linedone, maxrep; 8217680Spst char ch, *limit; 8317680Spst 8417680Spst while (--argc) { 8517680Spst if (*(cp = *++argv) == '-') { 8617680Spst switch (cp[1]) { 8717680Spst case 'n': 8817680Spst argc--; 8917680Spst name = *++argv; 90127668Sbms break; 9117680Spst 9217680Spst case 'h': 9317680Spst argc--; 9417680Spst host = *++argv; 9517680Spst break; 9617680Spst 9717680Spst case 'w': 9817680Spst if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) 9917680Spst width = i; 10017680Spst break; 101172683Smlaier 10217680Spst case 'l': 10317680Spst length = atoi(&cp[2]); 10417680Spst break; 10517680Spst 10617680Spst case 'i': 10717680Spst indent = atoi(&cp[2]); 10817680Spst break; 10917680Spst 11017680Spst case 'c': /* Print control chars */ 111172683Smlaier literal++; 112172683Smlaier break; 113172683Smlaier } 114172683Smlaier } else 11517680Spst acctfile = cp; 116172683Smlaier } 117172683Smlaier 118127668Sbms for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' '); 119172683Smlaier done = 0; 120127668Sbms 121127668Sbms while (!done) { 122127668Sbms col = indent; 123127668Sbms maxrep = -1; 124127668Sbms linedone = 0; 125127668Sbms while (!linedone) { 126127668Sbms switch (ch = getc(p)) { 127127668Sbms case EOF: 128127668Sbms linedone = done = 1; 129127668Sbms ch = '\n'; 13017680Spst break; 13117680Spst 13217680Spst case '\f': 13317680Spst lineno = length; 13417680Spst case '\n': 13517680Spst if (maxrep < 0) 13617680Spst maxrep = 0; 137127668Sbms linedone = 1; 13817680Spst break; 13917680Spst 140190207Srpaulo case '\b': 14117680Spst if (--col < indent) 14217680Spst col = indent; 143172683Smlaier break; 144127668Sbms 14517680Spst case '\r': 14617680Spst col = indent; 14717680Spst break; 14817680Spst 14917680Spst case '\t': 15017680Spst col = ((col - indent) | 07) + indent + 1; 15117680Spst break; 15217680Spst 15317680Spst case '\031': 15417680Spst /* 15517680Spst * lpd needs to use a different filter to 15617680Spst * print data so stop what we are doing and 15717680Spst * wait for lpd to restart us. 15817680Spst */ 15917680Spst if ((ch = getchar()) == '\1') { 16017680Spst fflush(stdout); 16117680Spst kill(getpid(), SIGSTOP); 162 break; 163 } else { 164 ungetc(ch, stdin); 165 ch = '\031'; 166 } 167 168 default: 169 if (col >= width || !literal && ch < ' ') { 170 col++; 171 break; 172 } 173 cp = &buf[0][col]; 174 for (i = 0; i < MAXREP; i++) { 175 if (i > maxrep) 176 maxrep = i; 177 if (*cp == ' ') { 178 *cp = ch; 179 if (col > maxcol[i]) 180 maxcol[i] = col; 181 break; 182 } 183 cp += MAXWIDTH; 184 } 185 col++; 186 break; 187 } 188 } 189 190 /* print out lines */ 191 for (i = 0; i <= maxrep; i++) { 192 for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) { 193 putc(*cp, o); 194 *cp++ = ' '; 195 } 196 if (i < maxrep) 197 putc('\r', o); 198 else 199 putc(ch, o); 200 if (++lineno >= length) { 201 fflush(o); 202 npages++; 203 lineno = 0; 204 } 205 maxcol[i] = -1; 206 } 207 } 208 if (lineno) { /* be sure to end on a page boundary */ 209 putchar('\f'); 210 npages++; 211 } 212 if (name && acctfile && access(acctfile, 02) >= 0 && 213 freopen(acctfile, "a", stdout) != NULL) { 214 printf("%7.2f\t%s:%s\n", (float)npages, host, name); 215 } 216 exit(0); 217} 218