blob: 415db0384e2ff80873e5f4c6adc26cdeb50d87f7 [file] [log] [blame]
rsc24c02862005-01-04 21:23:50 +00001#include <u.h>
2#include <libc.h>
3#include <draw.h>
rsc05a4d852007-03-26 20:55:26 +00004#include <thread.h>
rsc24c02862005-01-04 21:23:50 +00005#include <bio.h>
rsc05a4d852007-03-26 20:55:26 +00006#include <cursor.h>
rsc24c02862005-01-04 21:23:50 +00007#include "page.h"
8
9Document*
10initfilt(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf, char *type, char *cmd, int docopy)
11{
12 int ofd;
13 int p[2];
14 char xbuf[8192];
15 int n;
16
17 if(argc > 1) {
18 fprint(2, "can only view one %s file at a time\n", type);
19 return nil;
20 }
21
22 fprint(2, "converting from %s to postscript...\n", type);
23
24 if(docopy){
25 if(pipe(p) < 0){
26 fprint(2, "pipe fails: %r\n");
rsc05a4d852007-03-26 20:55:26 +000027 threadexits("Epipe");
rsc24c02862005-01-04 21:23:50 +000028 }
29 }else{
30 p[0] = open("/dev/null", ORDWR);
31 p[1] = open("/dev/null", ORDWR);
32 }
33
34 ofd = opentemp("/tmp/pagecvtXXXXXXXXX");
35 switch(fork()){
36 case -1:
37 fprint(2, "fork fails: %r\n");
rsc05a4d852007-03-26 20:55:26 +000038 threadexits("Efork");
rsc24c02862005-01-04 21:23:50 +000039 default:
rsc05a4d852007-03-26 20:55:26 +000040 close(p[0]);
rsc24c02862005-01-04 21:23:50 +000041 if(docopy){
rsc05a4d852007-03-26 20:55:26 +000042 write(p[1], buf, nbuf);
rsc24c02862005-01-04 21:23:50 +000043 if(b)
44 while((n = Bread(b, xbuf, sizeof xbuf)) > 0)
rsc05a4d852007-03-26 20:55:26 +000045 write(p[1], xbuf, n);
rsc24c02862005-01-04 21:23:50 +000046 else
47 while((n = read(stdinfd, xbuf, sizeof xbuf)) > 0)
rsc05a4d852007-03-26 20:55:26 +000048 write(p[1], xbuf, n);
rsc24c02862005-01-04 21:23:50 +000049 }
rsc05a4d852007-03-26 20:55:26 +000050 close(p[1]);
rsc24c02862005-01-04 21:23:50 +000051 waitpid();
52 break;
53 case 0:
rsc05a4d852007-03-26 20:55:26 +000054 close(p[1]);
55 dup(p[0], 0);
rsc24c02862005-01-04 21:23:50 +000056 dup(ofd, 1);
57 /* stderr shines through */
rsc05a4d852007-03-26 20:55:26 +000058 if(chatty)
59 fprint(2, "Execing '%s'\n", cmd);
60 execlp("rc", "rc", "-c", cmd, nil);
rsc24c02862005-01-04 21:23:50 +000061 break;
62 }
63
64 if(b)
65 Bterm(b);
66 seek(ofd, 0, 0);
67 b = emalloc(sizeof(Biobuf));
68 Binit(b, ofd, OREAD);
69
70 return initps(b, argc, argv, nil, 0);
71}
72
73Document*
74initdvi(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
75{
76 int fd;
77 char *name;
78 char cmd[256];
79 char fdbuf[20];
80
81 /*
82 * Stupid DVIPS won't take standard input.
83 */
84 if(b == nil){ /* standard input; spool to disk (ouch) */
85 fd = spooltodisk(buf, nbuf, &name);
rsc05a4d852007-03-26 20:55:26 +000086 sprint(fdbuf, "/dev/fd/%d", fd);
rsc24c02862005-01-04 21:23:50 +000087 b = Bopen(fdbuf, OREAD);
88 if(b == nil){
89 fprint(2, "cannot open disk spool file\n");
90 wexits("Bopen temp");
91 }
92 argv = &name;
93 argc = 1;
94 }
95
96 snprint(cmd, sizeof cmd, "dvips -Pps -r0 -q1 -f1 '%s'", argv[0]);
97 return initfilt(b, argc, argv, buf, nbuf, "dvi", cmd, 0);
98}
99
100Document*
101inittroff(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
102{
103 return initfilt(b, argc, argv, buf, nbuf, "troff", "lp -dstdout", 1);
104}
105
106Document*
107initmsdoc(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
108{
109 return initfilt(b, argc, argv, buf, nbuf, "microsoft office", "doc2ps", 1);
110}