/[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.108 - (show annotations)
Tue Nov 11 00:28:05 2025 UTC (4 months ago) by sysadm
Branch: MAIN
Changes since 1.107: +4 -0 lines
Content type: text/x-csrc
Use config.h

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

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