Subversion Repositories RepoView

Rev

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