Subversion Repositories RepoView

Rev

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