]> Git repositories of Nishi - repoview.git/commitdiff
can show file now
authorNishi <nishi@nishi.boats>
Wed, 21 Aug 2024 04:31:55 +0000 (04:31 +0000)
committerNishi <nishi@nishi.boats>
Wed, 21 Aug 2024 04:31:55 +0000 (04:31 +0000)
git-svn-id: file:///raid/svn-personal/repoview/trunk@11 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f

CGI/repo.c
CGI/rv_repo.h
CGI/theme/modern.c
CGI/util.c
config.h.tmpl

index 96e70fdb93670634fae9b0e00ef6199d37493643..d8024303c5271b6f90465e4fb6dc941d8ae272f2 100644 (file)
@@ -1,3 +1,269 @@
 /* $Id$ */
 
 #include "rv_repo.h"
+
+#include "../config.h"
+
+#include "rv_util.h"
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+char* rv_construct_repouser(const char* reponame, const char* username) {
+       char cbuf[2];
+       cbuf[0] = REPO_USER_DELIM;
+       cbuf[1] = 0;
+       return rv_strcat3(reponame, cbuf, username);
+}
+
+bool rv_repo_exists(const char* repouser) {
+       char* path = rv_strcat3(SVN_ROOT, "/", repouser);
+       if(access(path, F_OK) == 0) {
+               free(path);
+               return true;
+       }
+       return false;
+}
+
+void rv_repo_list(const char* username, void (*handler)(const char* name, const char* rev)) {
+       struct dirent** nl;
+       int n = scandir(SVN_ROOT, &nl, NULL, alphasort);
+       if(n < 0) return;
+       int i;
+       for(i = 0; i < n; i++) {
+               if(strcmp(nl[i]->d_name, "..") != 0 && strcmp(nl[i]->d_name, ".") != 0) {
+                       char* tmp = rv_strcat3(SVN_ROOT, "/", nl[i]->d_name);
+                       char* path = rv_strcat(tmp, "/db/current");
+                       free(tmp);
+                       char* str = rv_strdup(nl[i]->d_name);
+                       int j;
+                       for(j = 0; str[j] != 0; j++) {
+                               if(str[j] == REPO_USER_DELIM) {
+                                       str[j] = 0;
+                                       if(strcmp(str + j + 1, username) == 0) {
+                                               struct stat s;
+                                               char* rev = rv_strdup("???");
+                                               if(stat(path, &s) == 0) {
+                                                       free(rev);
+                                                       rev = malloc(s.st_size + 1);
+                                                       FILE* f = fopen(path, "r");
+                                                       fread(rev, 1, s.st_size, f);
+                                                       fclose(f);
+                                                       rev[s.st_size] = 0;
+                                               }
+                                               handler(str, rev);
+                                               free(rev);
+                                       }
+                                       break;
+                               }
+                       }
+                       free(path);
+                       free(str);
+               }
+               free(nl[i]);
+       }
+       free(nl);
+}
+
+void null_exec(char** cmd) {
+       pid_t pid = fork();
+       if(pid == 0) {
+               int null = open("/dev/null", O_RDWR);
+               dup2(STDOUT_FILENO, null);
+               execvp(cmd[0], cmd);
+               _exit(0);
+       } else {
+               waitpid(pid, 0, 0);
+       }
+}
+
+void rv_create_repo(const char* repouser) {
+       char* user = rv_strdup(repouser);
+       int i;
+       for(i = 0; user[i] != 0; i++) {
+               if(user[i] == REPO_USER_DELIM) {
+                       user[i] = 0;
+                       break;
+               }
+       }
+       char* path = rv_strcat3(SVN_ROOT, "/", repouser);
+       char* cmd[] = {"svnadmin", "create", path, NULL};
+       null_exec(cmd);
+       free(path);
+       FILE* f = fopen(APACHE_AUTHZ, "r+");
+       lockf(fileno(f), F_LOCK, 0);
+
+       fseek(f, 0, SEEK_END);
+
+       fprintf(f, "#%%START %s\n", repouser);
+       fprintf(f, "* = r\n");
+       fprintf(f, "%s = r\n", user);
+       fprintf(f, "#%%END\n");
+
+       lockf(fileno(f), F_ULOCK, 0);
+       free(user);
+}
+
+char* rv_get_readme(const char* repouser) {
+       char* tmp = rv_strcat3(SVN_ROOT, "/", repouser);
+       char* path = rv_strcat(tmp, "/README.txt");
+       free(tmp);
+       struct stat s;
+       if(stat(path, &s) == 0) {
+               FILE* f = fopen(path, "r");
+               char* buf = malloc(s.st_size + 1);
+               fread(buf, 1, s.st_size, f);
+               fclose(f);
+               buf[s.st_size] = 0;
+               return buf;
+       }
+       return NULL;
+}
+
+long long rv_get_filesize(const char* repouser, const char* path) {
+       char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser);
+       int pipes[2];
+       pipe(pipes);
+       pid_t pid = fork();
+       if(pid == 0) {
+               close(pipes[0]);
+               dup2(pipes[1], STDOUT_FILENO);
+               char* cmd[] = {"svnlook", "filesize", svnpath, (char*)path, NULL};
+               execvp("svnlook", cmd);
+               _exit(0);
+       } else {
+               close(pipes[1]);
+               char cbuf[2];
+               cbuf[1] = 0;
+               char* d = malloc(1);
+               d[0] = 0;
+               while(1) {
+                       int n = read(pipes[0], cbuf, 1);
+                       if(n == 0) break;
+                       char* tmp = d;
+                       d = rv_strcat(tmp, cbuf);
+                       free(tmp);
+               }
+               int status;
+               waitpid(pid, &status, 0);
+               if(WEXITSTATUS(status) != 0) {
+                       free(d);
+                       free(svnpath);
+                       return -1;
+               }
+               long long sz = atoll(d);
+               free(svnpath);
+               free(d);
+               return sz;
+       }
+}
+
+bool rv_get_list(const char* repouser, const char* path, void (*handler)(const char* pathname), int* isdir) {
+       char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser);
+       int pipes[2];
+       *isdir = 0;
+       pipe(pipes);
+       pid_t pid = fork();
+       if(pid == 0) {
+               close(pipes[0]);
+               dup2(pipes[1], STDOUT_FILENO);
+               char* cmd[] = {"svnlook", "-N", "tree", svnpath, (char*)path, NULL};
+               execvp("svnlook", cmd);
+               _exit(0);
+       } else {
+               close(pipes[1]);
+               char cbuf[2];
+               cbuf[1] = 0;
+               char* d = malloc(1);
+               d[0] = 0;
+               while(1) {
+                       int n = read(pipes[0], cbuf, 1);
+                       if(n == 0) break;
+                       char* tmp = d;
+                       d = rv_strcat(tmp, cbuf);
+                       free(tmp);
+               }
+               int status;
+               waitpid(pid, &status, 0);
+               if(WEXITSTATUS(status) != 0) {
+                       free(d);
+                       free(svnpath);
+                       return false;
+               }
+               int count = 0;
+               int incr = 0;
+               int i;
+               int phase = 0;
+       repeat:
+               for(i = 0;; i++) {
+                       if(d[i] == '\r') {
+                               d[i] = 0;
+                       } else if(d[i] == '\n' || d[i] == 0) {
+                               char oldc = d[i];
+                               d[i] = 0;
+                               count++;
+                               if(count > 1 && strlen(d + incr + 1) > 0 && d[incr] != 0) {
+                                       char* pathname = d + incr + 1;
+                                       if(phase == 0 && pathname[strlen(pathname) - 1] == '/') {
+                                               handler(d + incr + 1);
+                                       } else if(phase == 1 && pathname[strlen(pathname) - 1] != '/') {
+                                               handler(d + incr + 1);
+                                       }
+                               } else {
+                                       char* pathname = d + incr;
+                                       if(pathname[strlen(pathname) - 1] == '/') *isdir = 1;
+                               }
+                               d[i] = oldc;
+                               incr = i + 1;
+                               if(oldc == 0) break;
+                       }
+               }
+               phase++;
+               if(phase == 1) goto repeat;
+               free(d);
+       }
+       free(svnpath);
+       return true;
+}
+
+char* rv_read_file(const char* repouser, char* path) {
+       char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser);
+       int pipes[2];
+       pipe(pipes);
+       pid_t pid = fork();
+       if(pid == 0) {
+               close(pipes[0]);
+               dup2(pipes[1], STDOUT_FILENO);
+               char* cmd[] = {"svnlook", "cat", svnpath, (char*)path, NULL};
+               execvp("svnlook", cmd);
+               _exit(0);
+       } else {
+               close(pipes[1]);
+               char cbuf[2];
+               cbuf[1] = 0;
+               char* d = malloc(1);
+               d[0] = 0;
+               while(1) {
+                       int n = read(pipes[0], cbuf, 1);
+                       if(n == 0) break;
+                       char* tmp = d;
+                       d = rv_strcat(tmp, cbuf);
+                       free(tmp);
+               }
+               int status;
+               waitpid(pid, &status, 0);
+               if(WEXITSTATUS(status) != 0) {
+                       free(d);
+                       free(svnpath);
+                       return NULL;
+               }
+               return d;
+       }
+}
index e548190756ba79810a0c2845299877802101e755..e62bf3c16ed151512f2476b78c387c7f9f2d2442 100644 (file)
@@ -3,4 +3,15 @@
 #ifndef __RV_REPO_H__
 #define __RV_REPO_H__
 
+#include <stdbool.h>
+
+char* rv_construct_repouser(const char* reponame, const char* username);
+bool rv_repo_exists(const char* repouser);
+void rv_repo_list(const char* username, void (*handler)(const char* name, const char* rev));
+void rv_create_repo(const char* repouser);
+char* rv_get_readme(const char* repouser);
+bool rv_get_list(const char* repouser, const char* path, void (*handler)(const char* pathname), int* isdir);
+char* rv_read_file(const char* repouser, char* path);
+long long rv_get_filesize(const char* repouser, const char* path);
+
 #endif
index 3272419edceaa08b8933c8d28a355d859add697c..b834646dcbdeb07fdb7d7cb4c1cf7c20c6fbe1b3 100644 (file)
@@ -6,6 +6,7 @@
 #include "rv_version.h"
 #include "rv_auth.h"
 #include "rv_db.h"
+#include "rv_repo.h"
 
 #include "../../config.h"
 
@@ -21,8 +22,144 @@ char* title = NULL;
 char* desc = NULL;
 char* page = NULL;
 char* nav = NULL;
+char* grepouser;
 extern char* user;
 
+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, "&lt;");
+               } else if(input[i] == '>') {
+                       add_data(&r, "&gt;");
+               } 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, "&lt;");
+               } else if(input[i] == '>') {
+                       add_data(&r, "&gt;");
+               } else if(input[i] == '\n') {
+                       add_data(&r, "<br>");
+               } else {
+                       cbuf[0] = input[i];
+                       add_data(&r, cbuf);
+               }
+       }
+       return r;
+}
+
+void list_repo(const char* name, const char* rev) {
+       char* showname = html_escape(name);
+       char* urluser = url_escape(user);
+       char* urlrepo = url_escape(name);
+       add_data(&page, "<tr>");
+       add_data(&page, "<td><a href=\"");
+       add_data(&page, INSTANCE_ROOT);
+       add_data(&page, "/?page=repo&reponame=");
+       add_data(&page, urlrepo);
+       add_data(&page, "&username=");
+       add_data(&page, urluser);
+       add_data(&page, "\">");
+       add_data(&page, showname);
+       add_data(&page, "</a></td>");
+       add_data(&page, "<td>");
+       add_data(&page, rev);
+       add_data(&page, "</td>");
+       add_data(&page, "</tr>");
+       free(showname);
+       free(urluser);
+       free(urlrepo);
+}
+
+int fcounter = 0;
+void list_files(const char* pathname) {
+       if(fcounter == 0) {
+               add_data(&nav, "<li><a href=\"#filelist\">File List</a></li>\n");
+               add_data(&page, "<h2 id=\"filelist\">File List</h2>\n");
+               add_data(&page, "<tr style=\"background-color: #D2E1F6;\"><th>Name</th><th>Size</th></tr>\n");
+       }
+       fcounter++;
+       add_data(&page, "<tr style=\"background-color: #");
+       if((fcounter % 2) == 0) {
+               add_data(&page, "D2E1C0");
+       } else {
+               add_data(&page, "FFFFFF");
+       }
+       char* path = rv_get_query("path");
+       if(path == NULL) path = "/";
+       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(user);
+       add_data(&query, esc);
+       free(esc);
+       add_data(&query, "&path=");
+       char* urlpath = rv_strcat(path, pathname);
+       esc = url_escape(urlpath);
+       add_data(&query, esc);
+       free(esc);
+       char* sz = malloc(128);
+       sprintf(sz, "%lld", rv_get_filesize(grepouser, urlpath));
+       add_data(&page, "\"><td><a href=\"");
+       add_data(&page, query);
+       add_data(&page, "\">");
+       add_data(&page, pathname);
+       add_data(&page, "</a></td>\n");
+       add_data(&page, "<td>\n");
+       if(strcmp(sz, "-1") != 0) {
+               add_data(&page, sz);
+       } else {
+               add_data(&page, "&lt;DIR&gt;");
+       }
+       add_data(&page, "</td>\n");
+       free(sz);
+       add_data(&page, "</tr>\n");
+       free(query);
+       free(urlpath);
+}
+
 void render_page(void) {
        rv_load_query('Q');
        char* query = rv_get_query("page");
@@ -61,7 +198,11 @@ void render_page(void) {
                page = rv_strdup("");
 
                rv_load_query('P');
-               if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) {
+               if(user != NULL) {
+                       page = rv_strdup("It looks like you are already logged in.<br>Want to <a href=\"");
+                       add_data(&page, INSTANCE_ROOT);
+                       add_data(&page, "/?page=login\">log out</a>?\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"))) {
@@ -104,6 +245,9 @@ void render_page(void) {
                        add_data(&page, INSTANCE_ROOT);
                        add_data(&page, "/?page=login\">log in</a>?\n");
                } else {
+                       char cbuf[2];
+                       cbuf[0] = REPO_USER_DELIM;
+                       cbuf[1] = 0;
                        nav = rv_strdup("");
                        add_data(&nav, "<li><a href=\"#createrepo\">Create a repository</a></li>\n");
                        add_data(&nav, "<li><a href=\"#repolist\">Repository List</a></li>\n");
@@ -121,8 +265,65 @@ void render_page(void) {
                        add_data(&page, "                       <td><input type=\"submit\" value=\"Create\"></td>\n");
                        add_data(&page, "               </tr>\n");
                        add_data(&page, "       </table>\n");
+                       add_data(&page, "Repository name cannot contain '<code>");
+                       add_data(&page, cbuf);
+                       add_data(&page, "</code>'.");
                        add_data(&page, "</form>\n");
                        add_data(&page, "<h2 id=\"repolist\">Repository List</h2>\n");
+                       add_data(&page, "<table border=\"0\">\n");
+                       add_data(&page, "<tr><th>Repository name</th><th>Revision</th></tr>\n");
+                       rv_repo_list(user, list_repo);
+                       add_data(&page, "</table>\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.<br>Want to <a href=\"");
+                       add_data(&page, INSTANCE_ROOT);
+                       add_data(&page, "/?page=login\">log in</a>?\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) {
+                                       char cbuf[2];
+                                       cbuf[0] = REPO_USER_DELIM;
+                                       cbuf[1] = 0;
+                                       add_data(&page, "Repository name cannot contain '<code>");
+                                       add_data(&page, cbuf);
+                                       add_data(&page, "</code>'.");
+                                       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.<br>\n");
+                                       add_data(&page, "<a href=\"");
+                                       add_data(&page, INSTANCE_ROOT);
+                                       esc = url_escape(name);
+                                       add_data(&page, "/?page=repo&reponame=");
+                                       add_data(&page, esc);
+                                       free(esc);
+                                       esc = url_escape(user);
+                                       add_data(&page, "&username=");
+                                       add_data(&page, esc);
+                                       free(esc);
+                                       add_data(&page, "\">Go to the repository</a>.\n");
+                               }
+                               free(ru);
+                       }
                }
        } else if(strcmp(query, "logout") == 0) {
                title = rv_strdup("Logout");
@@ -140,6 +341,56 @@ void render_page(void) {
                        add_data(&page, "       <input type=\"submit\" value=\"Yes\">\n");
                        add_data(&page, "</form>\n");
                }
+       } else if(strcmp(query, "repo") == 0) {
+               title = rv_strdup("Repository");
+               desc = rv_strdup("");
+               page = rv_strdup("");
+               nav = rv_strdup("");
+               if(rv_get_query("username") == NULL || rv_get_query("reponame") == NULL) {
+                       add_data(&page, "Required parameters not set.");
+               } else {
+                       char* user = rv_get_query("username");
+                       char* repo = rv_get_query("reponame");
+                       char* repouser = rv_construct_repouser(repo, user);
+                       grepouser = repouser;
+                       if(rv_repo_exists(repouser)) {
+                               char* showuser = html_escape(user);
+                               char* showrepo = html_escape(repo);
+                               char* showreadme = rv_get_readme(repouser);
+                               desc = html_escape_nl_to_br(showreadme);
+                               add_data(&title, " - ");
+                               add_data(&title, showrepo);
+                               add_data(&title, "/");
+                               add_data(&title, showuser);
+                               free(showuser);
+                               free(showrepo);
+                               free(showreadme);
+
+                               int isdir;
+                               char* path = rv_get_query("path");
+                               if(path == NULL) path = "/";
+                               fcounter = 0;
+                               add_data(&page, "<table border=\"0\" style=\"width: 100%;\">");
+                               if(!rv_get_list(repouser, path, list_files, &isdir)) {
+                                       add_data(&page, "<tr><td>Path not found.</td></tr>\n");
+                               }
+                               add_data(&page, "</table>");
+                               if(isdir == 0) {
+                                       add_data(&nav, "<li><a href=\"#filecontent\">Content</a></li>");
+                                       add_data(&page, "<h2 id=\"filecontent\">Content</h2>\n");
+                                       add_data(&page, "<pre class=\"codeblock\"><code>");
+                                       char* data = rv_read_file(repouser, path);
+                                       char* esc = html_escape_nl_to_br(data);
+                                       add_data(&page, esc);
+                                       free(esc);
+                                       free(data);
+                                       add_data(&page, "</code></pre>");
+                               }
+                       } else {
+                               add_data(&page, "Repository does not exist.\n");
+                       }
+                       free(repouser);
+               }
        }
 
        if(title == NULL) title = rv_strdup("");
@@ -208,6 +459,9 @@ void render_stuff(void) {
        add_data(&buffer, "     padding-right: 25px;\n");
        add_data(&buffer, "     padding-top: 7px;\n");
        add_data(&buffer, "}\n");
+       add_data(&buffer, "th,td {\n");
+       add_data(&buffer, "     padding: 2px;\n");
+       add_data(&buffer, "}\n");
        add_data(&buffer, "body {\n");
        add_data(&buffer, "     background-color: #1F4677;\n");
        add_data(&buffer, "     width: 940px;\n");
@@ -225,6 +479,10 @@ void render_stuff(void) {
        add_data(&buffer, "     font-size: 22px;\n");
        add_data(&buffer, "     font-weight: bold;\n");
        add_data(&buffer, "}\n");
+       add_data(&buffer, "pre {\n");
+       add_data(&buffer, "     background-color: #dddddd;\n");
+       add_data(&buffer, "     border: solid 2px #bbbbbb;\n");
+       add_data(&buffer, "}\n");
        add_data(&buffer, "#index {\n");
        add_data(&buffer, "     list-style: none;\n");
        add_data(&buffer, "     line-height: normal;\n");
@@ -239,6 +497,9 @@ void render_stuff(void) {
        add_data(&buffer, "}\n");
        add_data(&buffer, "#descinside {\n");
        add_data(&buffer, "     float: left;\n");
+       add_data(&buffer, "     width: 700px;\n");
+       add_data(&buffer, "     overflow-y: scroll;\n");
+       add_data(&buffer, "     max-height: 128px;\n");
        add_data(&buffer, "}\n");
        add_data(&buffer, "#logo {\n");
        add_data(&buffer, "     float: right;\n");
@@ -247,7 +508,6 @@ void render_stuff(void) {
        add_data(&buffer, "     background-color: #FFFFFF;\n");
        add_data(&buffer, "     margin: -10px auto;\n");
        add_data(&buffer, "     padding: 8px 24px 24px;\n");
-       add_data(&buffer, "     min-height: 128px;\n");
        add_data(&buffer, "}\n");
        add_data(&buffer, "#pageindex {\n");
        add_data(&buffer, "     background-color: #FFFFFF;\n");
@@ -352,8 +612,8 @@ void render_stuff(void) {
        add_data(&buffer, "                     </div>\n");
        add_data(&buffer, "                     <div id=\"pagecontent\">\n");
        add_data(&buffer, page);
-       add_data(&buffer, "                             <div class=\"fixfloat\"></div>\n");
        add_data(&buffer, "                     </div>\n");
+       add_data(&buffer, "                     <div class=\"fixfloat\"></div>\n");
        add_data(&buffer, "             </div>\n");
        add_data(&buffer, "             <div id=\"footer\">\n");
        add_data(&buffer, "                     <div id=\"gotop\">\n");
index 4c84ecbc3e4f327a7e1be7d61f3da052022afb6b..ef8d199581400cfcf4bd06d5f9b61359f0f87086 100644 (file)
@@ -75,13 +75,6 @@ char* rv_url_decode(const char* str) {
        return r;
 }
 
-char* rv_construct_repouser(const char* reponame, const char* username) {
-       char cbuf[2];
-       cbuf[0] = REPO_USER_DELIM;
-       cbuf[1] = 0;
-       return rv_strcat3(reponame, cbuf, username);
-}
-
 char* rv_new_token(const char* username) {
        const char tokenstr[] = "0123456789abcdefghijklmnopqrstuvwxyz";
        char* token = malloc(17);
index 9c2d89c6c20eeec25b091a65084b17a82312461b..f2d25c97578f7f0781da1c8ae25234e3ffced089 100644 (file)
@@ -26,7 +26,7 @@
 #define INSTANCE_REPEAT        "resize-x"
 
 /* Repository/User delimeter. This character will be unusable in the username/repository name. */
-#define REPO_USER_DELIM '@'
+#define REPO_USER_DELIM '$'
 
 /* Theme. */
 #define USE_MODERN