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