Subversion Repositories Keine

Rev

Rev 6 | 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 7 2024-09-11 15:46:04Z 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
 
66
char* kn_manpage_process(const char* path) {
67
	char* b = malloc(1);
68
	b[0] = 0;
69
	int pipes[2];
70
	char cbuf[2];
71
	cbuf[1] = 0;
72
	pipe(pipes);
73
	pid_t pid = fork();
74
	if(pid == 0) {
75
		close(pipes[0]);
76
		dup2(pipes[1], STDOUT_FILENO);
77
		execlp("man", "man", path, NULL);
78
		_exit(1);
79
	} else {
80
		close(pipes[1]);
81
		char c;
82
		bool sta = false;
83
		char s = 0;
84
		char old = 0;
85
		char m = 0;
86
		while(1) {
87
			if(read(pipes[0], &c, 1) <= 0) break;
88
			if(c == 8) {
89
				sta = true;
90
			} else {
91
				if(s != 0) {
92
					if(sta) {
93
						sta = false;
94
						old = s;
95
					} else {
96
						if(old == 0) {
97
							char* tmp;
98
							if(m == 'B') {
99
								tmp = b;
100
								b = kn_strcat(b, "</b>");
101
								free(tmp);
102
							} else if(m == 'U') {
103
								tmp = b;
104
								b = kn_strcat(b, "</u>");
105
								free(tmp);
106
							}
107
							m = 0;
108
							cbuf[0] = s;
109
							tmp = b;
110
							b = kn_strcat(b, cbuf);
111
							free(tmp);
112
						} else {
113
							if(old == s) {
114
								cbuf[0] = s;
115
								char* tmp;
116
								if(m == 'U') {
117
									tmp = b;
118
									b = kn_strcat(b, "</u>");
119
									free(tmp);
120
								}
121
								if(m != 'B') {
122
									tmp = b;
123
									b = kn_strcat(b, "<b>");
124
									free(tmp);
125
								}
126
								m = 'B';
127
								tmp = b;
128
								b = kn_strcat(b, cbuf);
129
								free(tmp);
130
							} else if(old == '_') {
131
								cbuf[0] = s;
132
								char* tmp;
133
								if(m == 'B') {
134
									tmp = b;
135
									b = kn_strcat(b, "</b>");
136
									free(tmp);
137
								}
138
								if(m != 'U') {
139
									tmp = b;
140
									b = kn_strcat(b, "<u>");
141
									free(tmp);
142
								}
143
								tmp = b;
144
								b = kn_strcat(b, cbuf);
145
								free(tmp);
146
								tmp = b;
147
								b = kn_strcat(b, "</u>");
148
								free(tmp);
149
							}
150
							old = 0;
151
						}
152
					}
153
				}
154
				s = c;
155
			}
156
		}
157
		waitpid(pid, 0, 0);
158
		char* tmp;
159
		if(m == 'B') {
160
			tmp = b;
161
			b = kn_strcat(b, "</b>");
162
			free(tmp);
163
		} else if(m == 'U') {
164
			tmp = b;
165
			b = kn_strcat(b, "</u>");
166
			free(tmp);
167
		}
168
	}
169
	return b;
170
}