* (see COPYING for full license text)
*/
-#include "cgit.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+int htmlfd = STDOUT_FILENO;
char *fmt(const char *format, ...)
{
va_start(args, format);
len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args);
va_end(args);
- if (len>sizeof(buf[bufidx]))
- die("[html.c] string truncated: %s", format);
+ if (len>sizeof(buf[bufidx])) {
+ fprintf(stderr, "[html.c] string truncated: %s\n", format);
+ exit(1);
+ }
return buf[bufidx];
}
+void html_raw(const char *data, size_t size)
+{
+ write(htmlfd, data, size);
+}
+
void html(const char *txt)
{
write(htmlfd, txt, strlen(txt));
html(buf);
}
+void html_status(int code, const char *msg, int more_headers)
+{
+ htmlf("Status: %d %s\n", code, msg);
+ if (!more_headers)
+ html("\n");
+}
+
void html_txt(char *txt)
{
char *t = txt;
while(t && *t){
int c = *t;
if (c=='<' || c=='>' || c=='&') {
- *t = '\0';
- html(txt);
- *t = c;
+ write(htmlfd, txt, t - txt);
if (c=='>')
html(">");
else if (c=='<')
while(t && *t && len--){
int c = *t;
if (c=='<' || c=='>' || c=='&') {
- *t = '\0';
- html(txt);
- *t = c;
+ write(htmlfd, txt, t - txt);
if (c=='>')
html(">");
else if (c=='<')
}
t++;
}
- if (t!=txt) {
- char c = *t;
- *t = '\0';
- html(txt);
- *t = c;
- }
+ if (t!=txt)
+ write(htmlfd, txt, t - txt);
if (len<0)
html("...");
}
char *t = txt;
while(t && *t){
int c = *t;
- if (c=='<' || c=='>' || c=='\'') {
- *t = '\0';
- html(txt);
- *t = c;
+ if (c=='<' || c=='>' || c=='\'' || c=='\"') {
+ write(htmlfd, txt, t - txt);
if (c=='>')
html(">");
else if (c=='<')
html("<");
else if (c=='\'')
- html(""e;");
+ html("'");
+ else if (c=='"')
+ html(""");
+ txt = t+1;
+ }
+ t++;
+ }
+ if (t!=txt)
+ html(txt);
+}
+
+void html_url_path(char *txt)
+{
+ char *t = txt;
+ while(t && *t){
+ int c = *t;
+ if (c=='"' || c=='#' || c=='\'' || c=='?') {
+ write(htmlfd, txt, t - txt);
+ write(htmlfd, fmt("%%%2x", c), 3);
txt = t+1;
}
t++;
html(txt);
}
+void html_url_arg(char *txt)
+{
+ char *t = txt;
+ while(t && *t){
+ int c = *t;
+ if (c=='"' || c=='#' || c=='%' || c=='&' || c=='\'' || c=='+' || c=='?') {
+ write(htmlfd, txt, t - txt);
+ write(htmlfd, fmt("%%%2x", c), 3);
+ txt = t+1;
+ }
+ t++;
+ }
+ if (t!=txt)
+ html(txt);
+}
+
+void html_hidden(char *name, char *value)
+{
+ html("<input type='hidden' name='");
+ html_attr(name);
+ html("' value='");
+ html_attr(value);
+ html("'/>");
+}
+
+void html_option(char *value, char *text, char *selected_value)
+{
+ html("<option value='");
+ html_attr(value);
+ html("'");
+ if (selected_value && !strcmp(selected_value, value))
+ html(" selected='selected'");
+ html(">");
+ html_txt(text);
+ html("</option>\n");
+}
+
void html_link_open(char *url, char *title, char *class)
{
html("<a href='");
void html_fileperm(unsigned short mode)
{
- htmlf("%c%c%c", (mode & 4 ? 'r' : '-'),
+ htmlf("%c%c%c", (mode & 4 ? 'r' : '-'),
(mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-'));
}
-void html_filemode(unsigned short mode)
+int html_include(const char *filename)
+{
+ FILE *f;
+ char buf[4096];
+ size_t len;
+
+ if (!(f = fopen(filename, "r"))) {
+ fprintf(stderr, "[cgit] Failed to include file %s: %s (%d).\n",
+ filename, strerror(errno), errno);
+ return -1;
+ }
+ while((len = fread(buf, 1, 4096, f)) > 0)
+ write(htmlfd, buf, len);
+ fclose(f);
+ return 0;
+}
+
+int hextoint(char c)
{
- if (S_ISDIR(mode))
- html("d");
- else if (S_ISLNK(mode))
- html("l");
+ if (c >= 'a' && c <= 'f')
+ return 10 + c - 'a';
+ else if (c >= 'A' && c <= 'F')
+ return 10 + c - 'A';
+ else if (c >= '0' && c <= '9')
+ return c - '0';
else
- html("-");
- html_fileperm(mode >> 6);
- html_fileperm(mode >> 3);
- html_fileperm(mode);
+ return -1;
+}
+
+char *convert_query_hexchar(char *txt)
+{
+ int d1, d2, n;
+ n = strlen(txt);
+ if (n < 3) {
+ *txt = '\0';
+ return txt-1;
+ }
+ d1 = hextoint(*(txt+1));
+ d2 = hextoint(*(txt+2));
+ if (d1<0 || d2<0) {
+ memmove(txt, txt+3, n-2);
+ return txt-1;
+ } else {
+ *txt = d1 * 16 + d2;
+ memmove(txt+1, txt+3, n-2);
+ return txt;
+ }
+}
+
+int http_parse_querystring(char *txt, void (*fn)(const char *name, const char *value))
+{
+ char *t, *value = NULL, c;
+
+ if (!txt)
+ return 0;
+
+ t = txt = strdup(txt);
+ if (t == NULL) {
+ printf("Out of memory\n");
+ exit(1);
+ }
+ while((c=*t) != '\0') {
+ if (c=='=') {
+ *t = '\0';
+ value = t+1;
+ } else if (c=='+') {
+ *t = ' ';
+ } else if (c=='%') {
+ t = convert_query_hexchar(t);
+ } else if (c=='&') {
+ *t = '\0';
+ (*fn)(txt, value);
+ txt = t+1;
+ value = NULL;
+ }
+ t++;
+ }
+ if (t!=txt)
+ (*fn)(txt, value);
+ return 0;
}