11553Srgrimes/* 21553Srgrimes * Copyright (c) 1983, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 4. Neither the name of the University nor the names of its contributors 141553Srgrimes * may be used to endorse or promote products derived from this software 151553Srgrimes * without specific prior written permission. 161553Srgrimes * 171553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271553Srgrimes * SUCH DAMAGE. 281553Srgrimes */ 291553Srgrimes 301553Srgrimes#ifndef lint 3184693Sgadstatic const char copyright[] = 321553Srgrimes"@(#) Copyright (c) 1983, 1993\n\ 331553Srgrimes The Regents of the University of California. All rights reserved.\n"; 341553Srgrimes#endif /* not lint */ 351553Srgrimes 36117609Sgad#if 0 371553Srgrimes#ifndef lint 38117609Sgadstatic char sccsid[] = "@(#)lpf.c 8.1 (Berkeley) 6/6/93"; 391553Srgrimes#endif /* not lint */ 40117609Sgad#endif 411553Srgrimes 42117609Sgad#include "lp.cdefs.h" /* A cross-platform version of <sys/cdefs.h> */ 43117609Sgad__FBSDID("$FreeBSD$"); 44117609Sgad 451553Srgrimes/* 461553Srgrimes * filter which reads the output of nroff and converts lines 471553Srgrimes * with ^H's to overwritten lines. Thus this works like 'ul' 481553Srgrimes * but is much better: it can handle more than 2 overwrites 491553Srgrimes * and it is written with some style. 501553Srgrimes * modified by kls to use register references instead of arrays 511553Srgrimes * to try to gain a little speed. 521553Srgrimes */ 531553Srgrimes 541553Srgrimes#include <signal.h> 551553Srgrimes#include <unistd.h> 561553Srgrimes#include <stdlib.h> 571553Srgrimes#include <stdio.h> 58229225Sdim#include <string.h> 591553Srgrimes 601553Srgrimes#define MAXWIDTH 132 611553Srgrimes#define MAXREP 10 621553Srgrimes 631553Srgrimeschar buf[MAXREP][MAXWIDTH]; 641553Srgrimesint maxcol[MAXREP] = {-1}; 651553Srgrimesint lineno; 661553Srgrimesint width = 132; /* default line length */ 671553Srgrimesint length = 66; /* page length */ 681553Srgrimesint indent; /* indentation length */ 691553Srgrimesint npages = 1; 701553Srgrimesint literal; /* print control characters */ 711553Srgrimeschar *name; /* user's login name */ 721553Srgrimeschar *host; /* user's machine name */ 731553Srgrimeschar *acctfile; /* accounting information file */ 741553Srgrimes 751553Srgrimesint 7678146Sgadmain(int argc, char *argv[]) 771553Srgrimes{ 781553Srgrimes register FILE *p = stdin, *o = stdout; 791553Srgrimes register int i, col; 801553Srgrimes register char *cp; 811553Srgrimes int done, linedone, maxrep; 8217202Sjoerg char *limit; 8317202Sjoerg int ch; 841553Srgrimes 851553Srgrimes while (--argc) { 861553Srgrimes if (*(cp = *++argv) == '-') { 871553Srgrimes switch (cp[1]) { 881553Srgrimes case 'n': 891553Srgrimes argc--; 901553Srgrimes name = *++argv; 911553Srgrimes break; 921553Srgrimes 931553Srgrimes case 'h': 941553Srgrimes argc--; 951553Srgrimes host = *++argv; 961553Srgrimes break; 971553Srgrimes 981553Srgrimes case 'w': 991553Srgrimes if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) 1001553Srgrimes width = i; 1011553Srgrimes break; 1021553Srgrimes 1031553Srgrimes case 'l': 1041553Srgrimes length = atoi(&cp[2]); 1051553Srgrimes break; 1061553Srgrimes 1071553Srgrimes case 'i': 1081553Srgrimes indent = atoi(&cp[2]); 1091553Srgrimes break; 1101553Srgrimes 1111553Srgrimes case 'c': /* Print control chars */ 1121553Srgrimes literal++; 1131553Srgrimes break; 1141553Srgrimes } 1151553Srgrimes } else 1161553Srgrimes acctfile = cp; 1171553Srgrimes } 1181553Srgrimes 119229225Sdim memset(buf, ' ', sizeof(buf)); 1201553Srgrimes done = 0; 1218857Srgrimes 1221553Srgrimes while (!done) { 1231553Srgrimes col = indent; 1241553Srgrimes maxrep = -1; 1251553Srgrimes linedone = 0; 1261553Srgrimes while (!linedone) { 1271553Srgrimes switch (ch = getc(p)) { 1281553Srgrimes case EOF: 1291553Srgrimes linedone = done = 1; 1301553Srgrimes ch = '\n'; 1311553Srgrimes break; 1321553Srgrimes 1331553Srgrimes case '\f': 1341553Srgrimes lineno = length; 1351553Srgrimes case '\n': 1361553Srgrimes if (maxrep < 0) 1371553Srgrimes maxrep = 0; 1381553Srgrimes linedone = 1; 1391553Srgrimes break; 1401553Srgrimes 1411553Srgrimes case '\b': 1421553Srgrimes if (--col < indent) 1431553Srgrimes col = indent; 1441553Srgrimes break; 1451553Srgrimes 1461553Srgrimes case '\r': 1471553Srgrimes col = indent; 1481553Srgrimes break; 1491553Srgrimes 1501553Srgrimes case '\t': 1511553Srgrimes col = ((col - indent) | 07) + indent + 1; 1521553Srgrimes break; 1531553Srgrimes 1541553Srgrimes case '\031': 1551553Srgrimes /* 1561553Srgrimes * lpd needs to use a different filter to 1571553Srgrimes * print data so stop what we are doing and 1581553Srgrimes * wait for lpd to restart us. 1591553Srgrimes */ 1601553Srgrimes if ((ch = getchar()) == '\1') { 1611553Srgrimes fflush(stdout); 1621553Srgrimes kill(getpid(), SIGSTOP); 1631553Srgrimes break; 1641553Srgrimes } else { 1651553Srgrimes ungetc(ch, stdin); 1661553Srgrimes ch = '\031'; 1671553Srgrimes } 1681553Srgrimes 1691553Srgrimes default: 17084693Sgad if (col >= width || (!literal && ch < ' ')) { 1711553Srgrimes col++; 1721553Srgrimes break; 1731553Srgrimes } 1741553Srgrimes cp = &buf[0][col]; 1751553Srgrimes for (i = 0; i < MAXREP; i++) { 1761553Srgrimes if (i > maxrep) 1771553Srgrimes maxrep = i; 1781553Srgrimes if (*cp == ' ') { 1791553Srgrimes *cp = ch; 1801553Srgrimes if (col > maxcol[i]) 1811553Srgrimes maxcol[i] = col; 1821553Srgrimes break; 1831553Srgrimes } 1841553Srgrimes cp += MAXWIDTH; 1851553Srgrimes } 1861553Srgrimes col++; 1871553Srgrimes break; 1881553Srgrimes } 1891553Srgrimes } 1901553Srgrimes 1911553Srgrimes /* print out lines */ 1921553Srgrimes for (i = 0; i <= maxrep; i++) { 1931553Srgrimes for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) { 1941553Srgrimes putc(*cp, o); 1951553Srgrimes *cp++ = ' '; 1961553Srgrimes } 1971553Srgrimes if (i < maxrep) 1981553Srgrimes putc('\r', o); 1991553Srgrimes else 2001553Srgrimes putc(ch, o); 2011553Srgrimes if (++lineno >= length) { 2021553Srgrimes fflush(o); 2031553Srgrimes npages++; 2041553Srgrimes lineno = 0; 2051553Srgrimes } 2061553Srgrimes maxcol[i] = -1; 2071553Srgrimes } 2081553Srgrimes } 2091553Srgrimes if (lineno) { /* be sure to end on a page boundary */ 2101553Srgrimes putchar('\f'); 2111553Srgrimes npages++; 2121553Srgrimes } 2131553Srgrimes if (name && acctfile && access(acctfile, 02) >= 0 && 2141553Srgrimes freopen(acctfile, "a", stdout) != NULL) { 2151553Srgrimes printf("%7.2f\t%s:%s\n", (float)npages, host, name); 2161553Srgrimes } 2171553Srgrimes exit(0); 2181553Srgrimes} 219