Subversion Repositories Keine

Rev

Rev 9 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 nishi 1
/* $Id: man.c 11 2024-09-11 16:00:21Z nishi $ */
2
 
3
#include "../config.h"
4
 
5
#include "kn_man.h"
6
 
7
#include "kn_util.h"
8
 
9
#include <stdbool.h>
10
#include <stdlib.h>
11
#include <dirent.h>
12
#include <string.h>
13
#include <unistd.h>
14
#include <sys/wait.h>
15
#include <sys/types.h>
16
#include <sys/stat.h>
17
 
18
char* kn_find(const char* root, const char* name) {
19
	DIR* dir = opendir(root);
20
	if(dir != NULL) {
21
		struct dirent* d;
22
		while((d = readdir(dir)) != NULL) {
23
			if(strcmp(d->d_name, "..") != 0 && strcmp(d->d_name, ".") != 0) {
24
				char* path = kn_strcat3(root, "/", d->d_name);
25
				struct stat s;
26
				if(stat(path, &s) == 0) {
27
					if(S_ISDIR(s.st_mode)) {
28
						char* v;
29
						if((v = kn_find(path, name)) != NULL) {
30
							closedir(dir);
31
							return v;
32
						}
33
					} else if(strcmp(d->d_name, name) == 0) {
34
						closedir(dir);
35
						return path;
36
					}
37
				}
38
				free(path);
39
			}
40
		}
41
		closedir(dir);
42
	}
43
	return NULL;
44
}
45
 
46
bool kn_has_manpage(const char* str) {
6 nishi 47
#ifdef MANPAGE_DIRS
48
	int i;
49
	const char* dirs[] = MANPAGE_DIRS;
7 nishi 50
	for(i = 0; i < sizeof(dirs) / sizeof(*dirs); i++) {
6 nishi 51
		char* pth = kn_find(dirs[i], str);
7 nishi 52
		if(pth != NULL) {
6 nishi 53
			free(pth);
54
			return true;
55
		}
56
	}
57
	return false;
58
#else
4 nishi 59
	char* pth = kn_find(MANPAGE_DIR, str);
60
	if(pth == NULL) return false;
61
	free(pth);
6 nishi 62
#endif
4 nishi 63
	return true;
64
}
65
 
9 nishi 66
#define HTML(buf) (buf[0] == '<' ? "&lt;" : (buf[0] == '>' ? "&gt;" : (buf[0] == '&' ? "&amp;" : buf)))
67
 
4 nishi 68
char* kn_manpage_process(const char* path) {
69
	char* b = malloc(1);
70
	b[0] = 0;
71
	int pipes[2];
72
	char cbuf[2];
73
	cbuf[1] = 0;
74
	pipe(pipes);
75
	pid_t pid = fork();
76
	if(pid == 0) {
77
		close(pipes[0]);
78
		dup2(pipes[1], STDOUT_FILENO);
79
		execlp("man", "man", path, NULL);
80
		_exit(1);
81
	} else {
82
		close(pipes[1]);
83
		char c;
84
		bool sta = false;
85
		char s = 0;
86
		char old = 0;
87
		char m = 0;
88
		while(1) {
89
			if(read(pipes[0], &c, 1) <= 0) break;
90
			if(c == 8) {
91
				sta = true;
92
			} else {
93
				if(s != 0) {
94
					if(sta) {
95
						sta = false;
96
						old = s;
97
					} else {
98
						if(old == 0) {
99
							char* tmp;
100
							if(m == 'B') {
101
								tmp = b;
102
								b = kn_strcat(b, "</b>");
103
								free(tmp);
104
							} else if(m == 'U') {
105
								tmp = b;
106
								b = kn_strcat(b, "</u>");
107
								free(tmp);
108
							}
109
							m = 0;
110
							cbuf[0] = s;
111
							tmp = b;
9 nishi 112
							b = kn_strcat(b, HTML(cbuf));
4 nishi 113
							free(tmp);
114
						} else {
115
							if(old == s) {
116
								cbuf[0] = s;
117
								char* tmp;
118
								if(m == 'U') {
119
									tmp = b;
120
									b = kn_strcat(b, "</u>");
121
									free(tmp);
122
								}
123
								if(m != 'B') {
124
									tmp = b;
125
									b = kn_strcat(b, "<b>");
126
									free(tmp);
127
								}
128
								m = 'B';
129
								tmp = b;
9 nishi 130
								b = kn_strcat(b, HTML(cbuf));
4 nishi 131
								free(tmp);
132
							} else if(old == '_') {
133
								cbuf[0] = s;
134
								char* tmp;
135
								if(m == 'B') {
136
									tmp = b;
137
									b = kn_strcat(b, "</b>");
138
									free(tmp);
139
								}
140
								if(m != 'U') {
141
									tmp = b;
142
									b = kn_strcat(b, "<u>");
143
									free(tmp);
144
								}
11 nishi 145
								m = 'U';
4 nishi 146
								tmp = b;
9 nishi 147
								b = kn_strcat(b, HTML(cbuf));
4 nishi 148
								free(tmp);
149
								tmp = b;
150
								b = kn_strcat(b, "</u>");
151
								free(tmp);
152
							}
153
							old = 0;
154
						}
155
					}
156
				}
157
				s = c;
158
			}
159
		}
160
		waitpid(pid, 0, 0);
161
		char* tmp;
162
		if(m == 'B') {
163
			tmp = b;
164
			b = kn_strcat(b, "</b>");
165
			free(tmp);
166
		} else if(m == 'U') {
167
			tmp = b;
168
			b = kn_strcat(b, "</u>");
169
			free(tmp);
170
		}
171
	}
172
	return b;
173
}