summaryrefslogtreecommitdiff
path: root/sys/src/cmd/uhtml.c
blob: 49503877e61df3cdf76130852a764c919a547509 (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
112
113
114
115
116
117
118
119
120
121
#include <u.h>
#include <libc.h>
#include <ctype.h>

int nbuf;
char buf[4096+1];
char *cset = "utf";

void
usage(void)
{
	fprint(2, "%s [ -h ] [ -c charset ] [ file ]\n", argv0);
	exits("usage");
}

char*
strval(char *s)
{
	char *e, q;

	while(strchr("\t ", *s))
		s++;
	q = 0;
	if(*s == '"' || *s == '\'')
		q = *s++;
	for(e = s; *e; e++){
		if(*e == q)
			break;
		if(isalnum(*e))
			continue;
		if(*e == '-' || *e == '_')
			continue;
		break;
	}
	if(e - s > 1)
		return smprint("%.*s", (int)(e-s), s);
	return nil;
}

void
main(int argc, char *argv[])
{
	int pfd[2], pflag = 0;
	char *arg[4], *s;

	ARGBEGIN {
	case 'h':
		usage();
	case 'c':
		cset = EARGF(usage());
		break;
	case 'p':
		pflag = 1;
		break;
	} ARGEND;

	if(*argv){
		close(0);
		if(open(*argv, OREAD) != 1)
			sysfatal("open: %r");
	}
	if((nbuf = read(0, buf, sizeof(buf)-1)) < 0)
		sysfatal("read: %r");
	buf[nbuf] = 0;
	for(;;){
		if(s = cistrstr(buf, "encoding="))
			if(s = strval(s+9)){
				cset = s;
				break;
			}
		if(s = cistrstr(buf, "charset="))
			if(s = strval(s+8)){
				cset = s;
				break;
			}
		break;
	}

	if(pflag){
		print("%s\n", cset);
		exits(0);
	}

	if(pipe(pfd) < 0)
		sysfatal("pipe: %r");

	if(nbuf == 0){
		write(1, buf, 0);
		exits(0);
	}

	switch(rfork(RFFDG|RFREND|RFPROC|RFNOWAIT)){
	case -1:
		sysfatal("fork: %r");
	case 0:
		dup(pfd[0], 0);
		close(pfd[0]);
		close(pfd[1]);

		arg[0] = "rc";
		arg[1] = "-c";
		if(strcmp(cset, "utf"))
			arg[2] = smprint("tcs -f %s -t utf | tcs -f html -t utf", cset);
		else
			arg[2] = "tcs -f html -t utf";
		arg[3] = nil;
		exec("/bin/rc", arg);
	}

	dup(pfd[1], 1);
	close(pfd[0]);
	close(pfd[1]);

	while(nbuf > 0){
		if(write(1, buf, nbuf) != nbuf)
			sysfatal("write: %r");
		if((nbuf = read(0, buf, sizeof(buf))) < 0)
			sysfatal("read: %r");
	}
	exits(0);
}