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

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