Subversion Repositories RepoView

Rev

Rev 13 | Rev 15 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 nishi 1
/* $Id: modern.c 14 2024-08-21 14:24:05Z nishi $ */
2
 
3
#include "rv_query.h"
4
 
5
#include "rv_util.h"
6
#include "rv_version.h"
3 nishi 7
#include "rv_auth.h"
1 nishi 8
#include "rv_db.h"
11 nishi 9
#include "rv_repo.h"
1 nishi 10
 
11
#include "../../config.h"
12
 
13 nishi 13
#ifdef USE_ENSCRIPT
14
#include "rv_enscript.h"
15
#endif
16
 
7 nishi 17
#include <stdio.h>
1 nishi 18
#include <stdlib.h>
19
#include <string.h>
20
 
21
extern char* buffer;
22
void add_data(char** data, const char* txt);
23
void render_stuff();
24
 
25
char* title = NULL;
26
char* desc = NULL;
27
char* page = NULL;
10 nishi 28
char* nav = NULL;
11 nishi 29
char* grepouser;
6 nishi 30
extern char* user;
1 nishi 31
 
11 nishi 32
char* url_escape(const char* input) {
33
	const char hex[] = "0123456789ABCDEF";
34
	char* r = malloc(1);
35
	r[0] = 0;
36
	char cbuf[2];
37
	cbuf[1] = 0;
38
	int i;
39
	for(i = 0; input[i] != 0; i++) {
40
		if(input[i] == 0x20 || input[i] == 0x22 || input[i] == 0x25 || input[i] == 0x2d || input[i] == 0x2e || input[i] == 0x3c || input[i] == 0x3e || input[i] == 0x5c || input[i] == 0x5e || input[i] == 0x5f || input[i] == 0x60 || input[i] == 0x7b || input[i] == 0x7c || input[i] == 0x7d || input[i] == 0x7e || input[i] == 0x21 || input[i] == 0x23 || input[i] == 0x24 || input[i] == 0x26 || input[i] == 0x27 || input[i] == 0x28 || input[i] == 0x29 || input[i] == 0x2a || input[i] == 0x2b || input[i] == 0x2c || input[i] == 0x2f || input[i] == 0x3a || input[i] == 0x3b || input[i] == 0x3d || input[i] == 0x3f || input[i] == 0x40 || input[i] == 0x5b || input[i] == 0x5d) {
41
			add_data(&r, "%");
42
			cbuf[0] = hex[(input[i] >> 4) & 0xf];
43
			add_data(&r, cbuf);
44
			cbuf[0] = hex[input[i] & 0xf];
45
			add_data(&r, cbuf);
46
		} else {
47
			cbuf[0] = input[i];
48
			add_data(&r, cbuf);
49
		}
50
	}
51
	return r;
52
}
53
 
54
char* html_escape(const char* input) {
55
	char* r = malloc(1);
56
	r[0] = 0;
57
	char cbuf[2];
58
	cbuf[1] = 0;
59
	int i;
60
	for(i = 0; input[i] != 0; i++) {
61
		if(input[i] == '<') {
62
			add_data(&r, "&lt;");
63
		} else if(input[i] == '>') {
64
			add_data(&r, "&gt;");
65
		} else {
66
			cbuf[0] = input[i];
67
			add_data(&r, cbuf);
68
		}
69
	}
70
	return r;
71
}
72
 
73
char* html_escape_nl_to_br(const char* input) {
74
	char* r = malloc(1);
75
	r[0] = 0;
76
	char cbuf[2];
77
	cbuf[1] = 0;
78
	int i;
79
	for(i = 0; input[i] != 0; i++) {
80
		if(input[i] == '<') {
81
			add_data(&r, "&lt;");
82
		} else if(input[i] == '>') {
83
			add_data(&r, "&gt;");
84
		} else if(input[i] == '\n') {
85
			add_data(&r, "<br>");
86
		} else {
87
			cbuf[0] = input[i];
88
			add_data(&r, cbuf);
89
		}
90
	}
91
	return r;
92
}
93
 
94
void list_repo(const char* name, const char* rev) {
95
	char* showname = html_escape(name);
96
	char* urluser = url_escape(user);
97
	char* urlrepo = url_escape(name);
98
	add_data(&page, "<tr>");
99
	add_data(&page, "<td><a href=\"");
100
	add_data(&page, INSTANCE_ROOT);
101
	add_data(&page, "/?page=repo&reponame=");
102
	add_data(&page, urlrepo);
103
	add_data(&page, "&username=");
104
	add_data(&page, urluser);
105
	add_data(&page, "\">");
106
	add_data(&page, showname);
107
	add_data(&page, "</a></td>");
108
	add_data(&page, "<td>");
109
	add_data(&page, rev);
110
	add_data(&page, "</td>");
111
	add_data(&page, "</tr>");
112
	free(showname);
113
	free(urluser);
114
	free(urlrepo);
115
}
116
 
117
int fcounter = 0;
118
void list_files(const char* pathname) {
119
	if(fcounter == 0) {
120
		add_data(&nav, "<li><a href=\"#filelist\">File List</a></li>\n");
121
		add_data(&page, "<h2 id=\"filelist\">File List</h2>\n");
122
		add_data(&page, "<tr style=\"background-color: #D2E1F6;\"><th>Name</th><th>Size</th></tr>\n");
12 nishi 123
		char* path = rv_get_query("path");
124
		if(path == NULL) path = "/";
125
		if(strcmp(path, "/") != 0) {
126
			char* query = rv_strdup("?page=repo&reponame=");
127
			char* esc;
128
			esc = url_escape(rv_get_query("reponame"));
129
			add_data(&query, esc);
130
			free(esc);
131
			add_data(&query, "&username=");
132
			esc = url_escape(user);
133
			add_data(&query, esc);
134
			free(esc);
135
			add_data(&query, "&path=");
136
 
137
			char* urlpath = rv_strdup(path);
138
			int i;
139
			int counter = 0;
140
			int rep = urlpath[strlen(urlpath) - 1] == '/' ? 2 : 1;
141
			for(i = strlen(urlpath) - 1; i >= 0; i--) {
142
				char oldc = urlpath[i];
143
				urlpath[i] = 0;
144
				if(oldc == '/') {
145
					counter++;
146
					if(counter == 2) {
147
						break;
148
					}
149
				}
150
			}
151
 
152
			if(strlen(urlpath) == 0) {
153
				free(urlpath);
154
				urlpath = rv_strdup("/");
155
			}
156
 
157
			esc = url_escape(urlpath);
158
			add_data(&query, esc);
159
			free(esc);
160
 
161
			add_data(&page, "<tr><td><a href=\"");
162
			add_data(&page, query);
163
			add_data(&page, "\">../</a></td><td>&lt;DIR&gt;</td></tr>\n");
164
			fcounter++;
165
			free(query);
166
		}
11 nishi 167
	}
168
	fcounter++;
169
	add_data(&page, "<tr style=\"background-color: #");
170
	if((fcounter % 2) == 0) {
171
		add_data(&page, "D2E1C0");
172
	} else {
173
		add_data(&page, "FFFFFF");
174
	}
175
	char* path = rv_get_query("path");
176
	if(path == NULL) path = "/";
177
	char* query = rv_strdup("?page=repo&reponame=");
178
	char* esc;
179
	esc = url_escape(rv_get_query("reponame"));
180
	add_data(&query, esc);
181
	free(esc);
182
	add_data(&query, "&username=");
183
	esc = url_escape(user);
184
	add_data(&query, esc);
185
	free(esc);
186
	add_data(&query, "&path=");
13 nishi 187
	char* urlpath = rv_strcat3(path, "/", pathname);
11 nishi 188
	esc = url_escape(urlpath);
189
	add_data(&query, esc);
190
	free(esc);
191
	char* sz = malloc(128);
192
	sprintf(sz, "%lld", rv_get_filesize(grepouser, urlpath));
193
	add_data(&page, "\"><td><a href=\"");
194
	add_data(&page, query);
195
	add_data(&page, "\">");
196
	add_data(&page, pathname);
197
	add_data(&page, "</a></td>\n");
198
	add_data(&page, "<td>\n");
199
	if(strcmp(sz, "-1") != 0) {
200
		add_data(&page, sz);
201
	} else {
202
		add_data(&page, "&lt;DIR&gt;");
203
	}
204
	add_data(&page, "</td>\n");
205
	free(sz);
206
	add_data(&page, "</tr>\n");
207
	free(query);
208
	free(urlpath);
209
}
210
 
3 nishi 211
void render_page(void) {
1 nishi 212
	rv_load_query('Q');
213
	char* query = rv_get_query("page");
214
	if(query == NULL) query = "welcome";
215
 
3 nishi 216
	if(strcmp(query, "welcome") == 0) {
1 nishi 217
		title = rv_strdup("Welcome");
218
		desc = rv_strdup("Welcome to " INSTANCE_NAME ".");
219
		page = rv_strcat3("Welcome to " INSTANCE_NAME ".<br>This instance is running RepoView version ", rv_get_version(), ".");
13 nishi 220
#ifdef ALLOW_SIGNUP
221
	} else if(strcmp(query, "signup") == 0) {
222
		title = rv_strdup("Signup");
223
		desc = rv_strdup("You can create your account here.");
224
		page = rv_strdup("");
225
 
226
		add_data(&page, "<form action=\"");
227
		add_data(&page, INSTANCE_ROOT);
228
		add_data(&page, "/?page=sendsignup\" method=\"POST\">\n");
229
		add_data(&page, "	<table border=\"0\">\n");
230
		add_data(&page, "		<tr>\n");
231
		add_data(&page, "			<th>Username</th>\n");
232
		add_data(&page, "			<td>\n");
233
		add_data(&page, "				<input name=\"username\">\n");
234
		add_data(&page, "			</td>\n");
235
		add_data(&page, "		</tr>\n");
236
		add_data(&page, "		<tr>\n");
237
		add_data(&page, "			<th>Password</th>\n");
238
		add_data(&page, "			<td>\n");
239
		add_data(&page, "				<input name=\"password\" type=\"password\">\n");
240
		add_data(&page, "			</td>\n");
241
		add_data(&page, "		</tr>\n");
242
		add_data(&page, "	</table>\n");
243
		char cbuf[2];
244
		cbuf[0] = REPO_USER_DELIM;
245
		cbuf[1] = 0;
246
		add_data(&page, "Username cannot contain '<code>");
247
		add_data(&page, cbuf);
14 nishi 248
		add_data(&page, "</code>' and '<code>#</code>'.<br>");
13 nishi 249
		add_data(&page, "	<input type=\"submit\" value=\"Signup\">\n");
250
		add_data(&page, "</form>\n");
251
	} else if(strcmp(query, "sendsignup") == 0) {
252
		title = rv_strdup("Signup Result");
253
		page = rv_strdup("");
254
 
255
		rv_load_query('P');
256
		if(user != NULL) {
257
			page = rv_strdup("It looks like you are already logged in.<br>Want to <a href=\"");
258
			add_data(&page, INSTANCE_ROOT);
259
			add_data(&page, "/?page=logout\">log out</a>?\n");
260
		} else if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) {
261
			add_data(&page, "Invalid form.\n");
262
		} else {
263
			if(rv_has_user(rv_get_query("username"))) {
264
				add_data(&page, "User already exists.");
265
			} else {
266
				if(user != NULL) free(user);
267
				int i;
268
				bool reject = false;
269
				char* name = rv_get_query("username");
270
				for(i = 0; name[i] != 0; i++) {
14 nishi 271
					if(name[i] == REPO_USER_DELIM || name[i] == '#') {
13 nishi 272
						char cbuf[2];
273
						cbuf[0] = REPO_USER_DELIM;
274
						cbuf[1] = 0;
275
						add_data(&page, "Username cannot contain '<code>");
276
						add_data(&page, cbuf);
277
						add_data(&page, "</code>'.");
278
						reject = true;
279
						break;
280
					}
281
				}
282
				if(!reject) {
283
					rv_create_user(rv_get_query("username"), rv_get_query("password"));
284
					user = rv_strdup(rv_get_query("username"));
285
					add_data(&page, "Welcome.\n");
286
					rv_save_login(rv_get_query("username"));
287
				}
288
			}
289
		}
290
#endif
3 nishi 291
	} else if(strcmp(query, "login") == 0) {
1 nishi 292
		title = rv_strdup("Login");
293
		desc = rv_strdup("You can log in to your account here.");
294
		page = rv_strdup("");
295
 
296
		add_data(&page, "<form action=\"");
297
		add_data(&page, INSTANCE_ROOT);
298
		add_data(&page, "/?page=sendlogin\" method=\"POST\">\n");
299
		add_data(&page, "	<table border=\"0\">\n");
300
		add_data(&page, "		<tr>\n");
301
		add_data(&page, "			<th>Username</th>\n");
302
		add_data(&page, "			<td>\n");
303
		add_data(&page, "				<input name=\"username\">\n");
304
		add_data(&page, "			</td>\n");
305
		add_data(&page, "		</tr>\n");
306
		add_data(&page, "		<tr>\n");
307
		add_data(&page, "			<th>Password</th>\n");
308
		add_data(&page, "			<td>\n");
309
		add_data(&page, "				<input name=\"password\" type=\"password\">\n");
310
		add_data(&page, "			</td>\n");
311
		add_data(&page, "		</tr>\n");
312
		add_data(&page, "	</table>\n");
313
		add_data(&page, "	<input type=\"submit\" value=\"Login\">\n");
314
		add_data(&page, "</form>\n");
3 nishi 315
	} else if(strcmp(query, "sendlogin") == 0) {
1 nishi 316
		title = rv_strdup("Login Result");
317
		page = rv_strdup("");
318
 
319
		rv_load_query('P');
11 nishi 320
		if(user != NULL) {
321
			page = rv_strdup("It looks like you are already logged in.<br>Want to <a href=\"");
322
			add_data(&page, INSTANCE_ROOT);
13 nishi 323
			add_data(&page, "/?page=logout\">log out</a>?\n");
11 nishi 324
		} else if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) {
5 nishi 325
			add_data(&page, "Invalid form.\n");
3 nishi 326
		} else {
327
			if(rv_has_user(rv_get_query("username"))) {
5 nishi 328
				if(rv_check_password(rv_get_query("username"), rv_get_query("password"))) {
6 nishi 329
					if(user != NULL) free(user);
330
					user = rv_strdup(rv_get_query("username"));
5 nishi 331
					add_data(&page, "Welcome back.\n");
332
					rv_save_login(rv_get_query("username"));
333
				} else {
334
					add_data(&page, "Invalid password.");
335
				}
3 nishi 336
			} else {
5 nishi 337
				add_data(&page, "User does not exist.");
1 nishi 338
			}
339
		}
7 nishi 340
	} else if(strcmp(query, "sendlogout") == 0) {
341
		title = rv_strdup("Logout Result");
342
		page = rv_strdup("");
343
		if(user == NULL) {
344
			add_data(&page, "You were not logged in.\n");
345
		} else {
346
			rv_logout();
347
			add_data(&page, "Goodbye.\n");
348
			free(user);
349
			user = NULL;
350
		}
6 nishi 351
	} else if(strcmp(query, "mypage") == 0) {
352
		title = rv_strdup("My Page");
353
		desc = rv_strdup("You manage your information here.");
354
		if(user == NULL) {
355
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
356
			add_data(&page, INSTANCE_ROOT);
357
			add_data(&page, "/?page=login\">log in</a>?\n");
358
		}
9 nishi 359
	} else if(strcmp(query, "myrepo") == 0) {
360
		title = rv_strdup("My Repositories");
361
		desc = rv_strdup("You manage your repositories here.");
362
		if(user == NULL) {
363
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
364
			add_data(&page, INSTANCE_ROOT);
365
			add_data(&page, "/?page=login\">log in</a>?\n");
10 nishi 366
		} else {
11 nishi 367
			char cbuf[2];
368
			cbuf[0] = REPO_USER_DELIM;
369
			cbuf[1] = 0;
10 nishi 370
			nav = rv_strdup("");
371
			add_data(&nav, "<li><a href=\"#createrepo\">Create a repository</a></li>\n");
372
			add_data(&nav, "<li><a href=\"#repolist\">Repository List</a></li>\n");
373
			page = rv_strdup("");
374
			add_data(&page, "<h2 id=\"createrepo\">Create a repository</h2>\n");
375
			add_data(&page, "<form action=\"");
376
			add_data(&page, INSTANCE_ROOT);
377
			add_data(&page, "/?page=createrepo\" method=\"POST\">\n");
378
			add_data(&page, "	<table border=\"0\">\n");
379
			add_data(&page, "		<tr>\n");
380
			add_data(&page, "			<th>Repository name</th>\n");
381
			add_data(&page, "			<td>\n");
382
			add_data(&page, "				<input name=\"name\">\n");
383
			add_data(&page, "			</td>\n");
384
			add_data(&page, "			<td><input type=\"submit\" value=\"Create\"></td>\n");
385
			add_data(&page, "		</tr>\n");
386
			add_data(&page, "	</table>\n");
11 nishi 387
			add_data(&page, "Repository name cannot contain '<code>");
388
			add_data(&page, cbuf);
14 nishi 389
			add_data(&page, "</code>' and '<code>#</code>'.");
10 nishi 390
			add_data(&page, "</form>\n");
391
			add_data(&page, "<h2 id=\"repolist\">Repository List</h2>\n");
11 nishi 392
			add_data(&page, "<table border=\"0\">\n");
393
			add_data(&page, "<tr><th>Repository name</th><th>Revision</th></tr>\n");
394
			rv_repo_list(user, list_repo);
395
			add_data(&page, "</table>\n");
9 nishi 396
		}
11 nishi 397
	} else if(strcmp(query, "createrepo") == 0) {
398
		title = rv_strdup("Creating Repository Result");
399
		page = rv_strdup("");
400
 
401
		rv_load_query('P');
402
		if(user == NULL) {
403
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
404
			add_data(&page, INSTANCE_ROOT);
405
			add_data(&page, "/?page=login\">log in</a>?\n");
406
		} else if(rv_get_query("name") == NULL) {
407
			add_data(&page, "Invalid form.\n");
408
		} else {
409
			int i;
410
			bool reject = false;
411
			char* name = rv_get_query("name");
412
			for(i = 0; name[i] != 0; i++) {
14 nishi 413
				if(name[i] == REPO_USER_DELIM || name[i] == '#') {
11 nishi 414
					char cbuf[2];
415
					cbuf[0] = REPO_USER_DELIM;
416
					cbuf[1] = 0;
417
					add_data(&page, "Repository name cannot contain '<code>");
418
					add_data(&page, cbuf);
419
					add_data(&page, "</code>'.");
420
					reject = true;
421
					break;
422
				}
423
			}
424
			if(!reject) {
425
				char* ru = rv_construct_repouser(name, user);
426
				if(rv_repo_exists(ru)) {
427
					add_data(&page, "Repository already exists.");
428
				} else {
429
					char* esc;
430
					rv_create_repo(ru);
431
					add_data(&page, "Repository has been created.<br>\n");
432
					add_data(&page, "<a href=\"");
433
					add_data(&page, INSTANCE_ROOT);
434
					esc = url_escape(name);
435
					add_data(&page, "/?page=repo&reponame=");
436
					add_data(&page, esc);
437
					free(esc);
438
					esc = url_escape(user);
439
					add_data(&page, "&username=");
440
					add_data(&page, esc);
441
					free(esc);
442
					add_data(&page, "\">Go to the repository</a>.\n");
443
				}
444
				free(ru);
445
			}
446
		}
7 nishi 447
	} else if(strcmp(query, "logout") == 0) {
448
		title = rv_strdup("Logout");
449
		desc = rv_strdup("You can log out from your account here.");
450
		if(user == NULL) {
451
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
452
			add_data(&page, INSTANCE_ROOT);
453
			add_data(&page, "/?page=login\">log in</a>?\n");
454
		} else {
455
			page = rv_strdup("");
456
			add_data(&page, "Are you sure you want to log out?\n");
457
			add_data(&page, "<form method=\"POST\" action=\"");
458
			add_data(&page, INSTANCE_ROOT);
459
			add_data(&page, "/?page=sendlogout\">\n");
460
			add_data(&page, "	<input type=\"submit\" value=\"Yes\">\n");
461
			add_data(&page, "</form>\n");
462
		}
11 nishi 463
	} else if(strcmp(query, "repo") == 0) {
464
		title = rv_strdup("Repository");
465
		desc = rv_strdup("");
466
		page = rv_strdup("");
467
		nav = rv_strdup("");
468
		if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
469
			add_data(&page, "Required parameters not set.");
470
		} else {
471
			char* user = rv_get_query("username");
472
			char* repo = rv_get_query("reponame");
473
			char* repouser = rv_construct_repouser(repo, user);
474
			grepouser = repouser;
475
			if(rv_repo_exists(repouser)) {
476
				char* showuser = html_escape(user);
477
				char* showrepo = html_escape(repo);
478
				char* showreadme = rv_get_readme(repouser);
479
				desc = html_escape_nl_to_br(showreadme);
480
				add_data(&title, " - ");
481
				add_data(&title, showrepo);
482
				add_data(&title, "/");
483
				add_data(&title, showuser);
484
				free(showuser);
485
				free(showrepo);
486
				free(showreadme);
487
 
488
				int isdir;
489
				char* path = rv_get_query("path");
490
				if(path == NULL) path = "/";
491
				fcounter = 0;
492
				add_data(&page, "<table border=\"0\" style=\"width: 100%;\">");
493
				if(!rv_get_list(repouser, path, list_files, &isdir)) {
494
					add_data(&page, "<tr><td>Path not found.</td></tr>\n");
495
				}
496
				add_data(&page, "</table>");
497
				if(isdir == 0) {
498
					add_data(&nav, "<li><a href=\"#filecontent\">Content</a></li>");
499
					add_data(&page, "<h2 id=\"filecontent\">Content</h2>\n");
500
					add_data(&page, "<pre class=\"codeblock\"><code>");
13 nishi 501
#ifdef USE_ENSCRIPT
502
					int i;
503
					char* ext = NULL;
504
					for(i = strlen(path) - 1; i >= 0; i--) {
505
						if(path[i] == '.') {
506
							ext = path + i + 1;
507
							break;
508
						}
509
					}
510
					char* data = rv_enscript(repouser, path, ext);
511
					if(data != NULL) {
512
						add_data(&page, data);
513
						free(data);
514
					} else {
515
						data = rv_read_file(repouser, path);
516
						if(data != NULL) {
517
							char* esc = html_escape_nl_to_br(data);
518
							add_data(&page, esc);
519
							free(esc);
520
							free(data);
521
						} else {
522
							add_data(&page, "Cannot open the file.\n");
523
						}
524
					}
525
#else
11 nishi 526
					char* data = rv_read_file(repouser, path);
12 nishi 527
					if(data != NULL) {
528
						char* esc = html_escape_nl_to_br(data);
529
						add_data(&page, esc);
530
						free(esc);
531
						free(data);
532
					} else {
533
						add_data(&page, "Cannot open the file.\n");
534
					}
13 nishi 535
#endif
11 nishi 536
					add_data(&page, "</code></pre>");
537
				}
538
			} else {
539
				add_data(&page, "Repository does not exist.\n");
540
			}
541
			free(repouser);
542
		}
1 nishi 543
	}
544
 
545
	if(title == NULL) title = rv_strdup("");
546
	if(desc == NULL) desc = rv_strdup("");
547
	if(page == NULL) page = rv_strdup("");
10 nishi 548
	if(nav == NULL) nav = rv_strdup("");
1 nishi 549
	render_stuff();
550
	free(page);
551
	free(desc);
552
	free(title);
10 nishi 553
	free(nav);
1 nishi 554
}
555
 
3 nishi 556
char* escape(const char* str) {
1 nishi 557
	char* r = malloc(1);
558
	r[0] = 0;
559
	char cbuf[2];
560
	cbuf[1] = 0;
561
	int i;
3 nishi 562
	for(i = 0; str[i] != 0; i++) {
563
		if(str[i] == '<') {
1 nishi 564
			char* tmp = r;
565
			r = rv_strcat(tmp, "&lt;");
566
			free(tmp);
3 nishi 567
		} else if(str[i] == '>') {
1 nishi 568
			char* tmp = r;
569
			r = rv_strcat(tmp, "&gt;");
570
			free(tmp);
3 nishi 571
		} else {
1 nishi 572
			cbuf[0] = str[i];
573
			char* tmp = r;
574
			r = rv_strcat(tmp, cbuf);
575
			free(tmp);
576
		}
577
	}
578
	return r;
579
}
580
 
3 nishi 581
void render_stuff(void) {
1 nishi 582
	char* escaped;
583
	add_data(&buffer, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
584
	add_data(&buffer, "<html>\n");
585
	add_data(&buffer, "	<head>\n");
586
	add_data(&buffer, "		<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n");
587
	add_data(&buffer, "		<title>");
588
	add_data(&buffer, INSTANCE_NAME);
589
	add_data(&buffer, " - ");
590
	add_data(&buffer, title);
591
	add_data(&buffer, "</title>\n");
592
	add_data(&buffer, "		<style type=\"text/css\">\n");
593
	add_data(&buffer, "* {\n");
594
	add_data(&buffer, "	padding: 0;\n");
595
	add_data(&buffer, "	margin: 0;\n");
596
	add_data(&buffer, "}\n");
597
	add_data(&buffer, "li {\n");
598
	add_data(&buffer, "	list-style: outside;\n");
599
	add_data(&buffer, "	margin-left: 1.25em;\n");
600
	add_data(&buffer, "}\n");
601
	add_data(&buffer, "a {\n");
602
	add_data(&buffer, "	text-decoration: none;\n");
603
	add_data(&buffer, "}\n");
604
	add_data(&buffer, "#nav div {\n");
605
	add_data(&buffer, "	float: left;\n");
606
	add_data(&buffer, "	margin: 0 0;\n");
607
	add_data(&buffer, "	padding-left: 0;\n");
9 nishi 608
	add_data(&buffer, "	padding-right: 25px;\n");
1 nishi 609
	add_data(&buffer, "	padding-top: 7px;\n");
610
	add_data(&buffer, "}\n");
11 nishi 611
	add_data(&buffer, "th,td {\n");
612
	add_data(&buffer, "	padding: 2px;\n");
613
	add_data(&buffer, "}\n");
1 nishi 614
	add_data(&buffer, "body {\n");
615
	add_data(&buffer, "	background-color: #1F4677;\n");
616
	add_data(&buffer, "	width: 940px;\n");
617
	add_data(&buffer, "	margin: 5px auto;\n");
618
	add_data(&buffer, "	font-family: sans-serif;\n");
619
	add_data(&buffer, "}\n");
620
	add_data(&buffer, "#nav {\n");
621
	add_data(&buffer, "	background-color: white;\n");
6 nishi 622
	add_data(&buffer, "	background-image: url('");
623
	add_data(&buffer, INSTANCE_NAVBAR);
624
	add_data(&buffer, "');\n");
1 nishi 625
	add_data(&buffer, "	height: 44px;\n");
626
	add_data(&buffer, "	padding: 8px;\n");
627
	add_data(&buffer, "	padding-left: 32px;\n");
628
	add_data(&buffer, "	font-size: 22px;\n");
629
	add_data(&buffer, "	font-weight: bold;\n");
630
	add_data(&buffer, "}\n");
11 nishi 631
	add_data(&buffer, "pre {\n");
632
	add_data(&buffer, "	background-color: #dddddd;\n");
633
	add_data(&buffer, "	border: solid 2px #bbbbbb;\n");
12 nishi 634
	add_data(&buffer, "	padding: 8px;\n");
635
	add_data(&buffer, "	overflow: scroll;\n");
11 nishi 636
	add_data(&buffer, "}\n");
1 nishi 637
	add_data(&buffer, "#index {\n");
638
	add_data(&buffer, "	list-style: none;\n");
639
	add_data(&buffer, "	line-height: normal;\n");
640
	add_data(&buffer, "	margin: auto 0;\n");
641
	add_data(&buffer, "	padding-left: 0;\n");
642
	add_data(&buffer, "}\n");
643
	add_data(&buffer, "#desc {\n");
644
	add_data(&buffer, "	background-color: #D2E1F6;\n");
645
	add_data(&buffer, "	margin: 9px auto;\n");
646
	add_data(&buffer, "	height: 128px;\n");
647
	add_data(&buffer, "	padding: 24px;\n");
648
	add_data(&buffer, "}\n");
649
	add_data(&buffer, "#descinside {\n");
650
	add_data(&buffer, "	float: left;\n");
11 nishi 651
	add_data(&buffer, "	width: 700px;\n");
652
	add_data(&buffer, "	overflow-y: scroll;\n");
653
	add_data(&buffer, "	max-height: 128px;\n");
1 nishi 654
	add_data(&buffer, "}\n");
655
	add_data(&buffer, "#logo {\n");
656
	add_data(&buffer, "	float: right;\n");
657
	add_data(&buffer, "}\n");
658
	add_data(&buffer, "#content {\n");
659
	add_data(&buffer, "	background-color: #FFFFFF;\n");
660
	add_data(&buffer, "	margin: -10px auto;\n");
661
	add_data(&buffer, "	padding: 8px 24px 24px;\n");
662
	add_data(&buffer, "}\n");
663
	add_data(&buffer, "#pageindex {\n");
664
	add_data(&buffer, "	background-color: #FFFFFF;\n");
665
	add_data(&buffer, "	padding-right: 24px;\n");
666
	add_data(&buffer, "	padding-bottom: 24px;\n");
667
	add_data(&buffer, "	float: left;\n");
668
	add_data(&buffer, "	border-right: 4px #1F4677 solid;\n");
669
	add_data(&buffer, "	width: 150px;\n");
670
	add_data(&buffer, "}\n");
671
	add_data(&buffer, "#pagecontent {\n");
672
	add_data(&buffer, "	background-color: #FFFFFF;\n");
673
	add_data(&buffer, "	width: 670px;\n");
674
	add_data(&buffer, "	float: right;\n");
675
	add_data(&buffer, "	padding-left: 24px;\n");
676
	add_data(&buffer, "}\n");
677
	add_data(&buffer, "#footer {\n");
678
	add_data(&buffer, "	background-color: #D2E1F6;\n");
679
	add_data(&buffer, "	padding: 8px 8px 48px;\n");
680
	add_data(&buffer, "	margin: 8px auto;\n");
681
	add_data(&buffer, "	font-size: 15px;\n");
682
	add_data(&buffer, "	height: 32px;\n");
683
	add_data(&buffer, "}\n");
684
	add_data(&buffer, ".fixfloat {\n");
685
	add_data(&buffer, "	clear: both;\n");
686
	add_data(&buffer, "}\n");
687
	add_data(&buffer, "#copyright {\n");
688
	add_data(&buffer, "	float: right;\n");
689
	add_data(&buffer, "	font-size: 10px;\n");
690
	add_data(&buffer, "	margin-top: 16px;\n");
691
	add_data(&buffer, "}\n");
692
	add_data(&buffer, "#gotop {\n");
693
	add_data(&buffer, "	position: absolute;\n");
694
	add_data(&buffer, "}\n");
695
	add_data(&buffer, "h2, h3 {\n");
696
	add_data(&buffer, "	padding-top: 8px;\n");
697
	add_data(&buffer, "	padding-bottom: 8px;\n");
698
	add_data(&buffer, "}\n");
699
	add_data(&buffer, "img {\n");
700
	add_data(&buffer, "	border: none;\n");
701
	add_data(&buffer, "}\n");
702
	add_data(&buffer, "		</style>\n");
703
	add_data(&buffer, "	</head>\n");
704
	add_data(&buffer, "	<body>\n");
705
	add_data(&buffer, "		<div id=\"nav\">\n");
706
	add_data(&buffer, "			<div>\n");
707
	add_data(&buffer, "				<a href=\"");
708
	add_data(&buffer, INSTANCE_ROOT);
709
	add_data(&buffer, "/\">Home</a>\n");
710
	add_data(&buffer, "			</div>\n");
5 nishi 711
	if(user == NULL) {
712
		add_data(&buffer, "			<div>\n");
713
		add_data(&buffer, "				<a href=\"");
714
		add_data(&buffer, INSTANCE_ROOT);
715
		add_data(&buffer, "/?page=login\">Login</a>\n");
716
		add_data(&buffer, "			</div>\n");
13 nishi 717
#ifdef ALLOW_SIGNUP
718
		add_data(&buffer, "			<div>\n");
719
		add_data(&buffer, "				<a href=\"");
720
		add_data(&buffer, INSTANCE_ROOT);
721
		add_data(&buffer, "/?page=signup\">Signup</a>\n");
722
		add_data(&buffer, "			</div>\n");
723
#endif
7 nishi 724
	} else {
725
		add_data(&buffer, "			<div>\n");
726
		add_data(&buffer, "				<a href=\"");
727
		add_data(&buffer, INSTANCE_ROOT);
9 nishi 728
		add_data(&buffer, "/?page=mypage\">My Page</a>\n");
729
		add_data(&buffer, "			</div>\n");
730
 
731
		add_data(&buffer, "			<div>\n");
732
		add_data(&buffer, "				<a href=\"");
733
		add_data(&buffer, INSTANCE_ROOT);
734
		add_data(&buffer, "/?page=myrepo\">My Repositories</a>\n");
735
		add_data(&buffer, "			</div>\n");
736
 
737
		add_data(&buffer, "			<div>\n");
738
		add_data(&buffer, "				<a href=\"");
739
		add_data(&buffer, INSTANCE_ROOT);
7 nishi 740
		add_data(&buffer, "/?page=logout\">Logout</a>\n");
741
		add_data(&buffer, "			</div>\n");
5 nishi 742
	}
6 nishi 743
	if(user != NULL) {
744
		add_data(&buffer, "<div style=\"float: right;font-size: 10px;padding-top: 36px;padding-right: 0;font-style: italic;\">You have logged in as <a href=\"");
745
		add_data(&buffer, INSTANCE_ROOT);
746
		add_data(&buffer, "/?page=mypage\">");
747
		add_data(&buffer, user);
748
		add_data(&buffer, "</a></div>");
749
	}
1 nishi 750
	add_data(&buffer, "		</div>\n");
751
	add_data(&buffer, "		<div id=\"desc\">\n");
752
	add_data(&buffer, "			<div id=\"descinside\">\n");
753
	add_data(&buffer, "				<h1>");
754
	add_data(&buffer, title);
755
	add_data(&buffer, "</h1>\n");
756
	add_data(&buffer, "				<p>\n");
757
	add_data(&buffer, desc);
758
	add_data(&buffer, "				</p>\n");
759
	add_data(&buffer, "			</div>\n");
760
	add_data(&buffer, "			<img id=\"logo\" src=\"");
761
	add_data(&buffer, INSTANCE_LOGO);
762
	add_data(&buffer, "\" height=\"128px\" alt=\"logo\">\n");
763
	add_data(&buffer, "		</div>\n");
764
	add_data(&buffer, "		<div id=\"content\">\n");
765
	add_data(&buffer, "			<div id=\"pageindex\">\n");
766
	add_data(&buffer, "				<h3>Page Menu</h3>\n");
767
	add_data(&buffer, "				<ul>\n");
10 nishi 768
	add_data(&buffer, nav);
1 nishi 769
	add_data(&buffer, "				</ul>\n");
770
	add_data(&buffer, "			</div>\n");
771
	add_data(&buffer, "			<div id=\"pagecontent\">\n");
772
	add_data(&buffer, page);
773
	add_data(&buffer, "			</div>\n");
11 nishi 774
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
1 nishi 775
	add_data(&buffer, "		</div>\n");
776
	add_data(&buffer, "		<div id=\"footer\">\n");
777
	add_data(&buffer, "			<div id=\"gotop\">\n");
778
	add_data(&buffer, "				<a href=\"#top\">Top</a>\n");
779
	add_data(&buffer, "			</div>\n");
780
	add_data(&buffer, "			<div id=\"copyright\">\n");
781
	add_data(&buffer, "				");
782
	escaped = escape(INSTANCE_ADMIN);
783
	add_data(&buffer, escaped);
784
	free(escaped);
785
	add_data(&buffer, "\n");
786
	add_data(&buffer, "			</div>\n");
787
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
788
	add_data(&buffer, "		</div>\n");
789
	add_data(&buffer, "	</body>\n");
790
	add_data(&buffer, "</html>\n");
5 nishi 791
	if(user != NULL) free(user);
1 nishi 792
}