Subversion Repositories RepoView

Rev

Rev 32 | Rev 42 | 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 39 2024-08-22 03:38:21Z 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
 
39 nishi 17
#ifdef USE_AVATAR
18
#include "rv_avatar.h"
19
#endif
20
 
7 nishi 21
#include <stdio.h>
1 nishi 22
#include <stdlib.h>
23
#include <string.h>
39 nishi 24
#include <unistd.h>
1 nishi 25
 
26
extern char* buffer;
27
void add_data(char** data, const char* txt);
28
void render_stuff();
29
 
30
char* title = NULL;
31
char* desc = NULL;
32
char* page = NULL;
10 nishi 33
char* nav = NULL;
11 nishi 34
char* grepouser;
6 nishi 35
extern char* user;
1 nishi 36
 
11 nishi 37
char* url_escape(const char* input) {
38
	const char hex[] = "0123456789ABCDEF";
39
	char* r = malloc(1);
40
	r[0] = 0;
41
	char cbuf[2];
42
	cbuf[1] = 0;
43
	int i;
44
	for(i = 0; input[i] != 0; i++) {
45
		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) {
46
			add_data(&r, "%");
47
			cbuf[0] = hex[(input[i] >> 4) & 0xf];
48
			add_data(&r, cbuf);
49
			cbuf[0] = hex[input[i] & 0xf];
50
			add_data(&r, cbuf);
51
		} else {
52
			cbuf[0] = input[i];
53
			add_data(&r, cbuf);
54
		}
55
	}
56
	return r;
57
}
58
 
59
char* html_escape(const char* input) {
60
	char* r = malloc(1);
61
	r[0] = 0;
62
	char cbuf[2];
63
	cbuf[1] = 0;
64
	int i;
65
	for(i = 0; input[i] != 0; i++) {
66
		if(input[i] == '<') {
67
			add_data(&r, "&lt;");
68
		} else if(input[i] == '>') {
69
			add_data(&r, "&gt;");
70
		} else {
71
			cbuf[0] = input[i];
72
			add_data(&r, cbuf);
73
		}
74
	}
75
	return r;
76
}
77
 
78
char* html_escape_nl_to_br(const char* input) {
79
	char* r = malloc(1);
80
	r[0] = 0;
81
	char cbuf[2];
82
	cbuf[1] = 0;
83
	int i;
84
	for(i = 0; input[i] != 0; i++) {
85
		if(input[i] == '<') {
86
			add_data(&r, "&lt;");
87
		} else if(input[i] == '>') {
88
			add_data(&r, "&gt;");
89
		} else if(input[i] == '\n') {
90
			add_data(&r, "<br>");
91
		} else {
92
			cbuf[0] = input[i];
93
			add_data(&r, cbuf);
94
		}
95
	}
96
	return r;
97
}
98
 
99
void list_repo(const char* name, const char* rev) {
100
	char* showname = html_escape(name);
101
	char* urluser = url_escape(user);
102
	char* urlrepo = url_escape(name);
103
	add_data(&page, "<tr>");
104
	add_data(&page, "<td><a href=\"");
105
	add_data(&page, INSTANCE_ROOT);
106
	add_data(&page, "/?page=repo&reponame=");
107
	add_data(&page, urlrepo);
108
	add_data(&page, "&username=");
109
	add_data(&page, urluser);
110
	add_data(&page, "\">");
111
	add_data(&page, showname);
112
	add_data(&page, "</a></td>");
113
	add_data(&page, "<td>");
114
	add_data(&page, rev);
115
	add_data(&page, "</td>");
116
	add_data(&page, "</tr>");
117
	free(showname);
118
	free(urluser);
119
	free(urlrepo);
120
}
121
 
122
int fcounter = 0;
123
void list_files(const char* pathname) {
124
	if(fcounter == 0) {
125
		add_data(&nav, "<li><a href=\"#filelist\">File List</a></li>\n");
126
		add_data(&page, "<h2 id=\"filelist\">File List</h2>\n");
127
		add_data(&page, "<tr style=\"background-color: #D2E1F6;\"><th>Name</th><th>Size</th></tr>\n");
12 nishi 128
		char* path = rv_get_query("path");
129
		if(path == NULL) path = "/";
130
		if(strcmp(path, "/") != 0) {
131
			char* query = rv_strdup("?page=repo&reponame=");
132
			char* esc;
133
			esc = url_escape(rv_get_query("reponame"));
134
			add_data(&query, esc);
135
			free(esc);
136
			add_data(&query, "&username=");
15 nishi 137
			esc = url_escape(rv_get_query("username"));
12 nishi 138
			add_data(&query, esc);
139
			free(esc);
140
			add_data(&query, "&path=");
141
 
142
			char* urlpath = rv_strdup(path);
143
			int i;
144
			int counter = 0;
145
			int rep = urlpath[strlen(urlpath) - 1] == '/' ? 2 : 1;
146
			for(i = strlen(urlpath) - 1; i >= 0; i--) {
147
				char oldc = urlpath[i];
148
				urlpath[i] = 0;
149
				if(oldc == '/') {
150
					counter++;
151
					if(counter == 2) {
152
						break;
153
					}
154
				}
155
			}
156
 
157
			if(strlen(urlpath) == 0) {
158
				free(urlpath);
159
				urlpath = rv_strdup("/");
160
			}
161
 
162
			esc = url_escape(urlpath);
163
			add_data(&query, esc);
164
			free(esc);
165
 
166
			add_data(&page, "<tr><td><a href=\"");
167
			add_data(&page, query);
168
			add_data(&page, "\">../</a></td><td>&lt;DIR&gt;</td></tr>\n");
169
			fcounter++;
170
			free(query);
171
		}
11 nishi 172
	}
173
	fcounter++;
174
	add_data(&page, "<tr style=\"background-color: #");
175
	if((fcounter % 2) == 0) {
176
		add_data(&page, "D2E1C0");
177
	} else {
178
		add_data(&page, "FFFFFF");
179
	}
180
	char* path = rv_get_query("path");
181
	if(path == NULL) path = "/";
182
	char* query = rv_strdup("?page=repo&reponame=");
183
	char* esc;
184
	esc = url_escape(rv_get_query("reponame"));
185
	add_data(&query, esc);
186
	free(esc);
187
	add_data(&query, "&username=");
15 nishi 188
	esc = url_escape(rv_get_query("username"));
11 nishi 189
	add_data(&query, esc);
190
	free(esc);
191
	add_data(&query, "&path=");
13 nishi 192
	char* urlpath = rv_strcat3(path, "/", pathname);
11 nishi 193
	esc = url_escape(urlpath);
194
	add_data(&query, esc);
195
	free(esc);
196
	char* sz = malloc(128);
197
	sprintf(sz, "%lld", rv_get_filesize(grepouser, urlpath));
198
	add_data(&page, "\"><td><a href=\"");
199
	add_data(&page, query);
200
	add_data(&page, "\">");
201
	add_data(&page, pathname);
202
	add_data(&page, "</a></td>\n");
203
	add_data(&page, "<td>\n");
204
	if(strcmp(sz, "-1") != 0) {
205
		add_data(&page, sz);
206
	} else {
207
		add_data(&page, "&lt;DIR&gt;");
208
	}
209
	add_data(&page, "</td>\n");
210
	free(sz);
211
	add_data(&page, "</tr>\n");
212
	free(query);
213
	free(urlpath);
214
}
215
 
39 nishi 216
void generate_avatar(void) {
217
	if(user != NULL) {
218
		char* tmp = rv_strcat3(AVATAR_ROOT, "/", user);
219
		char* path = rv_strcat(tmp, ".png");
220
		free(tmp);
221
		if(access(path, F_OK) != 0) {
222
			rv_avatar_generate(path, user);
223
		}
224
		free(path);
225
	}
226
}
227
 
3 nishi 228
void render_page(void) {
1 nishi 229
	rv_load_query('Q');
230
	char* query = rv_get_query("page");
231
	if(query == NULL) query = "welcome";
232
 
39 nishi 233
#ifdef USE_AVATAR
234
	generate_avatar();
235
#endif
236
 
3 nishi 237
	if(strcmp(query, "welcome") == 0) {
1 nishi 238
		title = rv_strdup("Welcome");
239
		desc = rv_strdup("Welcome to " INSTANCE_NAME ".");
240
		page = rv_strcat3("Welcome to " INSTANCE_NAME ".<br>This instance is running RepoView version ", rv_get_version(), ".");
13 nishi 241
#ifdef ALLOW_SIGNUP
242
	} else if(strcmp(query, "signup") == 0) {
243
		title = rv_strdup("Signup");
244
		desc = rv_strdup("You can create your account here.");
245
		page = rv_strdup("");
246
 
247
		add_data(&page, "<form action=\"");
248
		add_data(&page, INSTANCE_ROOT);
249
		add_data(&page, "/?page=sendsignup\" method=\"POST\">\n");
250
		add_data(&page, "	<table border=\"0\">\n");
251
		add_data(&page, "		<tr>\n");
252
		add_data(&page, "			<th>Username</th>\n");
253
		add_data(&page, "			<td>\n");
254
		add_data(&page, "				<input name=\"username\">\n");
255
		add_data(&page, "			</td>\n");
256
		add_data(&page, "		</tr>\n");
257
		add_data(&page, "		<tr>\n");
258
		add_data(&page, "			<th>Password</th>\n");
259
		add_data(&page, "			<td>\n");
260
		add_data(&page, "				<input name=\"password\" type=\"password\">\n");
261
		add_data(&page, "			</td>\n");
262
		add_data(&page, "		</tr>\n");
263
		add_data(&page, "	</table>\n");
264
		char cbuf[2];
265
		cbuf[0] = REPO_USER_DELIM;
266
		cbuf[1] = 0;
267
		add_data(&page, "Username cannot contain '<code>");
268
		add_data(&page, cbuf);
22 nishi 269
		add_data(&page, "</code>', '<code>#</code>', '<code>\\</code>', and '<code>/</code>'.<br>");
13 nishi 270
		add_data(&page, "	<input type=\"submit\" value=\"Signup\">\n");
271
		add_data(&page, "</form>\n");
272
	} else if(strcmp(query, "sendsignup") == 0) {
273
		title = rv_strdup("Signup Result");
274
		page = rv_strdup("");
275
 
276
		rv_load_query('P');
277
		if(user != NULL) {
278
			page = rv_strdup("It looks like you are already logged in.<br>Want to <a href=\"");
279
			add_data(&page, INSTANCE_ROOT);
280
			add_data(&page, "/?page=logout\">log out</a>?\n");
281
		} else if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) {
282
			add_data(&page, "Invalid form.\n");
283
		} else {
284
			if(rv_has_user(rv_get_query("username"))) {
285
				add_data(&page, "User already exists.");
286
			} else {
287
				if(user != NULL) free(user);
288
				int i;
289
				bool reject = false;
290
				char* name = rv_get_query("username");
291
				for(i = 0; name[i] != 0; i++) {
22 nishi 292
					if(name[i] == REPO_USER_DELIM || name[i] == '#' || name[i] == '\\' || name[i] == '/') {
13 nishi 293
						char cbuf[2];
294
						cbuf[0] = REPO_USER_DELIM;
295
						cbuf[1] = 0;
296
						add_data(&page, "Username cannot contain '<code>");
297
						add_data(&page, cbuf);
298
						add_data(&page, "</code>'.");
299
						reject = true;
300
						break;
301
					}
302
				}
303
				if(!reject) {
304
					rv_create_user(rv_get_query("username"), rv_get_query("password"));
305
					user = rv_strdup(rv_get_query("username"));
306
					add_data(&page, "Welcome.\n");
307
					rv_save_login(rv_get_query("username"));
308
				}
309
			}
310
		}
311
#endif
3 nishi 312
	} else if(strcmp(query, "login") == 0) {
1 nishi 313
		title = rv_strdup("Login");
314
		desc = rv_strdup("You can log in to your account here.");
315
		page = rv_strdup("");
316
 
317
		add_data(&page, "<form action=\"");
318
		add_data(&page, INSTANCE_ROOT);
319
		add_data(&page, "/?page=sendlogin\" method=\"POST\">\n");
320
		add_data(&page, "	<table border=\"0\">\n");
321
		add_data(&page, "		<tr>\n");
322
		add_data(&page, "			<th>Username</th>\n");
323
		add_data(&page, "			<td>\n");
324
		add_data(&page, "				<input name=\"username\">\n");
325
		add_data(&page, "			</td>\n");
326
		add_data(&page, "		</tr>\n");
327
		add_data(&page, "		<tr>\n");
328
		add_data(&page, "			<th>Password</th>\n");
329
		add_data(&page, "			<td>\n");
330
		add_data(&page, "				<input name=\"password\" type=\"password\">\n");
331
		add_data(&page, "			</td>\n");
332
		add_data(&page, "		</tr>\n");
333
		add_data(&page, "	</table>\n");
334
		add_data(&page, "	<input type=\"submit\" value=\"Login\">\n");
335
		add_data(&page, "</form>\n");
3 nishi 336
	} else if(strcmp(query, "sendlogin") == 0) {
1 nishi 337
		title = rv_strdup("Login Result");
338
		page = rv_strdup("");
339
 
340
		rv_load_query('P');
11 nishi 341
		if(user != NULL) {
342
			page = rv_strdup("It looks like you are already logged in.<br>Want to <a href=\"");
343
			add_data(&page, INSTANCE_ROOT);
13 nishi 344
			add_data(&page, "/?page=logout\">log out</a>?\n");
11 nishi 345
		} else if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) {
5 nishi 346
			add_data(&page, "Invalid form.\n");
3 nishi 347
		} else {
348
			if(rv_has_user(rv_get_query("username"))) {
5 nishi 349
				if(rv_check_password(rv_get_query("username"), rv_get_query("password"))) {
6 nishi 350
					if(user != NULL) free(user);
351
					user = rv_strdup(rv_get_query("username"));
5 nishi 352
					add_data(&page, "Welcome back.\n");
353
					rv_save_login(rv_get_query("username"));
354
				} else {
355
					add_data(&page, "Invalid password.");
356
				}
3 nishi 357
			} else {
5 nishi 358
				add_data(&page, "User does not exist.");
1 nishi 359
			}
360
		}
7 nishi 361
	} else if(strcmp(query, "sendlogout") == 0) {
362
		title = rv_strdup("Logout Result");
363
		page = rv_strdup("");
364
		if(user == NULL) {
365
			add_data(&page, "You were not logged in.\n");
366
		} else {
367
			rv_logout();
368
			add_data(&page, "Goodbye.\n");
369
			free(user);
370
			user = NULL;
371
		}
27 nishi 372
#ifdef USE_MYPAGE
6 nishi 373
	} else if(strcmp(query, "mypage") == 0) {
374
		title = rv_strdup("My Page");
375
		desc = rv_strdup("You manage your information here.");
376
		if(user == NULL) {
377
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
378
			add_data(&page, INSTANCE_ROOT);
379
			add_data(&page, "/?page=login\">log in</a>?\n");
39 nishi 380
		} else {
381
			page = rv_strdup("");
382
			add_data(&page, "<h2 id=\"youricon\">Your Icon</h2>\n");
383
			add_data(&page, "<a href=\"");
384
			add_data(&page, WWW_AVATAR_ROOT);
385
			add_data(&page, "/");
386
			add_data(&page, user);
387
			add_data(&page, ".png\"><img src=\"");
388
			add_data(&page, WWW_AVATAR_ROOT);
389
			add_data(&page, "/");
390
			add_data(&page, user);
391
			add_data(&page, ".png\" alt=\"Your Icon\"></a>");
392
			add_data(&page, "<form action=\"");
393
			add_data(&page, INSTANCE_ROOT);
394
			add_data(&page, "/?page=uploadpfp\" method=\"POST\" enctype=\"multipart/form-data\">\n");
395
			add_data(&page, "	<input type=\"file\" name=\"pfp\">\n");
396
			add_data(&page, "	<input type=\"submit\" value=\"Upload\">\n");
397
			add_data(&page, "</form>\n");
6 nishi 398
		}
27 nishi 399
#endif
9 nishi 400
	} else if(strcmp(query, "myrepo") == 0) {
401
		title = rv_strdup("My Repositories");
402
		desc = rv_strdup("You manage your repositories here.");
403
		if(user == NULL) {
404
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
405
			add_data(&page, INSTANCE_ROOT);
406
			add_data(&page, "/?page=login\">log in</a>?\n");
10 nishi 407
		} else {
11 nishi 408
			char cbuf[2];
409
			cbuf[0] = REPO_USER_DELIM;
410
			cbuf[1] = 0;
10 nishi 411
			nav = rv_strdup("");
412
			add_data(&nav, "<li><a href=\"#createrepo\">Create a repository</a></li>\n");
413
			add_data(&nav, "<li><a href=\"#repolist\">Repository List</a></li>\n");
414
			page = rv_strdup("");
415
			add_data(&page, "<h2 id=\"createrepo\">Create a repository</h2>\n");
416
			add_data(&page, "<form action=\"");
417
			add_data(&page, INSTANCE_ROOT);
418
			add_data(&page, "/?page=createrepo\" method=\"POST\">\n");
419
			add_data(&page, "	<table border=\"0\">\n");
420
			add_data(&page, "		<tr>\n");
421
			add_data(&page, "			<th>Repository name</th>\n");
422
			add_data(&page, "			<td>\n");
423
			add_data(&page, "				<input name=\"name\">\n");
424
			add_data(&page, "			</td>\n");
425
			add_data(&page, "			<td><input type=\"submit\" value=\"Create\"></td>\n");
426
			add_data(&page, "		</tr>\n");
427
			add_data(&page, "	</table>\n");
11 nishi 428
			add_data(&page, "Repository name cannot contain '<code>");
429
			add_data(&page, cbuf);
22 nishi 430
			add_data(&page, "</code>', '<code>#</code>', '<code>\\</code>', and '<code>/</code>'.");
10 nishi 431
			add_data(&page, "</form>\n");
432
			add_data(&page, "<h2 id=\"repolist\">Repository List</h2>\n");
11 nishi 433
			add_data(&page, "<table border=\"0\">\n");
434
			add_data(&page, "<tr><th>Repository name</th><th>Revision</th></tr>\n");
435
			rv_repo_list(user, list_repo);
436
			add_data(&page, "</table>\n");
9 nishi 437
		}
11 nishi 438
	} else if(strcmp(query, "createrepo") == 0) {
439
		title = rv_strdup("Creating Repository Result");
440
		page = rv_strdup("");
441
 
442
		rv_load_query('P');
443
		if(user == NULL) {
444
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
445
			add_data(&page, INSTANCE_ROOT);
446
			add_data(&page, "/?page=login\">log in</a>?\n");
447
		} else if(rv_get_query("name") == NULL) {
448
			add_data(&page, "Invalid form.\n");
449
		} else {
450
			int i;
451
			bool reject = false;
452
			char* name = rv_get_query("name");
453
			for(i = 0; name[i] != 0; i++) {
22 nishi 454
				if(name[i] == REPO_USER_DELIM || name[i] == '#' || name[i] == '\\' || name[i] == '/') {
11 nishi 455
					char cbuf[2];
456
					cbuf[0] = REPO_USER_DELIM;
457
					cbuf[1] = 0;
458
					add_data(&page, "Repository name cannot contain '<code>");
459
					add_data(&page, cbuf);
460
					add_data(&page, "</code>'.");
461
					reject = true;
462
					break;
463
				}
464
			}
465
			if(!reject) {
466
				char* ru = rv_construct_repouser(name, user);
467
				if(rv_repo_exists(ru)) {
468
					add_data(&page, "Repository already exists.");
469
				} else {
470
					char* esc;
471
					rv_create_repo(ru);
472
					add_data(&page, "Repository has been created.<br>\n");
473
					add_data(&page, "<a href=\"");
474
					add_data(&page, INSTANCE_ROOT);
475
					esc = url_escape(name);
476
					add_data(&page, "/?page=repo&reponame=");
477
					add_data(&page, esc);
478
					free(esc);
479
					esc = url_escape(user);
480
					add_data(&page, "&username=");
481
					add_data(&page, esc);
482
					free(esc);
483
					add_data(&page, "\">Go to the repository</a>.\n");
484
				}
485
				free(ru);
486
			}
487
		}
7 nishi 488
	} else if(strcmp(query, "logout") == 0) {
489
		title = rv_strdup("Logout");
490
		desc = rv_strdup("You can log out from your account here.");
491
		if(user == NULL) {
492
			page = rv_strdup("It looks like you are not logged in.<br>Want to <a href=\"");
493
			add_data(&page, INSTANCE_ROOT);
494
			add_data(&page, "/?page=login\">log in</a>?\n");
495
		} else {
496
			page = rv_strdup("");
497
			add_data(&page, "Are you sure you want to log out?\n");
498
			add_data(&page, "<form method=\"POST\" action=\"");
499
			add_data(&page, INSTANCE_ROOT);
500
			add_data(&page, "/?page=sendlogout\">\n");
501
			add_data(&page, "	<input type=\"submit\" value=\"Yes\">\n");
502
			add_data(&page, "</form>\n");
503
		}
11 nishi 504
	} else if(strcmp(query, "repo") == 0) {
505
		title = rv_strdup("Repository");
506
		desc = rv_strdup("");
507
		page = rv_strdup("");
508
		nav = rv_strdup("");
15 nishi 509
		rv_load_query('Q');
11 nishi 510
		if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
511
			add_data(&page, "Required parameters not set.");
512
		} else {
15 nishi 513
			char* ruser = rv_get_query("username");
11 nishi 514
			char* repo = rv_get_query("reponame");
15 nishi 515
			char* repouser = rv_construct_repouser(repo, ruser);
11 nishi 516
			grepouser = repouser;
517
			if(rv_repo_exists(repouser)) {
15 nishi 518
				char* showuser = html_escape(ruser);
11 nishi 519
				char* showrepo = html_escape(repo);
520
				char* showreadme = rv_get_readme(repouser);
521
				desc = html_escape_nl_to_br(showreadme);
522
				add_data(&title, " - ");
32 nishi 523
				add_data(&title, showuser);
524
				add_data(&title, "/");
11 nishi 525
				add_data(&title, showrepo);
526
				free(showuser);
527
				free(showrepo);
528
				free(showreadme);
15 nishi 529
#ifdef WWW_SVN_ROOT
16 nishi 530
				add_data(&nav, "<li><a href=\"#repoinfo\">Info</a></li>\n");
15 nishi 531
				add_data(&page, "<h2 id=\"repoinfo\">Info</h2>\n");
532
				add_data(&page, "<a href=\"");
533
				add_data(&page, WWW_SVN_ROOT);
534
				add_data(&page, "/");
535
				char* escru = url_escape(repouser);
536
				add_data(&page, escru);
537
				free(escru);
538
				add_data(&page, "\">Raw repository</a>");
539
#endif
11 nishi 540
 
541
				int isdir;
542
				char* path = rv_get_query("path");
543
				if(path == NULL) path = "/";
544
				fcounter = 0;
545
				add_data(&page, "<table border=\"0\" style=\"width: 100%;\">");
15 nishi 546
				bool rej = false;
11 nishi 547
				if(!rv_get_list(repouser, path, list_files, &isdir)) {
548
					add_data(&page, "<tr><td>Path not found.</td></tr>\n");
15 nishi 549
					rej = true;
11 nishi 550
				}
551
				add_data(&page, "</table>");
15 nishi 552
				if(isdir == 0 && !rej) {
11 nishi 553
					add_data(&nav, "<li><a href=\"#filecontent\">Content</a></li>");
554
					add_data(&page, "<h2 id=\"filecontent\">Content</h2>\n");
555
					add_data(&page, "<pre class=\"codeblock\"><code>");
13 nishi 556
#ifdef USE_ENSCRIPT
557
					int i;
558
					char* ext = NULL;
559
					for(i = strlen(path) - 1; i >= 0; i--) {
560
						if(path[i] == '.') {
561
							ext = path + i + 1;
562
							break;
563
						}
564
					}
565
					char* data = rv_enscript(repouser, path, ext);
566
					if(data != NULL) {
567
						add_data(&page, data);
568
						free(data);
569
					} else {
570
						data = rv_read_file(repouser, path);
571
						if(data != NULL) {
572
							char* esc = html_escape_nl_to_br(data);
573
							add_data(&page, esc);
574
							free(esc);
575
							free(data);
576
						} else {
577
							add_data(&page, "Cannot open the file.\n");
578
						}
579
					}
580
#else
11 nishi 581
					char* data = rv_read_file(repouser, path);
12 nishi 582
					if(data != NULL) {
583
						char* esc = html_escape_nl_to_br(data);
584
						add_data(&page, esc);
585
						free(esc);
586
						free(data);
587
					} else {
588
						add_data(&page, "Cannot open the file.\n");
589
					}
13 nishi 590
#endif
11 nishi 591
					add_data(&page, "</code></pre>");
592
				}
15 nishi 593
				if(user != NULL && strcmp(user, ruser) == 0) {
594
					char* esc;
595
					add_data(&nav, "<li><a href=\"#managerepo\">Manage The Repository</a></li>\n");
596
					add_data(&page, "<h2 id=\"managerepo\">Manage The Repository</h2>\n");
597
					add_data(&page, "<form action=\"");
598
					add_data(&page, INSTANCE_ROOT);
599
					add_data(&page, "/?page=sendmanrepo&username=");
600
					esc = url_escape(ruser);
601
					add_data(&page, esc);
602
					free(esc);
603
					add_data(&page, "&reponame=");
21 nishi 604
					esc = url_escape(repo);
15 nishi 605
					add_data(&page, esc);
606
					free(esc);
607
					add_data(&page, "\" method=\"POST\">\n");
608
					add_data(&page, "<table border=\"0\" style=\"width: 100%;\">\n");
609
					add_data(&page, "	<tr>\n");
610
					add_data(&page, "		<th>README</th>\n");
611
					add_data(&page, "		<td>\n");
612
					add_data(&page, "			<textarea name=\"readme\" style=\"width: 100%;resize: none;height: 128px;\">\n");
613
					char* readme = rv_get_readme(repouser);
614
					esc = html_escape(readme);
615
					add_data(&page, esc);
616
					free(esc);
617
					free(readme);
618
					add_data(&page, "			</textarea>\n");
619
					add_data(&page, "		</td>\n");
620
					add_data(&page, "	</tr>\n");
621
					add_data(&page, "</table>\n");
622
					add_data(&page, "<input type=\"submit\" value=\"Send\">\n");
623
					add_data(&page, "</form>\n");
624
					add_data(&page, "<a href=\"");
625
					add_data(&page, INSTANCE_ROOT);
626
					add_data(&page, "/?page=deleterepo&username=");
627
					esc = url_escape(ruser);
628
					add_data(&page, esc);
629
					free(esc);
630
					add_data(&page, "&reponame=");
631
					esc = url_escape(ruser);
632
					add_data(&page, esc);
633
					free(esc);
634
					add_data(&page, "\">\n");
635
					add_data(&page, "Delete repository\n");
636
					add_data(&page, "</a>\n");
637
				}
11 nishi 638
			} else {
639
				add_data(&page, "Repository does not exist.\n");
640
			}
641
			free(repouser);
642
		}
15 nishi 643
	} else if(strcmp(query, "deleterepo") == 0) {
644
		title = rv_strdup("Delete The Repository");
645
		page = rv_strdup("");
646
 
647
		rv_load_query('Q');
648
		if(user == NULL) {
649
			add_data(&page, "It looks like you are not logged in.<br>Want to <a href=\"");
650
			add_data(&page, INSTANCE_ROOT);
651
			add_data(&page, "/?page=login\">log in</a>?\n");
652
		} else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
653
			add_data(&page, "Invalid Form.\n");
654
		} else {
655
			char* esc;
656
			add_data(&page, "Are you sure you want to delete the repository?\n");
657
			add_data(&page, "<form method=\"POST\" action=\"");
658
			add_data(&page, INSTANCE_ROOT);
659
			add_data(&page, "/?page=senddeleterepo&username=");
660
			esc = url_escape(rv_get_query("username"));
661
			add_data(&page, esc);
662
			free(esc);
663
			add_data(&page, "&reponame=");
664
			esc = url_escape(rv_get_query("reponame"));
665
			add_data(&page, esc);
666
			free(esc);
667
			add_data(&page, "\">");
668
			add_data(&page, "	<input type=\"submit\" value=\"Yes\">\n");
669
			add_data(&page, "</form>\n");
670
		}
671
	} else if(strcmp(query, "senddeleterepo") == 0) {
672
		title = rv_strdup("Deleting Repository Result");
673
		page = rv_strdup("");
674
 
675
		rv_load_query('Q');
676
		if(user == NULL) {
677
			add_data(&page, "It looks like you are not logged in.<br>Want to <a href=\"");
678
			add_data(&page, INSTANCE_ROOT);
679
			add_data(&page, "/?page=login\">log in</a>?\n");
680
		} else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
681
			add_data(&page, "Invalid Form.\n");
682
		} else if(strcmp(rv_get_query("username"), user) != 0) {
683
			add_data(&page, "You are not the owner of the repository.\n");
684
		} else {
685
			char* repouser = rv_construct_repouser(rv_get_query("reponame"), rv_get_query("username"));
686
			if(rv_repo_exists(repouser)) {
687
				rv_remove_repo(repouser);
688
				add_data(&page, "Deleted the repository successfully.<br>\n");
689
			} else {
690
				add_data(&page, "Repository does not exist.<br>\n");
691
			}
692
		}
693
	} else if(strcmp(query, "sendmanrepo") == 0) {
694
		title = rv_strdup("Modifying Repository Result");
695
		page = rv_strdup("");
696
 
697
		rv_load_query('Q');
698
		if(user == NULL) {
699
			add_data(&page, "It looks like you are not logged in.<br>Want to <a href=\"");
700
			add_data(&page, INSTANCE_ROOT);
701
			add_data(&page, "/?page=login\">log in</a>?\n");
702
		} else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
703
			add_data(&page, "Invalid Form.\n");
704
		} else if(strcmp(rv_get_query("username"), user) != 0) {
705
			add_data(&page, "You are not the owner of the repository.\n");
706
		} else {
707
			char* esc;
708
			rv_load_query('P');
709
			char* readme = rv_get_query("readme");
710
			if(readme != NULL) {
711
				rv_load_query('Q');
712
				char* name = rv_construct_repouser(rv_get_query("reponame"), rv_get_query("username"));
713
				rv_set_readme(name, readme);
714
				free(name);
715
			}
716
			rv_load_query('Q');
717
			add_data(&page, "Modified the repository successfully.<br>\n");
718
			add_data(&page, "<a href=\"");
719
			add_data(&page, INSTANCE_ROOT);
720
			add_data(&page, "?page=repo&username=");
721
			esc = url_escape(rv_get_query("username"));
722
			add_data(&page, esc);
723
			free(esc);
724
			add_data(&page, "&reponame=");
725
			esc = url_escape(rv_get_query("reponame"));
726
			add_data(&page, esc);
727
			free(esc);
728
			add_data(&page, "\">Go back to the repository</a>.\n");
729
		}
1 nishi 730
	}
731
 
732
	if(title == NULL) title = rv_strdup("");
733
	if(desc == NULL) desc = rv_strdup("");
734
	if(page == NULL) page = rv_strdup("");
10 nishi 735
	if(nav == NULL) nav = rv_strdup("");
39 nishi 736
 
737
#ifdef USE_AVATAR
738
	generate_avatar();
739
#endif
740
 
1 nishi 741
	render_stuff();
15 nishi 742
freeall:
1 nishi 743
	free(page);
744
	free(desc);
745
	free(title);
10 nishi 746
	free(nav);
1 nishi 747
}
748
 
3 nishi 749
char* escape(const char* str) {
1 nishi 750
	char* r = malloc(1);
751
	r[0] = 0;
752
	char cbuf[2];
753
	cbuf[1] = 0;
754
	int i;
3 nishi 755
	for(i = 0; str[i] != 0; i++) {
756
		if(str[i] == '<') {
1 nishi 757
			char* tmp = r;
758
			r = rv_strcat(tmp, "&lt;");
759
			free(tmp);
3 nishi 760
		} else if(str[i] == '>') {
1 nishi 761
			char* tmp = r;
762
			r = rv_strcat(tmp, "&gt;");
763
			free(tmp);
3 nishi 764
		} else {
1 nishi 765
			cbuf[0] = str[i];
766
			char* tmp = r;
767
			r = rv_strcat(tmp, cbuf);
768
			free(tmp);
769
		}
770
	}
771
	return r;
772
}
773
 
3 nishi 774
void render_stuff(void) {
1 nishi 775
	char* escaped;
776
	add_data(&buffer, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
777
	add_data(&buffer, "<html>\n");
778
	add_data(&buffer, "	<head>\n");
779
	add_data(&buffer, "		<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n");
780
	add_data(&buffer, "		<title>");
781
	add_data(&buffer, INSTANCE_NAME);
782
	add_data(&buffer, " - ");
783
	add_data(&buffer, title);
784
	add_data(&buffer, "</title>\n");
785
	add_data(&buffer, "		<style type=\"text/css\">\n");
786
	add_data(&buffer, "* {\n");
787
	add_data(&buffer, "	padding: 0;\n");
788
	add_data(&buffer, "	margin: 0;\n");
789
	add_data(&buffer, "}\n");
790
	add_data(&buffer, "li {\n");
791
	add_data(&buffer, "	list-style: outside;\n");
792
	add_data(&buffer, "	margin-left: 1.25em;\n");
793
	add_data(&buffer, "}\n");
794
	add_data(&buffer, "a {\n");
795
	add_data(&buffer, "	text-decoration: none;\n");
796
	add_data(&buffer, "}\n");
797
	add_data(&buffer, "#nav div {\n");
798
	add_data(&buffer, "	float: left;\n");
799
	add_data(&buffer, "	margin: 0 0;\n");
800
	add_data(&buffer, "	padding-left: 0;\n");
9 nishi 801
	add_data(&buffer, "	padding-right: 25px;\n");
1 nishi 802
	add_data(&buffer, "	padding-top: 7px;\n");
803
	add_data(&buffer, "}\n");
11 nishi 804
	add_data(&buffer, "th,td {\n");
805
	add_data(&buffer, "	padding: 2px;\n");
806
	add_data(&buffer, "}\n");
1 nishi 807
	add_data(&buffer, "body {\n");
808
	add_data(&buffer, "	background-color: #1F4677;\n");
809
	add_data(&buffer, "	width: 940px;\n");
810
	add_data(&buffer, "	margin: 5px auto;\n");
811
	add_data(&buffer, "	font-family: sans-serif;\n");
812
	add_data(&buffer, "}\n");
813
	add_data(&buffer, "#nav {\n");
814
	add_data(&buffer, "	background-color: white;\n");
6 nishi 815
	add_data(&buffer, "	background-image: url('");
816
	add_data(&buffer, INSTANCE_NAVBAR);
817
	add_data(&buffer, "');\n");
1 nishi 818
	add_data(&buffer, "	height: 44px;\n");
819
	add_data(&buffer, "	padding: 8px;\n");
820
	add_data(&buffer, "	padding-left: 32px;\n");
821
	add_data(&buffer, "	font-size: 22px;\n");
822
	add_data(&buffer, "	font-weight: bold;\n");
823
	add_data(&buffer, "}\n");
11 nishi 824
	add_data(&buffer, "pre {\n");
825
	add_data(&buffer, "	background-color: #dddddd;\n");
826
	add_data(&buffer, "	border: solid 2px #bbbbbb;\n");
12 nishi 827
	add_data(&buffer, "	padding: 8px;\n");
828
	add_data(&buffer, "	overflow: scroll;\n");
11 nishi 829
	add_data(&buffer, "}\n");
1 nishi 830
	add_data(&buffer, "#index {\n");
831
	add_data(&buffer, "	list-style: none;\n");
832
	add_data(&buffer, "	line-height: normal;\n");
833
	add_data(&buffer, "	margin: auto 0;\n");
834
	add_data(&buffer, "	padding-left: 0;\n");
835
	add_data(&buffer, "}\n");
836
	add_data(&buffer, "#desc {\n");
837
	add_data(&buffer, "	background-color: #D2E1F6;\n");
838
	add_data(&buffer, "	margin: 9px auto;\n");
839
	add_data(&buffer, "	height: 128px;\n");
840
	add_data(&buffer, "	padding: 24px;\n");
841
	add_data(&buffer, "}\n");
842
	add_data(&buffer, "#descinside {\n");
843
	add_data(&buffer, "	float: left;\n");
11 nishi 844
	add_data(&buffer, "	width: 700px;\n");
845
	add_data(&buffer, "	overflow-y: scroll;\n");
846
	add_data(&buffer, "	max-height: 128px;\n");
1 nishi 847
	add_data(&buffer, "}\n");
848
	add_data(&buffer, "#logo {\n");
849
	add_data(&buffer, "	float: right;\n");
850
	add_data(&buffer, "}\n");
851
	add_data(&buffer, "#content {\n");
852
	add_data(&buffer, "	background-color: #FFFFFF;\n");
853
	add_data(&buffer, "	margin: -10px auto;\n");
854
	add_data(&buffer, "	padding: 8px 24px 24px;\n");
855
	add_data(&buffer, "}\n");
856
	add_data(&buffer, "#pageindex {\n");
857
	add_data(&buffer, "	background-color: #FFFFFF;\n");
858
	add_data(&buffer, "	padding-right: 24px;\n");
859
	add_data(&buffer, "	padding-bottom: 24px;\n");
860
	add_data(&buffer, "	float: left;\n");
861
	add_data(&buffer, "	border-right: 4px #1F4677 solid;\n");
862
	add_data(&buffer, "	width: 150px;\n");
863
	add_data(&buffer, "}\n");
864
	add_data(&buffer, "#pagecontent {\n");
865
	add_data(&buffer, "	background-color: #FFFFFF;\n");
866
	add_data(&buffer, "	width: 670px;\n");
867
	add_data(&buffer, "	float: right;\n");
868
	add_data(&buffer, "	padding-left: 24px;\n");
869
	add_data(&buffer, "}\n");
870
	add_data(&buffer, "#footer {\n");
871
	add_data(&buffer, "	background-color: #D2E1F6;\n");
872
	add_data(&buffer, "	padding: 8px 8px 48px;\n");
873
	add_data(&buffer, "	margin: 8px auto;\n");
874
	add_data(&buffer, "	font-size: 15px;\n");
875
	add_data(&buffer, "	height: 32px;\n");
876
	add_data(&buffer, "}\n");
877
	add_data(&buffer, ".fixfloat {\n");
878
	add_data(&buffer, "	clear: both;\n");
879
	add_data(&buffer, "}\n");
880
	add_data(&buffer, "#copyright {\n");
881
	add_data(&buffer, "	float: right;\n");
882
	add_data(&buffer, "	font-size: 10px;\n");
883
	add_data(&buffer, "	margin-top: 16px;\n");
884
	add_data(&buffer, "}\n");
885
	add_data(&buffer, "#gotop {\n");
886
	add_data(&buffer, "	position: absolute;\n");
887
	add_data(&buffer, "}\n");
888
	add_data(&buffer, "h2, h3 {\n");
889
	add_data(&buffer, "	padding-top: 8px;\n");
890
	add_data(&buffer, "	padding-bottom: 8px;\n");
891
	add_data(&buffer, "}\n");
892
	add_data(&buffer, "img {\n");
893
	add_data(&buffer, "	border: none;\n");
894
	add_data(&buffer, "}\n");
895
	add_data(&buffer, "		</style>\n");
896
	add_data(&buffer, "	</head>\n");
897
	add_data(&buffer, "	<body>\n");
898
	add_data(&buffer, "		<div id=\"nav\">\n");
899
	add_data(&buffer, "			<div>\n");
900
	add_data(&buffer, "				<a href=\"");
901
	add_data(&buffer, INSTANCE_ROOT);
902
	add_data(&buffer, "/\">Home</a>\n");
903
	add_data(&buffer, "			</div>\n");
5 nishi 904
	if(user == NULL) {
905
		add_data(&buffer, "			<div>\n");
906
		add_data(&buffer, "				<a href=\"");
907
		add_data(&buffer, INSTANCE_ROOT);
908
		add_data(&buffer, "/?page=login\">Login</a>\n");
909
		add_data(&buffer, "			</div>\n");
13 nishi 910
#ifdef ALLOW_SIGNUP
911
		add_data(&buffer, "			<div>\n");
912
		add_data(&buffer, "				<a href=\"");
913
		add_data(&buffer, INSTANCE_ROOT);
914
		add_data(&buffer, "/?page=signup\">Signup</a>\n");
915
		add_data(&buffer, "			</div>\n");
916
#endif
7 nishi 917
	} else {
27 nishi 918
#ifdef USE_MYPAGE
7 nishi 919
		add_data(&buffer, "			<div>\n");
920
		add_data(&buffer, "				<a href=\"");
921
		add_data(&buffer, INSTANCE_ROOT);
9 nishi 922
		add_data(&buffer, "/?page=mypage\">My Page</a>\n");
923
		add_data(&buffer, "			</div>\n");
27 nishi 924
#endif
9 nishi 925
 
926
		add_data(&buffer, "			<div>\n");
927
		add_data(&buffer, "				<a href=\"");
928
		add_data(&buffer, INSTANCE_ROOT);
929
		add_data(&buffer, "/?page=myrepo\">My Repositories</a>\n");
930
		add_data(&buffer, "			</div>\n");
931
 
932
		add_data(&buffer, "			<div>\n");
933
		add_data(&buffer, "				<a href=\"");
934
		add_data(&buffer, INSTANCE_ROOT);
7 nishi 935
		add_data(&buffer, "/?page=logout\">Logout</a>\n");
936
		add_data(&buffer, "			</div>\n");
5 nishi 937
	}
6 nishi 938
	if(user != NULL) {
939
		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=\"");
940
		add_data(&buffer, INSTANCE_ROOT);
941
		add_data(&buffer, "/?page=mypage\">");
942
		add_data(&buffer, user);
943
		add_data(&buffer, "</a></div>");
944
	}
1 nishi 945
	add_data(&buffer, "		</div>\n");
946
	add_data(&buffer, "		<div id=\"desc\">\n");
947
	add_data(&buffer, "			<div id=\"descinside\">\n");
948
	add_data(&buffer, "				<h1>");
949
	add_data(&buffer, title);
950
	add_data(&buffer, "</h1>\n");
951
	add_data(&buffer, "				<p>\n");
952
	add_data(&buffer, desc);
953
	add_data(&buffer, "				</p>\n");
954
	add_data(&buffer, "			</div>\n");
955
	add_data(&buffer, "			<img id=\"logo\" src=\"");
956
	add_data(&buffer, INSTANCE_LOGO);
957
	add_data(&buffer, "\" height=\"128px\" alt=\"logo\">\n");
958
	add_data(&buffer, "		</div>\n");
959
	add_data(&buffer, "		<div id=\"content\">\n");
960
	add_data(&buffer, "			<div id=\"pageindex\">\n");
961
	add_data(&buffer, "				<h3>Page Menu</h3>\n");
962
	add_data(&buffer, "				<ul>\n");
10 nishi 963
	add_data(&buffer, nav);
1 nishi 964
	add_data(&buffer, "				</ul>\n");
965
	add_data(&buffer, "			</div>\n");
966
	add_data(&buffer, "			<div id=\"pagecontent\">\n");
967
	add_data(&buffer, page);
968
	add_data(&buffer, "			</div>\n");
11 nishi 969
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
1 nishi 970
	add_data(&buffer, "		</div>\n");
971
	add_data(&buffer, "		<div id=\"footer\">\n");
972
	add_data(&buffer, "			<div id=\"gotop\">\n");
973
	add_data(&buffer, "				<a href=\"#top\">Top</a>\n");
974
	add_data(&buffer, "			</div>\n");
975
	add_data(&buffer, "			<div id=\"copyright\">\n");
976
	add_data(&buffer, "				");
977
	escaped = escape(INSTANCE_ADMIN);
978
	add_data(&buffer, escaped);
979
	free(escaped);
980
	add_data(&buffer, "\n");
981
	add_data(&buffer, "			</div>\n");
982
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
15 nishi 983
#ifdef INSTANCE_BANNERS
984
	add_data(&buffer, "			<div id=\"banners\" style=\"clear: both;\">\n");
985
	add_data(&buffer, INSTANCE_BANNERS);
986
	add_data(&buffer, "			</div>\n");
987
#else
988
	add_data(&buffer, "			<div class=\"fixfloat\"></div>\n");
989
#endif
1 nishi 990
	add_data(&buffer, "		</div>\n");
991
	add_data(&buffer, "	</body>\n");
992
	add_data(&buffer, "</html>\n");
5 nishi 993
	if(user != NULL) free(user);
1 nishi 994
}