Lars Hjemli | 7640d90 | 2006-12-10 22:41:14 +0100 | [diff] [blame] | 1 | /* html.c: helper functions for html output |
| 2 | * |
Lukas Fleischer | f7f26f8 | 2014-01-08 15:10:49 +0100 | [diff] [blame] | 3 | * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com> |
Lars Hjemli | 7640d90 | 2006-12-10 22:41:14 +0100 | [diff] [blame] | 4 | * |
| 5 | * Licensed under GNU General Public License v2 |
| 6 | * (see COPYING for full license text) |
| 7 | */ |
| 8 | |
Lukas Fleischer | 3edfd83 | 2013-04-06 13:30:54 +0200 | [diff] [blame] | 9 | #include "cgit.h" |
John Keeping | 8f20879 | 2013-04-06 11:37:59 +0100 | [diff] [blame] | 10 | #include "html.h" |
Lukas Fleischer | 927b0ae | 2016-09-29 08:38:45 +0200 | [diff] [blame^] | 11 | #include "url.h" |
Lars Hjemli | b1f9b9c | 2008-02-23 22:45:33 +0100 | [diff] [blame] | 12 | |
Mark Lodato | a2c6355 | 2010-02-09 10:12:43 -0500 | [diff] [blame] | 13 | /* Percent-encoding of each character, except: a-zA-Z0-9!$()*,./:;@- */ |
| 14 | static const char* url_escape_table[256] = { |
John Keeping | 438bac6 | 2015-03-08 16:32:27 +0000 | [diff] [blame] | 15 | "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", |
| 16 | "%08", "%09", "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", |
| 17 | "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17", |
| 18 | "%18", "%19", "%1a", "%1b", "%1c", "%1d", "%1e", "%1f", |
| 19 | "%20", NULL, "%22", "%23", NULL, "%25", "%26", "%27", |
| 20 | NULL, NULL, NULL, "%2b", NULL, NULL, NULL, NULL, |
| 21 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 22 | NULL, NULL, NULL, NULL, "%3c", "%3d", "%3e", "%3f", |
| 23 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 24 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 25 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 26 | NULL, NULL, NULL, NULL, "%5c", NULL, "%5e", NULL, |
| 27 | "%60", NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 28 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 29 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 30 | NULL, NULL, NULL, "%7b", "%7c", "%7d", NULL, "%7f", |
| 31 | "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87", |
| 32 | "%88", "%89", "%8a", "%8b", "%8c", "%8d", "%8e", "%8f", |
| 33 | "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97", |
| 34 | "%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f", |
| 35 | "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7", |
| 36 | "%a8", "%a9", "%aa", "%ab", "%ac", "%ad", "%ae", "%af", |
| 37 | "%b0", "%b1", "%b2", "%b3", "%b4", "%b5", "%b6", "%b7", |
| 38 | "%b8", "%b9", "%ba", "%bb", "%bc", "%bd", "%be", "%bf", |
| 39 | "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7", |
| 40 | "%c8", "%c9", "%ca", "%cb", "%cc", "%cd", "%ce", "%cf", |
| 41 | "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", |
| 42 | "%d8", "%d9", "%da", "%db", "%dc", "%dd", "%de", "%df", |
| 43 | "%e0", "%e1", "%e2", "%e3", "%e4", "%e5", "%e6", "%e7", |
| 44 | "%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee", "%ef", |
| 45 | "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", |
| 46 | "%f8", "%f9", "%fa", "%fb", "%fc", "%fd", "%fe", "%ff" |
Mark Lodato | a2c6355 | 2010-02-09 10:12:43 -0500 | [diff] [blame] | 47 | }; |
| 48 | |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 49 | char *fmt(const char *format, ...) |
| 50 | { |
| 51 | static char buf[8][1024]; |
| 52 | static int bufidx; |
| 53 | int len; |
| 54 | va_list args; |
| 55 | |
| 56 | bufidx++; |
| 57 | bufidx &= 7; |
| 58 | |
| 59 | va_start(args, format); |
| 60 | len = vsnprintf(buf[bufidx], sizeof(buf[bufidx]), format, args); |
| 61 | va_end(args); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 62 | if (len > sizeof(buf[bufidx])) { |
Lars Hjemli | b1f9b9c | 2008-02-23 22:45:33 +0100 | [diff] [blame] | 63 | fprintf(stderr, "[html.c] string truncated: %s\n", format); |
| 64 | exit(1); |
| 65 | } |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 66 | return buf[bufidx]; |
| 67 | } |
| 68 | |
John Keeping | fd00d2f | 2013-04-07 14:40:50 +0100 | [diff] [blame] | 69 | char *fmtalloc(const char *format, ...) |
| 70 | { |
| 71 | struct strbuf sb = STRBUF_INIT; |
| 72 | va_list args; |
| 73 | |
| 74 | va_start(args, format); |
| 75 | strbuf_vaddf(&sb, format, args); |
| 76 | va_end(args); |
| 77 | |
| 78 | return strbuf_detach(&sb, NULL); |
| 79 | } |
| 80 | |
Lars Hjemli | e5da4bc | 2008-08-06 10:53:50 +0200 | [diff] [blame] | 81 | void html_raw(const char *data, size_t size) |
| 82 | { |
John Keeping | fd31aa6 | 2014-01-12 17:13:48 +0000 | [diff] [blame] | 83 | if (write(STDOUT_FILENO, data, size) != size) |
John Keeping | 1fec7cd | 2013-05-18 15:57:03 +0100 | [diff] [blame] | 84 | die_errno("write error on html output"); |
Lars Hjemli | e5da4bc | 2008-08-06 10:53:50 +0200 | [diff] [blame] | 85 | } |
| 86 | |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 87 | void html(const char *txt) |
| 88 | { |
Jason A. Donenfeld | 6d7e359 | 2013-03-20 20:44:20 +0100 | [diff] [blame] | 89 | html_raw(txt, strlen(txt)); |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | void htmlf(const char *format, ...) |
| 93 | { |
John Keeping | fd00d2f | 2013-04-07 14:40:50 +0100 | [diff] [blame] | 94 | va_list args; |
| 95 | struct strbuf buf = STRBUF_INIT; |
| 96 | |
| 97 | va_start(args, format); |
| 98 | strbuf_vaddf(&buf, format, args); |
| 99 | va_end(args); |
| 100 | html(buf.buf); |
| 101 | strbuf_release(&buf); |
| 102 | } |
| 103 | |
| 104 | void html_txtf(const char *format, ...) |
| 105 | { |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 106 | va_list args; |
| 107 | |
| 108 | va_start(args, format); |
John Keeping | fd00d2f | 2013-04-07 14:40:50 +0100 | [diff] [blame] | 109 | html_vtxtf(format, args); |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 110 | va_end(args); |
John Keeping | fd00d2f | 2013-04-07 14:40:50 +0100 | [diff] [blame] | 111 | } |
| 112 | |
| 113 | void html_vtxtf(const char *format, va_list ap) |
| 114 | { |
| 115 | va_list cp; |
| 116 | struct strbuf buf = STRBUF_INIT; |
| 117 | |
| 118 | va_copy(cp, ap); |
| 119 | strbuf_vaddf(&buf, format, cp); |
| 120 | va_end(cp); |
| 121 | html_txt(buf.buf); |
| 122 | strbuf_release(&buf); |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 123 | } |
| 124 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 125 | void html_txt(const char *txt) |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 126 | { |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 127 | const char *t = txt; |
Jason A. Donenfeld | bdae1d8 | 2013-03-03 23:21:33 -0500 | [diff] [blame] | 128 | while (t && *t) { |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 129 | int c = *t; |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 130 | if (c == '<' || c == '>' || c == '&') { |
Mark Lodato | d187b98 | 2010-09-04 14:18:16 -0400 | [diff] [blame] | 131 | html_raw(txt, t - txt); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 132 | if (c == '>') |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 133 | html(">"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 134 | else if (c == '<') |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 135 | html("<"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 136 | else if (c == '&') |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 137 | html("&"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 138 | txt = t + 1; |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 139 | } |
| 140 | t++; |
| 141 | } |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 142 | if (t != txt) |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 143 | html(txt); |
| 144 | } |
| 145 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 146 | void html_ntxt(int len, const char *txt) |
Lars Hjemli | 9d8d9b6 | 2006-12-22 00:58:18 +0100 | [diff] [blame] | 147 | { |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 148 | const char *t = txt; |
Jason A. Donenfeld | bdae1d8 | 2013-03-03 23:21:33 -0500 | [diff] [blame] | 149 | while (t && *t && len--) { |
Lars Hjemli | 9d8d9b6 | 2006-12-22 00:58:18 +0100 | [diff] [blame] | 150 | int c = *t; |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 151 | if (c == '<' || c == '>' || c == '&') { |
Mark Lodato | d187b98 | 2010-09-04 14:18:16 -0400 | [diff] [blame] | 152 | html_raw(txt, t - txt); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 153 | if (c == '>') |
Lars Hjemli | 9d8d9b6 | 2006-12-22 00:58:18 +0100 | [diff] [blame] | 154 | html(">"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 155 | else if (c == '<') |
Lars Hjemli | 9d8d9b6 | 2006-12-22 00:58:18 +0100 | [diff] [blame] | 156 | html("<"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 157 | else if (c == '&') |
Lars Hjemli | 9d8d9b6 | 2006-12-22 00:58:18 +0100 | [diff] [blame] | 158 | html("&"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 159 | txt = t + 1; |
Lars Hjemli | 9d8d9b6 | 2006-12-22 00:58:18 +0100 | [diff] [blame] | 160 | } |
| 161 | t++; |
| 162 | } |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 163 | if (t != txt) |
Mark Lodato | d187b98 | 2010-09-04 14:18:16 -0400 | [diff] [blame] | 164 | html_raw(txt, t - txt); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 165 | if (len < 0) |
Lars Hjemli | 9d8d9b6 | 2006-12-22 00:58:18 +0100 | [diff] [blame] | 166 | html("..."); |
| 167 | } |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 168 | |
John Keeping | fd00d2f | 2013-04-07 14:40:50 +0100 | [diff] [blame] | 169 | void html_attrf(const char *fmt, ...) |
| 170 | { |
| 171 | va_list ap; |
| 172 | struct strbuf sb = STRBUF_INIT; |
| 173 | |
| 174 | va_start(ap, fmt); |
| 175 | strbuf_vaddf(&sb, fmt, ap); |
| 176 | va_end(ap); |
| 177 | |
| 178 | html_attr(sb.buf); |
| 179 | strbuf_release(&sb); |
| 180 | } |
| 181 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 182 | void html_attr(const char *txt) |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 183 | { |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 184 | const char *t = txt; |
Jason A. Donenfeld | bdae1d8 | 2013-03-03 23:21:33 -0500 | [diff] [blame] | 185 | while (t && *t) { |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 186 | int c = *t; |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 187 | if (c == '<' || c == '>' || c == '\'' || c == '\"' || c == '&') { |
Mark Lodato | d187b98 | 2010-09-04 14:18:16 -0400 | [diff] [blame] | 188 | html_raw(txt, t - txt); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 189 | if (c == '>') |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 190 | html(">"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 191 | else if (c == '<') |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 192 | html("<"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 193 | else if (c == '\'') |
Lars Hjemli | 7efcef0 | 2009-01-29 22:21:15 +0100 | [diff] [blame] | 194 | html("'"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 195 | else if (c == '"') |
Lars Hjemli | 7efcef0 | 2009-01-29 22:21:15 +0100 | [diff] [blame] | 196 | html("""); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 197 | else if (c == '&') |
Lukas Fleischer | 6938232 | 2011-05-24 20:38:40 +0200 | [diff] [blame] | 198 | html("&"); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 199 | txt = t + 1; |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 200 | } |
| 201 | t++; |
| 202 | } |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 203 | if (t != txt) |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 204 | html(txt); |
| 205 | } |
| 206 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 207 | void html_url_path(const char *txt) |
Lars Hjemli | 22a597e | 2008-10-05 16:52:57 +0200 | [diff] [blame] | 208 | { |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 209 | const char *t = txt; |
Jason A. Donenfeld | bdae1d8 | 2013-03-03 23:21:33 -0500 | [diff] [blame] | 210 | while (t && *t) { |
Eric Wong | 9cae75d | 2011-07-21 03:24:54 +0000 | [diff] [blame] | 211 | unsigned char c = *t; |
Mark Lodato | a2c6355 | 2010-02-09 10:12:43 -0500 | [diff] [blame] | 212 | const char *e = url_escape_table[c]; |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 213 | if (e && c != '+' && c != '&') { |
Mark Lodato | d187b98 | 2010-09-04 14:18:16 -0400 | [diff] [blame] | 214 | html_raw(txt, t - txt); |
Jonathon Mah | 7415274 | 2011-04-10 04:10:03 -0700 | [diff] [blame] | 215 | html(e); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 216 | txt = t + 1; |
Lars Hjemli | 22a597e | 2008-10-05 16:52:57 +0200 | [diff] [blame] | 217 | } |
| 218 | t++; |
| 219 | } |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 220 | if (t != txt) |
Lars Hjemli | 22a597e | 2008-10-05 16:52:57 +0200 | [diff] [blame] | 221 | html(txt); |
| 222 | } |
| 223 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 224 | void html_url_arg(const char *txt) |
Lars Hjemli | a36a0d9 | 2008-10-05 12:49:46 +0200 | [diff] [blame] | 225 | { |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 226 | const char *t = txt; |
Jason A. Donenfeld | bdae1d8 | 2013-03-03 23:21:33 -0500 | [diff] [blame] | 227 | while (t && *t) { |
Eric Wong | 9cae75d | 2011-07-21 03:24:54 +0000 | [diff] [blame] | 228 | unsigned char c = *t; |
Mark Lodato | a2c6355 | 2010-02-09 10:12:43 -0500 | [diff] [blame] | 229 | const char *e = url_escape_table[c]; |
Jonathon Mah | 7415274 | 2011-04-10 04:10:03 -0700 | [diff] [blame] | 230 | if (c == ' ') |
| 231 | e = "+"; |
Mark Lodato | a2c6355 | 2010-02-09 10:12:43 -0500 | [diff] [blame] | 232 | if (e) { |
Mark Lodato | d187b98 | 2010-09-04 14:18:16 -0400 | [diff] [blame] | 233 | html_raw(txt, t - txt); |
Jonathon Mah | 7415274 | 2011-04-10 04:10:03 -0700 | [diff] [blame] | 234 | html(e); |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 235 | txt = t + 1; |
Lars Hjemli | a36a0d9 | 2008-10-05 12:49:46 +0200 | [diff] [blame] | 236 | } |
| 237 | t++; |
| 238 | } |
Lukas Fleischer | 53bc747 | 2013-03-03 16:04:29 +0100 | [diff] [blame] | 239 | if (t != txt) |
Lars Hjemli | a36a0d9 | 2008-10-05 12:49:46 +0200 | [diff] [blame] | 240 | html(txt); |
| 241 | } |
| 242 | |
Jason A. Donenfeld | 513b386 | 2016-01-14 14:28:37 +0100 | [diff] [blame] | 243 | void html_header_arg_in_quotes(const char *txt) |
| 244 | { |
| 245 | const char *t = txt; |
| 246 | while (t && *t) { |
| 247 | unsigned char c = *t; |
| 248 | const char *e = NULL; |
| 249 | if (c == '\\') |
| 250 | e = "\\\\"; |
| 251 | else if (c == '\r') |
| 252 | e = "\\r"; |
| 253 | else if (c == '\n') |
| 254 | e = "\\n"; |
| 255 | else if (c == '"') |
| 256 | e = "\\\""; |
| 257 | if (e) { |
| 258 | html_raw(txt, t - txt); |
| 259 | html(e); |
| 260 | txt = t + 1; |
| 261 | } |
| 262 | t++; |
| 263 | } |
| 264 | if (t != txt) |
| 265 | html(txt); |
| 266 | |
| 267 | } |
| 268 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 269 | void html_hidden(const char *name, const char *value) |
Lars Hjemli | e39d738 | 2006-12-28 02:01:49 +0100 | [diff] [blame] | 270 | { |
| 271 | html("<input type='hidden' name='"); |
| 272 | html_attr(name); |
| 273 | html("' value='"); |
| 274 | html_attr(value); |
| 275 | html("'/>"); |
| 276 | } |
| 277 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 278 | void html_option(const char *value, const char *text, const char *selected_value) |
Lars Hjemli | 6ec5f36 | 2007-10-28 12:08:45 +0100 | [diff] [blame] | 279 | { |
| 280 | html("<option value='"); |
| 281 | html_attr(value); |
| 282 | html("'"); |
| 283 | if (selected_value && !strcmp(selected_value, value)) |
Lars Hjemli | 2915483 | 2007-11-11 13:04:28 +0100 | [diff] [blame] | 284 | html(" selected='selected'"); |
Lars Hjemli | 6ec5f36 | 2007-10-28 12:08:45 +0100 | [diff] [blame] | 285 | html(">"); |
| 286 | html_txt(text); |
| 287 | html("</option>\n"); |
| 288 | } |
| 289 | |
Lars Hjemli | 1a64fd2 | 2011-03-06 23:57:26 +0100 | [diff] [blame] | 290 | void html_intoption(int value, const char *text, int selected_value) |
| 291 | { |
| 292 | htmlf("<option value='%d'%s>", value, |
| 293 | value == selected_value ? " selected='selected'" : ""); |
| 294 | html_txt(text); |
| 295 | html("</option>"); |
| 296 | } |
| 297 | |
Mark Lodato | 8aab27f | 2010-02-08 23:04:41 -0500 | [diff] [blame] | 298 | void html_link_open(const char *url, const char *title, const char *class) |
Lars Hjemli | 0d169ad | 2006-12-09 15:18:17 +0100 | [diff] [blame] | 299 | { |
| 300 | html("<a href='"); |
| 301 | html_attr(url); |
| 302 | if (title) { |
| 303 | html("' title='"); |
| 304 | html_attr(title); |
| 305 | } |
| 306 | if (class) { |
| 307 | html("' class='"); |
| 308 | html_attr(class); |
| 309 | } |
| 310 | html("'>"); |
| 311 | } |
| 312 | |
| 313 | void html_link_close(void) |
| 314 | { |
| 315 | html("</a>"); |
| 316 | } |
Lars Hjemli | 6cb326c | 2006-12-17 23:07:28 +0100 | [diff] [blame] | 317 | |
| 318 | void html_fileperm(unsigned short mode) |
| 319 | { |
Lars Hjemli | b1f9b9c | 2008-02-23 22:45:33 +0100 | [diff] [blame] | 320 | htmlf("%c%c%c", (mode & 4 ? 'r' : '-'), |
Lars Hjemli | 6cb326c | 2006-12-17 23:07:28 +0100 | [diff] [blame] | 321 | (mode & 2 ? 'w' : '-'), (mode & 1 ? 'x' : '-')); |
| 322 | } |
| 323 | |
Lars Hjemli | 5e75128 | 2007-05-18 23:56:10 +0200 | [diff] [blame] | 324 | int html_include(const char *filename) |
| 325 | { |
| 326 | FILE *f; |
| 327 | char buf[4096]; |
| 328 | size_t len; |
| 329 | |
Harley Laue | 112b208 | 2008-04-29 17:59:53 +0200 | [diff] [blame] | 330 | if (!(f = fopen(filename, "r"))) { |
| 331 | fprintf(stderr, "[cgit] Failed to include file %s: %s (%d).\n", |
| 332 | filename, strerror(errno), errno); |
Lars Hjemli | 5e75128 | 2007-05-18 23:56:10 +0200 | [diff] [blame] | 333 | return -1; |
Harley Laue | 112b208 | 2008-04-29 17:59:53 +0200 | [diff] [blame] | 334 | } |
Jason A. Donenfeld | bdae1d8 | 2013-03-03 23:21:33 -0500 | [diff] [blame] | 335 | while ((len = fread(buf, 1, 4096, f)) > 0) |
Mark Lodato | d187b98 | 2010-09-04 14:18:16 -0400 | [diff] [blame] | 336 | html_raw(buf, len); |
Lars Hjemli | 5e75128 | 2007-05-18 23:56:10 +0200 | [diff] [blame] | 337 | fclose(f); |
| 338 | return 0; |
| 339 | } |
Lars Hjemli | e87e896 | 2008-04-08 21:11:36 +0200 | [diff] [blame] | 340 | |
Lukas Fleischer | 927b0ae | 2016-09-29 08:38:45 +0200 | [diff] [blame^] | 341 | void http_parse_querystring(const char *txt, void (*fn)(const char *name, const char *value)) |
Lars Hjemli | e87e896 | 2008-04-08 21:11:36 +0200 | [diff] [blame] | 342 | { |
Lukas Fleischer | 927b0ae | 2016-09-29 08:38:45 +0200 | [diff] [blame^] | 343 | const char *t = txt; |
Lars Hjemli | e87e896 | 2008-04-08 21:11:36 +0200 | [diff] [blame] | 344 | |
Lukas Fleischer | 927b0ae | 2016-09-29 08:38:45 +0200 | [diff] [blame^] | 345 | while (t && *t) { |
| 346 | char *name = url_decode_parameter_name(&t); |
| 347 | if (*name) { |
| 348 | char *value = url_decode_parameter_value(&t); |
| 349 | fn(name, value); |
| 350 | free(value); |
Lars Hjemli | e87e896 | 2008-04-08 21:11:36 +0200 | [diff] [blame] | 351 | } |
Lukas Fleischer | 927b0ae | 2016-09-29 08:38:45 +0200 | [diff] [blame^] | 352 | free(name); |
Lars Hjemli | e87e896 | 2008-04-08 21:11:36 +0200 | [diff] [blame] | 353 | } |
Lars Hjemli | e87e896 | 2008-04-08 21:11:36 +0200 | [diff] [blame] | 354 | } |