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