so://phie

soso

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>

5

6#define TPEE_IMPL

7#include <tpee.h>

8#define TPEE_EXT_IMPL

9#include <tpee_ext.h>

10#define BUF_IMPL

11#include <buf.h>

12#define ORB_IMPL

13#include <orb.h>

14#define UTIL_IMPL

15#include "util.h" // IWYU pragma: keep

16

17#define SOSO_PORT "SOSO_PORT"

18

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"

24

25TPEE_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}

40

41TPEE_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}

58

59TPEE_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}

120

121// #include "registry.h"

122

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 = &REGISTRY[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// }

165

166TPEE_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}

175

176TPEE_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}

191

192void on_signal(int signal) {

193 (void) signal;

194 // do nothing

195}

196

197void 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}

204

205int 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}