summaryrefslogtreecommitdiffabout
path: root/html.c
Unidiff
Diffstat (limited to 'html.c') (more/less context) (ignore whitespace changes)
-rw-r--r--html.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/html.c b/html.c
index 0962e71..98ffaf9 100644
--- a/html.c
+++ b/html.c
@@ -1,187 +1,251 @@
1/* html.c: helper functions for html output 1/* html.c: helper functions for html output
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include <unistd.h> 9#include <unistd.h>
10#include <stdio.h> 10#include <stdio.h>
11#include <stdlib.h> 11#include <stdlib.h>
12#include <stdarg.h> 12#include <stdarg.h>
13#include <string.h> 13#include <string.h>
14 14
15int htmlfd = STDOUT_FILENO; 15int htmlfd = STDOUT_FILENO;
16 16
17char *fmt(const char *format, ...) 17char *fmt(const char *format, ...)
18{ 18{
19 static char buf[8][1024]; 19 static char buf[8][1024];
20 static int bufidx; 20 static int bufidx;
21 int len; 21 int len;
22 va_list args; 22 va_list args;
23 23
24 bufidx++; 24 bufidx++;
25 bufidx &= 7; 25 bufidx &= 7;
26 26
27 va_start(args, format); 27 va_start(args, format);
28 len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args); 28 len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args);
29 va_end(args); 29 va_end(args);
30 if (len>sizeof(buf[bufidx])) { 30 if (len>sizeof(buf[bufidx])) {
31 fprintf(stderr, "[html.c] string truncated: %s\n", format); 31 fprintf(stderr, "[html.c] string truncated: %s\n", format);
32 exit(1); 32 exit(1);
33 } 33 }
34 return buf[bufidx]; 34 return buf[bufidx];
35} 35}
36 36
37void html(const char *txt) 37void html(const char *txt)
38{ 38{
39 write(htmlfd, txt, strlen(txt)); 39 write(htmlfd, txt, strlen(txt));
40} 40}
41 41
42void htmlf(const char *format, ...) 42void htmlf(const char *format, ...)
43{ 43{
44 static char buf[65536]; 44 static char buf[65536];
45 va_list args; 45 va_list args;
46 46
47 va_start(args, format); 47 va_start(args, format);
48 vsnprintf(buf, sizeof(buf), format, args); 48 vsnprintf(buf, sizeof(buf), format, args);
49 va_end(args); 49 va_end(args);
50 html(buf); 50 html(buf);
51} 51}
52 52
53void html_txt(char *txt) 53void html_txt(char *txt)
54{ 54{
55 char *t = txt; 55 char *t = txt;
56 while(t && *t){ 56 while(t && *t){
57 int c = *t; 57 int c = *t;
58 if (c=='<' || c=='>' || c=='&') { 58 if (c=='<' || c=='>' || c=='&') {
59 *t = '\0'; 59 *t = '\0';
60 html(txt); 60 html(txt);
61 *t = c; 61 *t = c;
62 if (c=='>') 62 if (c=='>')
63 html("&gt;"); 63 html("&gt;");
64 else if (c=='<') 64 else if (c=='<')
65 html("&lt;"); 65 html("&lt;");
66 else if (c=='&') 66 else if (c=='&')
67 html("&amp;"); 67 html("&amp;");
68 txt = t+1; 68 txt = t+1;
69 } 69 }
70 t++; 70 t++;
71 } 71 }
72 if (t!=txt) 72 if (t!=txt)
73 html(txt); 73 html(txt);
74} 74}
75 75
76void html_ntxt(int len, char *txt) 76void html_ntxt(int len, char *txt)
77{ 77{
78 char *t = txt; 78 char *t = txt;
79 while(t && *t && len--){ 79 while(t && *t && len--){
80 int c = *t; 80 int c = *t;
81 if (c=='<' || c=='>' || c=='&') { 81 if (c=='<' || c=='>' || c=='&') {
82 *t = '\0'; 82 *t = '\0';
83 html(txt); 83 html(txt);
84 *t = c; 84 *t = c;
85 if (c=='>') 85 if (c=='>')
86 html("&gt;"); 86 html("&gt;");
87 else if (c=='<') 87 else if (c=='<')
88 html("&lt;"); 88 html("&lt;");
89 else if (c=='&') 89 else if (c=='&')
90 html("&amp;"); 90 html("&amp;");
91 txt = t+1; 91 txt = t+1;
92 } 92 }
93 t++; 93 t++;
94 } 94 }
95 if (t!=txt) { 95 if (t!=txt) {
96 char c = *t; 96 char c = *t;
97 *t = '\0'; 97 *t = '\0';
98 html(txt); 98 html(txt);
99 *t = c; 99 *t = c;
100 } 100 }
101 if (len<0) 101 if (len<0)
102 html("..."); 102 html("...");
103} 103}
104 104
105void html_attr(char *txt) 105void html_attr(char *txt)
106{ 106{
107 char *t = txt; 107 char *t = txt;
108 while(t && *t){ 108 while(t && *t){
109 int c = *t; 109 int c = *t;
110 if (c=='<' || c=='>' || c=='\'') { 110 if (c=='<' || c=='>' || c=='\'') {
111 *t = '\0'; 111 *t = '\0';
112 html(txt); 112 html(txt);
113 *t = c; 113 *t = c;
114 if (c=='>') 114 if (c=='>')
115 html("&gt;"); 115 html("&gt;");
116 else if (c=='<') 116 else if (c=='<')
117 html("&lt;"); 117 html("&lt;");
118 else if (c=='\'') 118 else if (c=='\'')
119 html("&quote;"); 119 html("&quote;");
120 txt = t+1; 120 txt = t+1;
121 } 121 }
122 t++; 122 t++;
123 } 123 }
124 if (t!=txt) 124 if (t!=txt)
125 html(txt); 125 html(txt);
126} 126}
127 127
128void html_hidden(char *name, char *value) 128void html_hidden(char *name, char *value)
129{ 129{
130 html("<input type='hidden' name='"); 130 html("<input type='hidden' name='");
131 html_attr(name); 131 html_attr(name);
132 html("' value='"); 132 html("' value='");
133 html_attr(value); 133 html_attr(value);
134 html("'/>"); 134 html("'/>");
135} 135}
136 136
137void html_option(char *value, char *text, char *selected_value) 137void html_option(char *value, char *text, char *selected_value)
138{ 138{
139 html("<option value='"); 139 html("<option value='");
140 html_attr(value); 140 html_attr(value);
141 html("'"); 141 html("'");
142 if (selected_value && !strcmp(selected_value, value)) 142 if (selected_value && !strcmp(selected_value, value))
143 html(" selected='selected'"); 143 html(" selected='selected'");
144 html(">"); 144 html(">");
145 html_txt(text); 145 html_txt(text);
146 html("</option>\n"); 146 html("</option>\n");
147} 147}
148 148
149void html_link_open(char *url, char *title, char *class) 149void html_link_open(char *url, char *title, char *class)
150{ 150{
151 html("<a href='"); 151 html("<a href='");
152 html_attr(url); 152 html_attr(url);
153 if (title) { 153 if (title) {
154 html("' title='"); 154 html("' title='");
155 html_attr(title); 155 html_attr(title);
156 } 156 }
157 if (class) { 157 if (class) {
158 html("' class='"); 158 html("' class='");
159 html_attr(class); 159 html_attr(class);
160 } 160 }
161 html("'>"); 161 html("'>");
162} 162}
163 163
164void html_link_close(void) 164void html_link_close(void)
165{ 165{
166 html("</a>"); 166 html("</a>");
167} 167}
168 168
169void html_fileperm(unsigned short mode) 169void html_fileperm(unsigned short mode)
170{ 170{
171 htmlf("%c%c%c", (mode & 4 ? 'r' : '-'), 171 htmlf("%c%c%c", (mode & 4 ? 'r' : '-'),
172 (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-')); 172 (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-'));
173} 173}
174 174
175int html_include(const char *filename) 175int html_include(const char *filename)
176{ 176{
177 FILE *f; 177 FILE *f;
178 char buf[4096]; 178 char buf[4096];
179 size_t len; 179 size_t len;
180 180
181 if (!(f = fopen(filename, "r"))) 181 if (!(f = fopen(filename, "r")))
182 return -1; 182 return -1;
183 while((len = fread(buf, 1, 4096, f)) > 0) 183 while((len = fread(buf, 1, 4096, f)) > 0)
184 write(htmlfd, buf, len); 184 write(htmlfd, buf, len);
185 fclose(f); 185 fclose(f);
186 return 0; 186 return 0;
187} 187}
188
189int hextoint(char c)
190{
191 if (c >= 'a' && c <= 'f')
192 return 10 + c - 'a';
193 else if (c >= 'A' && c <= 'F')
194 return 10 + c - 'A';
195 else if (c >= '0' && c <= '9')
196 return c - '0';
197 else
198 return -1;
199}
200
201char *convert_query_hexchar(char *txt)
202{
203 int d1, d2;
204 if (strlen(txt) < 3) {
205 *txt = '\0';
206 return txt-1;
207 }
208 d1 = hextoint(*(txt+1));
209 d2 = hextoint(*(txt+2));
210 if (d1<0 || d2<0) {
211 strcpy(txt, txt+3);
212 return txt-1;
213 } else {
214 *txt = d1 * 16 + d2;
215 strcpy(txt+1, txt+3);
216 return txt;
217 }
218}
219
220int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value))
221{
222 char *t, *value = NULL, c;
223
224 if (!txt)
225 return 0;
226
227 t = txt = strdup(txt);
228 if (t == NULL) {
229 printf("Out of memory\n");
230 exit(1);
231 }
232 while((c=*t) != '\0') {
233 if (c=='=') {
234 *t = '\0';
235 value = t+1;
236 } else if (c=='+') {
237 *t = ' ';
238 } else if (c=='%') {
239 t = convert_query_hexchar(t);
240 } else if (c=='&') {
241 *t = '\0';
242 (*fn)(txt, value);
243 txt = t+1;
244 value = NULL;
245 }
246 t++;
247 }
248 if (t!=txt)
249 (*fn)(txt, value);
250 return 0;
251}