1 /*-
2  * Copyright (c) 1979, 1980, 1981, 1986, 1988, 1990, 1991, 1992
3  *     The Regents of the University of California.
4  * Copyright (C) Caldera International Inc.  2001-2002.
5  * Copyright (c) 2003, 2004, 2005, 2012
6  *	Thorsten "mirabilos" Glaser <tg@mirbsd.org>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms,
10  * with or without modification, are permitted provided
11  * that the following conditions are met:
12  *
13  * Redistributions of source code and documentation must retain
14  * the above copyright notice, this list of conditions and the
15  * following disclaimer.  Redistributions in binary form must
16  * reproduce the above copyright notice, this list of conditions
17  * and the following disclaimer in the documentation and/or other
18  * materials provided with the distribution.
19  *
20  * All advertising materials mentioning features or use of this
21  * software must display the following acknowledgement:
22  *   This product includes software developed or owned by
23  *   Caldera International, Inc.
24  *
25  * Neither the name of Caldera International, Inc. nor the names
26  * of other contributors may be used to endorse or promote products
27  * derived from this software without specific prior written permission.
28  *
29  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
30  * INTERNATIONAL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
31  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
34  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
35  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
38  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
39  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
40  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  */
42 
43 #include "tdef.h"
44 #include <termios.h>
45 extern
46 #include "d.h"
47 extern
48 #include "v.h"
49 #ifdef NROFF
50 extern
51 #include "tw.h"
52 #endif
53 #include "sdef.h"
54 #include <setjmp.h>
55 jmp_buf sjbuf;
56 
57 __SCCSID("@(#)n2.c	4.2 (Berkeley) 4/18/91");
58 __RCSID("$MirOS: src/usr.bin/oldroff/nroff/n2.c,v 1.8 2012/06/28 22:21:20 tg Exp $");
59 
60 /*
61 troff2.c
62 
63 output, cleanup
64 */
65 
66 extern struct s *frame, *stk, *nxf;
67 extern filep ip;
68 extern filep offset;
69 extern char *enda;
70 
71 
72 extern char obuf[OBUFSZ];
73 extern char *obufp;
74 extern int dilev;
75 extern int eschar;
76 extern int tlss;
77 extern int tflg;
78 extern int ascii;
79 extern int print;
80 extern char trtab[];
81 extern int waitf;
82 extern char ptname[];
83 extern int ptid;
84 extern int em;
85 extern int ds;
86 extern int mflg;
87 extern filep woff;
88 extern int nflush;
89 extern int lgf;
90 extern int app;
91 extern int nfo;
92 extern int donef;
93 extern int *pendw;
94 extern int nofeed;
95 extern int trap;
96 extern struct termios ttys;
97 extern int ttysave;
98 extern struct termios ttysavespace;
99 extern int quiet;
100 extern int pendnf;
101 extern int ndone;
102 extern int lead;
103 extern int ralss;
104 extern int paper;
105 extern int gflag;
106 extern char *unlkp;
107 extern char nextf[];
108 extern int pipeflg;
109 extern int ejf;
110 extern int no_out;
111 extern int level;
112 extern int stopmesg;
113 extern int xxx;
114 int toolate;
115 int error;
116 #ifndef NROFF
117 extern int acctf;
118 #endif
119 
pchar(c)120 pchar(c)
121 int c;
122 {
123 	register i, j;
124 
125 	if((i=c) & MOT){pchar1(i); return;}
126 	switch(j = i & CMASK){
127 		case 0:
128 		case IMP:
129 		case RIGHT:
130 		case LEFT:
131 			return;
132 		case HX:
133 			j = (tlss>>9) | ((i&~0777)>>3);
134 			if(i & 040000){
135 				j &= ~(040000>>3);
136 				if(j > dip->blss)dip->blss = j;
137 			}else{
138 				if(j > dip->alss)dip->alss = j;
139 				ralss = dip->alss;
140 			}
141 			tlss = 0;
142 			return;
143 		case LX:
144 			tlss = i;
145 			return;
146 		case PRESC:
147 			if(dip == &d[0])j = eschar;
148 		default:
149 			i = (trtab[j] & BMASK) | (i & ~CMASK);
150 	}
151 	pchar1(i);
152 }
pchar1(c)153 pchar1(c)
154 int c;
155 {
156 	register i, j, *k;
157 	extern int chtab[];
158 
159 	j = (i = c) & CMASK;
160 	if(dip != &d[0]){
161 		wbf(i);
162 		dip->op = offset;
163 		return;
164 	}
165 	if(!tflg && !print){
166 		if(j == '\n')dip->alss = dip->blss = 0;
167 		return;
168 	}
169 	if(no_out || (j == FILLER))return;
170 #ifndef NROFF
171 	if(ascii){
172 		if(i & MOT){
173 			oput(' ');
174 			return;
175 		}
176 		if(j < 0177){
177 			oput(i);
178 			return;
179 		}
180 		switch(j){
181 			case 0200:
182 			case 0210:
183 				oput('-');
184 				break;
185 			case 0211:
186 				oputs("fi");
187 				break;
188 			case 0212:
189 				oputs("fl");
190 				break;
191 			case 0213:
192 				oputs("ff");
193 				break;
194 			case 0214:
195 				oputs("ffi");
196 				break;
197 			case 0215:
198 				oputs("ffl");
199 				break;
200 			default:
201 				for(k=chtab; *++k != j; k++)
202 					if(*k == 0)return;
203 				oput('\\');
204 				oput('(');
205 				oput(*--k & BMASK);
206 				oput(*k >> BYTE);
207 		}
208 	}else
209 #endif
210 	ptout(i);
211 }
oput(i)212 oput(i)
213 char i;
214 {
215 	*obufp++ = i;
216 	if(obufp == (obuf + OBUFSZ + ascii - 1))flusho();
217 }
oputs(i)218 oputs(i)
219 char *i;
220 {
221 	while(*i != 0)oput(*i++);
222 }
flusho()223 flusho(){
224 	if(!ascii)*obufp++ = 0;
225 	if(!ptid){
226 		while((ptid=open(ptname,1)) < 0){
227 			if(++waitf <=2)prstr("Waiting for Typesetter.\n");
228 			sleep(15);
229 		}
230 	}
231 	if(no_out == 0){
232 		if (!toolate) {
233 			toolate++;
234 #ifdef NROFF
235 			if(t.bset || t.breset){
236 				if(!ttysave) {
237 					tcgetattr(1, &ttys);
238 					ttysavespace = ttys;
239 					ttysave = 1;
240 				}
241 #ifdef OXTABS
242 				if (t.breset & 0x0C00)
243 					ttys.c_oflag &= ~OXTABS;
244 #endif
245 				if (t.breset & 0x0010)
246 					ttys.c_oflag &= ~ONLCR;
247 				tcsetattr(1, TCSAFLUSH, &ttys);
248 			}
249 			{
250 			const char *p = t.twinit;
251 			while (*p++)
252 				;
253 			write(ptid, t.twinit, p-t.twinit-1);
254 			}
255 #endif
256 		}
257 		toolate += write(ptid, obuf, obufp-obuf);
258 	}
259 	obufp = obuf;
260 }
done(x)261 done(x) int x;{
262 	register i;
263 
264 	error |= x;
265 	level = 0;
266 	app = ds = lgf = 0;
267 	if(i=em){
268 		donef = -1;
269 		em = 0;
270 		if(control(i,0))longjmp(sjbuf,1);
271 	}
272 	if(!nfo)done3(0);
273 	mflg = 0;
274 	dip = &d[0];
275 	if(woff)wbt(0);
276 	if(pendw)getword(1);
277 	pendnf = 0;
278 	if(donef == 1)done1(0);
279 	donef = 1;
280 	ip = 0;
281 	frame = stk;
282 	nxf = frame + 1;
283 	if(!ejf)tbreak();
284 	nflush++;
285 	eject((struct s *)0);
286 	longjmp(sjbuf,1);
287 }
done1(x)288 done1(x) int x; {
289 	error |= x;
290 	if(v.nl){
291 		trap = 0;
292 		eject((struct s *)0);
293 		longjmp(sjbuf,1);
294 	}
295 	if(nofeed){
296 		ptlead();
297 		flusho();
298 		done3(0);
299 	}else{
300 		if(!gflag)lead += TRAILER;
301 		done2(0);
302 	}
303 }
done2(x)304 done2(x) int x; {
305 	register i;
306 
307 	ptlead();
308 #ifndef NROFF
309 	if(!ascii){
310 		oput(T_INIT);
311 		oput(T_STOP);
312 		if(!gflag)for(i=8; i>0; i--)oput(T_PAD);
313 		if(stopmesg)prstr("Troff finished.\n");
314 	}
315 #endif
316 	flusho();
317 	done3(x);
318 }
done3(x)319 done3(x) int x;{
320 	error |= x;
321 	signal(SIGINT, SIG_IGN);
322 	signal(SIGTERM, SIG_IGN);
323 	if (unlkp != NULL)
324 		unlink(unlkp);
325 #ifdef NROFF
326 	twdone();
327 #endif
328 	if(quiet){
329 		ttys.c_lflag |= ECHO;
330 		tcsetattr(0, TCSAFLUSH, &ttys);
331 	}
332 	if(ascii)mesg(1);
333 #ifndef NROFF
334 	report();
335 #endif
336 	exit(error);
337 }
edone(x)338 edone(x) int x;{
339 	frame = stk;
340 	nxf = frame + 1;
341 	ip = 0;
342 	done(x);
343 }
344 #ifndef NROFF
report()345 report(){
346 	struct {int use; int uid;} a;
347 
348 	if((ptid != 1) && paper ){
349 		lseek(acctf,0L,2);
350 		a.use = paper;
351 		a.uid = getuid();
352 		write(acctf,(char *)&a,sizeof(a));
353 		close(acctf);
354 	}
355 }
356 #endif
357 #ifdef NROFF
casepi()358 casepi(){
359 	register i;
360 	int id[2];
361 
362 	if(toolate || skip() || !getname() || (pipe(id) == -1) ||
363 	   ((i=fork()) == -1)){
364 		prstr("Pipe not created.\n");
365 		return;
366 	}
367 	ptid = id[1];
368 	if(i>0){
369 		close(id[0]);
370 		toolate++;
371 		pipeflg++;
372 		return;
373 	}
374 	close(0);
375 	dup(id[0]);
376 	close(id[1]);
377 	execl(nextf,nextf,0);
378 	prstr("Cannot exec: ");
379 	prstr(nextf);
380 	prstr("\n");
381 	exit(-4);
382 }
383 #endif
384