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
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] */
21 /* Short name, like "a" or "b" */
24 /* Like "Anime" or "Random" */
27 /* Cooldown after you post text */
30 /* Cooldown after you post textless */
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 */
57 * This requires db access to retrieve, so it may be 0 for
58 * most of the object's life
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 */
78 /* Comes from a struct filetype. A copy, needs to be freed */
82 /* The name the uploader called the file (HTML-esc'd) */
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" */
98 /* The main server ignores this, but mod tools use it */
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
109 /* 0-terminated and normalized */
136 /* tripcode - calculated from email */
150 size_t file_name_len
;
152 size_t file_contents_len
;
156 size_t challenge_id_len
;
158 /* challengeresponse= */
159 char *challenge_response
;
160 size_t challenge_response_len
;
164 * Everything below is filled in by rb79.c as derived data
166 enum action_t action_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
;
198 /* Filetype/thumbnailing options */
201 const char *mime_type
;
203 const char *install_command
;
204 const char *thumb_creation_command
;
205 const char *static_thumbnail
;
209 #define NUM_CHALLENGE_ANSWERS 5
211 /* wakarimasen-style CAPTCHA */
214 const char *question
;
215 const char *answers
[NUM_CHALLENGE_ANSWERS
];
218 /* regex-backed wordfilter */
219 struct wordfilter_input
{
222 const char *replacement
;
225 /* regex-backed forbidden input */
226 struct forbidden_input
{
230 const char *ban_reason
;
233 /* See config.def.h for detailed descriptions. */
234 struct configuration
{
236 const char *static_www_folder
;
237 const char *work_path
;
238 const char *temp_dir_template
;
239 const char *trip_salt
;
240 size_t trip_salt_len
;
241 const struct board
*boards
;
243 size_t max_form_data_size
;
244 size_t max_file_size
;
246 const struct filetype
*filetypes
;
247 size_t filetypes_num
;
248 const char *file_description_prog
;
249 const char **headers
;
251 const struct challenge
*challenges
;
252 size_t challenges_num
;
253 const struct wordfilter_input
*wordfilter_inputs
;
254 size_t wordfilter_inputs_num
;
255 const struct forbidden_input
*forbidden_inputs
;
256 size_t forbidden_inputs_num
;
259 /* db_writeback_ZZZ takes a callback. */
260 typedef int (*post_writeback
)(struct prepared_post
*p
, FILE *f
, uint_fast8_t
261 is_op
, uint_fast8_t is_summary
, uint_fast8_t
262 is_recent
, const char *board_name
,
263 uintmax_t in_thread
, uintmax_t
264 total_posts_in_thread
, uint_fast8_t hr_before
);
266 /* db-ZZZ.c (currently only sqlite3, but it used to be MySQL) */
267 int setup_dbs(const struct configuration
*conf
);
269 int db_construct_post_link(const char *board
, size_t board_len
, const
270 char *post
, size_t post_len
, int *found
, char **out
,
273 int db_cull_threads(size_t board_idx
, size_t *out_num_pages
);
275 int db_check_bans(const char *ip
, size_t board_idx
, time_t now
,
276 int *out_is_banned
, char **out_ban_until
, int *out_is_secret
,
277 char **out_ban_reason
);
279 int db_check_cooldowns(const char *ip
, size_t board_idx
, time_t now
,
280 int *out_is_cooled
, char **out_cooldown_length
);
282 int db_cull_and_report_threads(size_t board_idx
, uintmax_t **out_thread_ids
,
283 size_t *out_thread_id_num
,
284 size_t *out_num_pages
);
286 int db_extract_subject(size_t board_idx
, uintmax_t thread
, char **out_subject
,
287 size_t *out_subject_len
);
289 int db_insert_ban(uint_fast8_t global_ban
, size_t board_idx
, const
290 char *first_ip
, const char *last_ip
, const char *message
,
292 is_secret
, time_t ban_start
, time_t ban_expiry
);
294 int db_insert_post(const char *ip
, size_t in_thread
, int cooldown
, struct
295 post_cmd
*pc
, int *thread_dne
, int *thread_closed
,
299 int db_is_op(size_t board_idx
, uintmax_t post_id
, uint_fast8_t *out_is_op
);
301 int db_moderate_post(size_t board_idx
, uintmax_t post_id
, const
302 char *moderator_comment
, uint_fast8_t change_sticky
,
303 uint_fast8_t sticky_status
,
304 uint_fast8_t change_close
, uint_fast8_t close_status
);
306 int db_remove_thread_and_files(size_t board_idx
, uintmax_t thread_id
);
308 int db_remove_post_and_files(size_t board_idx
, uintmax_t thread_id
);
310 int db_update_file_info(size_t board_idx
, uintmax_t post_id
, const char *info
,
311 size_t info_len
, const char *system_full_path
, size_t
312 system_full_path_len
,
313 const char *system_thumb_path
, size_t
314 system_thumb_path_len
);
316 int db_writeback_posts_in_thread(size_t board_idx
, uintmax_t thread
, FILE *f
,
317 post_writeback pw_function
);
319 int db_writeback_recent_posts(FILE *f
, post_writeback pw_function
);
321 int db_writeback_thread_summaries(size_t board_idx
, uintmax_t *thread_ids
,
322 size_t thread_ids_num
, FILE *f
);
327 int setup_locks(const struct configuration
*conf
);
329 int lock_acquire(size_t board_idx
);
331 int lock_acquire_recent(void);
333 int lock_release(size_t board_idx
);
335 int lock_release_recent(void);
337 int clean_locks(void);
340 int setup_multipart(void);
342 int multipart_decompose(const char *full_data
, size_t full_data_len
, struct
345 int clean_multipart(void);
347 /* preconditions.c */
348 int preconditions_check(const struct configuration
*conf
);
350 /* sanitize-comment.c */
351 int setup_sanitize_comment(const struct configuration
*conf
);
353 int st_sanitize_text(struct post_cmd
*pc
, int *our_fault
,
354 uint_fast8_t *is_forbidden
, int *ban_duration
, const
357 int clean_sanitize_comment(void);
359 /* sanitize-file.c */
360 int setup_sanitize_file(const struct configuration
*conf
);
362 int sf_check_mime_type(const char *buf
, size_t len
, const struct
363 filetype
**out_filetype
);
365 int sf_describe_file(const char *mimetype
, const char *filepath
,
366 char **out_description
, size_t *out_len
);
368 int sf_install_files(size_t board_idx
, const char *buf
, size_t len
, time_t *now
,
369 const struct filetype
*filetype
, char **out_abs_path
,
371 size_t *out_path_len
, char **out_thumb_path
,
372 size_t *out_thumb_path_len
,
375 int clean_sanitize_file(void);
378 int setup_tripcodes(const struct configuration
*conf
);
380 int tripcodes_calculate(struct post_cmd
*p
);
382 int clean_tripcodes(void);
385 char * util_iso8601_from_time_t(time_t t
);
387 int util_normalize_ip(const char *in
, char **out
);
389 int util_rebuild(struct configuration
*conf
);
392 int setup_write_thread(const struct configuration
*conf
);
394 int wt_remove_files(const char *system_full_path
, size_t system_full_path_len
,
395 const char *system_thumb_path
, size_t
396 system_thumb_path_len
);
398 int wt_remove_thread_page(size_t board_idx
, uintmax_t thread_id
);
400 int wt_write_board(size_t board_idx
, uintmax_t *thread_ids
, size_t
401 thread_ids_num
, size_t board_pages_num
);
403 int wt_write_post(struct prepared_post
*p
, FILE *f
, uint_fast8_t is_op
,
404 uint_fast8_t is_summary
, uint_fast8_t is_recent
, const
406 uintmax_t in_thread
, uintmax_t total_posts_in_thread
,
407 uint_fast8_t hr_before
);
409 int wt_write_recent_page(void);
411 int wt_write_thread(size_t board_idx
, uintmax_t thread
);
413 void clean_write_thread(void);