aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/page/filter.c
blob: f9b2a8a2d09184d57e282d85d645ad317fe6bc13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <bio.h>
#include <cursor.h>
#include "page.h"

Document*
initfilt(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf, char *type, char *cmd, int docopy)
{
	int ofd;
	int p[2];
	char xbuf[8192];
	int n;
	char template[] = "/tmp/pagecvtXXXXXXXXX";

	if(argc > 1) {
		fprint(2, "can only view one %s file at a time\n", type);
		return nil;
	}

	fprint(2, "converting from %s to postscript...\n", type);

	if(docopy){
		if(pipe(p) < 0){
			fprint(2, "pipe fails: %r\n");
			threadexits("Epipe");
		}
	}else{
		p[0] = open("/dev/null", ORDWR);
		p[1] = open("/dev/null", ORDWR);
	}

	ofd = opentemp(template, ORDWR|ORCLOSE);
	switch(fork()){
	case -1:
		fprint(2, "fork fails: %r\n");
		threadexits("Efork");
	default:
		close(p[0]);
		if(docopy){
			write(p[1], buf, nbuf);
			if(b)
				while((n = Bread(b, xbuf, sizeof xbuf)) > 0)
					write(p[1], xbuf, n);
			else
				while((n = read(stdinfd, xbuf, sizeof xbuf)) > 0)
					write(p[1], xbuf, n);
		}
		close(p[1]);
		waitpid();
		break;
	case 0:
		close(p[1]);
		dup(p[0], 0);
		dup(ofd, 1);
		/* stderr shines through */
		if(chatty)
			fprint(2, "Execing '%s'\n", cmd);
		execlp("rc", "rc", "-c", cmd, nil);
		break;
	}

	if(b)
		Bterm(b);
	seek(ofd, 0, 0);
	b = emalloc(sizeof(Biobuf));
	Binit(b, ofd, OREAD);

	return initps(b, argc, argv, nil, 0);
}

Document*
initdvi(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
{
	int fd;
	char *name;
	char cmd[256];
	char fdbuf[20];

	/*
	 * Stupid DVIPS won't take standard input.
	 */
	if(b == nil){	/* standard input; spool to disk (ouch) */
		fd = spooltodisk(buf, nbuf, &name);
		sprint(fdbuf, "/dev/fd/%d", fd);
		b = Bopen(fdbuf, OREAD);
		if(b == nil){
			fprint(2, "cannot open disk spool file\n");
			wexits("Bopen temp");
		}
		argv = &name;
		argc = 1;
	}

	snprint(cmd, sizeof cmd, "dvips -Pps -r0 -q1 -f1 '%s'", argv[0]);
	return initfilt(b, argc, argv, buf, nbuf, "dvi", cmd, 0);
}

Document*
inittroff(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
{
	return initfilt(b, argc, argv, buf, nbuf, "troff", "9 tr2post | 9 psfonts", 1);
}

Document*
initmsdoc(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
{
	return initfilt(b, argc, argv, buf, nbuf, "microsoft office", "doc2ps", 1);
}