Subversion Repositories RepoView

Rev

Rev 14 | Rev 16 | 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 15 2024-08-21 15:36:37Z 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=");
15 nishi 132
			esc = url_escape(rv_get_query("username"));
12 nishi 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=");
15 nishi 183
	esc = url_escape(rv_get_query("username"));
11 nishi 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("");
15 nishi 468
		rv_load_query('Q');
11 nishi 469
		if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
470
			add_data(&page, "Required parameters not set.");
471
		} else {
15 nishi 472
			char* ruser = rv_get_query("username");
11 nishi 473
			char* repo = rv_get_query("reponame");
15 nishi 474
			char* repouser = rv_construct_repouser(repo, ruser);
11 nishi 475
			grepouser = repouser;
476
			if(rv_repo_exists(repouser)) {
15 nishi 477
				char* showuser = html_escape(ruser);
11 nishi 478
				char* showrepo = html_escape(repo);
479
				char* showreadme = rv_get_readme(repouser);
480
				desc = html_escape_nl_to_br(showreadme);
481
				add_data(&title, " - ");
482
				add_data(&title, showrepo);
483
				add_data(&title, "/");
484
				add_data(&title, showuser);
485
				free(showuser);
486
				free(showrepo);
487
				free(showreadme);
15 nishi 488
#ifdef WWW_SVN_ROOT
489
				add_data(&page, "<h2 id=\"repoinfo\">Info</h2>\n");
490
				add_data(&page, "<a href=\"");
491
				add_data(&page, WWW_SVN_ROOT);
492
				add_data(&page, "/");
493
				char* escru = url_escape(repouser);
494
				add_data(&page, escru);
495
				free(escru);
496
				add_data(&page, "\">Raw repository</a>");
497
#endif
11 nishi 498
 
499
				int isdir;
500
				char* path = rv_get_query("path");
501
				if(path == NULL) path = "/";
502
				fcounter = 0;
503
				add_data(&page, "<table border=\"0\" style=\"width: 100%;\">");
15 nishi 504
				bool rej = false;
11 nishi 505
				if(!rv_get_list(repouser, path, list_files, &isdir)) {
506
					add_data(&page, "<tr><td>Path not found.</td></tr>\n");
15 nishi 507
					rej = true;
11 nishi 508
				}
509
				add_data(&page, "</table>");
15 nishi 510
				if(isdir == 0 && !rej) {
11 nishi 511
					add_data(&nav, "<li><a href=\"#filecontent\">Content</a></li>");
512
					add_data(&page, "<h2 id=\"filecontent\">Content</h2>\n");
513
					add_data(&page, "<pre class=\"codeblock\"><code>");
13 nishi 514
#ifdef USE_ENSCRIPT
515
					int i;
516
					char* ext = NULL;
517
					for(i = strlen(path) - 1; i >= 0; i--) {
518
						if(path[i] == '.') {
519
							ext = path + i + 1;
520
							break;
521
						}
522
					}
523
					char* data = rv_enscript(repouser, path, ext);
524
					if(data != NULL) {
525
						add_data(&page, data);
526
						free(data);
527
					} else {
528
						data = rv_read_file(repouser, path);
529
						if(data != NULL) {
530
							char* esc = html_escape_nl_to_br(data);
531
							add_data(&page, esc);
532
							free(esc);
533
							free(data);
534
						} else {
535
							add_data(&page, "Cannot open the file.\n");
536
						}
537
					}
538
#else
11 nishi 539
					char* data = rv_read_file(repouser, path);
12 nishi 540
					if(data != NULL) {
541
						char* esc = html_escape_nl_to_br(data);
542
						add_data(&page, esc);
543
						free(esc);
544
						free(data);
545
					} else {
546
						add_data(&page, "Cannot open the file.\n");
547
					}
13 nishi 548
#endif
11 nishi 549
					add_data(&page, "</code></pre>");
550
				}
15 nishi 551
				if(user != NULL && strcmp(user, ruser) == 0) {
552
					char* esc;
553
					add_data(&nav, "<li><a href=\"#managerepo\">Manage The Repository</a></li>\n");
554
					add_data(&page, "<h2 id=\"managerepo\">Manage The Repository</h2>\n");
555
					add_data(&page, "<form action=\"");
556
					add_data(&page, INSTANCE_ROOT);
557
					add_data(&page, "/?page=sendmanrepo&username=");
558
					esc = url_escape(ruser);
559
					add_data(&page, esc);
560
					free(esc);
561
					add_data(&page, "&reponame=");
562
					esc = url_escape(ruser);
563
					add_data(&page, esc);
564
					free(esc);
565
					add_data(&page, "\" method=\"POST\">\n");
566
					add_data(&page, "<table border=\"0\" style=\"width: 100%;\">\n");
567
					add_data(&page, "	<tr>\n");
568
					add_data(&page, "		<th>README</th>\n");
569
					add_data(&page, "		<td>\n");
570
					add_data(&page, "			<textarea name=\"readme\" style=\"width: 100%;resize: none;height: 128px;\">\n");
571
					char* readme = rv_get_readme(repouser);
572
					esc = html_escape(readme);
573
					add_data(&page, esc);
574
					free(esc);
575
					free(readme);
576
					add_data(&page, "			</textarea>\n");
577
					add_data(&page, "		</td>\n");
578
					add_data(&page, "	</tr>\n");
579
					add_data(&page, "</table>\n");
580
					add_data(&page, "<input type=\"submit\" value=\"Send\">\n");
581
					add_data(&page, "</form>\n");
582
					add_data(&page, "<a href=\"");
583
					add_data(&page, INSTANCE_ROOT);
584
					add_data(&page, "/?page=deleterepo&username=");
585
					esc = url_escape(ruser);
586
					add_data(&page, esc);
587
					free(esc);
588
					add_data(&page, "&reponame=");
589
					esc = url_escape(ruser);
590
					add_data(&page, esc);
591
					free(esc);
592
					add_data(&page, "\">\n");
593
					add_data(&page, "Delete repository\n");
594
					add_data(&page, "</a>\n");
595
				}
11 nishi 596
			} else {
597
				add_data(&page, "Repository does not exist.\n");
598
			}
599
			free(repouser);
600
		}
15 nishi 601
	} else if(strcmp(query, "deleterepo") == 0) {
602
		title = rv_strdup("Delete The Repository");
603
		page = rv_strdup("");
604
 
605
		rv_load_query('Q');
606
		if(user == NULL) {
607
			add_data(&page, "It looks like you are not logged in.<br>Want to <a href=\"");
608
			add_data(&page, INSTANCE_ROOT);
609
			add_data(&page, "/?page=login\">log in</a>?\n");
610
		} else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
611
			add_data(&page, "Invalid Form.\n");
612
		} else {
613
			char* esc;
614
			add_data(&page, "Are you sure you want to delete the repository?\n");
615
			add_data(&page, "<form method=\"POST\" action=\"");
616
			add_data(&page, INSTANCE_ROOT);
617
			add_data(&page, "/?page=senddeleterepo&username=");
618
			esc = url_escape(rv_get_query("username"));
619
			add_data(&page, esc);
620
			free(esc);
621
			add_data(&page, "&reponame=");
622
			esc = url_escape(rv_get_query("reponame"));
623
			add_data(&page, esc);
624
			free(esc);
625
			add_data(&page, "\">");
626
			add_data(&page, "	<input type=\"submit\" value=\"Yes\">\n");
627
			add_data(&page, "</form>\n");
628
		}
629
	} else if(strcmp(query, "senddeleterepo") == 0) {
630
		title = rv_strdup("Deleting Repository Result");
631
		page = rv_strdup("");
632
 
633
		rv_load_query('Q');
634
		if(user == NULL) {
635
			add_data(&page, "It looks like you are not logged in.<br>Want to <a href=\"");
636
			add_data(&page, INSTANCE_ROOT);
637
			add_data(&page, "/?page=login\">log in</a>?\n");
638
		} else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
639
			add_data(&page, "Invalid Form.\n");
640
		} else if(strcmp(rv_get_query("username"), user) != 0) {
641
			add_data(&page, "You are not the owner of the repository.\n");
642
		} else {
643
			char* repouser = rv_construct_repouser(rv_get_query("reponame"), rv_get_query("username"));
644
			if(rv_repo_exists(repouser)) {
645
				rv_remove_repo(repouser);
646
				add_data(&page, "Deleted the repository successfully.<br>\n");
647
			} else {
648
				add_data(&page, "Repository does not exist.<br>\n");
649
			}
650
		}
651
	} else if(strcmp(query, "sendmanrepo") == 0) {
652
		title = rv_strdup("Modifying Repository Result");
653
		page = rv_strdup("");
654
 
655
		rv_load_query('Q');
656
		if(user == NULL) {
657
			add_data(&page, "It looks like you are not logged in.<br>Want to <a href=\"");
658
			add_data(&page, INSTANCE_ROOT);
659
			add_data(&page, "/?page=login\">log in</a>?\n");
660
		} else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
661
			add_data(&page, "Invalid Form.\n");
662
		} else if(strcmp(rv_get_query("username"), user) != 0) {
663
			add_data(&page, "You are not the owner of the repository.\n");
664
		} else {
665
			char* esc;
666
			rv_load_query('P');
667
			char* readme = rv_get_query("readme");
668
			if(readme != NULL) {
669
				rv_load_query('Q');
670
				char* name = rv_construct_repouser(rv_get_query("reponame"), rv_get_query("username"));
671
				rv_set_readme(name, readme);
672
				free(name);
673
			}
674
			rv_load_query('Q');
675
			add_data(&page, "Modified the repository successfully.<br>\n");
676
			add_data(&page, "<a href=\"");
677
			add_data(&page, INSTANCE_ROOT);
678
			add_data(&page, "?page=repo&username=");
679
			esc = url_escape(rv_get_query("username"));
680
			add_data(&page, esc);
681
			free(esc);
682
			add_data(&page, "&reponame=");
683
			esc = url_escape(rv_get_query("reponame"));
684
			add_data(&page, esc);
685
			free(esc);
686
			add_data(&page, "\">Go back to the repository</a>.\n");
687
		}
1 nishi 688
	}
689
 
690
	if(title == NULL) title = rv_strdup("");
691
	if(desc == NULL) desc = rv_strdup("");
692
	if(page == NULL) page = rv_strdup("");
10 nishi 693
	if(nav == NULL) nav = rv_strdup("");
1 nishi 694
	render_stuff();
15 nishi 695
freeall:
1 nishi 696
	free(page);
697
	free(desc);
698
	free(title);
10 nishi 699
	free(nav);
1 nishi 700
}
701
 
3 nishi 702
char* escape(const char* str) {
1 nishi 703
	char* r = malloc(1);
704
	r[0] = 0;
705
	char cbuf[2];
706
	cbuf[1] = 0;
707
	int i;
3 nishi 708
	for(i = 0; str[i] != 0; i++) {
709
		if(str[i] == '<') {
1 nishi 710
			char* tmp = r;
711
			r = rv_strcat(tmp, "&lt;");
712
			free(tmp);
3 nishi 713
		} else if(str[i] == '>') {
1 nishi 714
			char* tmp = r;
715
			r = rv_strcat(tmp, "&gt;");
716
			free(tmp);
3 nishi 717
		} else {
1 nishi 718
			cbuf[0] = str[i];
719
			char* tmp = r;
720
			r = rv_strcat(tmp, cbuf);
721
			free(tmp);
722
		}
723
	}
724
	return r;
725
}
726
 
3 nishi 727
void render_stuff(void) {
1 nishi 728
	char* escaped;
729
	add_data(&buffer, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
730
	add_data(&buffer, "<html>\n");
731
	add_data(&buffer, "	<head>\n");
732
	add_data(&buffer, "		<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n");
733
	add_data(&buffer, "		<title>");
734
	add_data(&buffer, INSTANCE_NAME);
735
	add_data(&buffer, " - ");
736
	add_data(&buffer, title);
737
	add_data(&buffer, "</title>\n");
738
	add_data(&buffer, "		<style type=\"text/css\">\n");
739
	add_data(&buffer, "* {\n");
740
	add_data(&buffer, "	padding: 0;\n");
741
	add_data(&buffer, "	margin: 0;\n");
742
	add_data(&buffer, "}\n");
743
	add_data(&buffer, "li {\n");
744
	add_data(&buffer, "	list-style: outside;\n");
745
	add_data(&buffer, "	margin-left: 1.25em;\n");
746
	add_data(&buffer, "}\n");
747
	add_data(&buffer, "a {\n");
748
	add_data(&buffer, "	text-decoration: none;\n");
749
	add_data(&buffer, "}\n");
750
	add_data(&buffer, "#nav div {\n");
751
	add_data(&buffer, "	float: left;\n");
752
	add_data(&buffer, "	margin: 0 0;\n");
753
	add_data(&buffer, "	padding-left: 0;\n");
9 nishi 754
	add_data(&buffer, "	padding-right: 25px;\n");
1 nishi 755
	add_data(&buffer, "	padding-top: 7px;\n");
756
	add_data(&buffer, "}\n");
11 nishi 757
	add_data(&buffer, "th,td {\n");
758
	add_data(&buffer, "	padding: 2px;\n");
759
	add_data(&buffer, "}\n");
1 nishi 760
	add_data(&buffer, "body {\n");
761
	add_data(&buffer, "	background-color: #1F4677;\n");
762
	add_data(&buffer, "	width: 940px;\n");
763
	add_data(&buffer, "	margin: 5px auto;\n");
764
	add_data(&buffer, "	font-family: sans-serif;\n");
765
	add_data(&buffer, "}\n");
766
	add_data(&buffer, "#nav {\n");
767
	add_data(&buffer, "	background-color: white;\n");
6 nishi 768
	add_data(&buffer, "	background-image: url('");
769
	add_data(&buffer, INSTANCE_NAVBAR);
770
	add_data(&buffer, "');\n");
1 nishi 771
	add_data(&buffer, "	height: 44px;\n");
772
	add_data(&buffer, "	padding: 8px;\n");
773
	add_data(&buffer, "	padding-left: 32px;\n");
774
	add_data(&buffer, "	font-size: 22px;\n");
775
	add_data(&buffer, "	font-weight: bold;\n");
776
	add_data(&buffer, "}\n");
11 nishi 777
	add_data(&buffer, "pre {\n");
778
	add_data(&buffer, "	background-color: #dddddd;\n");
779
	add_data(&buffer, "	border: solid 2px #bbbbbb;\n");
12 nishi 780
	add_data(&buffer, "	padding: 8px;\n");
781
	add_data(&buffer, "	overflow: scroll;\n");
11 nishi 782
	add_data(&buffer, "}\n");
1 nishi 783
	add_data(&buffer, "#index {\n");
784
	add_data(&buffer, "	list-style: none;\n");
785
	add_data(&buffer, "	line-height: normal;\n");
786
	add_data(&buffer, "	margin: auto 0;\n");
787
	add_data(&buffer, "	padding-left: 0;\n");
788
	add_data(&buffer, "}\n");
789
	add_data(&buffer, "#desc {\n");
790
	add_data(&buffer, "	background-color: #D2E1F6;\n");
791
	add_data(&buffer, "	margin: 9px auto;\n");
792
	add_data(&buffer, "	height: 128px;\n");
793
	add_data(&buffer, "	padding: 24px;\n");
794
	add_data(&buffer, "}\n");
795
	add_data(&buffer, "#descinside {\n");
796
	add_data(&buffer, "	float: left;\n");
11 nishi 797
	add_data(&buffer, "	width: 700px;\n");
798
	add_data(&buffer, "	overflow-y: scroll;\n");
799
	add_data(&buffer, "	max-height: 128px;\n");
1 nishi 800
	add_data(&buffer, "}\n");
801
	add_data(&buffer, "#logo {\n");
802
	add_data(&buffer, "	float: right;\n");
803
	add_data(&buffer, "}\n");
804
	add_data(&buffer, "#content {\n");
805
	add_data(&buffer, "	background-color: #FFFFFF;\n");
806
	add_data(&buffer, "	margin: -10px auto;\n");
807
	add_data(&buffer, "	padding: 8px 24px 24px;\n");
808
	add_data(&buffer, "}\n");
809
	add_data(&buffer, "#pageindex {\n");
810
	add_data(&buffer, "	background-color: #FFFFFF;\n");
811
	add_data(&buffer, "	padding-right: 24px;\n");
812
	add_data(&buffer, "	padding-bottom: 24px;\n");
813
	add_data(&buffer, "	float: left;\n");
814
	add_data(&buffer, "	border-right: 4px #1F4677 solid;\n");
815
	add_data(&buffer, "	width: 150px;\n");
816
	add_data(&buffer, "}\n");
817
	add_data(&buffer, "#pagecontent {\n");
818
	add_data(&buffer, "	background-color: #FFFFFF;\n");
819
	add_data(&buffer, "	width: 670px;\n");
820
	add_data(&buffer, "	float: right;\n");
821
	add_data(&buffer, "	padding-left: 24px;\n");
822
	add_data(&buffer, "}\n");
823
	add_data(&buffer, "#footer {\n");
824
	add_data(&buffer, "	background-color: #D2E1F6;\n");
825
	add_data(&buffer, "	padding: 8px 8px 48px;\n");
826
	add_data(&buffer, "	margin: 8px auto;\n");
827
	add_data(&buffer, "	font-size: 15px;\n");
828
	add_data(&buffer, "	height: 32px;\n");
829
	add_data(&buffer, "}\n");
830
	add_data(&buffer, ".fixfloat {\n");
831
	add_data(&buffer, "	clear: both;\n");
832
	add_data(&buffer, "}\n");
833
	add_data(&buffer, "#copyright {\n");
834
	add_data(&buffer, "	float: right;\n");
835
	add_data(&buffer, "	font-size: 10px;\n");
836
	add_data(&buffer, "	margin-top: 16px;\n");
837
	add_data(&buffer, "}\n");
838
	add_data(&buffer, "#gotop {\n");
839
	add_data(&buffer, "	position: absolute;\n");
840
	add_data(&buffer, "}\n");
841
	add_data(&buffer, "h2, h3 {\n");
842
	add_data(&buffer, "	padding-top: 8px;\n");
843
	add_data(&buffer, "	padding-bottom: 8px;\n");
844
	add_data(&buffer, "}\n");
845
	add_data(&buffer, "img {\n");
846
	add_data(&buffer, "	border: none;\n");
847
	add_data(&buffer, "}\n");
848
	add_data(&buffer, "		</style>\n");
849
	add_data(&buffer, "	</head>\n");
850
	add_data(&buffer, "	<body>\n");
851
	add_data(&buffer, "		<div id=\"nav\">\n");
852
	add_data(&buffer, "			<div>\n");
853
	add_data(&buffer, "				<a href=\"");
854
	add_data(&buffer, INSTANCE_ROOT);
855
	add_data(&buffer, "/\">Home</a>\n");
856
	add_data(&buffer, "			</div>\n");
5 nishi 857
	if(user == NULL) {
858
		add_data(&buffer, "			<div>\n");
859
		add_data(&buffer, "				<a href=\"");
860
		add_data(&buffer, INSTANCE_ROOT);
861
		add_data(&buffer, "/?page=login\">Login</a>\n");
862
		add_data(&buffer, "			</div>\n");
13 nishi 863
#ifdef ALLOW_SIGNUP
864
		add_data(&buffer, "			<div>\n");
865
		add_data(&buffer, "				<a href=\"");
866
		add_data(&buffer, INSTANCE_ROOT);
867
		add_data(&buffer, "/?page=signup\">Signup</a>\n");
868
		add_data(&buffer, "			</div>\n");
869
#endif
7 nishi 870
	} else {
871
		add_data(&buffer, "			<div>\n");
872
		add_data(&buffer, "				<a href=\"");
873
		add_data(&buffer, INSTANCE_ROOT);
9 nishi 874
		add_data(&buffer, "/?page=mypage\">My Page</a>\n");
875
		add_data(&buffer, "			</div>\n");
876
 
877
		add_data(&buffer, "			<div>\n");
878
		add_data(&buffer, "				<a href=\"");
879
		add_data(&buffer, INSTANCE_ROOT);
880
		add_data(&buffer, "/?page=myrepo\">My Repositories</a>\n");
881
		add_data(&buffer, "			</div>\n");
882
 
883
		add_data(&buffer, "			<div>\n");
884
		add_data(&buffer, "				<a href=\"");
885
		add_data(&buffer, INSTANCE_ROOT);
7 nishi 886
		add_data(&buffer, "/?page=logout\">Logout</a>\n");
887
		add_data(&buffer, "			</div>\n");
5 nishi 888
	}
6 nishi 889
	if(user != NULL) {
890
		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=\"");
891
		add_data(&buffer, INSTANCE_ROOT);
892
		add_data(&buffer, "/?page=mypage\">");
893
		add_data(&buffer, user);
894
		add_data(&buffer, "</a></div>");
895
	}
1 nishi 896
	add_data(&buffer, "		</div>\n");
897
	add_data(&buffer, "		<div id=\"desc\">\n");
898
	add_data(&buffer, "			<div id=\"descinside\">\n");
899
	add_data(&buffer, "				<h1>");
900
	add_data(&buffer, title);
901
	add_data(&buffer, "</h1>\n");
902
	add_data(&buffer, "				<p>\n");
903
	add_data(&buffer, desc);
904
	add_data(&buffer, "				</p>\n");
905
	add_data(&buffer, "			</div>\n");
906
	add_data(&buffer, "			<img id=\"logo\" src=\"");
907
	add_data(&buffer, INSTANCE_LOGO);
908
	add_data(&buffer, "\" height=\"128px\" alt=\"logo\">\n");
909
	add_data(&buffer, "		</div>\n");
910
	add_data(&buffer, "		<div id=\"content\">\n");
911
	add_data(&buffer, "			<div id=\"pageindex\">\n");
912
	add_data(&buffer, "				<h3>Page Menu</h3>\n");
913
	add_data(&buffer, "				<ul>\n");
10 nishi 914
	add_data(&buffer, nav);
1 nishi 915
	add_data(&buffer, "				</ul>\n");
916
	add_data(&buffer, "			</div>\n");
917
	add_data(&buffer, "			<div id=\"pagecontent\">\n");
918
	add_data(&buffer, page);
919
	add_data(&buffer, "			</div>\n");
11 nishi 920
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
1 nishi 921
	add_data(&buffer, "		</div>\n");
922
	add_data(&buffer, "		<div id=\"footer\">\n");
923
	add_data(&buffer, "			<div id=\"gotop\">\n");
924
	add_data(&buffer, "				<a href=\"#top\">Top</a>\n");
925
	add_data(&buffer, "			</div>\n");
926
	add_data(&buffer, "			<div id=\"copyright\">\n");
927
	add_data(&buffer, "				");
928
	escaped = escape(INSTANCE_ADMIN);
929
	add_data(&buffer, escaped);
930
	free(escaped);
931
	add_data(&buffer, "\n");
932
	add_data(&buffer, "			</div>\n");
933
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
15 nishi 934
#ifdef INSTANCE_BANNERS
935
	add_data(&buffer, "			<div id=\"banners\" style=\"clear: both;\">\n");
936
	add_data(&buffer, INSTANCE_BANNERS);
937
	add_data(&buffer, "			</div>\n");
938
#else
939
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
940
#endif
1 nishi 941
	add_data(&buffer, "		</div>\n");
942
	add_data(&buffer, "	</body>\n");
943
	add_data(&buffer, "</html>\n");
5 nishi 944
	if(user != NULL) free(user);
1 nishi 945
}