1139749Simp/* 291355Simp * Copyright (c) 1983, 1993 391355Simp * The Regents of the University of California. All rights reserved. 491355Simp * 591355Simp * Redistribution and use in source and binary forms, with or without 691355Simp * modification, are permitted provided that the following conditions 791355Simp * are met: 891355Simp * 1. Redistributions of source code must retain the above copyright 991355Simp * notice, this list of conditions and the following disclaimer. 1091355Simp * 2. Redistributions in binary form must reproduce the above copyright 1191355Simp * notice, this list of conditions and the following disclaimer in the 1291355Simp * documentation and/or other materials provided with the distribution. 1391355Simp * 4. Neither the name of the University nor the names of its contributors 1491355Simp * may be used to endorse or promote products derived from this software 1591355Simp * without specific prior written permission. 1691355Simp * 1791355Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1891355Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1991355Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2091355Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2191355Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2291355Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2391355Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2491355Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2591355Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2691355Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2791355Simp * SUCH DAMAGE. 2891355Simp */ 2991355Simp 3091355Simp#ifndef lint 3191355Simpstatic const char copyright[] = 3291355Simp"@(#) Copyright (c) 1983, 1993\n\ 33165217Sjhb The Regents of the University of California. All rights reserved.\n"; 3491355Simp#endif /* not lint */ 3591355Simp 3691355Simp#if 0 37154599Sjhb#ifndef lint 3891355Simpstatic char sccsid[] = "@(#)lpf.c 8.1 (Berkeley) 6/6/93"; 39154599Sjhb#endif /* not lint */ 40102440Sjhb#endif 41172394Smarius 42172394Smarius#include "lp.cdefs.h" /* A cross-platform version of <sys/cdefs.h> */ 43102440Sjhb__FBSDID("$FreeBSD: releng/10.2/usr.sbin/lpr/filters/lpf.c 242091 2012-10-25 20:16:38Z ed $"); 44153898Simp 45153898Simp/* 46128058Simp * filter which reads the output of nroff and converts lines 4791355Simp * with ^H's to overwritten lines. Thus this works like 'ul' 4891355Simp * but is much better: it can handle more than 2 overwrites 4991355Simp * and it is written with some style. 5091355Simp * modified by kls to use register references instead of arrays 5191355Simp * to try to gain a little speed. 5291355Simp */ 53169221Sjhb 54169221Sjhb#include <signal.h> 55169221Sjhb#include <unistd.h> 56169221Sjhb#include <stdlib.h> 57169221Sjhb#include <stdio.h> 58163163Sjmg#include <string.h> 59163163Sjmg 60163163Sjmg#define MAXWIDTH 132 61163163Sjmg#define MAXREP 10 6291355Simp 6391355Simpstatic char buf[MAXREP][MAXWIDTH]; 6491355Simpstatic int maxcol[MAXREP] = {-1}; 65119266Simpstatic int lineno; 6691355Simpstatic int width = 132; /* default line length */ 6791355Simpstatic int length = 66; /* page length */ 68119266Simpstatic int indent; /* indentation length */ 69113544Smdoddstatic int npages = 1; 70113544Smdoddstatic int literal; /* print control characters */ 71113544Smdoddstatic char *name; /* user's login name */ 72113544Smdoddstatic char *host; /* user's machine name */ 73153560Sjhbstatic char *acctfile; /* accounting information file */ 74153560Sjhb 75164264Sjhbint 76166176Sjhbmain(int argc, char *argv[]) 77166176Sjhb{ 78169221Sjhb register FILE *p = stdin, *o = stdout; 79164264Sjhb register int i, col; 80164264Sjhb register char *cp; 81166176Sjhb int done, linedone, maxrep; 8291355Simp char *limit; 8391355Simp int ch; 8491355Simp 85189306Sjhb while (--argc) { 86189306Sjhb if (*(cp = *++argv) == '-') { 87201279Sjhb switch (cp[1]) { 88201279Sjhb case 'n': 8991355Simp argc--; 9091355Simp name = *++argv; 9191355Simp break; 92172394Smarius 9392233Simp case 'h': 9491355Simp argc--; 9591355Simp host = *++argv; 96111056Simp break; 97111056Simp 98111056Simp case 'w': 99111056Simp if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) 100117115Stmm width = i; 101120155Siwasaki break; 102128058Simp 103169615Simp case 'l': 104169615Simp length = atoi(&cp[2]); 105169615Simp break; 106169615Simp 107169615Simp case 'i': 108169615Simp indent = atoi(&cp[2]); 109142735Simp break; 110169615Simp 111169615Simp case 'c': /* Print control chars */ 112169615Simp literal++; 113169615Simp break; 114142735Simp } 115164067Sjhb } else 11691355Simp acctfile = cp; 117 } 118 119 memset(buf, ' ', sizeof(buf)); 120 done = 0; 121 122 while (!done) { 123 col = indent; 124 maxrep = -1; 125 linedone = 0; 126 while (!linedone) { 127 switch (ch = getc(p)) { 128 case EOF: 129 linedone = done = 1; 130 ch = '\n'; 131 break; 132 133 case '\f': 134 lineno = length; 135 case '\n': 136 if (maxrep < 0) 137 maxrep = 0; 138 linedone = 1; 139 break; 140 141 case '\b': 142 if (--col < indent) 143 col = indent; 144 break; 145 146 case '\r': 147 col = indent; 148 break; 149 150 case '\t': 151 col = ((col - indent) | 07) + indent + 1; 152 break; 153 154 case '\031': 155 /* 156 * lpd needs to use a different filter to 157 * print data so stop what we are doing and 158 * wait for lpd to restart us. 159 */ 160 if ((ch = getchar()) == '\1') { 161 fflush(stdout); 162 kill(getpid(), SIGSTOP); 163 break; 164 } else { 165 ungetc(ch, stdin); 166 ch = '\031'; 167 } 168 169 default: 170 if (col >= width || (!literal && ch < ' ')) { 171 col++; 172 break; 173 } 174 cp = &buf[0][col]; 175 for (i = 0; i < MAXREP; i++) { 176 if (i > maxrep) 177 maxrep = i; 178 if (*cp == ' ') { 179 *cp = ch; 180 if (col > maxcol[i]) 181 maxcol[i] = col; 182 break; 183 } 184 cp += MAXWIDTH; 185 } 186 col++; 187 break; 188 } 189 } 190 191 /* print out lines */ 192 for (i = 0; i <= maxrep; i++) { 193 for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) { 194 putc(*cp, o); 195 *cp++ = ' '; 196 } 197 if (i < maxrep) 198 putc('\r', o); 199 else 200 putc(ch, o); 201 if (++lineno >= length) { 202 fflush(o); 203 npages++; 204 lineno = 0; 205 } 206 maxcol[i] = -1; 207 } 208 } 209 if (lineno) { /* be sure to end on a page boundary */ 210 putchar('\f'); 211 npages++; 212 } 213 if (name && acctfile && access(acctfile, 02) >= 0 && 214 freopen(acctfile, "a", stdout) != NULL) { 215 printf("%7.2f\t%s:%s\n", (float)npages, host, name); 216 } 217 exit(0); 218} 219