/* $Id: modern.c 59 2024-08-22 06:08:54Z nishi $ */ #include "rv_query.h" #include "rv_util.h" #include "rv_version.h" #include "rv_auth.h" #include "rv_db.h" #include "rv_repo.h" #include "rv_multipart.h" #include "../../config.h" #ifdef USE_ENSCRIPT #include "rv_enscript.h" #endif #ifdef USE_AVATAR #include "rv_avatar.h" #endif #ifdef USE_GRAPHICSMAGICK #include "rv_magick.h" #endif #include #include #include #include #include extern char* nocache; extern char* buffer; void add_data(char** data, const char* txt); void render_stuff(); char* title = NULL; char* desc = NULL; char* page = NULL; char* nav = NULL; char* logopath = NULL; char* grepouser; extern char* user; bool invalid_char(char c) { if(c >= '0' && c <= '9') return false; if(c >= 'a' && c <= 'z') return false; if(c >= 'A' && c <= 'Z') return false; if(c == '_' && c == '-' && c == '.') return false; return true; } char* url_escape(const char* input) { const char hex[] = "0123456789ABCDEF"; char* r = malloc(1); r[0] = 0; char cbuf[2]; cbuf[1] = 0; int i; for(i = 0; input[i] != 0; i++) { 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) { add_data(&r, "%"); cbuf[0] = hex[(input[i] >> 4) & 0xf]; add_data(&r, cbuf); cbuf[0] = hex[input[i] & 0xf]; add_data(&r, cbuf); } else { cbuf[0] = input[i]; add_data(&r, cbuf); } } return r; } char* html_escape(const char* input) { char* r = malloc(1); r[0] = 0; char cbuf[2]; cbuf[1] = 0; int i; for(i = 0; input[i] != 0; i++) { if(input[i] == '<') { add_data(&r, "<"); } else if(input[i] == '>') { add_data(&r, ">"); } else { cbuf[0] = input[i]; add_data(&r, cbuf); } } return r; } char* html_escape_nl_to_br(const char* input) { char* r = malloc(1); r[0] = 0; char cbuf[2]; cbuf[1] = 0; int i; for(i = 0; input[i] != 0; i++) { if(input[i] == '<') { add_data(&r, "<"); } else if(input[i] == '>') { add_data(&r, ">"); } else if(input[i] == '\n') { add_data(&r, "
"); } else { cbuf[0] = input[i]; add_data(&r, cbuf); } } return r; } int fcounter = 0; char* instead_username = NULL; void list_repo(const char* name, const char* rev) { char* showname = html_escape(name); char* urluser = url_escape(instead_username == NULL ? user : instead_username); char* urlrepo = url_escape(name); add_data(&page, ""); add_data(&page, showname); add_data(&page, ""); add_data(&page, ""); add_data(&page, rev); add_data(&page, ""); add_data(&page, ""); free(showname); free(urluser); free(urlrepo); } void list_files(const char* pathname) { if(fcounter == 0) { add_data(&nav, "
  • File List
  • \n"); add_data(&page, "

    File List

    \n"); add_data(&page, "NameSize\n"); char* path = rv_get_query("path"); if(path == NULL) path = "/"; if(strcmp(path, "/") != 0) { char* query = rv_strdup("?page=repo&reponame="); char* esc; esc = url_escape(rv_get_query("reponame")); add_data(&query, esc); free(esc); add_data(&query, "&username="); esc = url_escape(rv_get_query("username")); add_data(&query, esc); free(esc); add_data(&query, "&path="); char* urlpath = rv_strdup(path); int i; int counter = 0; int rep = urlpath[strlen(urlpath) - 1] == '/' ? 2 : 1; for(i = strlen(urlpath) - 1; i >= 0; i--) { char oldc = urlpath[i]; urlpath[i] = 0; if(oldc == '/') { counter++; if(counter == 2) { break; } } } if(strlen(urlpath) == 0) { free(urlpath); urlpath = rv_strdup("/"); } esc = url_escape(urlpath); add_data(&query, esc); free(esc); add_data(&page, "../<DIR>\n"); fcounter++; free(query); } } fcounter++; add_data(&page, ""); add_data(&page, pathname); add_data(&page, "\n"); add_data(&page, "\n"); if(strcmp(sz, "-1") != 0) { add_data(&page, sz); } else { add_data(&page, "<DIR>"); } add_data(&page, "\n"); free(sz); add_data(&page, "\n"); free(query); free(urlpath); } void generate_avatar(void) { if(user != NULL) { char* tmp = rv_strcat3(AVATAR_ROOT, "/", user); char* path = rv_strcat(tmp, ".png"); free(tmp); if(access(path, F_OK) != 0) { rv_avatar_generate(path, user); } free(path); } if(rv_get_query("username") != NULL) { char* un = rv_get_query("username"); char* tmp = rv_strcat3(AVATAR_ROOT, "/", un); char* path = rv_strcat(tmp, ".png"); free(tmp); if(access(path, F_OK) != 0) { rv_avatar_generate(path, un); } free(path); } } void render_page(void) { rv_load_query('Q'); char* query = rv_get_query("page"); if(query == NULL) query = "welcome"; #ifdef USE_AVATAR generate_avatar(); #endif if(strcmp(query, "welcome") == 0) { title = rv_strdup("Welcome"); desc = rv_strdup("Welcome to " INSTANCE_NAME "."); page = rv_strcat3("Welcome to " INSTANCE_NAME ".
    This instance is running RepoView version ", rv_get_version(), "."); #ifdef ALLOW_SIGNUP } else if(strcmp(query, "signup") == 0) { title = rv_strdup("Signup"); desc = rv_strdup("You can create your account here."); page = rv_strdup(""); add_data(&page, "
    \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, "
    Username\n"); add_data(&page, " \n"); add_data(&page, "
    Password\n"); add_data(&page, " \n"); add_data(&page, "
    \n"); char cbuf[2]; cbuf[0] = REPO_USER_DELIM; cbuf[1] = 0; add_data(&page, "Username cannot contain '"); add_data(&page, cbuf); add_data(&page, "'.
    "); add_data(&page, " \n"); add_data(&page, "
    \n"); } else if(strcmp(query, "sendsignup") == 0) { title = rv_strdup("Signup Result"); page = rv_strdup(""); rv_load_query('P'); if(user != NULL) { page = rv_strdup("It looks like you are already logged in.
    Want to log out?\n"); } else if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) { add_data(&page, "Invalid form.\n"); } else { if(rv_has_user(rv_get_query("username"))) { add_data(&page, "User already exists."); } else { if(user != NULL) free(user); int i; bool reject = false; char* name = rv_get_query("username"); for(i = 0; name[i] != 0; i++) { if(name[i] == REPO_USER_DELIM || invalid_char(name[i])) { char cbuf[2]; cbuf[0] = REPO_USER_DELIM; cbuf[1] = 0; add_data(&page, "Username cannot contain '"); add_data(&page, cbuf); add_data(&page, "'."); reject = true; break; } } if(!reject) { rv_create_user(rv_get_query("username"), rv_get_query("password")); user = rv_strdup(rv_get_query("username")); add_data(&page, "Welcome.\n"); rv_save_login(rv_get_query("username")); } } } #endif } else if(strcmp(query, "login") == 0) { title = rv_strdup("Login"); desc = rv_strdup("You can log in to your account here."); page = rv_strdup(""); add_data(&page, "
    \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, "
    Username\n"); add_data(&page, " \n"); add_data(&page, "
    Password\n"); add_data(&page, " \n"); add_data(&page, "
    \n"); add_data(&page, " \n"); add_data(&page, "
    \n"); } else if(strcmp(query, "sendlogin") == 0) { title = rv_strdup("Login Result"); page = rv_strdup(""); rv_load_query('P'); if(user != NULL) { page = rv_strdup("It looks like you are already logged in.
    Want to log out?\n"); } else if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) { add_data(&page, "Invalid form.\n"); } else { if(rv_has_user(rv_get_query("username"))) { if(rv_check_password(rv_get_query("username"), rv_get_query("password"))) { if(user != NULL) free(user); user = rv_strdup(rv_get_query("username")); add_data(&page, "Welcome back.\n"); rv_save_login(rv_get_query("username")); } else { add_data(&page, "Invalid password."); } } else { add_data(&page, "User does not exist."); } } } else if(strcmp(query, "sendlogout") == 0) { title = rv_strdup("Logout Result"); page = rv_strdup(""); if(user == NULL) { add_data(&page, "You were not logged in.\n"); } else { rv_logout(); add_data(&page, "Goodbye.\n"); free(user); user = NULL; } #ifdef USE_MYPAGE } else if(strcmp(query, "mypage") == 0) { title = rv_strdup("My Page"); desc = rv_strdup("You manage your information here."); if(user == NULL) { page = rv_strdup("It looks like you are not logged in.
    Want to log in?\n"); } else { page = rv_strdup(""); nav = rv_strdup(""); add_data(&nav, "
  • Your Icon
  • \n"); add_data(&nav, "
  • Bio
  • \n"); add_data(&page, "
    \n"); add_data(&page, "

    Your Icon

    \n"); add_data(&page, " \"Your
    "); add_data(&page, " \n"); add_data(&page, "

    Bio

    \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, "
    \n"); } #endif #ifdef USE_AVATAR } else if(strcmp(query, "upload") == 0) { title = rv_strdup("Uploading My Page Result"); page = rv_strdup(""); if(user == NULL) { add_data(&page, "It looks like you are not logged in.
    Want to log in?\n"); } else { struct multipart_entry* entry = rv_get_multipart("pfp"); if(entry != NULL && entry->length > 0) { char* tmp = rv_strcat3(AVATAR_ROOT, "/", user); char* path = rv_strcat(tmp, ".tmp"); char* outpath = rv_strcat(tmp, ".png"); free(tmp); FILE* f = fopen(path, "wb"); fwrite(entry->data, 1, entry->length, f); fclose(f); char* reason; if(rv_resize_picture(path, outpath, &reason)) { add_data(&page, "Uploaded the profile picture successfully.
    \n"); } else { add_data(&page, "Failed to upload the profile picture.
    \n"); char* esc = html_escape(reason); add_data(&page, esc); free(esc); add_data(&page, "\n"); free(reason); } free(path); free(outpath); } entry = rv_get_multipart("bio"); if(entry != NULL) { char* path = rv_strcat3(BIO_ROOT, "/", user); FILE* f = fopen(path, "w"); fwrite(entry->data, 1, entry->length, f); fclose(f); free(path); add_data(&page, "Uploaded the bio successfully.
    \n"); } } #endif } else if(strcmp(query, "myrepo") == 0) { title = rv_strdup("My Repositories"); desc = rv_strdup("You manage your repositories here."); if(user == NULL) { page = rv_strdup("It looks like you are not logged in.
    Want to log in?\n"); } else { char cbuf[2]; cbuf[0] = REPO_USER_DELIM; cbuf[1] = 0; nav = rv_strdup(""); add_data(&nav, "
  • Create a repository
  • \n"); add_data(&nav, "
  • Repository List
  • \n"); page = rv_strdup(""); add_data(&page, "

    Create a repository

    \n"); add_data(&page, "
    \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, "
    Repository name\n"); add_data(&page, " \n"); add_data(&page, "
    \n"); add_data(&page, "Repository name cannot contain '"); add_data(&page, cbuf); add_data(&page, "'."); add_data(&page, "
    \n"); add_data(&page, "

    Repository List

    \n"); add_data(&page, "\n"); add_data(&page, "\n"); fcounter = 0; rv_repo_list(user, list_repo); add_data(&page, "
    Repository nameRevision
    \n"); } } else if(strcmp(query, "createrepo") == 0) { title = rv_strdup("Creating Repository Result"); page = rv_strdup(""); rv_load_query('P'); if(user == NULL) { page = rv_strdup("It looks like you are not logged in.
    Want to log in?\n"); } else if(rv_get_query("name") == NULL) { add_data(&page, "Invalid form.\n"); } else { int i; bool reject = false; char* name = rv_get_query("name"); for(i = 0; name[i] != 0; i++) { if(name[i] == REPO_USER_DELIM || invalid_char(name[i])) { char cbuf[2]; cbuf[0] = REPO_USER_DELIM; cbuf[1] = 0; add_data(&page, "Repository name cannot contain '"); add_data(&page, cbuf); add_data(&page, "'."); reject = true; break; } } if(!reject) { char* ru = rv_construct_repouser(name, user); if(rv_repo_exists(ru)) { add_data(&page, "Repository already exists."); } else { char* esc; rv_create_repo(ru); add_data(&page, "Repository has been created.
    \n"); add_data(&page, "Go to the repository.\n"); } free(ru); } } } else if(strcmp(query, "logout") == 0) { title = rv_strdup("Logout"); desc = rv_strdup("You can log out from your account here."); if(user == NULL) { page = rv_strdup("It looks like you are not logged in.
    Want to log in?\n"); } else { page = rv_strdup(""); add_data(&page, "Are you sure you want to log out?\n"); add_data(&page, "
    \n"); add_data(&page, " \n"); add_data(&page, "
    \n"); } } else if(strcmp(query, "repo") == 0) { title = rv_strdup("Repository"); desc = rv_strdup(""); page = rv_strdup(""); nav = rv_strdup(""); rv_load_query('Q'); if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) { add_data(&page, "Required parameters not set."); } else { char* ruser = rv_get_query("username"); char* repo = rv_get_query("reponame"); char* repouser = rv_construct_repouser(repo, ruser); grepouser = repouser; if(rv_repo_exists(repouser)) { char* showuser = html_escape(ruser); char* showrepo = html_escape(repo); char* showreadme = rv_get_readme(repouser); desc = html_escape_nl_to_br(showreadme); add_data(&title, " - "); add_data(&title, showuser); add_data(&title, "/"); add_data(&title, showrepo); free(showuser); free(showrepo); free(showreadme); #ifdef WWW_SVN_ROOT add_data(&nav, "
  • Info
  • \n"); add_data(&page, "

    Info

    \n"); add_data(&page, "Raw repository"); #endif int isdir; char* path = rv_get_query("path"); if(path == NULL) path = "/"; fcounter = 0; add_data(&page, ""); bool rej = false; if(!rv_get_list(repouser, path, list_files, &isdir)) { add_data(&page, "\n"); rej = true; } add_data(&page, "
    Path not found.
    "); if(isdir == 0 && !rej) { add_data(&nav, "
  • Content
  • "); add_data(&page, "

    Content

    \n"); add_data(&page, "
    ");
    #ifdef USE_ENSCRIPT
    					int i;
    					char* ext = NULL;
    					for(i = strlen(path) - 1; i >= 0; i--) {
    						if(path[i] == '.') {
    							ext = path + i + 1;
    							break;
    						}
    					}
    					char* data = rv_enscript(repouser, path, ext);
    					if(data != NULL) {
    						add_data(&page, data);
    						free(data);
    					} else {
    						data = rv_read_file(repouser, path);
    						if(data != NULL) {
    							char* esc = html_escape_nl_to_br(data);
    							add_data(&page, esc);
    							free(esc);
    							free(data);
    						} else {
    							add_data(&page, "Cannot open the file.\n");
    						}
    					}
    #else
    					char* data = rv_read_file(repouser, path);
    					if(data != NULL) {
    						char* esc = html_escape_nl_to_br(data);
    						add_data(&page, esc);
    						free(esc);
    						free(data);
    					} else {
    						add_data(&page, "Cannot open the file.\n");
    					}
    #endif
    					add_data(&page, "
    "); } if(user != NULL && strcmp(user, ruser) == 0) { char* esc; add_data(&nav, "
  • Manage The Repository
  • \n"); add_data(&page, "

    Manage The Repository

    \n"); add_data(&page, "
    \n"); add_data(&page, "\n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, " \n"); add_data(&page, "
    README\n"); add_data(&page, " \n"); add_data(&page, "
    \n"); add_data(&page, "\n"); add_data(&page, "
    \n"); add_data(&page, "\n"); add_data(&page, "Delete repository\n"); add_data(&page, "\n"); } } else { add_data(&page, "Repository does not exist.\n"); } free(repouser); } } else if(strcmp(query, "deleterepo") == 0) { title = rv_strdup("Delete The Repository"); page = rv_strdup(""); rv_load_query('Q'); if(user == NULL) { add_data(&page, "It looks like you are not logged in.
    Want to log in?\n"); } else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) { add_data(&page, "Invalid Form.\n"); } else { char* esc; add_data(&page, "Are you sure you want to delete the repository?\n"); add_data(&page, "
    "); add_data(&page, " \n"); add_data(&page, "
    \n"); } } else if(strcmp(query, "senddeleterepo") == 0) { title = rv_strdup("Deleting Repository Result"); page = rv_strdup(""); rv_load_query('Q'); if(user == NULL) { add_data(&page, "It looks like you are not logged in.
    Want to log in?\n"); } else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) { add_data(&page, "Invalid Form.\n"); } else if(strcmp(rv_get_query("username"), user) != 0) { add_data(&page, "You are not the owner of the repository.\n"); } else { char* repouser = rv_construct_repouser(rv_get_query("reponame"), rv_get_query("username")); if(rv_repo_exists(repouser)) { rv_remove_repo(repouser); add_data(&page, "Deleted the repository successfully.
    \n"); } else { add_data(&page, "Repository does not exist.
    \n"); } } } else if(strcmp(query, "person") == 0) { title = rv_strdup("Person"); page = rv_strdup(""); nav = rv_strdup(""); rv_load_query('Q'); if(rv_get_query("username") == NULL) { add_data(&page, "Invalid Form.\n"); } else { if(rv_has_user(rv_get_query("username"))) { add_data(&nav, "
  • Repository List
  • "); add_data(&title, " - "); add_data(&title, rv_get_query("username")); char* path = rv_strcat3(BIO_ROOT, "/", rv_get_query("username")); FILE* f = fopen(path, "r"); if(f != NULL) { struct stat s; stat(path, &s); char* buf = malloc(s.st_size + 1); fread(buf, 1, s.st_size, f); buf[s.st_size] = 0; desc = html_escape_nl_to_br(buf); fclose(f); } char* tmp = rv_strcat3(WWW_AVATAR_ROOT, "/", rv_get_query("username")); logopath = rv_strcat(tmp, ".png"); free(tmp); free(path); add_data(&page, "

    Repository List

    \n"); add_data(&page, "\n"); add_data(&page, "\n"); fcounter = 0; instead_username = rv_get_query("username"); rv_repo_list(rv_get_query("username"), list_repo); add_data(&page, "
    Repository nameRevision
    \n"); } else { add_data(&page, "User does not exist.\n"); } } } else if(strcmp(query, "sendmanrepo") == 0) { title = rv_strdup("Modifying Repository Result"); page = rv_strdup(""); rv_load_query('Q'); if(user == NULL) { add_data(&page, "It looks like you are not logged in.
    Want to log in?\n"); } else if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) { add_data(&page, "Invalid Form.\n"); } else if(strcmp(rv_get_query("username"), user) != 0) { add_data(&page, "You are not the owner of the repository.\n"); } else { char* esc; rv_load_query('P'); char* readme = rv_get_query("readme"); if(readme != NULL) { rv_load_query('Q'); char* name = rv_construct_repouser(rv_get_query("reponame"), rv_get_query("username")); rv_set_readme(name, readme); free(name); } rv_load_query('Q'); add_data(&page, "Modified the repository successfully.
    \n"); add_data(&page, "Go back to the repository.\n"); } } if(title == NULL) title = rv_strdup(""); if(desc == NULL) desc = rv_strdup(""); if(page == NULL) page = rv_strdup(""); if(nav == NULL) nav = rv_strdup(""); #ifdef USE_AVATAR generate_avatar(); #endif render_stuff(); freeall: free(page); free(desc); free(title); free(nav); if(logopath != NULL) free(logopath); } char* escape(const char* str) { char* r = malloc(1); r[0] = 0; char cbuf[2]; cbuf[1] = 0; int i; for(i = 0; str[i] != 0; i++) { if(str[i] == '<') { char* tmp = r; r = rv_strcat(tmp, "<"); free(tmp); } else if(str[i] == '>') { char* tmp = r; r = rv_strcat(tmp, ">"); free(tmp); } else { cbuf[0] = str[i]; char* tmp = r; r = rv_strcat(tmp, cbuf); free(tmp); } } return r; } void render_stuff(void) { char* escaped; add_data(&buffer, "\n"); add_data(&buffer, "\n"); add_data(&buffer, " \n"); add_data(&buffer, " \n"); add_data(&buffer, " "); add_data(&buffer, INSTANCE_NAME); add_data(&buffer, " - "); add_data(&buffer, title); add_data(&buffer, "\n"); add_data(&buffer, " \n"); add_data(&buffer, " \n"); add_data(&buffer, " \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, " Home\n"); add_data(&buffer, "
    \n"); if(user == NULL) { add_data(&buffer, "
    \n"); add_data(&buffer, " Login\n"); add_data(&buffer, "
    \n"); #ifdef ALLOW_SIGNUP add_data(&buffer, "
    \n"); add_data(&buffer, " Signup\n"); add_data(&buffer, "
    \n"); #endif } else { #ifdef USE_MYPAGE add_data(&buffer, "
    \n"); add_data(&buffer, " My Page\n"); add_data(&buffer, "
    \n"); #endif add_data(&buffer, "
    \n"); add_data(&buffer, " My Repositories\n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, " Logout\n"); add_data(&buffer, "
    \n"); } if(user != NULL) { #ifdef USE_AVATAR #ifdef USE_MYPAGE add_data(&buffer, ""); #endif add_data(&buffer, "\"Your"); #ifdef USE_MYPAGE add_data(&buffer, ""); #endif #endif add_data(&buffer, ""); } add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "

    "); add_data(&buffer, title); add_data(&buffer, "

    \n"); add_data(&buffer, "

    \n"); add_data(&buffer, desc); add_data(&buffer, "

    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, " \"logo\"\n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "

    Page Menu

    \n"); add_data(&buffer, "
      \n"); add_data(&buffer, nav); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, page); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, " Top\n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); add_data(&buffer, " "); escaped = escape(INSTANCE_ADMIN); add_data(&buffer, escaped); free(escaped); add_data(&buffer, "\n"); add_data(&buffer, "
    \n"); add_data(&buffer, "
    \n"); #ifdef INSTANCE_BANNERS add_data(&buffer, "
    \n"); add_data(&buffer, INSTANCE_BANNERS); add_data(&buffer, "
    \n"); #else add_data(&buffer, "
    \n"); #endif add_data(&buffer, "
    \n"); add_data(&buffer, " \n"); add_data(&buffer, "\n"); if(user != NULL) free(user); }