Subversion Repositories RepoView

Rev

Rev 13 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
13 nishi 1
/* $Id: enscript.c 65 2024-08-23 11:00:12Z nishi $ */
2
 
3
#include "rv_enscript.h"
4
 
5
#include "../config.h"
6
 
7
#include "rv_util.h"
8
#include "rv_repo.h"
9
 
10
#include <string.h>
11
#include <stdbool.h>
12
#include <unistd.h>
13
#include <stdlib.h>
14
#include <sys/wait.h>
15
 
16
char* rv_enscript(const char* repouser, const char* path, const char* lang) {
17
	if(rv_get_filesize(repouser, path) > 1024 * 128) return NULL;
18
	char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser);
19
	int spipes[2];
20
	pipe(spipes);
21
	pid_t pid = fork();
22
	if(pid == 0) {
23
		close(spipes[0]);
24
		dup2(spipes[1], STDOUT_FILENO);
25
		char* cmd[] = {"svnlook", "cat", svnpath, (char*)path, NULL};
26
		execvp("svnlook", cmd);
27
		_exit(0);
28
	} else {
29
		close(spipes[1]);
30
		int pipes[2];
31
		pipe(pipes);
32
		pid_t epid = fork();
33
		if(epid == 0) {
34
			close(pipes[0]);
35
			dup2(spipes[0], STDIN_FILENO);
36
			dup2(pipes[1], STDOUT_FILENO);
37
			char* hl = rv_strcat("--highlight=", lang);
38
			char* cmd[] = {"enscript", "-whtml", "--color", "-p", "-", hl, NULL};
39
			execvp("enscript", cmd);
40
			_exit(0);
41
		}
42
		close(pipes[1]);
43
		char cbuf[2];
44
		cbuf[1] = 0;
45
		char* d = malloc(1);
46
		d[0] = 0;
47
		while(1) {
48
			int n = read(pipes[0], cbuf, 1);
49
			if(n == 0) break;
50
			char* tmp = d;
51
			d = rv_strcat(tmp, cbuf);
52
			free(tmp);
53
		}
54
		close(pipes[0]);
55
		close(spipes[0]);
56
		int status;
57
		bool bad = false;
58
		waitpid(pid, &status, 0);
59
		if(WEXITSTATUS(status) != 0) {
60
			free(d);
61
			free(svnpath);
62
			bad = true;
63
		}
64
		waitpid(epid, &status, 0);
65
		if(WEXITSTATUS(status) != 0) {
66
			if(!bad) {
67
				free(d);
68
				free(svnpath);
69
				bad = true;
70
			}
71
		}
72
		if(bad) return NULL;
73
		free(svnpath);
74
		if(strlen(d) == 0) {
75
			free(d);
76
			return NULL;
77
		}
78
		char* newdata = malloc(1);
79
		newdata[0] = 0;
80
		int i;
81
		int incr = 0;
82
		bool log = false;
83
		for(i = 0;; i++) {
84
			if(d[i] == '\n' || d[i] == 0) {
85
				char oldc = d[i];
86
				d[i] = 0;
87
 
88
				if(strcmp(d + incr, "<PRE>") == 0) {
89
					log = true;
90
				} else if(strcmp(d + incr, "</PRE>") == 0) {
91
					log = false;
92
				} else if(log) {
93
					char* tmp = newdata;
94
					newdata = rv_strcat3(tmp, d + incr, "\n");
95
					free(tmp);
96
				}
97
 
98
				incr = i + 1;
99
				if(oldc == 0) break;
100
			}
101
		}
65 nishi 102
		free(d);
13 nishi 103
		return newdata;
104
	}
105
}