timekeeper.c (2347B)
1 #include <assert.h> 2 3 #define const 4 5 #include <err.h> 6 #include <limits.h> 7 #include <stdio.h> 8 #include <unistd.h> 9 #include <string.h> 10 11 #include <sqlbox.h> 12 13 #include "config.h" 14 15 #include "pages/common.h" 16 #include "pages/pages.h" 17 #include "stmt.h" 18 #include "util.h" 19 20 #define Promises "stdio rpath wpath cpath proc recvfd unix sendfd" 21 22 static char *pages[] = { 23 [PageIndex] = "index", 24 [PageLogin] = "login", 25 [PageLogout] = "logout", 26 [PageAccount] = "account", 27 [PageMain] = "times", 28 [PageExport] = "export", 29 [PageArchive] = "archive", 30 [PageAbout] = "about" 31 }; 32 33 int 34 initdb(struct pagedata *pd) 35 { 36 enum StmtID i; 37 38 for (i = StmtInit0; i <= StmtInitLast; ++i) 39 if (sqlbox_exec(pd->db, pd->dbid, i, 0, NULL, 0) != SQLBOX_CODE_OK) 40 return 1; 41 return 0; 42 } 43 44 int 45 main(void) 46 { 47 enum kcgi_err status; 48 struct kfcgi *fcgi; 49 struct pagedata pd = { 50 .keys = keys, 51 .pages = pages, 52 .pagesz = Len(pages) 53 }; 54 struct sqlbox_cfg cfg; 55 struct sqlbox_src srcs[] = { 56 { .fname = DataDir "/timekeeper.db", .mode = SQLBOX_SRC_RWC } 57 }; 58 enum kcgi_err (*pagefunctions[])(struct pagedata *) = { 59 [PageIndex] = pageindex, 60 [PageLogin] = pagelogin, 61 [PageLogout] = pagelogout, 62 [PageAccount] = pageaccount, 63 [PageMain] = pagemain, 64 [PageExport] = pageexport, 65 [PageArchive] = pagearchive, 66 [PageAbout] = pagefrag 67 }; 68 69 if (unveil(DataDir, "rwc") || unveil(NULL, NULL)) 70 kutil_err(NULL, NULL, "unveil"); 71 72 memset(&cfg, 0, sizeof(cfg)); 73 cfg.msg.func_short = warnx; 74 cfg.srcs.srcsz = 1; 75 cfg.srcs.srcs = srcs; 76 cfg.stmts.stmtsz = StmtMax; 77 cfg.stmts.stmts = pstmts; 78 79 if ((pd.db = sqlbox_alloc(&cfg)) == NULL) 80 kutil_err(NULL, NULL, "Unable to alloc database"); 81 if (!(pd.dbid = sqlbox_open(pd.db, 0))) 82 kutil_err(NULL, NULL, "Unable to open database"); 83 84 if (khttp_fcgi_init(&fcgi, pd.keys, KeyMax, pages, PageMax, 0) != KCGI_OK) 85 kutil_err(NULL, NULL, "Unable to initialize fcgi"); 86 87 if (pledge(Promises, Promises)) 88 kutil_err(NULL, NULL, "pledge"); 89 90 if (initdb(&pd)) 91 err(1, "Unable to setup database"); 92 93 status = KCGI_OK; 94 while ((status = loadpagerequest(fcgi, &pd)) == KCGI_OK) { 95 /* Ignore return value */ 96 showpage(&pd, pages, pagefunctions, Len(pages), 97 tk_errorpage); 98 freepagerequest(&pd); 99 } 100 101 sqlbox_free(pd.db); 102 khttp_fcgi_free(fcgi); 103 if (status != KCGI_EXIT) 104 kutil_err(NULL, NULL, "Unable to parse request"); 105 return 0; 106 }