/[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.107 - (show annotations)
Mon Nov 10 14:24:37 2025 UTC (4 months ago) by sysadm
Branch: MAIN
Changes since 1.106: +1 -1 lines
Content type: text/x-csrc
Replace ":" with ":"

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

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