server: handle pcre2 now returning -1 for "no match"
[rb-79.git] / rb79.h
blob209d9818b8a7084dff1239a4838e75a903d554ca
1 /*
2 * Copyright (c) 2017-2018, De Rais <derais@cock.li>
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Defines what's needed to identifiy a board['s folder] */
20 struct board {
21 /* Short name, like "a" or "b" */
22 const char *name;
24 /* Like "Anime" or "Random" */
25 const char *title;
27 /* Cooldown after you post text */
28 int text_cooldown;
30 /* Cooldown after you post textless */
31 int blank_cooldown;
33 /* How many threads are on each page */
34 unsigned int threads_per_page;
36 /* How many pages total */
37 unsigned int num_pages;
39 /* Whether posts here show up in /recent */
40 unsigned int appears_in_recent;
43 /* Things users can try to do */
44 enum action_t { NONE, REPLY, NEWTHREAD, REBUILD };
47 * A post as it will be stored in (or retrieved from) the database.
48 * As part of post_cmd, this will be built up by rb79.c, inserted
49 * into the db by db_insert_post, and retrieved for writing to
50 * filesystem in write-thread.c
52 struct prepared_post {
53 /* When it was issued */
54 time_t now;
57 * This requires db access to retrieve, so it may be 0 for
58 * most of the object's life
60 uintmax_t id;
62 /* Flags, in case this is the OP of a thread */
63 uint_fast8_t thread_closed;
64 uint_fast8_t thread_stickied;
66 /* HTML-esc'd, ready for inserting into pages */
67 char *name;
68 size_t name_len;
69 char *email;
70 size_t email_len;
71 char *tripcode;
72 size_t tripcode_len;
73 char *subject;
74 size_t subject_len;
75 char *comment;
76 size_t comment_len;
78 /* Comes from a struct filetype. A copy, needs to be freed */
79 char *ext;
80 size_t ext_len;
82 /* The name the uploader called the file (HTML-esc'd) */
83 char *file_name;
84 size_t file_name_len;
86 /* The path for the full file, like /m/src/123.jpg */
87 char *system_full_path;
88 size_t system_full_path_len;
90 /* The path for the thumbnail, like /m/src/123s.jpg */
91 char *system_thumb_path;
92 size_t system_thumb_path_len;
94 /* A string like "image/jpeg, 30KiB, 500x399" */
95 char *file_info;
96 size_t file_info_len;
98 /* The main server ignores this, but mod tools use it */
99 char *ip;
100 size_t ip_len;
102 struct post_cmd {
104 * Strings are filled in by multipart.c, where we are quite
105 * thankful that everything is guaranteed to be UTF-8.
106 * Parsing, if needed, is done by rb79.c
108 struct {
109 /* 0-terminated and normalized */
110 char *ip;
112 /* action= */
113 char *action;
114 size_t action_len;
116 /* board= */
117 char *board;
118 size_t board_len;
120 /* thread= */
121 char *thread;
122 size_t thread_len;
124 /* post= */
125 char *post;
126 size_t post_len;
128 /* name= */
129 char *name;
130 size_t name_len;
132 /* email= */
133 char *email;
134 size_t email_len;
136 /* tripcode - calculated from email */
137 char *tripcode;
138 size_t tripcode_len;
140 /* subject= */
141 char *subject;
142 size_t subject_len;
144 /* comment= */
145 char *comment;
146 size_t comment_len;
148 /* file upload */
149 char *file_name;
150 size_t file_name_len;
151 char *file_contents;
152 size_t file_contents_len;
154 /* challengeid= */
155 char *challenge_id;
156 size_t challenge_id_len;
158 /* challengeresponse= */
159 char *challenge_response;
160 size_t challenge_response_len;
161 } raw;
164 * Everything below is filled in by rb79.c as derived data
166 enum action_t action_id;
167 uintmax_t board_idx;
168 uintmax_t thread_id;
170 /* This is what goes into the database. */
171 struct prepared_post prepared;
174 * The following is intermediate data for sanitizing input
175 * comments. XXX: figure out if these can be safely removed
176 * from this object, because they're sort of messy.
179 /* A sort of normalized UTF-8 comment */
180 char *scannable_comment;
181 size_t scannable_comment_len;
182 size_t *comment_position_map;
183 size_t comment_position_map_len;
184 char *scannable_name;
185 size_t scannable_name_len;
186 size_t *name_position_map;
187 size_t name_position_map_len;
188 char *scannable_email;
189 size_t scannable_email_len;
190 size_t *email_position_map;
191 size_t email_position_map_len;
192 char *scannable_subject;
193 size_t scannable_subject_len;
194 size_t *subject_position_map;
195 size_t subject_position_map_len;
196 char *scannable_filename;
197 size_t scannable_filename_len;
198 size_t *filename_position_map;
199 size_t filename_position_map_len;
202 /* Filetype/thumbnailing options */
203 struct filetype {
204 /* */
205 const char *mime_type;
206 const char *ext;
207 const char *install_command;
208 const char *thumb_creation_command;
209 const char *static_thumbnail;
213 #define NUM_CHALLENGE_ANSWERS 5
215 /* wakarimasen-style CAPTCHA */
216 struct challenge {
217 /* */
218 const char *question;
219 const char *answers[NUM_CHALLENGE_ANSWERS];
222 /* regex-backed wordfilter */
223 struct wordfilter_input {
224 /* */
225 const char *pattern;
226 const char *replacement;
229 /* regex-backed forbidden input */
230 struct forbidden_input {
231 /* */
232 const char *pattern;
233 int ban_duration;
234 const char *ban_reason;
237 /* See config.def.h for detailed descriptions. */
238 struct configuration {
239 /* */
240 const char *static_www_folder;
241 const char *work_path;
242 const char *temp_dir_template;
243 const char *trip_salt;
244 size_t trip_salt_len;
245 const struct board *boards;
246 size_t boards_num;
247 size_t max_form_data_size;
248 size_t max_file_size;
249 size_t max_text_len;
250 const struct filetype *filetypes;
251 size_t filetypes_num;
252 const char *file_description_prog;
253 const char **headers;
254 size_t headers_num;
255 const struct challenge *challenges;
256 size_t challenges_num;
257 const struct wordfilter_input *wordfilter_inputs;
258 size_t wordfilter_inputs_num;
259 const struct forbidden_input *forbidden_inputs;
260 size_t forbidden_inputs_num;
263 /* db_writeback_ZZZ takes a callback. */
264 typedef int (*post_writeback)(struct prepared_post *p, FILE *f, uint_fast8_t
265 is_op, uint_fast8_t is_summary, uint_fast8_t
266 is_recent, const char *board_name,
267 uintmax_t in_thread, uintmax_t
268 total_posts_in_thread, uint_fast8_t hr_before);
270 /* db-ZZZ.c (currently only sqlite3, but it used to be MySQL) */
271 int setup_dbs(const struct configuration *conf);
273 int db_construct_post_link(const char *board, size_t board_len, const
274 char *post, size_t post_len, int *found, char **out,
275 size_t *out_len);
277 int db_cull_threads(size_t board_idx, size_t *out_num_pages);
279 int db_check_bans(const char *ip, size_t board_idx, time_t now,
280 int *out_is_banned, char **out_ban_until, int *out_is_secret,
281 char **out_ban_reason);
283 int db_check_cooldowns(const char *ip, size_t board_idx, time_t now,
284 int *out_is_cooled, char **out_cooldown_length);
286 int db_cull_and_report_threads(size_t board_idx, uintmax_t **out_thread_ids,
287 size_t *out_thread_id_num,
288 size_t *out_num_pages);
290 int db_extract_subject(size_t board_idx, uintmax_t thread, char **out_subject,
291 size_t *out_subject_len);
293 int db_insert_ban(uint_fast8_t global_ban, size_t board_idx, const
294 char *first_ip, const char *last_ip, const char *message,
295 uint_fast8_t
296 is_secret, time_t ban_start, time_t ban_expiry);
298 int db_insert_post(const char *ip, size_t in_thread, int cooldown, struct
299 post_cmd *pc, int *thread_dne, int *thread_closed,
300 int *thread_full,
301 uintmax_t *post_id);
303 int db_is_op(size_t board_idx, uintmax_t post_id, uint_fast8_t *out_is_op);
305 int db_moderate_post(size_t board_idx, uintmax_t post_id, const
306 char *moderator_comment, uint_fast8_t change_sticky,
307 uint_fast8_t sticky_status,
308 uint_fast8_t change_close, uint_fast8_t close_status);
310 int db_remove_thread_and_files(size_t board_idx, uintmax_t thread_id);
312 int db_remove_post_and_files(size_t board_idx, uintmax_t thread_id);
314 int db_update_file_info(size_t board_idx, uintmax_t post_id, const char *info,
315 size_t info_len, const char *system_full_path, size_t
316 system_full_path_len,
317 const char *system_thumb_path, size_t
318 system_thumb_path_len);
320 int db_writeback_posts_in_thread(size_t board_idx, uintmax_t thread, FILE *f,
321 post_writeback pw_function);
323 int db_writeback_recent_posts(FILE *f, post_writeback pw_function);
325 int db_writeback_thread_summaries(size_t board_idx, uintmax_t *thread_ids,
326 size_t thread_ids_num, FILE *f);
328 int clean_dbs(void);
330 /* locks.c */
331 int setup_locks(const struct configuration *conf);
333 int lock_acquire(size_t board_idx);
335 int lock_acquire_recent(void);
337 int lock_release(size_t board_idx);
339 int lock_release_recent(void);
341 int clean_locks(void);
343 /* multipart.c */
344 int setup_multipart(void);
346 int multipart_decompose(const char *full_data, size_t full_data_len, struct
347 post_cmd *post_cmd);
349 int clean_multipart(void);
351 /* preconditions.c */
352 int preconditions_check(const struct configuration *conf);
354 /* sanitize-comment.c */
355 int setup_sanitize_comment(const struct configuration *conf);
357 int st_sanitize_text(struct post_cmd *pc, int *our_fault,
358 uint_fast8_t *is_forbidden, int *ban_duration, const
359 char **ban_reason);
361 int clean_sanitize_comment(void);
363 /* sanitize-file.c */
364 int setup_sanitize_file(const struct configuration *conf);
366 int sf_check_mime_type(const char *buf, size_t len, const struct
367 filetype **out_filetype);
369 int sf_describe_file(const char *mimetype, const char *filepath,
370 char **out_description, size_t *out_len);
372 int sf_install_files(size_t board_idx, const char *buf, size_t len, time_t *now,
373 const struct filetype *filetype, char **out_abs_path,
374 char **out_path,
375 size_t *out_path_len, char **out_thumb_path,
376 size_t *out_thumb_path_len,
377 int *our_fault);
379 int clean_sanitize_file(void);
381 /* tripcodes.c */
382 int setup_tripcodes(const struct configuration *conf);
384 int tripcodes_calculate(struct post_cmd *p);
386 int clean_tripcodes(void);
388 /* util.c */
389 char * util_iso8601_from_time_t(time_t t);
391 int util_normalize_ip(const char *in, char **out);
393 int util_rebuild(struct configuration *conf);
395 /* write-thread.c */
396 int setup_write_thread(const struct configuration *conf);
398 int wt_remove_files(const char *system_full_path, size_t system_full_path_len,
399 const char *system_thumb_path, size_t
400 system_thumb_path_len);
402 int wt_remove_thread_page(size_t board_idx, uintmax_t thread_id);
404 int wt_write_board(size_t board_idx, uintmax_t *thread_ids, size_t
405 thread_ids_num, size_t board_pages_num);
407 int wt_write_post(struct prepared_post *p, FILE *f, uint_fast8_t is_op,
408 uint_fast8_t is_summary, uint_fast8_t is_recent, const
409 char *board_name,
410 uintmax_t in_thread, uintmax_t total_posts_in_thread,
411 uint_fast8_t hr_before);
413 int wt_write_recent_page(void);
415 int wt_write_thread(size_t board_idx, uintmax_t thread);
417 void clean_write_thread(void);