#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include static sqlite3 *db = NULL; static sqlite3_stmt *stmt = NULL; static void cleanup(void) { if (stmt) { sqlite3_finalize(stmt); } if (db) { sqlite3_close(db); } } int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: %s /path/to/data.db\n", argv[0]); return 64; } atexit(cleanup); int r; if ((r = sqlite3_open_v2(argv[1], &db, SQLITE_OPEN_READONLY, NULL)) != SQLITE_OK) { fprintf(stderr, "Cannot open database: %s\n", sqlite3_errstr(r)); return r; } if ((r = sqlite3_prepare(db, "SELECT title,title_zh,text,text_zh FROM v_random_quote", -1, &stmt, NULL)) != SQLITE_OK) { fprintf(stderr, "Cannot prepare statement: %s\n", sqlite3_errstr(r)); return r; } FCGX_Stream *in, *out, *err; FCGX_ParamArray envp; while(FCGX_Accept(&in, &out, &err, &envp) >= 0) { const char *url = FCGX_GetParam("REQUEST_URI", envp); switch (r = sqlite3_step(stmt)) { case SQLITE_DONE: FCGX_FPrintF(out, "Status: 500 Internal Server Error\r\n" "Content-type: text/plain\r\n" "\r\n" "No data is available.\n"); break; case SQLITE_BUSY: case SQLITE_MISUSE: case SQLITE_ERROR: fprintf(stderr, "Cannot query: %d\n", r); FCGX_FPrintF(out, "Status: 500 Internal Server Error\r\n" "Content-type: text/plain\r\n" "\r\n" "%s\n", sqlite3_errstr(r)); break; case SQLITE_ROW: char *title = (char *) sqlite3_column_text(stmt, 0); char *title_zh = (char *) sqlite3_column_text(stmt, 1); char *text = (char *) sqlite3_column_text(stmt, 2); char *text_zh = (char *) sqlite3_column_text(stmt, 3); if (!strncmp(url, "/hitokoto.css", 13)) { FCGX_FPrintF(out, "Content-Type: text/css; charset=utf-8\r\n" "\r\n" "#hitokoto::before { content: \"%s\" }\n" "#hitokoto::after { content: \"%s\" }\n" "#hitokoto_zh::before { content: \"%s\" }\n" "#hitokoto_zh::after { content: \"%s\" }\n", text, title, text_zh ? text_zh : "", title_zh ? title_zh : ""); } else { FCGX_FPrintF(out, "Content-type: application/json; charset=utf-8\r\n" "\r\n" "{\"title\":\"%s\",\"title_zh\":\"%s\",\"text\":\"%s\",\"text_zh\":\"%s\"}\n", title, title_zh ? title_zh : "", text, text_zh ? text_zh : ""); } break; } if ((r = sqlite3_reset(stmt))) { fprintf(stderr, "sqlite3_reset: %d\n", r); } } }