Subversion Repositories RepoView

Rev

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