2 * Copyright (c) 2017-2020, 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.
24 #include <sys/types.h>
31 /* Try and acquire all lock files, in order */
33 try_get_all_lock_files(size_t num_boards
)
35 for (size_t j
= 0; j
< num_boards
; ++j
) {
36 if (lock_acquire(j
) < 0) {
44 /* Try and release all lock files, in order */
46 try_drop_all_lock_files(size_t num_boards
)
48 for (size_t j
= 0; j
< num_boards
; ++j
) {
55 /* Make sure we can write to the directory where all the www files will be */
57 try_write_work_dir(const char *work_dir
)
61 /* First, the directories should be there */
62 if (mkdir(work_dir
, 0755) < 0) {
63 if (errno
!= EEXIST
) {
64 PERROR_MESSAGE("mkdir");
65 ERROR_MESSAGE("Cannot create directory %s", work_dir
);
76 /* Make sure we can write to the directory where all the www files will be */
78 try_write_www_dir(const struct board
*boards
, size_t boards_num
, const
79 char *static_www_folder
)
86 /* First, the directories should be there */
87 for (size_t j
= 0; j
< boards_num
; ++j
) {
88 len
= snprintf(0, 0, "%s/%s", static_www_folder
,
92 ERROR_MESSAGE("overflow");
96 if (!(path
= malloc(len
+ 1))) {
97 PERROR_MESSAGE("malloc");
101 sprintf(path
, "%s/%s", static_www_folder
, boards
[j
].name
);
103 if (mkdir(path
, 0755) < 0) {
104 if (errno
!= EEXIST
) {
105 PERROR_MESSAGE("mkdir");
106 ERROR_MESSAGE("Cannot create directory %s",
116 /* The /recent page */
117 len
= snprintf(0, 0, "%s/recent", static_www_folder
);
120 ERROR_MESSAGE("overflow");
124 if (!(path
= malloc(len
+ 1))) {
125 PERROR_MESSAGE("malloc");
129 sprintf(path
, "%s/recent", static_www_folder
);
131 if (mkdir(path
, 0755) < 0) {
132 if (errno
!= EEXIST
) {
133 PERROR_MESSAGE("mkdir");
134 ERROR_MESSAGE("Cannot create directory %s", path
);
142 /* Now, the src/ and res/ dirs should be there */
143 for (size_t j
= 0; j
< boards_num
; ++j
) {
144 len
= snprintf(0, 0, "%s/%s/src", static_www_folder
,
148 ERROR_MESSAGE("overflow");
152 if (!(path
= malloc(len
+ 1))) {
153 PERROR_MESSAGE("malloc");
157 sprintf(path
, "%s/%s/src", static_www_folder
, boards
[j
].name
);
159 if (mkdir(path
, 0755) < 0) {
160 if (errno
!= EEXIST
) {
161 PERROR_MESSAGE("mkdir");
162 ERROR_MESSAGE("Cannot create directory %s",
168 sprintf(path
, "%s/%s/res", static_www_folder
, boards
[j
].name
);
170 if (mkdir(path
, 0755) < 0) {
171 if (errno
!= EEXIST
) {
172 PERROR_MESSAGE("mkdir");
173 ERROR_MESSAGE("Cannot create directory %s",
183 /* Now, we need to be able to write there */
184 for (size_t j
= 0; j
< boards_num
; ++j
) {
186 len
= snprintf(0, 0, "%s/%s/src/a", static_www_folder
,
190 ERROR_MESSAGE("overflow");
194 if (!(path
= malloc(len
+ 1))) {
195 PERROR_MESSAGE("malloc");
199 sprintf(path
, "%s/%s/src/a", static_www_folder
, boards
[j
].name
);
201 if (!(f
= fopen(path
, "a"))) {
202 PERROR_MESSAGE("fopen");
203 ERROR_MESSAGE("Cannot create dummy file %s", path
);
208 PERROR_MESSAGE("fclose");
209 ERROR_MESSAGE("Cannot close dummy file %s", path
);
214 sprintf(path
, "%s/%s/res/a", static_www_folder
, boards
[j
].name
);
216 if (!(f
= fopen(path
, "a"))) {
217 PERROR_MESSAGE("fopen");
218 ERROR_MESSAGE("Cannot create dummy file %s", path
);
223 PERROR_MESSAGE("fclose");
224 ERROR_MESSAGE("Cannot close dummy file %s", path
);
233 len
= snprintf(0, 0, "%s/recent/a", static_www_folder
);
236 ERROR_MESSAGE("overflow");
240 if (!(path
= malloc(len
+ 1))) {
241 PERROR_MESSAGE("malloc");
245 sprintf(path
, "%s/recent/a", static_www_folder
);
247 if (!(f
= fopen(path
, "a"))) {
248 PERROR_MESSAGE("fopen");
249 ERROR_MESSAGE("Cannot create dummy file %s", path
);
254 PERROR_MESSAGE("fclose");
255 ERROR_MESSAGE("Cannot close dummy file %s", path
);
268 * Returns < 0 in case something isn't set up right
272 * - conf is correctly set up.
274 * Postconditions (success):
276 * - The ZZZ_setup() functions in other files have all been called,
277 * and all returned successfully.
280 preconditions_check(const struct configuration
*conf
)
284 uintmax_t max_size
= (size_t) -1;
286 for (j
= 0; j
< conf
->filetypes_num
; ++j
) {
287 const struct filetype
*f
= &conf
->filetypes
[j
];
289 if (f
->thumb_creation_command
&&
290 f
->static_thumbnail
) {
291 ERROR_MESSAGE("Filetype for %s cannot have both "
292 "thumb_creation_command and static_thumbnail",
297 if (!f
->thumb_creation_command
&&
298 !f
->static_thumbnail
) {
299 ERROR_MESSAGE("Filetype for %s must have one of "
300 "thumb_creation_command or static_thumbnail",
306 for (j
= 0; j
< conf
->boards_num
; ++j
) {
307 const struct board
*b
= &conf
->boards
[j
];
310 ERROR_MESSAGE("Board /%s/'s num_pages must be positive",
315 if (!b
->threads_per_page
) {
316 ERROR_MESSAGE("Board /%s/'s threads_per_page must be "
317 "positive", b
->name
);
321 if (b
->num_pages
* b
->threads_per_page
> max_size
) {
322 ERROR_MESSAGE("Board /%s/'s threads cannot be "
323 "fit in memory", b
->name
);
327 if (!strcmp(b
->name
, "recent")) {
328 ERROR_MESSAGE("The board name /recent/ is reserved");
333 if (try_write_work_dir(conf
->work_path
) < 0) {
337 if (setup_multipart() < 0) {
341 if (setup_sanitize_comment(conf
) < 0) {
345 if (setup_sanitize_file(conf
) < 0) {
349 if (setup_tripcodes(conf
) < 0) {
353 if (setup_locks(conf
) < 0) {
357 if (setup_write_thread(conf
) < 0) {
361 if (try_get_all_lock_files(conf
->boards_num
) < 0) {
365 /* Since we have the lock files now, we need not fear races */
366 if (setup_dbs(conf
) < 0) {
370 if (try_write_www_dir(conf
->boards
, conf
->boards_num
,
371 conf
->static_www_folder
) < 0) {
378 if (try_drop_all_lock_files(conf
->boards_num
) < 0) {