all repos — cgit @ 68cb84839f8fbc20688b22202489f4c2a54d3f55

a hyperfast web frontend for git written in c

html.c (view raw)

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