Blob


1 /*
2 * This file is in the public domain.
3 */
5 #define FD_RESERVE 5
6 #define QUERY_MAXLEN 1025 /* including NUL */
8 struct bufferevent;
9 struct event;
10 struct fcgi;
11 struct sqlite3;
12 struct sqlite3_stmt;
13 struct template;
15 enum {
16 METHOD_UNKNOWN,
17 METHOD_GET,
18 METHOD_POST,
19 };
21 #define ATTR_PRINTF(A, B) __attribute__((__format__ (printf, A, B)))
23 struct logger {
24 __dead void (*fatal)(int, const char *, ...) ATTR_PRINTF(2, 3);
25 __dead void (*fatalx)(int, const char *, ...) ATTR_PRINTF(2, 3);
26 void (*warn)(const char *, ...) ATTR_PRINTF(1, 2);
27 void (*warnx)(const char *, ...) ATTR_PRINTF(1, 2);
28 void (*info)(const char *, ...) ATTR_PRINTF(1, 2);
29 void (*debug)(const char *, ...) ATTR_PRINTF(1, 2);
30 };
32 extern const struct logger *logger;
33 #define fatal(...) logger->fatal(1, __VA_ARGS__)
34 #define fatalx(...) logger->fatalx(1, __VA_ARGS__)
35 #define log_warn(...) logger->warn(__VA_ARGS__)
36 #define log_warnx(...) logger->warnx(__VA_ARGS__)
37 #define log_info(...) logger->info(__VA_ARGS__)
38 #define log_debug(...) logger->debug(__VA_ARGS__)
40 #ifdef DEBUG
41 #define DPRINTF log_debug
42 #else
43 #define DPRINTF(...) do {} while (0)
44 #endif
46 struct client {
47 uint32_t clt_id;
48 int clt_fd;
49 struct fcgi *clt_fcgi;
50 char *clt_server_name;
51 char *clt_script_name;
52 char *clt_path_info;
53 char *clt_query;
54 int clt_method;
55 char clt_buf[1024];
56 size_t clt_buflen;
58 SPLAY_ENTRY(client) clt_nodes;
59 };
60 SPLAY_HEAD(client_tree, client);
62 struct fcgi {
63 uint32_t fcg_id;
64 int fcg_s;
65 struct client_tree fcg_clients;
66 struct bufferevent *fcg_bev;
67 int fcg_toread;
68 int fcg_want;
69 int fcg_padding;
70 int fcg_type;
71 int fcg_rec_id;
72 int fcg_keep_conn;
73 int fcg_done;
75 struct env *fcg_env;
77 SPLAY_ENTRY(fcgi) fcg_nodes;
78 };
79 SPLAY_HEAD(fcgi_tree, fcgi);
81 struct env {
82 int env_sockfd;
83 struct event env_sockev;
84 struct event env_pausev;
85 struct fcgi_tree env_fcgi_socks;
87 struct sqlite3 *env_db;
88 struct sqlite3_stmt *env_query;
89 };
91 /* fcgi.c */
92 int fcgi_end_request(struct client *, int);
93 int fcgi_abort_request(struct client *);
94 void fcgi_accept(int, short, void *);
95 void fcgi_read(struct bufferevent *, void *);
96 void fcgi_write(struct bufferevent *, void *);
97 void fcgi_error(struct bufferevent *, short, void *);
98 void fcgi_free(struct fcgi *);
99 int clt_putc(struct client *, char);
100 int clt_puts(struct client *, const char *);
101 int clt_putsan(struct client *, const char *);
102 int clt_write_bufferevent(struct client *, struct bufferevent *);
103 int clt_flush(struct client *);
104 int clt_write(struct client *, const uint8_t *, size_t);
105 int clt_printf(struct client *, const char *, ...)
106 __attribute__((__format__(printf, 2, 3)))
107 __attribute__((__nonnull__(2)));
108 int fcgi_cmp(struct fcgi *, struct fcgi *);
109 int fcgi_client_cmp(struct client *, struct client *);
111 /* msearchd.c */
112 extern const char *tmpl_head;
113 extern const char *tmpl_search;
114 extern const char *tmpl_search_header;
115 extern const char *tmpl_foot;
117 /* server.c */
118 int server_main(const char *);
119 int server_handle(struct env *, struct client *);
120 void server_client_free(struct client *);
122 SPLAY_PROTOTYPE(client_tree, client, clt_nodes, fcgi_client_cmp);
123 SPLAY_PROTOTYPE(fcgi_tree, fcgi, fcg_nodes, fcgi_cmp);