From d5bdb0a0c921f1786c7e0f3804834208fcab061c Mon Sep 17 00:00:00 2001 From: Nishi Date: Wed, 21 Aug 2024 12:31:40 +0000 Subject: [PATCH] add enscript git-svn-id: file:///raid/svn-personal/repoview/trunk@13 7e8b2a19-8934-dd40-8cb3-db22cdd5a80f --- CGI/db/dbm.c | 2 + CGI/db/sqlite.c | 16 +++++++ CGI/enscript.c | 105 ++++++++++++++++++++++++++++++++++++++++++ CGI/rv_db.h | 1 + CGI/rv_enscript.h | 8 ++++ CGI/sanity.c | 3 ++ CGI/theme/modern.c | 112 ++++++++++++++++++++++++++++++++++++++++++++- config.h.tmpl | 6 +++ objs.c | 4 ++ 9 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 CGI/enscript.c create mode 100644 CGI/rv_enscript.h diff --git a/CGI/db/dbm.c b/CGI/db/dbm.c index b39d3b0..efbf2a9 100644 --- a/CGI/db/dbm.c +++ b/CGI/db/dbm.c @@ -23,3 +23,5 @@ char* rv_who_has_token(const char* token) {} bool rv_has_token(const char* token) {} void rv_remove_token(const char* token) {} + +void rv_create_user(const char* username, const char* password) {} diff --git a/CGI/db/sqlite.c b/CGI/db/sqlite.c index 520b727..15fce17 100644 --- a/CGI/db/sqlite.c +++ b/CGI/db/sqlite.c @@ -111,6 +111,22 @@ bool rv_check_password(const char* username, const char* password) { return user.valid; } +void rv_create_user(const char* username, const char* password) { + char* err; + int ret; + char* sha512 = rv_sha512(password); + char* esc = escape_sql(username); + char* tmp = rv_strcat3("insert into users values('", esc, "', '"); + char* query = rv_strcat3(tmp, sha512, "')"); + free(sha512); + free(tmp); + free(esc); + ret = sqlite3_exec(sql, query, NULL, NULL, &err); + if(ret != SQLITE_OK) { + sqlite3_free(err); + } +} + void rv_save_token(const char* username, const char* token) { char* err; int ret; diff --git a/CGI/enscript.c b/CGI/enscript.c new file mode 100644 index 0000000..3f565a1 --- /dev/null +++ b/CGI/enscript.c @@ -0,0 +1,105 @@ +/* $Id$ */ + +#include "rv_enscript.h" + +#include "../config.h" + +#include "rv_util.h" +#include "rv_repo.h" + +#include +#include +#include +#include +#include + +char* rv_enscript(const char* repouser, const char* path, const char* lang) { + if(rv_get_filesize(repouser, path) > 1024 * 128) return NULL; + char* svnpath = rv_strcat3(SVN_ROOT, "/", repouser); + int spipes[2]; + pipe(spipes); + pid_t pid = fork(); + if(pid == 0) { + close(spipes[0]); + dup2(spipes[1], STDOUT_FILENO); + char* cmd[] = {"svnlook", "cat", svnpath, (char*)path, NULL}; + execvp("svnlook", cmd); + _exit(0); + } else { + close(spipes[1]); + int pipes[2]; + pipe(pipes); + pid_t epid = fork(); + if(epid == 0) { + close(pipes[0]); + dup2(spipes[0], STDIN_FILENO); + dup2(pipes[1], STDOUT_FILENO); + char* hl = rv_strcat("--highlight=", lang); + char* cmd[] = {"enscript", "-whtml", "--color", "-p", "-", hl, NULL}; + execvp("enscript", cmd); + _exit(0); + } + 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); + } + close(pipes[0]); + close(spipes[0]); + int status; + bool bad = false; + waitpid(pid, &status, 0); + if(WEXITSTATUS(status) != 0) { + free(d); + free(svnpath); + bad = true; + } + waitpid(epid, &status, 0); + if(WEXITSTATUS(status) != 0) { + if(!bad) { + free(d); + free(svnpath); + bad = true; + } + } + if(bad) return NULL; + free(svnpath); + if(strlen(d) == 0) { + free(d); + return NULL; + } + char* newdata = malloc(1); + newdata[0] = 0; + free(d); + int i; + int incr = 0; + bool log = false; + for(i = 0;; i++) { + if(d[i] == '\n' || d[i] == 0) { + char oldc = d[i]; + d[i] = 0; + + if(strcmp(d + incr, "
") == 0) {
+					log = true;
+				} else if(strcmp(d + incr, "
") == 0) { + log = false; + } else if(log) { + char* tmp = newdata; + newdata = rv_strcat3(tmp, d + incr, "\n"); + free(tmp); + } + + incr = i + 1; + if(oldc == 0) break; + } + } + return newdata; + } +} diff --git a/CGI/rv_db.h b/CGI/rv_db.h index 37a68a3..8eb933f 100644 --- a/CGI/rv_db.h +++ b/CGI/rv_db.h @@ -13,5 +13,6 @@ void rv_save_token(const char* username, const char* token); char* rv_who_has_token(const char* token); bool rv_has_token(const char* token); void rv_remove_token(const char* token); +void rv_create_user(const char* username, const char* password); #endif diff --git a/CGI/rv_enscript.h b/CGI/rv_enscript.h new file mode 100644 index 0000000..609b6b9 --- /dev/null +++ b/CGI/rv_enscript.h @@ -0,0 +1,8 @@ +/* $Id$ */ + +#ifndef __RV_ENSCRIPT_H__ +#define __RV_ENSCRIPT_H__ + +char* rv_enscript(const char* repouser, const char* path, const char* lang); + +#endif diff --git a/CGI/sanity.c b/CGI/sanity.c index 2be7a4b..79db11a 100644 --- a/CGI/sanity.c +++ b/CGI/sanity.c @@ -49,16 +49,19 @@ void rv_check_sanity(void) { bool svnlook = rv_find_executable("svnlook"); bool svnadmin = rv_find_executable("svnadmin"); bool htpasswd = rv_find_executable("htpasswd"); + bool enscript = rv_find_executable("enscript"); if(!svnlook) sane = false; if(!svnadmin) sane = false; if(!htpasswd) sane = false; + if(!enscript) 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"); + if(!enscript) printf("enscript not found\n"); exit(1); } } diff --git a/CGI/theme/modern.c b/CGI/theme/modern.c index 675b926..c27d77f 100644 --- a/CGI/theme/modern.c +++ b/CGI/theme/modern.c @@ -10,6 +10,10 @@ #include "../../config.h" +#ifdef USE_ENSCRIPT +#include "rv_enscript.h" +#endif + #include #include #include @@ -180,7 +184,7 @@ void list_files(const char* pathname) { add_data(&query, esc); free(esc); add_data(&query, "&path="); - char* urlpath = rv_strcat(path, pathname); + char* urlpath = rv_strcat3(path, "/", pathname); esc = url_escape(urlpath); add_data(&query, esc); free(esc); @@ -213,6 +217,77 @@ void render_page(void) { 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) { + 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."); @@ -245,7 +320,7 @@ void render_page(void) { if(user != NULL) { page = rv_strdup("It looks like you are already logged in.
Want to log out?\n"); + add_data(&page, "/?page=logout\">log out?\n"); } else if(rv_get_query("username") == NULL || rv_get_query("password") == NULL) { add_data(&page, "Invalid form.\n"); } else { @@ -423,6 +498,31 @@ void render_page(void) { 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);
    @@ -432,6 +532,7 @@ void render_page(void) {
     					} else {
     						add_data(&page, "Cannot open the file.\n");
     					}
    +#endif
     					add_data(&page, "
    "); } } else { @@ -613,6 +714,13 @@ void render_stuff(void) { add_data(&buffer, INSTANCE_ROOT); add_data(&buffer, "/?page=login\">Login\n"); add_data(&buffer, " \n"); +#ifdef ALLOW_SIGNUP + add_data(&buffer, "
    \n"); + add_data(&buffer, " Signup\n"); + add_data(&buffer, "
    \n"); +#endif } else { add_data(&buffer, "
    \n"); add_data(&buffer, "