/[LeafOK_CVS]/lbbs/src/bbs_main.c
ViewVC logotype

Contents of /lbbs/src/bbs_main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.102 - (show annotations)
Fri Nov 7 04:58:09 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.101: +4 -0 lines
Content type: text/x-csrc
Load / Reload BWF config file on startup / reload

1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 /*
3 * bbs_main
4 * - entry and major procedures of user interactive access
5 *
6 * Copyright (C) 2004-2025 Leaflet <leaflet@leafok.com>
7 */
8
9 #include "article_favor.h"
10 #include "article_view_log.h"
11 #include "bbs.h"
12 #include "bbs_cmd.h"
13 #include "bbs_main.h"
14 #include "bwf.h"
15 #include "common.h"
16 #include "database.h"
17 #include "editor.h"
18 #include "io.h"
19 #include "log.h"
20 #include "login.h"
21 #include "menu.h"
22 #include "screen.h"
23 #include "section_list.h"
24 #include "section_list_display.h"
25 #include "trie_dict.h"
26 #include "user_list.h"
27 #include "user_priv.h"
28 #include <errno.h>
29 #include <signal.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33 #include <unistd.h>
34
35 int bbs_info()
36 {
37 prints("欢迎光临 \033[1;33m%s \033[32m[%s] \033[37m( %s )\033[m\r\n",
38 BBS_name, BBS_server, APP_INFO);
39
40 return iflush();
41 }
42
43 int bbs_welcome(void)
44 {
45 int u_online = 0;
46 int u_anonymous = 0;
47 int u_total = 0;
48 int u_login_count = 0;
49
50 if (get_user_online_list_count(&u_online, &u_anonymous) < 0)
51 {
52 log_error("get_user_online_list_count() error\n");
53 u_online = 0;
54 }
55 u_online += u_anonymous;
56 u_online++; // current user
57 if (BBS_priv.uid == 0)
58 {
59 u_anonymous++;
60 }
61
62 if (get_user_list_count(&u_total) < 0)
63 {
64 log_error("get_user_list_count() error\n");
65 u_total = 0;
66 }
67
68 if (get_user_login_count(&u_login_count) < 0)
69 {
70 log_error("get_user_login_count() error\n");
71 u_login_count = 0;
72 }
73
74 // Display logo
75 display_file(DATA_WELCOME, 2);
76
77 // Display welcome message
78 prints("\r\033[1;35m欢迎光临\033[33m 【 %s 】 \033[35mBBS\r\n"
79 "\033[32m目前上站人数 [\033[36m%d/%d\033[32m] "
80 "匿名游客[\033[36m%d\033[32m] "
81 "注册用户数[\033[36m%d/%d\033[32m]\r\n"
82 "从 [\033[36m%s\033[32m] 起,累计访问人次:[\033[36m%d\033[32m]\033[m\r\n",
83 BBS_name, u_online, BBS_max_client, u_anonymous, u_total,
84 BBS_max_user_count, BBS_start_dt, u_login_count);
85
86 iflush();
87
88 return 0;
89 }
90
91 int bbs_logout(void)
92 {
93 MYSQL *db;
94
95 db = db_open();
96 if (db == NULL)
97 {
98 return -1;
99 }
100
101 if (user_online_exp(db) < 0)
102 {
103 return -2;
104 }
105
106 if (user_online_del(db) < 0)
107 {
108 return -3;
109 }
110
111 mysql_close(db);
112
113 display_file(DATA_GOODBYE, 1);
114
115 log_common("User [%s] logout, idle for %ld seconds since last input\n", BBS_username, time(NULL) - BBS_last_access_tm);
116
117 return 0;
118 }
119
120 int bbs_center()
121 {
122 int ch;
123 time_t t_last_action;
124
125 BBS_last_access_tm = t_last_action = time(NULL);
126
127 clearscr();
128
129 show_top("", BBS_name, "");
130 show_active_board();
131 show_bottom("");
132 display_menu(&bbs_menu);
133 iflush();
134
135 while (!SYS_server_exit)
136 {
137 ch = igetch(100);
138
139 if (ch != KEY_NULL && ch != KEY_TIMEOUT)
140 {
141 BBS_last_access_tm = time(NULL);
142 #ifdef _DEBUG
143 log_error("Debug: BBS_last_access_tm is updated\n");
144 #endif
145 }
146
147 if (bbs_menu.choose_step == 0 && time(NULL) - t_last_action >= 10)
148 {
149 t_last_action = time(NULL);
150
151 show_active_board();
152 show_bottom("");
153 display_menu_cursor(&bbs_menu, 1);
154 iflush();
155 }
156
157 if (user_online_update("MENU") < 0)
158 {
159 log_error("user_online_update(MENU) error\n");
160 }
161
162 switch (ch)
163 {
164 case KEY_NULL: // broken pipe
165 log_error("KEY_NULL\n");
166 return 0;
167 case KEY_TIMEOUT:
168 if (time(NULL) - BBS_last_access_tm >= BBS_max_user_idle_time)
169 {
170 log_error("User input timeout\n");
171 return 0;
172 }
173 continue;
174 case CR:
175 default:
176 switch (menu_control(&bbs_menu, ch))
177 {
178 case EXITBBS:
179 case EXITMENU:
180 return 0;
181 case REDRAW:
182 t_last_action = time(NULL);
183 clearscr();
184 show_top("", BBS_name, "");
185 show_active_board();
186 show_bottom("");
187 display_menu(&bbs_menu);
188 break;
189 case NOREDRAW:
190 case UNKNOWN_CMD:
191 default:
192 break;
193 }
194 iflush();
195 }
196 }
197
198 return 0;
199 }
200
201 int bbs_charset_select()
202 {
203 char msg[LINE_BUFFER_LEN];
204 int ch;
205
206 snprintf(msg, sizeof(msg),
207 "\rChoose character set in 5 seconds [UTF-8, GBK]: [U/g]");
208
209 while (!SYS_server_exit)
210 {
211 ch = press_any_key_ex(msg, 5);
212 switch (ch)
213 {
214 case KEY_NULL:
215 return -1;
216 case KEY_TIMEOUT:
217 case CR:
218 case 'u':
219 case 'U':
220 return 0;
221 case 'g':
222 case 'G':
223 if (io_conv_init("GBK") < 0)
224 {
225 log_error("io_conv_init(%s) error\n", "GBK");
226 return -1;
227 }
228 return 0;
229 default:
230 continue;
231 }
232 }
233
234 return 0;
235 }
236
237 int bbs_main()
238 {
239 struct sigaction act = {0};
240 char msg[LINE_BUFFER_LEN];
241
242 // Set signal handler
243 act.sa_handler = SIG_IGN;
244 if (sigaction(SIGHUP, &act, NULL) == -1)
245 {
246 log_error("set signal action of SIGHUP error: %d\n", errno);
247 goto cleanup;
248 }
249 act.sa_handler = SIG_DFL;
250 if (sigaction(SIGCHLD, &act, NULL) == -1)
251 {
252 log_error("set signal action of SIGCHLD error: %d\n", errno);
253 goto cleanup;
254 }
255
256 // Set data pools in shared memory readonly
257 if (set_trie_dict_shm_readonly() < 0)
258 {
259 goto cleanup;
260 }
261 if (set_article_block_shm_readonly() < 0)
262 {
263 goto cleanup;
264 }
265 if (set_section_list_shm_readonly() < 0)
266 {
267 goto cleanup;
268 }
269 if (set_user_list_pool_shm_readonly() < 0)
270 {
271 goto cleanup;
272 }
273
274 // Load menu in shared memory
275 if (set_menu_shm_readonly(&bbs_menu) < 0)
276 {
277 goto cleanup;
278 }
279
280 // Set default charset
281 if (io_conv_init(BBS_default_charset) < 0)
282 {
283 log_error("io_conv_init(%s) error\n", BBS_default_charset);
284 goto cleanup;
285 }
286
287 set_input_echo(0);
288
289 // Set user charset
290 bbs_charset_select();
291
292 // System info
293 if (bbs_info() < 0)
294 {
295 goto cleanup;
296 }
297
298 // Welcome
299 if (bbs_welcome() < 0)
300 {
301 goto cleanup;
302 }
303
304 // User login
305 if (SSH_v2)
306 {
307 snprintf(msg, sizeof(msg), "\033[1m%s 欢迎使用ssh方式访问 \033[1;33m按任意键继续...\033[m", BBS_username);
308 press_any_key_ex(msg, 60);
309 }
310 else if (bbs_login() < 0)
311 {
312 goto cleanup;
313 }
314 log_common("User [%s] login\n", BBS_username);
315
316 // Load section aid locations
317 if (section_aid_locations_load(BBS_priv.uid) < 0)
318 {
319 log_error("article_view_log_load() error\n");
320 goto cleanup;
321 }
322
323 // Load article view log
324 if (article_view_log_load(BBS_priv.uid, &BBS_article_view_log, 0) < 0)
325 {
326 log_error("article_view_log_load() error\n");
327 goto cleanup;
328 }
329
330 // Load article favorite
331 if (article_favor_load(BBS_priv.uid, &BBS_article_favor, 0) < 0)
332 {
333 log_error("article_favor_load() error\n");
334 goto cleanup;
335 }
336
337 // Init editor memory pool
338 if (editor_memory_pool_init() < 0)
339 {
340 log_error("editor_memory_pool_init() error\n");
341 goto cleanup;
342 }
343
344 clearscr();
345
346 // BBS Top 10
347 display_file(VAR_BBS_TOP, 1);
348
349 // Main
350 bbs_center();
351
352 // Logout
353 bbs_logout();
354
355 // Save section aid locations
356 if (section_aid_locations_save(BBS_priv.uid) < 0)
357 {
358 log_error("article_view_log_save() error\n");
359 }
360
361 // Save incremental article view log
362 if (article_view_log_save_inc(&BBS_article_view_log) < 0)
363 {
364 log_error("article_view_log_save_inc() error\n");
365 }
366
367 // Save incremental article favorite
368 if (article_favor_save_inc(&BBS_article_favor) < 0)
369 {
370 log_error("article_favor_save_inc() error\n");
371 }
372
373 cleanup:
374 // Cleanup iconv
375 io_conv_cleanup();
376
377 // Cleanup editor memory pool
378 editor_memory_pool_cleanup();
379
380 // Unload article view log
381 article_view_log_unload(&BBS_article_view_log);
382
383 // Unload article favor
384 article_favor_unload(&BBS_article_favor);
385
386 // Detach menu in shared memory
387 detach_menu_shm(&bbs_menu);
388 detach_menu_shm(&top10_menu);
389
390 // Detach data pools shm
391 detach_user_list_pool_shm();
392 detach_section_list_shm();
393 detach_article_block_shm();
394 detach_trie_dict_shm();
395
396 // Cleanup BWF
397 bwf_unload();
398
399 return 0;
400 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1