misc: correctly proceed to thread-deletion in rb79-delete-post
[rb-79.git] / rb79-moderate-post.c
blob0c3e855cabaf4afc13f7dff4e47e1ef54a6633ba
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.
18 #include <errno.h>
19 #include <locale.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
25 #include <sodium.h>
27 #include "macros.h"
28 #include "rb79.h"
30 #include "config.h"
32 const char *program_name = "rb79-moderate-post";
34 /* Show usage message, do not exit */
35 void usage(void)
37 size_t len = strlen(program_name);
39 printf("Usage: %s -b board-name\n", program_name);
40 printf(" %*s -p post-id\n", (int) len, "");
41 printf(" %*s [ -a message ]\n", (int) len, "");
42 printf(" %*s [ -s | -S ] # Sticky or unsticky\n", (int) len,
43 "");
44 printf(" %*s [ -c | -C ] # Close or unclose\n", (int) len, "");
47 /* Do the thing */
48 int main(int argc, char **argv)
50 int ret = EINVAL;
51 struct configuration conf = { 0 };
52 int opt = 0;
53 const char *b_arg = 0;
54 size_t board_idx = 0;
55 const char *p_arg = 0;
56 uintmax_t post_id = 0;
57 const char *a_arg = 0;
58 uint_fast8_t must_sticky = 0;
59 uint_fast8_t must_unsticky = 0;
60 uint_fast8_t must_close = 0;
61 uint_fast8_t must_unclose = 0;
62 uint_fast8_t actually_is_op = 0;
64 setlocale(LC_ALL, "");
66 /* Parse options */
67 while ((opt = getopt(argc, argv, "b:p:a:sScC")) != -1) {
68 switch (opt) {
69 case 'b':
71 if (b_arg) {
72 ERROR_MESSAGE("-b already specified");
73 goto done;
76 b_arg = optarg;
77 break;
78 case 'p':
80 if (p_arg) {
81 ERROR_MESSAGE("-p already specified");
82 goto done;
85 p_arg = optarg;
86 break;
87 case 'a':
89 if (a_arg) {
90 ERROR_MESSAGE("-a already specified");
91 goto done;
94 a_arg = optarg;
95 break;
96 case 's':
97 must_sticky = 1;
98 break;
99 case 'S':
100 must_unsticky = 1;
101 break;
102 case 'c':
103 must_close = 1;
104 break;
105 case 'C':
106 must_unclose = 1;
107 break;
108 default:
109 usage();
110 goto done;
114 if (!b_arg ||
115 !p_arg) {
116 usage();
117 goto done;
120 if (must_unsticky &&
121 must_sticky) {
122 ERROR_MESSAGE("-s and -S are mutually exclusive");
123 goto done;
126 if (must_unclose &&
127 must_close) {
128 ERROR_MESSAGE("-c and -C are mutually exclusive");
129 goto done;
132 conf = (struct configuration) {
133 /* */
134 .static_www_folder = static_www_folder, /* */
135 .work_path = work_path, /* */
136 .temp_dir_template = temp_dir_template, /* */
137 .trip_salt = trip_salt, /* */
138 .trip_salt_len = strlen(trip_salt), /* */
139 .boards = boards, /* */
140 .boards_num = NUM_OF(boards), /* */
141 .max_form_data_size = max_form_data_size, /* */
142 .max_file_size = max_file_size, /* */
143 .max_text_len = max_text_len, /* */
144 .filetypes = filetypes, /* */
145 .filetypes_num = NUM_OF(filetypes), /* */
146 .file_description_prog = file_description_prog, /* */
147 .headers = headers, /* */
148 .headers_num = NUM_OF(headers), /* */
149 .challenges = challenges, /* */
150 .challenges_num = NUM_OF(challenges), /* */
151 .wordfilter_inputs = wordfilter_inputs, /* */
152 .wordfilter_inputs_num = NUM_OF(wordfilter_inputs), /* */
155 /* Interpret board */
156 board_idx = (size_t) -1;
158 for (size_t j = 0; j < conf.boards_num; ++j) {
159 if (!strcmp(conf.boards[j].name, b_arg)) {
160 board_idx = j;
164 if (board_idx == (size_t) -1) {
165 ERROR_MESSAGE("No board \"%s\" known", b_arg);
166 goto done;
169 /* Interpret post */
170 errno = 0;
171 post_id = strtoull(p_arg, 0, 0);
173 if (errno) {
174 ret = errno;
175 PERROR_MESSAGE("strtoull");
176 goto done;
179 /* Set up a minimal part of the system */
180 if (setup_locks(&conf) < 0) {
181 goto done;
184 if (setup_dbs(&conf) < 0) {
185 goto done;
188 if (setup_write_thread(&conf) < 0) {
189 goto done;
192 if (db_is_op(board_idx, post_id, &actually_is_op) < 0) {
193 goto done;
196 if (!actually_is_op &&
197 (must_sticky ||
198 must_unsticky ||
199 must_close ||
200 must_unclose)) {
201 ERROR_MESSAGE("Board /%s/, post %ju is not an OP, "
202 "cannot apply -s, -S, -C, -c",
203 conf.boards[board_idx].name,
204 post_id);
205 goto done;
208 if (db_moderate_post(board_idx, post_id, a_arg, (must_sticky ||
209 must_unsticky),
210 must_sticky, (must_close ||
211 must_unclose),
212 must_close) < 0) {
213 goto done;
216 util_rebuild(&conf);
217 ret = 0;
218 done:
219 clean_locks();
220 clean_dbs();
221 clean_write_thread();
223 return ret;