timekeeper

My first (abandoned unfinished) web application for time tracking
git clone git://jacobedwards.org/timekeeper
Log | Files | Refs | README

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 }