Subversion Repositories Keine

Rev

Rev 6 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 nishi 1
/* $Id: man.c 4 2024-09-11 10:22:22Z 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) {
47
	char* pth = kn_find(MANPAGE_DIR, str);
48
	if(pth == NULL) return false;
49
	free(pth);
50
	return true;
51
}
52
 
53
char* kn_manpage_process(const char* path) {
54
	char* b = malloc(1);
55
	b[0] = 0;
56
	int pipes[2];
57
	char cbuf[2];
58
	cbuf[1] = 0;
59
	pipe(pipes);
60
	pid_t pid = fork();
61
	if(pid == 0) {
62
		close(pipes[0]);
63
		dup2(pipes[1], STDOUT_FILENO);
64
		execlp("man", "man", path, NULL);
65
		_exit(1);
66
	} else {
67
		close(pipes[1]);
68
		char c;
69
		bool sta = false;
70
		char s = 0;
71
		char old = 0;
72
		char m = 0;
73
		while(1) {
74
			if(read(pipes[0], &c, 1) <= 0) break;
75
			if(c == 8) {
76
				sta = true;
77
			} else {
78
				if(s != 0) {
79
					if(sta) {
80
						sta = false;
81
						old = s;
82
					} else {
83
						if(old == 0) {
84
							char* tmp;
85
							if(m == 'B') {
86
								tmp = b;
87
								b = kn_strcat(b, "</b>");
88
								free(tmp);
89
							} else if(m == 'U') {
90
								tmp = b;
91
								b = kn_strcat(b, "</u>");
92
								free(tmp);
93
							}
94
							m = 0;
95
							cbuf[0] = s;
96
							tmp = b;
97
							b = kn_strcat(b, cbuf);
98
							free(tmp);
99
						} else {
100
							if(old == s) {
101
								cbuf[0] = s;
102
								char* tmp;
103
								if(m == 'U') {
104
									tmp = b;
105
									b = kn_strcat(b, "</u>");
106
									free(tmp);
107
								}
108
								if(m != 'B') {
109
									tmp = b;
110
									b = kn_strcat(b, "<b>");
111
									free(tmp);
112
								}
113
								m = 'B';
114
								tmp = b;
115
								b = kn_strcat(b, cbuf);
116
								free(tmp);
117
							} else if(old == '_') {
118
								cbuf[0] = s;
119
								char* tmp;
120
								if(m == 'B') {
121
									tmp = b;
122
									b = kn_strcat(b, "</b>");
123
									free(tmp);
124
								}
125
								if(m != 'U') {
126
									tmp = b;
127
									b = kn_strcat(b, "<u>");
128
									free(tmp);
129
								}
130
								tmp = b;
131
								b = kn_strcat(b, cbuf);
132
								free(tmp);
133
								tmp = b;
134
								b = kn_strcat(b, "</u>");
135
								free(tmp);
136
							}
137
							old = 0;
138
						}
139
					}
140
				}
141
				s = c;
142
			}
143
		}
144
		waitpid(pid, 0, 0);
145
		char* tmp;
146
		if(m == 'B') {
147
			tmp = b;
148
			b = kn_strcat(b, "</b>");
149
			free(tmp);
150
		} else if(m == 'U') {
151
			tmp = b;
152
			b = kn_strcat(b, "</u>");
153
			free(tmp);
154
		}
155
	}
156
	return b;
157
}