My pretty neat website
git clone git://soophie.de/soso
blob: a6038646e61a385f56be5971aa96d59987310556 (7781 bytes)[raw]
1
#include <unistd.h>2
#include <signal.h>3
#include <execinfo.h>4
#include <git2.h>6
#define TPEE_IMPL7
#include <tpee.h>8
#define TPEE_EXT_IMPL9
#include <tpee_ext.h>10
#define BUF_IMPL11
#include <buf.h>12
#define ORB_IMPL13
#include <orb.h>14
#define UTIL_IMPL15
#include "util.h" // IWYU pragma: keep17
#define SOSO_PORT "SOSO_PORT"19
#include "module/page.h"20
#include "module/default.h"21
#include "module/index.h"22
#include "module/git_list.h"23
#include "module/git_repo.h"25
TPEE_GET("/", index_page) {26
(void) req;27
buf_t out = BUF_NULL;28
orb_ctx_t ctx = orb_ctx_create(&out);29
orb_module_t index_module = orb_module_create(&INDEX_TYPE, NULL);30
orb_module_t page_module = orb_module_create(&PAGE_TYPE, &((page_param_list_t) {31
.title = "Index",32
.module = &index_module,33
}));34
orb_module_run(&page_module, &ctx);35
tpee_resp_t resp = tpee_resp_create(TPEE_STATUS_OK);36
tpee_resp_body(&resp, (char *) out.bytes, out.len);37
buf_free(&out);38
return resp;39
}41
TPEE_GET("/git", git_list_page) {42
(void) req;43
buf_t out = BUF_NULL;44
orb_ctx_t ctx = orb_ctx_create(&out);45
orb_module_t git_list_module = orb_module_create(&GIT_LIST_TYPE, &((git_list_param_list_t) {46
.path = "/home/git",47
}));48
orb_module_t page_module = orb_module_create(&PAGE_TYPE, &((page_param_list_t) {49
.title = "Index",50
.module = &git_list_module,51
}));52
orb_module_run(&page_module, &ctx);53
tpee_resp_t resp = tpee_resp_create(TPEE_STATUS_OK);54
tpee_resp_body(&resp, (char *) out.bytes, out.len);55
buf_free(&out);56
return resp;57
}59
TPEE_GET("/git/*", git_repo_page) {60
char *repo_name = tpee_ext_get_path_var(req->url, "/git/{repo_name}", "repo_name");61
if (!repo_name) return tpee_resp_create(TPEE_STATUS_NOT_FOUND);62
char *tab_mode = NULL;63
if (tpee_ext_is_path_match(req->url, "/git/{repo_name}/{tab_mode}")) {64
tab_mode = tpee_ext_get_path_var(req->url, "/git/{repo_name}/{tab_mode}", "tab_mode");65
}66
if (!tab_mode) {67
tab_mode = strdup("log");68
}69
const char *tab_mode_list[] = { "log", "tree", "refs", "commit", "blob", "raw" };70
size_t tab_mode_list_len = sizeof(tab_mode_list) / sizeof(tab_mode_list[0]);71
bool is_tab_mode_valid = false;72
for (size_t i = 0; i < tab_mode_list_len; i++) {73
if (strcmp(tab_mode, tab_mode_list[i]) == 0) {74
is_tab_mode_valid = true;75
break;76
}77
}78
if (!is_tab_mode_valid) {79
return tpee_resp_create(TPEE_STATUS_NOT_FOUND);80
}81
const char *git_base_path = "/home/git/";82
size_t repo_path_len = strlen(git_base_path) + strlen(repo_name) + 1;83
char repo_path[repo_path_len];84
snprintf(repo_path, repo_path_len, "%s%s", git_base_path, repo_name);85
tpee_pairs_t query_list = tpee_req_queries(req);86
buf_t out = BUF_NULL;87
orb_ctx_t ctx = orb_ctx_create(&out);88
orb_module_t git_repo_module = orb_module_create(&GIT_REPO_TYPE, &((git_repo_param_list_t) {89
.repo_name = repo_name,90
.repo_path = repo_path,91
.tab_mode = tab_mode,92
.flag_ref_oid = tpee_pairs_get(&query_list, "ref"),93
.flag_oid = tpee_pairs_get(&query_list, "oid"),94
.flag_path = tpee_pairs_get(&query_list, "path"),95
}));96
orb_module_t page_module = orb_module_create(&PAGE_TYPE, &((page_param_list_t) {97
.title = repo_name,98
.module = &git_repo_module,99
}));100
orb_module_t *module = &page_module;101
if (strcmp(tab_mode, "raw") == 0) {102
module = &git_repo_module;103
}104
orb_module_run(module, &ctx);105
tpee_pairs_free(&query_list);106
if (tab_mode) {107
free(tab_mode);108
}109
free(repo_name);110
if (ctx.rc.is_fatal) {111
tpee_resp_t resp = tpee_resp_create(TPEE_STATUS_NOT_FOUND);112
buf_free(&out);113
return resp;114
}115
tpee_resp_t resp = tpee_resp_create(TPEE_STATUS_OK);116
tpee_resp_body(&resp, (char *) out.bytes, out.len);117
buf_free(&out);118
return resp;119
}121
// #include "registry.h"123
// TPEE_GET("/orb/module/*", orb_module_serve) {124
// char *module_id = tpee_ext_get_path_var(req->url, "/orb/module/{module_id}", "module_id");125
// tpee_resp_t resp = tpee_resp_create(TPEE_STATUS_NOT_FOUND);126
// if (module_id) {127
// const orb_module_type_t *module_type = NULL;128
// for (size_t i = 0; i < REGISTRY_LEN; i++) {129
// const registry_entry_t *entry = ®ISTRY[i];130
// if (strcmp(module_id, entry->id) == 0) {131
// module_type = entry->type;132
// break;133
// }134
// }135
// if (module_type) {136
// buf_t out = BUF_NULL;137
// orb_ctx_t ctx = orb_ctx_create(&out);138
// void *param_list = NULL;139
// tpee_pairs_t query_list = tpee_req_queries(req);140
// if (module_type == &INDEX_TYPE) {141
// param_list = calloc(1, sizeof(index_param_list_t));142
// index_param_list_t *index_param_list = param_list;143
// index_param_list->title = tpee_pairs_get(&query_list, "title");144
// }145
// if (module_type == &ABOUT_TYPE) {146
// param_list = calloc(1, sizeof(about_param_list_t));147
// about_param_list_t *about_param_list = param_list;148
// about_param_list->headline = tpee_pairs_get(&query_list, "headline");149
// about_param_list->subline = tpee_pairs_get(&query_list, "subline");150
// }151
// orb_module_t module = orb_module_create(module_type, param_list);152
// orb_module_run(&module, &ctx);153
// tpee_pairs_free(&query_list);154
// if (param_list) {155
// free(param_list);156
// }157
// resp.status = TPEE_STATUS_OK;158
// tpee_resp_body(&resp, (char *) out.bytes, out.len);159
// buf_free(&out);160
// }161
// free(module_id);162
// }163
// return resp;164
// }166
TPEE_GET("/asset/*", asset_serve) {167
const char *prefix = "/asset/";168
const char *filepath = "./asset/";169
size_t filename_len = strlen(filepath) + strlen(req->url) - strlen(prefix) + 1;170
char filename[filename_len];171
snprintf(filename, filename_len, "%s%s", filepath, req->url + strlen(prefix));172
tpee_resp_t resp = tpee_ext_serve_file(filename);173
return resp;174
}176
TPEE_DEFAULT(default_page) {177
(void) req;178
buf_t out = BUF_NULL;179
orb_ctx_t ctx = orb_ctx_create(&out);180
orb_module_t default_module = orb_module_create(&DEFAULT_TYPE, NULL);181
orb_module_t page_module = orb_module_create(&PAGE_TYPE, &((page_param_list_t) {182
.title = "404",183
.module = &default_module,184
}));185
orb_module_run(&page_module, &ctx);186
tpee_resp_t resp = tpee_resp_create(TPEE_STATUS_OK);187
tpee_resp_body(&resp, (char *) out.bytes, out.len);188
buf_free(&out);189
return resp;190
}192
void on_signal(int signal) {193
(void) signal;194
// do nothing195
}197
void on_segfault(int signal) {198
void *list[10];199
size_t size = backtrace(list, 10);200
fprintf(stderr, "ERROR: signal %d:\n", signal);201
backtrace_symbols_fd(list, size, STDOUT_FILENO);202
exit(1);203
}205
int main(void) {206
struct sigaction action;207
action.sa_handler = on_signal;208
action.sa_flags = 0;209
sigemptyset(&action.sa_mask);210
sigaction(SIGINT, &action, NULL);211
struct sigaction sigint_action;212
sigint_action.sa_handler = on_segfault;213
sigint_action.sa_flags = 0;214
sigemptyset(&sigint_action.sa_mask);215
sigaction(SIGSEGV, &sigint_action, NULL);216
char *port_str = getenv(SOSO_PORT);217
if (!port_str) {218
printf("no port specified! set environment variable SOSO_PORT.\n");219
return 1;220
}221
char *end = NULL;222
int port = strtoimax(port_str, &end, 10);223
if (end == port_str || *end != '\0') {224
printf("invalid port specified! set environment variable SOSO_PORT.\n");225
return 1;226
}227
tpee_t *tpee = tpee_init();228
if (tpee_bind(tpee, "0.0.0.0", port, NULL, 0) != TPEE_ERR_OK) {229
printf("failed to bind port!\n");230
return 1;231
}232
git_libgit2_init();233
git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);234
if (tpee_listen(tpee) == TPEE_ERR_OK) {235
printf("ready and listening (pid: %d, port: %d)\n", getpid(), port);236
pause();237
}238
git_libgit2_shutdown();239
printf("stopped\n");240
tpee_close(tpee);241
tpee_cleanup(tpee);242
return 0;243
}