1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)lpf.c 5.1 (Berkeley) 05/15/85"; 9 #endif not lint 10 11 /* 12 * filter which reads the output of nroff and converts lines 13 * with ^H's to overwritten lines. Thus this works like 'ul' 14 * but is much better: it can handle more than 2 overwrites 15 * and it is written with some style. 16 * modified by kls to use register references instead of arrays 17 * to try to gain a little speed. 18 */ 19 20 #include <stdio.h> 21 #include <signal.h> 22 23 #define MAXWIDTH 132 24 #define MAXREP 10 25 26 char buf[MAXREP][MAXWIDTH]; 27 int maxcol[MAXREP] = {-1}; 28 int lineno; 29 int width = 132; /* default line length */ 30 int length = 66; /* page length */ 31 int indent; /* indentation length */ 32 int npages = 1; 33 int literal; /* print control characters */ 34 char *name; /* user's login name */ 35 char *host; /* user's machine name */ 36 char *acctfile; /* accounting information file */ 37 38 main(argc, argv) 39 int argc; 40 char *argv[]; 41 { 42 register FILE *p = stdin, *o = stdout; 43 register int i, col; 44 register char *cp; 45 int done, linedone, maxrep; 46 char ch, *limit; 47 48 while (--argc) { 49 if (*(cp = *++argv) == '-') { 50 switch (cp[1]) { 51 case 'n': 52 argc--; 53 name = *++argv; 54 break; 55 56 case 'h': 57 argc--; 58 host = *++argv; 59 break; 60 61 case 'w': 62 if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH) 63 width = i; 64 break; 65 66 case 'l': 67 length = atoi(&cp[2]); 68 break; 69 70 case 'i': 71 indent = atoi(&cp[2]); 72 break; 73 74 case 'c': /* Print control chars */ 75 literal++; 76 break; 77 } 78 } else 79 acctfile = cp; 80 } 81 82 for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' '); 83 done = 0; 84 85 while (!done) { 86 col = indent; 87 maxrep = -1; 88 linedone = 0; 89 while (!linedone) { 90 switch (ch = getc(p)) { 91 case EOF: 92 linedone = done = 1; 93 ch = '\n'; 94 break; 95 96 case '\f': 97 lineno = length; 98 case '\n': 99 if (maxrep < 0) 100 maxrep = 0; 101 linedone = 1; 102 break; 103 104 case '\b': 105 if (--col < indent) 106 col = indent; 107 break; 108 109 case '\r': 110 col = indent; 111 break; 112 113 case '\t': 114 col = ((col - indent) | 07) + indent + 1; 115 break; 116 117 case '\031': 118 /* 119 * lpd needs to use a different filter to 120 * print data so stop what we are doing and 121 * wait for lpd to restart us. 122 */ 123 if ((ch = getchar()) == '\1') { 124 fflush(stdout); 125 kill(getpid(), SIGSTOP); 126 break; 127 } else { 128 ungetc(ch, stdin); 129 ch = '\031'; 130 } 131 132 default: 133 if (col >= width || !literal && ch < ' ') { 134 col++; 135 break; 136 } 137 cp = &buf[0][col]; 138 for (i = 0; i < MAXREP; i++) { 139 if (i > maxrep) 140 maxrep = i; 141 if (*cp == ' ') { 142 *cp = ch; 143 if (col > maxcol[i]) 144 maxcol[i] = col; 145 break; 146 } 147 cp += MAXWIDTH; 148 } 149 col++; 150 break; 151 } 152 } 153 154 /* print out lines */ 155 for (i = 0; i <= maxrep; i++) { 156 for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) { 157 putc(*cp, o); 158 *cp++ = ' '; 159 } 160 if (i < maxrep) 161 putc('\r', o); 162 else 163 putc(ch, o); 164 if (++lineno >= length) { 165 fflush(o); 166 npages++; 167 lineno = 0; 168 } 169 maxcol[i] = -1; 170 } 171 } 172 if (lineno) { /* be sure to end on a page boundary */ 173 putchar('\f'); 174 npages++; 175 } 176 if (name && acctfile && access(acctfile, 02) >= 0 && 177 freopen(acctfile, "a", stdout) != NULL) { 178 printf("%7.2f\t%s:%s\n", (float)npages, host, name); 179 } 180 exit(0); 181 } 182