]> Git repositories of Nishi - repoview.git/commitdiff
init
authorNishi <nishi@nishi.boats>
Tue, 20 Aug 2024 19:18:25 +0000 (19:18 +0000)
committerNishi <nishi@nishi.boats>
Tue, 20 Aug 2024 19:18:25 +0000 (19:18 +0000)
git-svn-id: file:///raid/svn-personal/repoview/trunk@1 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f

24 files changed:
CGI/Makefile [new file with mode: 0644]
CGI/auth/cookie.c [new file with mode: 0644]
CGI/db/dbm.c [new file with mode: 0644]
CGI/db/sqlite.c [new file with mode: 0644]
CGI/main.c [new file with mode: 0644]
CGI/page.c [new file with mode: 0644]
CGI/query.c [new file with mode: 0644]
CGI/rv_db.h [new file with mode: 0644]
CGI/rv_page.h [new file with mode: 0644]
CGI/rv_query.h [new file with mode: 0644]
CGI/rv_sanity.h [new file with mode: 0644]
CGI/rv_util.h [new file with mode: 0644]
CGI/rv_version.h [new file with mode: 0644]
CGI/sanity.c [new file with mode: 0644]
CGI/theme/modern.c [new file with mode: 0644]
CGI/theme/optimized.c [new file with mode: 0644]
CGI/util.c [new file with mode: 0644]
CGI/version.c [new file with mode: 0644]
Makefile [new file with mode: 0644]
Platform/generic.mk [new file with mode: 0644]
check.c [new file with mode: 0644]
config.h.tmpl [new file with mode: 0644]
libs.c [new file with mode: 0644]
objs.c [new file with mode: 0644]

diff --git a/CGI/Makefile b/CGI/Makefile
new file mode 100644 (file)
index 0000000..33e4761
--- /dev/null
@@ -0,0 +1,19 @@
+# $Id$
+
+include $(PWD)/Platform/$(PLATFORM).mk
+
+.PHONY: all clean
+.SUFFIXES: .c .o
+
+OBJS = main.o sanity.o version.o util.o query.o page.o $(EXTOBJS)
+
+all: repoview.cgi
+
+repoview.cgi: $(OBJS)
+       $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTLIBS)
+
+.c.o:
+       $(CC) -I $(PWD)/CGI $(CFLAGS) -c -o $@ $<
+
+clean:
+       rm -f *.cgi *.o */*.o
diff --git a/CGI/auth/cookie.c b/CGI/auth/cookie.c
new file mode 100644 (file)
index 0000000..a0749a0
--- /dev/null
@@ -0,0 +1 @@
+/* $Id$ */
diff --git a/CGI/db/dbm.c b/CGI/db/dbm.c
new file mode 100644 (file)
index 0000000..a0749a0
--- /dev/null
@@ -0,0 +1 @@
+/* $Id$ */
diff --git a/CGI/db/sqlite.c b/CGI/db/sqlite.c
new file mode 100644 (file)
index 0000000..b513e6f
--- /dev/null
@@ -0,0 +1,106 @@
+/* $Id$ */
+
+#include "rv_db.h"
+
+#include "../../config.h"
+
+#include "rv_util.h"
+
+#include <sqlite3.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+sqlite3* sql;
+
+void rv_init_db(void){
+       int ret;
+       ret = sqlite3_open(DB_ROOT "/db.sqlite3", &sql);
+       if(ret != SQLITE_OK){
+               rv_error_http();
+               printf("SQLite3 database error\n");
+               exit(1);
+       }
+       char* err;
+       ret = sqlite3_exec(
+               sql,
+               "create table if not exists users(user text, password text)",
+               NULL,
+               NULL,
+               &err
+       );
+       if(ret != SQLITE_OK){
+               sqlite3_free(err);
+               rv_error_http();
+               printf("SQLite3 database error\n");
+               exit(1);
+       }
+       ret = sqlite3_exec(
+               sql,
+               "create table if not exists tokens(user text, token text)",
+               NULL,
+               NULL,
+               &err
+       );
+       if(ret != SQLITE_OK){
+               sqlite3_free(err);
+               rv_error_http();
+               printf("SQLite3 database error\n");
+               exit(1);
+       }
+}
+
+void rv_close_db(void){
+       sqlite3_close(sql);
+}
+
+int count = 0;
+
+int sqlcount(void* param, int ncol, char** row, char** col){
+       count = ncol;
+       fprintf(stderr, "%d\n", ncol);
+       return 0;
+}
+
+bool rv_has_user(const char* username){
+       char* err;
+       char cbuf[2];
+       cbuf[1] = 0;
+       char* query = rv_strdup("select * from users where user = '");
+       int i;
+       for(i = 0; username[i] != 0; i++){
+               if(username[i] == '\''){
+                       cbuf[0] = username[i];
+                       char* tmp = query;
+                       tmp = rv_strcat(tmp, cbuf);
+                       free(tmp);
+                       cbuf[0] = username[i];
+                       tmp = query;
+                       query = rv_strcat(tmp, cbuf);
+                       free(tmp);
+               }else{
+                       cbuf[0] = username[i];
+                       char* tmp = query;
+                       query = rv_strcat(tmp, cbuf);
+                       free(tmp);
+               }
+       }
+       char* tmp = query;
+       query = rv_strcat(tmp, "'");
+       free(tmp);
+       int ret;
+       fprintf(stderr, "%s\n", query);
+       ret = sqlite3_exec(
+               sql,
+               query,
+               sqlcount,
+               NULL,
+               &err
+       );
+       free(query);
+       if(ret != SQLITE_OK){
+               sqlite3_free(err);
+       }
+       return count > 0;
+}
diff --git a/CGI/main.c b/CGI/main.c
new file mode 100644 (file)
index 0000000..a3dd2bc
--- /dev/null
@@ -0,0 +1,41 @@
+/* $Id$ */
+
+#include <stdio.h>
+
+#include "../config.h"
+
+#include "rv_sanity.h"
+#include "rv_query.h"
+#include "rv_page.h"
+#include "rv_util.h"
+#include "rv_db.h"
+
+#include <stdlib.h>
+
+char* postdata;
+
+int main(){
+       rv_check_sanity();
+       rv_init_db();
+       rv_parse_query(getenv("QUERY_STRING"));
+       rv_save_query('Q');
+       postdata = malloc(1);
+       postdata[0] = 0;
+       char cbuf[2];
+       cbuf[1] = 0;
+       while(1){
+               fread(cbuf, 1, 1, stdin);
+               if(feof(stdin)) break;
+               char* tmp = postdata;
+               postdata = rv_strcat(tmp, cbuf);
+               free(tmp);
+       }
+       rv_parse_query(postdata);
+       rv_save_query('P');
+       rv_process_page();
+       printf("Content-Type: text/html\r\n");
+       printf("\r\n");
+       rv_print_page();
+       rv_free_query();
+       rv_close_db();
+}
diff --git a/CGI/page.c b/CGI/page.c
new file mode 100644 (file)
index 0000000..1f73d11
--- /dev/null
@@ -0,0 +1,31 @@
+/* $Id$ */
+
+#include "rv_page.h"
+
+#include "rv_query.h"
+#include "rv_util.h"
+
+#include "../config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+char* buffer;
+
+void render_page(void);
+
+void add_data(char** data, const char* txt){
+       char* tmp = *data;
+       *data = rv_strcat(tmp, txt);
+       free(tmp);
+}
+
+void rv_process_page(void){
+       buffer = malloc(1);
+       buffer[0] = 0;
+       render_page();
+}
+
+void rv_print_page(void){
+       printf("%s\n", buffer);
+}
diff --git a/CGI/query.c b/CGI/query.c
new file mode 100644 (file)
index 0000000..61a91b3
--- /dev/null
@@ -0,0 +1,99 @@
+/* $Id$ */
+
+#include "rv_query.h"
+
+#include "rv_util.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+struct query_entry {
+       char* key;
+       char* value;
+};
+
+struct query_entry** qentries;
+
+struct query_entry** query;
+struct query_entry** postquery;
+
+void rv_save_query(char c){
+       if(c == 'Q'){
+               query = qentries;
+       }else if(c == 'P'){
+               postquery = qentries;
+       }
+}
+
+void rv_load_query(char c){
+       if(c == 'Q'){
+               qentries = query;
+       }else if(c == 'P'){
+               qentries = postquery;
+       }
+}
+
+void rv_parse_query(const char* oldquery){
+       char* query = rv_strdup(oldquery);
+       int i;
+       int incr = 0;
+       qentries = malloc(sizeof(*qentries));
+       qentries[0] = NULL;
+       for(i = 0;; i++){
+               if(query[i] == '&' || query[i] == 0){
+                       char oldc = query[i];
+                       query[i] = 0;
+
+                       char* key = query + incr;
+                       char* value = "";
+
+                       int j;
+                       for(j = 0; key[j] != 0; j++){
+                               if(key[j] == '='){
+                                       key[j] = 0;
+                                       value = key + j + 1;
+                                       break;
+                               }
+                       }
+
+                       struct query_entry* entry = malloc(sizeof(*entry));
+                       entry->key = rv_url_decode(key);
+                       entry->value = rv_url_decode(value);
+
+                       struct query_entry** old_entries = qentries;
+                       for(j = 0; old_entries[j] != NULL; j++);
+                       qentries = malloc(sizeof(*qentries) * (j + 2));
+                       for(j = 0; old_entries[j] != NULL; j++){
+                               qentries[j] = old_entries[j];
+                       }
+                       qentries[j] = entry;
+                       qentries[j + 1] = NULL;
+                       free(old_entries);
+
+                       incr = i + 1;
+                       if(oldc == 0) break;
+               }
+       }
+       free(query);
+}
+
+void rv_free_query(void){
+       int i;
+       for(i = 0; qentries[i] != NULL; i++){
+               free(qentries[i]->key);
+               free(qentries[i]->value);
+               free(qentries[i]);
+       }
+       free(qentries);
+}
+
+char* rv_get_query(const char* key){
+       int i;
+       for(i = 0; qentries[i] != NULL; i++){
+               if(strcmp(qentries[i]->key, key) == 0){
+                       return qentries[i]->value;
+               }
+       }
+       return NULL;
+}
diff --git a/CGI/rv_db.h b/CGI/rv_db.h
new file mode 100644 (file)
index 0000000..307916a
--- /dev/null
@@ -0,0 +1,12 @@
+/* $Id$ */
+
+#ifndef __RV_DB_H__
+#define __RV_DB_H__
+
+#include <stdbool.h>
+
+void rv_init_db(void);
+void rv_close_db(void);
+bool rv_has_user(const char* name);
+
+#endif
diff --git a/CGI/rv_page.h b/CGI/rv_page.h
new file mode 100644 (file)
index 0000000..97d43ea
--- /dev/null
@@ -0,0 +1,9 @@
+/* $Id$ */
+
+#ifndef __RV_PAGE_H__
+#define __RV_PAGE_H__
+
+void rv_process_page(void);
+void rv_print_page(void);
+
+#endif
diff --git a/CGI/rv_query.h b/CGI/rv_query.h
new file mode 100644 (file)
index 0000000..6133fc7
--- /dev/null
@@ -0,0 +1,13 @@
+/* $Id$ */
+
+#ifndef __RV_QUERY_H__
+#define __RV_QUERY_H__
+
+void rv_parse_query(const char* query);
+void rv_free_query(void);
+char* rv_get_query(const char* key);
+
+void rv_save_query(char c);
+void rv_load_query(char c);
+
+#endif
diff --git a/CGI/rv_sanity.h b/CGI/rv_sanity.h
new file mode 100644 (file)
index 0000000..0ad0384
--- /dev/null
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+#ifndef __RV_SANITY_H__
+#define __RV_SANITY_H__
+
+void rv_check_sanity(void);
+
+#endif
diff --git a/CGI/rv_util.h b/CGI/rv_util.h
new file mode 100644 (file)
index 0000000..c59e113
--- /dev/null
@@ -0,0 +1,18 @@
+/* $Id$ */
+
+#ifndef __RV_UTIL_H__
+#define __RV_UTIL_H__
+
+#ifdef __MINGW32__
+#define PATH_DELIM ';'
+#else
+#define PATH_DELIM ':'
+#endif
+
+char* rv_strcat(const char* a, const char* b);
+char* rv_strcat3(const char* a, const char* b, const char* c);
+char* rv_strdup(const char* str);
+char* rv_url_decode(const char* str);
+void rv_error_http(void);
+
+#endif
diff --git a/CGI/rv_version.h b/CGI/rv_version.h
new file mode 100644 (file)
index 0000000..4a12131
--- /dev/null
@@ -0,0 +1,8 @@
+/* $Id$ */
+
+#ifndef __RV_VERSION_H__
+#define __RV_VERSION_H__
+
+const char* rv_get_version(void);
+
+#endif
diff --git a/CGI/sanity.c b/CGI/sanity.c
new file mode 100644 (file)
index 0000000..b7fe418
--- /dev/null
@@ -0,0 +1,64 @@
+/* $Id$ */
+
+#include "rv_sanity.h"
+
+#include "rv_version.h"
+#include "rv_util.h"
+#include "../config.h"
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+bool rv_find_executable(const char* name){
+#ifdef USE_PATH
+       char* path = rv_strcat(USE_PATH, "");
+#else
+       char* path = rv_strcat(getenv("PATH"), "");
+#endif
+       int i;
+       int incr = 0;
+       for(i = 0;; i++){
+               if(path[i] == 0 || path[i] == PATH_DELIM){
+                       char oldc = path[i];
+                       path[i] = 0;
+                       char* exec = rv_strcat3(path + incr, "/", name);
+#ifdef __MINGW32__
+                       char* tmp = exec;
+                       exec = rv_strcat(exec, ".exe");
+                       free(tmp);
+#endif
+                       if(access(exec, F_OK) == 0){
+                               free(exec);
+                               free(path);
+                               return true;
+                       }
+                       free(exec);
+                       incr = i + 1;
+                       if(oldc == 0) break;
+               }
+       }
+       free(path);
+       return false;
+}
+
+void rv_check_sanity(void){
+       bool sane = true;
+
+       bool svnlook = rv_find_executable("svnlook");
+       bool svnadmin = rv_find_executable("svnadmin");
+       bool htpasswd = rv_find_executable("htpasswd");
+
+       if(!svnlook) sane = false;
+       if(!svnadmin) sane = false;
+       if(!htpasswd) sane = false;
+
+       if(!sane){
+               rv_error_http();
+               if(!svnlook) printf("svnlook not found\n");
+               if(!svnadmin) printf("svnadmin not found\n");
+               if(!htpasswd) printf("htpasswd not found\n");
+               exit(1);
+       }
+}
diff --git a/CGI/theme/modern.c b/CGI/theme/modern.c
new file mode 100644 (file)
index 0000000..56016a6
--- /dev/null
@@ -0,0 +1,265 @@
+/* $Id$ */
+
+#include "rv_query.h"
+
+#include "rv_util.h"
+#include "rv_version.h"
+#include "rv_db.h"
+
+#include "../../config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+extern char* buffer;
+void add_data(char** data, const char* txt);
+void render_stuff();
+
+char* title = NULL;
+char* desc = NULL;
+char* page = NULL;
+
+void render_page(void){
+       rv_load_query('Q');
+       char* query = rv_get_query("page");
+       if(query == NULL) query = "welcome";
+
+       if(strcmp(query, "welcome") == 0){
+               title = rv_strdup("Welcome");
+               desc = rv_strdup("Welcome to " INSTANCE_NAME ".");
+               page = rv_strcat3("Welcome to " INSTANCE_NAME ".<br>This instance is running RepoView version ", rv_get_version(), ".");
+       }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, "<form action=\"");
+               add_data(&page, INSTANCE_ROOT);
+               add_data(&page, "/?page=sendlogin\" method=\"POST\">\n");
+               add_data(&page, "       <table border=\"0\">\n");
+               add_data(&page, "               <tr>\n");
+               add_data(&page, "                       <th>Username</th>\n");
+               add_data(&page, "                       <td>\n");
+               add_data(&page, "                               <input name=\"username\">\n");
+               add_data(&page, "                       </td>\n");
+               add_data(&page, "               </tr>\n");
+               add_data(&page, "               <tr>\n");
+               add_data(&page, "                       <th>Password</th>\n");
+               add_data(&page, "                       <td>\n");
+               add_data(&page, "                               <input name=\"password\" type=\"password\">\n");
+               add_data(&page, "                       </td>\n");
+               add_data(&page, "               </tr>\n");
+               add_data(&page, "       </table>\n");
+               add_data(&page, "       <input type=\"submit\" value=\"Login\">\n");
+               add_data(&page, "</form>\n");
+       }else if(strcmp(query, "sendlogin") == 0){
+               title = rv_strdup("Login Result");
+               page = rv_strdup("");
+
+               rv_load_query('P');
+               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"))){
+                       }else{
+                               add_data(&page, "User does not exist");
+                       }
+               }
+       }
+
+       if(title == NULL) title = rv_strdup("");
+       if(desc == NULL) desc = rv_strdup("");
+       if(page == NULL) page = rv_strdup("");
+       render_stuff();
+       free(page);
+       free(desc);
+       free(title);
+}
+
+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, "&lt;");
+                       free(tmp);
+               }else if(str[i] == '>'){
+                       char* tmp = r;
+                       r = rv_strcat(tmp, "&gt;");
+                       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, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
+       add_data(&buffer, "<html>\n");
+       add_data(&buffer, "     <head>\n");
+       add_data(&buffer, "             <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n");
+       add_data(&buffer, "             <title>");
+       add_data(&buffer, INSTANCE_NAME);
+       add_data(&buffer, " - ");
+       add_data(&buffer, title);
+       add_data(&buffer, "</title>\n");
+       add_data(&buffer, "             <style type=\"text/css\">\n");
+       add_data(&buffer, "* {\n");
+       add_data(&buffer, "     padding: 0;\n");
+       add_data(&buffer, "     margin: 0;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "li {\n");
+       add_data(&buffer, "     list-style: outside;\n");
+       add_data(&buffer, "     margin-left: 1.25em;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "a {\n");
+       add_data(&buffer, "     text-decoration: none;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#nav div {\n");
+       add_data(&buffer, "     float: left;\n");
+       add_data(&buffer, "     margin: 0 0;\n");
+       add_data(&buffer, "     padding-left: 0;\n");
+       add_data(&buffer, "     padding-right: 20px;\n");
+       add_data(&buffer, "     padding-top: 7px;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "body {\n");
+       add_data(&buffer, "     background-color: #1F4677;\n");
+       add_data(&buffer, "     width: 940px;\n");
+       add_data(&buffer, "     margin: 5px auto;\n");
+       add_data(&buffer, "     font-family: sans-serif;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#nav {\n");
+       add_data(&buffer, "     background-color: white;\n");
+       add_data(&buffer, "     height: 44px;\n");
+       add_data(&buffer, "     padding: 8px;\n");
+       add_data(&buffer, "     padding-left: 32px;\n");
+       add_data(&buffer, "     font-size: 22px;\n");
+       add_data(&buffer, "     font-weight: bold;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#index {\n");
+       add_data(&buffer, "     list-style: none;\n");
+       add_data(&buffer, "     line-height: normal;\n");
+       add_data(&buffer, "     margin: auto 0;\n");
+       add_data(&buffer, "     padding-left: 0;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#desc {\n");
+       add_data(&buffer, "     background-color: #D2E1F6;\n");
+       add_data(&buffer, "     margin: 9px auto;\n");
+       add_data(&buffer, "     height: 128px;\n");
+       add_data(&buffer, "     padding: 24px;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#descinside {\n");
+       add_data(&buffer, "     float: left;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#logo {\n");
+       add_data(&buffer, "     float: right;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#content {\n");
+       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");
+       add_data(&buffer, "     padding-right: 24px;\n");
+       add_data(&buffer, "     padding-bottom: 24px;\n");
+       add_data(&buffer, "     float: left;\n");
+       add_data(&buffer, "     border-right: 4px #1F4677 solid;\n");
+       add_data(&buffer, "     width: 150px;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#pagecontent {\n");
+       add_data(&buffer, "     background-color: #FFFFFF;\n");
+       add_data(&buffer, "     width: 670px;\n");
+       add_data(&buffer, "     float: right;\n");
+       add_data(&buffer, "     padding-left: 24px;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#footer {\n");
+       add_data(&buffer, "     background-color: #D2E1F6;\n");
+       add_data(&buffer, "     padding: 8px 8px 48px;\n");
+       add_data(&buffer, "     margin: 8px auto;\n");
+       add_data(&buffer, "     font-size: 15px;\n");
+       add_data(&buffer, "     height: 32px;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, ".fixfloat {\n");
+       add_data(&buffer, "     clear: both;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#copyright {\n");
+       add_data(&buffer, "     float: right;\n");
+       add_data(&buffer, "     font-size: 10px;\n");
+       add_data(&buffer, "     margin-top: 16px;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "#gotop {\n");
+       add_data(&buffer, "     position: absolute;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "h2, h3 {\n");
+       add_data(&buffer, "     padding-top: 8px;\n");
+       add_data(&buffer, "     padding-bottom: 8px;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "img {\n");
+       add_data(&buffer, "     border: none;\n");
+       add_data(&buffer, "}\n");
+       add_data(&buffer, "             </style>\n");
+       add_data(&buffer, "     </head>\n");
+       add_data(&buffer, "     <body>\n");
+       add_data(&buffer, "             <div id=\"nav\">\n");
+       add_data(&buffer, "                     <div>\n");
+       add_data(&buffer, "                             <a href=\"");
+       add_data(&buffer, INSTANCE_ROOT);
+       add_data(&buffer, "/\">Home</a>\n");
+       add_data(&buffer, "                     </div>\n");
+       add_data(&buffer, "                     <div>\n");
+       add_data(&buffer, "                             <a href=\"");
+       add_data(&buffer, INSTANCE_ROOT);
+       add_data(&buffer, "/?page=login\">Login</a>\n");
+       add_data(&buffer, "                     </div>\n");
+       add_data(&buffer, "             </div>\n");
+       add_data(&buffer, "             <div id=\"desc\">\n");
+       add_data(&buffer, "                     <div id=\"descinside\">\n");
+       add_data(&buffer, "                             <h1>");
+       add_data(&buffer, title);
+       add_data(&buffer, "</h1>\n");
+       add_data(&buffer, "                             <p>\n");
+       add_data(&buffer, desc);
+       add_data(&buffer, "                             </p>\n");
+       add_data(&buffer, "                     </div>\n");
+       add_data(&buffer, "                     <img id=\"logo\" src=\"");
+       add_data(&buffer, INSTANCE_LOGO);
+       add_data(&buffer, "\" height=\"128px\" alt=\"logo\">\n");
+       add_data(&buffer, "             </div>\n");
+       add_data(&buffer, "             <div id=\"content\">\n");
+       add_data(&buffer, "                     <div id=\"pageindex\">\n");
+       add_data(&buffer, "                             <h3>Page Menu</h3>\n");
+       add_data(&buffer, "                             <ul>\n");
+       add_data(&buffer, "                             </ul>\n");
+       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>\n");
+       add_data(&buffer, "             <div id=\"footer\">\n");
+       add_data(&buffer, "                     <div id=\"gotop\">\n");
+       add_data(&buffer, "                             <a href=\"#top\">Top</a>\n");
+       add_data(&buffer, "                     </div>\n");
+       add_data(&buffer, "                     <div id=\"copyright\">\n");
+       add_data(&buffer, "                             ");
+       escaped = escape(INSTANCE_ADMIN);
+       add_data(&buffer, escaped);
+       free(escaped);
+       add_data(&buffer, "\n");
+       add_data(&buffer, "                     </div>\n");
+       add_data(&buffer, "                     <div class=\"fixfloat\"></div>\n");
+       add_data(&buffer, "             </div>\n");
+       add_data(&buffer, "     </body>\n");
+       add_data(&buffer, "</html>\n");
+}
diff --git a/CGI/theme/optimized.c b/CGI/theme/optimized.c
new file mode 100644 (file)
index 0000000..c39e650
--- /dev/null
@@ -0,0 +1,7 @@
+/* $Id$ */
+
+extern char* buffer;
+void add_data(char** data, const char* txt);
+
+void render_page(void){
+}
diff --git a/CGI/util.c b/CGI/util.c
new file mode 100644 (file)
index 0000000..7e8d1b3
--- /dev/null
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+#include "rv_util.h"
+
+#include "../config.h"
+
+#include "rv_version.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char* rv_strcat(const char* a, const char* b){
+       char* str = malloc(strlen(a) + strlen(b) + 1);
+       memcpy(str, a, strlen(a));
+       memcpy(str + strlen(a), b, strlen(b));
+       str[strlen(a) + strlen(b)] = 0;
+       return str;
+}
+
+char* rv_strcat3(const char* a, const char* b, const char* c){
+       char* tmp = rv_strcat(a, b);
+       char* str = rv_strcat(tmp, c);
+       free(tmp);
+       return str;
+}
+
+char* rv_strdup(const char* str){
+       return rv_strcat(str, "");
+}
+
+void rv_error_http(void){
+       printf("Content-Type: text/plain\r\n");
+       printf("Status: 500 Internal Server Error\r\n");
+       printf("\r\n");
+       printf("This is RepoView version %s, named `%s`.\n", rv_get_version(), INSTANCE_NAME);
+       printf("Unrecoverable error has occured.\n");
+       printf("Admin contact: %s\n", INSTANCE_ADMIN);
+       printf("Developer contact: Nishi <nishi@nishi.boats>\n");
+       printf("-----\n");
+}
+
+int hex_to_num(char c){
+       if('0' <= c && c <= '9'){
+               return c - '0';
+       }else if('a' <= c && c <= 'f'){
+               return c - 'a' + 10;
+       }else if('A' <= c && c <= 'F'){
+               return c - 'A' + 10;
+       }
+       return 0;
+}
+
+char* rv_url_decode(const char* str){
+       char* r = malloc(1);
+       r[0] = 0;
+       int i;
+       char cbuf[2];
+       cbuf[1] = 0;
+       for(i = 0; str[i] != 0; i++){
+               if(str[i] == '%'){
+                       if(str[i + 1] == 0) break;
+                       if(str[i + 2] == 0) break;
+                       cbuf[0] = (hex_to_num(str[i + 1]) << 4) | hex_to_num(str[i + 2]);
+                       char* tmp = r;
+                       r = rv_strcat(tmp, cbuf);
+                       free(tmp);
+                       i += 2;
+               }else{
+                       cbuf[0] = str[i];
+                       char* tmp = r;
+                       r = rv_strcat(tmp, cbuf);
+                       free(tmp);
+               }
+       }
+       return r;
+}
diff --git a/CGI/version.c b/CGI/version.c
new file mode 100644 (file)
index 0000000..6359256
--- /dev/null
@@ -0,0 +1,9 @@
+/* $Id$ */
+
+#include "rv_version.h"
+
+const char* rv_version = "1.00";
+
+const char* rv_get_version(void){
+       return rv_version;
+}
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..c348819
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,27 @@
+# $Id$
+
+PWD = `pwd`
+PLATFORM = generic
+
+FLAGS = PWD=$(PWD) PLATFORM=$(PLATFORM) EXTOBJS="`./objs`" EXTLIBS="`./libs`"
+
+.PHONY: all clean ./CGI
+
+all: ./CGI
+
+./CGI:: check objs libs
+       $(MAKE) -C $@ $(FLAGS)
+
+objs:: objs.c check
+       cc -o $@ objs.c
+
+libs:: libs.c check
+       cc -o $@ libs.c
+
+check:: check.c config.h
+       cc -o $@ check.c
+       ./check
+
+clean:
+       $(MAKE) -C ./CGI clean $(FLAGS)
+       rm -f objs libs check
diff --git a/Platform/generic.mk b/Platform/generic.mk
new file mode 100644 (file)
index 0000000..c26df9c
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+CC = cc
+CFLAGS = -std=c99
+LDFLAGS =
+LIBS =
diff --git a/check.c b/check.c
new file mode 100644 (file)
index 0000000..d20cf23
--- /dev/null
+++ b/check.c
@@ -0,0 +1,89 @@
+/* $Id$ */
+
+#include "config.h"
+
+#include <stdio.h>
+
+int check_db(void){
+       int counter = 0;
+       const char* db = "";
+#ifdef USE_SQLITE
+       counter++;
+       db = "SQLite";
+#endif
+#ifdef USE_GDBM
+       counter++;
+       db = "GDBM";
+#endif
+#ifdef USE_NDBM
+       counter++;
+       db = "NDBM";
+#endif
+       if(counter > 1){
+               fprintf(stderr, "You cannot use multiple database types at once.\n");
+               return 1;
+       }else if(counter == 0){
+               fprintf(stderr, "You must select a database type.\n");
+               return 1;
+       }else{
+               printf("Database type is %s\n", db);
+       }
+       return 0;
+}
+
+int check_theme(void){
+       int counter = 0;
+       const char* theme = "";
+#ifdef USE_MODERN
+       counter++;
+       theme = "Modern";
+#endif
+#ifdef USE_OPTIMIZED
+       counter++;
+       theme = "Optimized";
+#endif
+       if(counter > 1){
+               fprintf(stderr, "You cannot use multiple themes at once.\n");
+               return 1;
+       }else if(counter == 0){
+               fprintf(stderr, "You must select a theme.\n");
+               return 1;
+       }else{
+               printf("Theme is %s\n", theme);
+       }
+       return 0;
+}
+
+int check_auth(void){
+       int counter = 0;
+       const char* method = "";
+#ifdef USE_COOKIE
+       counter++;
+       method = "Cookie";
+#endif
+       if(counter > 1){
+               fprintf(stderr, "You cannot use multiple authentication methods at once.\n");
+               return 1;
+       }else if(counter == 0){
+               fprintf(stderr, "You must select an authentication method.\n");
+               return 1;
+       }else{
+               printf("Authentication method is %s\n", method);
+       }
+       return 0;
+}
+
+int main(){
+       int st;
+       st = check_db();
+       if(st != 0) goto fail;
+       st = check_auth();
+       if(st != 0) goto fail;
+       st = check_theme();
+       if(st != 0) goto fail;
+       printf("Config validation successful.\n");
+       return 0;
+fail:
+       fprintf(stderr, "Config validation failure.\n");
+       return st;
+}
diff --git a/config.h.tmpl b/config.h.tmpl
new file mode 100644 (file)
index 0000000..7e1cf05
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * This is the config.h template.
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/* Your instance name. */
+#define INSTANCE_NAME  "Unnamed"
+
+/* Admin name/email. */
+#define INSTANCE_ADMIN "John Doe <john.doe@example.com>"
+
+/* Instance Root. */
+#define INSTANCE_ROOT  "/cgi-bin"
+
+/* Instance Logo. */
+#define INSTANCE_LOGO  "/logo.png"
+
+/* Theme. */
+#undef USE_OPTIMIZED
+#define USE_MODERN
+
+/* Database type. */
+#define USE_SQLITE
+#undef USE_GDBM
+#undef USE_NDBM
+
+/* Authentication type. */
+#define USE_COOKIE
+
+/* PATH, uses PATH from environment automatically if not defined. */
+#undef USE_PATH
+
+/* SVN filesystem root. */
+#define SVN_ROOT "/www/svn"
+
+/* Database root. */
+#define DB_ROOT "/www/db"
+
+/* Apache htpasswd file. */
+#define APACHE_PASSWD "/www/passwd"
+
+#endif
+
+/*
+vim: syntax=c
+*/
diff --git a/libs.c b/libs.c
new file mode 100644 (file)
index 0000000..e3ff25a
--- /dev/null
+++ b/libs.c
@@ -0,0 +1,15 @@
+/* $Id$ */
+
+#include "config.h"
+
+#include <stdio.h>
+
+int main(){
+#if defined(USE_SQLITE)
+       printf("-lsqlite3");
+#elif defined(USE_GDBM)
+       printf("-lgdbm -lgdbm_compat");
+#endif
+       printf("\n");
+       return 0;
+}
diff --git a/objs.c b/objs.c
new file mode 100644 (file)
index 0000000..1ac24ab
--- /dev/null
+++ b/objs.c
@@ -0,0 +1,23 @@
+#include "config.h"
+
+#include <stdio.h>
+
+int main(){
+#if defined(USE_SQLITE)
+       printf("db/sqlite.o");
+#elif defined(USE_GDBM) || defined(USE_NDBM)
+       printf("db/dbm.o");
+#endif
+       printf(" ");
+#if defined(USE_MODERN)
+       printf("theme/modern.o");
+#elif defined(USE_OPTIMIZED)
+       printf("theme/optimized.o");
+#endif
+       printf(" ");
+#if defined(USE_COOKIE)
+       printf("auth/cookie.o");
+#endif
+       printf("\n");
+       return 0;
+}