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

Annotation of /lbbs/src/login.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.80 - (hide annotations)
Sun Jan 4 13:24:00 2026 UTC (2 months, 1 week ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.79: +2 -0 lines
Content type: text/x-csrc
Clear current line before prompt for username / password

1 sysadm 1.65 /* SPDX-License-Identifier: GPL-3.0-or-later */
2     /*
3     * login
4     * - user authentication and online status manager
5     *
6 sysadm 1.79 * Copyright (C) 2004-2026 Leaflet <leaflet@leafok.com>
7 sysadm 1.65 */
8 sysadm 1.1
9 sysadm 1.68 #ifdef HAVE_CONFIG_H
10     #include "config.h"
11     #endif
12    
13 sysadm 1.1 #include "bbs.h"
14     #include "common.h"
15 sysadm 1.48 #include "database.h"
16     #include "io.h"
17 sysadm 1.50 #include "ip_mask.h"
18 sysadm 1.14 #include "log.h"
19 sysadm 1.48 #include "login.h"
20 sysadm 1.14 #include "screen.h"
21 sysadm 1.48 #include "user_priv.h"
22     #include <ctype.h>
23 sysadm 1.34 #include <errno.h>
24 sysadm 1.48 #include <stdlib.h>
25 sysadm 1.14 #include <string.h>
26 sysadm 1.3 #include <regex.h>
27 sysadm 1.14 #include <unistd.h>
28 sysadm 1.69 #include <mysql.h>
29 sysadm 1.56 #include <sys/param.h>
30 sysadm 1.1
31 sysadm 1.64 static const int BBS_username_min_len = 3; // common len = 5, special len = 3
32     static const int BBS_password_min_len = 5; // legacy len = 5, current len = 6
33    
34 sysadm 1.67 static const int BBS_allowed_login_failures_within_interval = 10;
35     static const int BBS_login_failures_count_interval = 10; // minutes
36     static const int BBS_allowed_login_failures_per_account = 3;
37    
38     const int BBS_login_retry_times = 3;
39    
40 sysadm 1.41 int bbs_login(void)
41 sysadm 1.1 {
42 sysadm 1.15 char username[BBS_username_max_len + 1];
43     char password[BBS_password_max_len + 1];
44 sysadm 1.77 int i;
45 sysadm 1.74 int ret;
46 sysadm 1.2
47 sysadm 1.77 for (i = 0; !SYS_server_exit && i < BBS_login_retry_times; i++)
48 sysadm 1.11 {
49 sysadm 1.80 clrtoeol();
50 sysadm 1.49 prints("\033[1;33m请输入帐号\033[m(试用请输入`\033[1;36mguest\033[m', "
51     "注册请输入`\033[1;31mnew\033[m'): ");
52 sysadm 1.11 iflush();
53    
54 sysadm 1.24 if (str_input(username, sizeof(username), DOECHO) < 0)
55     {
56     continue;
57     }
58 sysadm 1.11
59     if (strcmp(username, "guest") == 0)
60     {
61 sysadm 1.41 load_guest_info();
62 sysadm 1.77 log_common("User [%s] authenticated successfully", username);
63 sysadm 1.11 return 0;
64     }
65    
66     if (strcmp(username, "new") == 0)
67     {
68 sysadm 1.42 display_file(DATA_REGISTER, 1);
69 sysadm 1.51 return -1;
70 sysadm 1.11 }
71    
72 sysadm 1.17 if (username[0] != '\0')
73 sysadm 1.11 {
74 sysadm 1.80 clrtoeol();
75 sysadm 1.49 prints("\033[1;37m请输入密码\033[m: ");
76 sysadm 1.11 iflush();
77    
78 sysadm 1.24 if (str_input(password, sizeof(password), NOECHO) < 0)
79     {
80     continue;
81     }
82 sysadm 1.11
83 sysadm 1.74 ret = check_user(username, password);
84     if (ret == 2) // Enforce update user agreement
85     {
86     BBS_update_eula = 1;
87     ret = 0;
88     }
89    
90 sysadm 1.77 if (ret == 0)
91     {
92     log_common("User [%s] authenticated successfully", username);
93     return 0;
94     }
95    
96     log_common("User [%s] authentication failed (%d/%d)", username,
97     i + 1, BBS_login_retry_times);
98 sysadm 1.31 iflush();
99 sysadm 1.11 }
100 sysadm 1.24 }
101    
102 sysadm 1.77 display_file(DATA_LOGIN_ERROR, 1);
103     return -1;
104 sysadm 1.11 }
105 sysadm 1.2
106 sysadm 1.41 int check_user(const char *username, const char *password)
107 sysadm 1.11 {
108 sysadm 1.44 MYSQL *db = NULL;
109     MYSQL_RES *rs = NULL;
110 sysadm 1.11 MYSQL_ROW row;
111 sysadm 1.15 char sql[SQL_BUFFER_LEN];
112 sysadm 1.44 int ret = 0;
113 sysadm 1.40 int BBS_uid = 0;
114 sysadm 1.22 char client_addr[IP_ADDR_LEN];
115 sysadm 1.27 int i;
116     int ok = 1;
117 sysadm 1.34 char user_tz_env[BBS_user_tz_max_len + 2];
118 sysadm 1.11
119 sysadm 1.41 db = db_open();
120     if (db == NULL)
121     {
122 sysadm 1.44 ret = -1;
123     goto cleanup;
124 sysadm 1.41 }
125    
126 sysadm 1.11 // Verify format
127 sysadm 1.27 for (i = 0; ok && username[i] != '\0'; i++)
128     {
129 sysadm 1.70 if (!(isalpha((int)username[i]) || (i > 0 && (isdigit((int)username[i]) || username[i] == '_'))))
130 sysadm 1.27 {
131     ok = 0;
132     }
133     }
134 sysadm 1.64 if (ok && (i < BBS_username_min_len || i > BBS_username_max_len))
135 sysadm 1.27 {
136     ok = 0;
137     }
138     for (i = 0; ok && password[i] != '\0'; i++)
139     {
140 sysadm 1.70 if (!isalnum((int)password[i]))
141 sysadm 1.27 {
142     ok = 0;
143     }
144     }
145 sysadm 1.64 if (ok && (i < BBS_password_min_len || i > BBS_password_max_len))
146 sysadm 1.27 {
147     ok = 0;
148     }
149    
150     if (!ok)
151 sysadm 1.5 {
152 sysadm 1.49 prints("\033[1;31m用户名或密码格式错误...\033[m\r\n");
153 sysadm 1.44 ret = 1;
154     goto cleanup;
155 sysadm 1.5 }
156    
157 sysadm 1.13 // Begin transaction
158     if (mysql_query(db, "SET autocommit=0") != 0)
159     {
160 sysadm 1.75 log_error("SET autocommit=0 error: %s", mysql_error(db));
161 sysadm 1.44 ret = -1;
162     goto cleanup;
163 sysadm 1.13 }
164    
165     if (mysql_query(db, "BEGIN") != 0)
166     {
167 sysadm 1.75 log_error("Begin transaction error: %s", mysql_error(db));
168 sysadm 1.44 ret = -1;
169     goto cleanup;
170 sysadm 1.13 }
171    
172 sysadm 1.22 // Failed login attempts from the same source (subnet /24) during certain time period
173     strncpy(client_addr, hostaddr_client, sizeof(client_addr) - 1);
174     client_addr[sizeof(client_addr) - 1] = '\0';
175    
176     snprintf(sql, sizeof(sql),
177     "SELECT COUNT(*) AS err_count FROM user_err_login_log "
178 sysadm 1.44 "WHERE login_dt >= SUBDATE(NOW(), INTERVAL %d MINUTE) "
179 sysadm 1.22 "AND login_ip LIKE '%s'",
180 sysadm 1.44 BBS_login_failures_count_interval,
181 sysadm 1.22 ip_mask(client_addr, 1, '%'));
182     if (mysql_query(db, sql) != 0)
183     {
184 sysadm 1.75 log_error("Query user_list error: %s", mysql_error(db));
185 sysadm 1.44 ret = -1;
186     goto cleanup;
187 sysadm 1.22 }
188     if ((rs = mysql_store_result(db)) == NULL)
189     {
190 sysadm 1.75 log_error("Get user_list data failed");
191 sysadm 1.44 ret = -1;
192     goto cleanup;
193 sysadm 1.22 }
194     if ((row = mysql_fetch_row(rs)))
195     {
196 sysadm 1.52 if (atoi(row[0]) >= BBS_allowed_login_failures_within_interval)
197 sysadm 1.22 {
198 sysadm 1.52 prints("\033[1;31m来源存在多次失败登陆尝试,请稍后再试,或使用Web方式访问\033[m\r\n");
199 sysadm 1.44 ret = 1;
200     goto cleanup;
201 sysadm 1.22 }
202     }
203     mysql_free_result(rs);
204 sysadm 1.44 rs = NULL;
205 sysadm 1.22
206 sysadm 1.52 // Failed login attempts against the current username since last successful login
207 sysadm 1.22 snprintf(sql, sizeof(sql),
208     "SELECT COUNT(*) AS err_count FROM user_err_login_log "
209 sysadm 1.52 "LEFT JOIN user_list ON user_err_login_log.username = user_list.username "
210     "LEFT JOIN user_pubinfo ON user_list.UID = user_pubinfo.UID "
211     "WHERE user_err_login_log.username = '%s' "
212     "AND (user_err_login_log.login_dt >= user_pubinfo.last_login_dt "
213     "OR user_pubinfo.last_login_dt IS NULL)",
214 sysadm 1.22 username);
215     if (mysql_query(db, sql) != 0)
216     {
217 sysadm 1.75 log_error("Query user_list error: %s", mysql_error(db));
218 sysadm 1.44 ret = -1;
219     goto cleanup;
220 sysadm 1.22 }
221     if ((rs = mysql_store_result(db)) == NULL)
222     {
223 sysadm 1.75 log_error("Get user_list data failed");
224 sysadm 1.44 ret = -1;
225     goto cleanup;
226 sysadm 1.22 }
227     if ((row = mysql_fetch_row(rs)))
228     {
229 sysadm 1.53 if (atoi(row[0]) >= BBS_allowed_login_failures_per_account)
230 sysadm 1.22 {
231 sysadm 1.52 prints("\033[1;31m账户存在多次失败登陆尝试,请使用Web方式登录解锁\033[m\r\n");
232 sysadm 1.44 ret = 1;
233     goto cleanup;
234 sysadm 1.22 }
235     }
236     mysql_free_result(rs);
237 sysadm 1.44 rs = NULL;
238 sysadm 1.22
239 sysadm 1.18 snprintf(sql, sizeof(sql),
240 sysadm 1.22 "SELECT UID, username, p_login FROM user_list "
241     "WHERE username = '%s' AND password = SHA2('%s', 256) AND enable",
242     username, password);
243 sysadm 1.11 if (mysql_query(db, sql) != 0)
244     {
245 sysadm 1.75 log_error("Query user_list error: %s", mysql_error(db));
246 sysadm 1.44 ret = -1;
247     goto cleanup;
248 sysadm 1.11 }
249     if ((rs = mysql_store_result(db)) == NULL)
250 sysadm 1.2 {
251 sysadm 1.75 log_error("Get user_list data failed");
252 sysadm 1.44 ret = -1;
253     goto cleanup;
254 sysadm 1.11 }
255 sysadm 1.15 if ((row = mysql_fetch_row(rs)))
256 sysadm 1.11 {
257 sysadm 1.40 BBS_uid = atoi(row[0]);
258 sysadm 1.17 strncpy(BBS_username, row[1], sizeof(BBS_username) - 1);
259     BBS_username[sizeof(BBS_username) - 1] = '\0';
260 sysadm 1.13 int p_login = atoi(row[2]);
261    
262     mysql_free_result(rs);
263 sysadm 1.44 rs = NULL;
264 sysadm 1.13
265     // Add user login log
266 sysadm 1.18 snprintf(sql, sizeof(sql),
267 sysadm 1.22 "INSERT INTO user_login_log(UID, login_dt, login_ip) "
268 sysadm 1.40 "VALUES(%d, NOW(), '%s')",
269 sysadm 1.22 BBS_uid, hostaddr_client);
270 sysadm 1.13 if (mysql_query(db, sql) != 0)
271     {
272 sysadm 1.75 log_error("Insert into user_login_log error: %s", mysql_error(db));
273 sysadm 1.44 ret = -1;
274     goto cleanup;
275 sysadm 1.13 }
276    
277     // Commit transaction
278     if (mysql_query(db, "COMMIT") != 0)
279     {
280 sysadm 1.75 log_error("Commit transaction error: %s", mysql_error(db));
281 sysadm 1.44 ret = -1;
282     goto cleanup;
283 sysadm 1.13 }
284    
285     if (p_login == 0)
286 sysadm 1.11 {
287 sysadm 1.49 prints("\033[1;31m您目前无权登陆...\033[m\r\n");
288 sysadm 1.44 ret = 1;
289     goto cleanup;
290 sysadm 1.11 }
291     }
292     else
293     {
294     mysql_free_result(rs);
295 sysadm 1.44 rs = NULL;
296 sysadm 1.2
297 sysadm 1.18 snprintf(sql, sizeof(sql),
298 sysadm 1.22 "INSERT INTO user_err_login_log(username, password, login_dt, login_ip) "
299     "VALUES('%s', '%s', NOW(), '%s')",
300     username, password, hostaddr_client);
301 sysadm 1.11 if (mysql_query(db, sql) != 0)
302     {
303 sysadm 1.75 log_error("Insert into user_err_login_log error: %s", mysql_error(db));
304 sysadm 1.44 ret = -1;
305     goto cleanup;
306 sysadm 1.11 }
307    
308 sysadm 1.13 // Commit transaction
309     if (mysql_query(db, "COMMIT") != 0)
310     {
311 sysadm 1.75 log_error("Commit transaction error: %s", mysql_error(db));
312 sysadm 1.44 ret = -1;
313     goto cleanup;
314 sysadm 1.13 }
315    
316 sysadm 1.49 prints("\033[1;31m错误的用户名或密码...\033[m\r\n");
317 sysadm 1.44 ret = 1;
318     goto cleanup;
319 sysadm 1.11 }
320 sysadm 1.13
321     // Set AUTOCOMMIT = 1
322     if (mysql_query(db, "SET autocommit=1") != 0)
323     {
324 sysadm 1.75 log_error("SET autocommit=1 error: %s", mysql_error(db));
325 sysadm 1.44 ret = -1;
326     goto cleanup;
327 sysadm 1.13 }
328 sysadm 1.2
329 sysadm 1.11 ret = load_user_info(db, BBS_uid);
330    
331     switch (ret)
332 sysadm 1.2 {
333 sysadm 1.11 case 0: // Login successfully
334 sysadm 1.76 if (!SSH_v2 && checklevel2(&BBS_priv, P_MAN_S))
335     {
336     prints("\033[1;31m非普通账户必须使用SSH方式登录\033[m\r\n");
337     ret = 1;
338     goto cleanup;
339     }
340 sysadm 1.11 break;
341     case -1: // Load data error
342 sysadm 1.49 prints("\033[1;31m读取用户数据错误...\033[m\r\n");
343 sysadm 1.44 ret = -1;
344     goto cleanup;
345 sysadm 1.74 case -2: // Enforce update user agreement
346 sysadm 1.76 if (!SSH_v2 && checklevel2(&BBS_priv, P_MAN_S))
347     {
348     prints("\033[1;31m非普通账户必须使用SSH方式登录\033[m\r\n");
349     ret = 1;
350     goto cleanup;
351     }
352 sysadm 1.74 ret = 2;
353 sysadm 1.44 goto cleanup;
354 sysadm 1.11 case -3: // Dead
355 sysadm 1.49 prints("\033[1;31m很遗憾,您已经永远离开了我们的世界!\033[m\r\n");
356 sysadm 1.44 ret = 1;
357     goto cleanup;
358 sysadm 1.11 default:
359 sysadm 1.44 ret = -2;
360     goto cleanup;
361 sysadm 1.2 }
362    
363 sysadm 1.18 snprintf(sql, sizeof(sql),
364 sysadm 1.22 "UPDATE user_pubinfo SET visit_count = visit_count + 1, "
365 sysadm 1.40 "last_login_dt = NOW() WHERE UID = %d",
366 sysadm 1.22 BBS_uid);
367 sysadm 1.13 if (mysql_query(db, sql) != 0)
368     {
369 sysadm 1.75 log_error("Update user_pubinfo error: %s", mysql_error(db));
370 sysadm 1.44 ret = -1;
371     goto cleanup;
372 sysadm 1.13 }
373    
374 sysadm 1.15 if (user_online_add(db) != 0)
375     {
376 sysadm 1.44 ret = -1;
377     goto cleanup;
378 sysadm 1.15 }
379    
380 sysadm 1.45 BBS_last_access_tm = BBS_login_tm = time(NULL);
381 sysadm 1.13
382 sysadm 1.34 // Set user tz to process env
383     if (BBS_user_tz[0] != '\0')
384     {
385     user_tz_env[0] = ':';
386     strncpy(user_tz_env + 1, BBS_user_tz, sizeof(user_tz_env) - 2);
387     user_tz_env[sizeof(user_tz_env) - 1] = '\0';
388    
389     if (setenv("TZ", user_tz_env, 1) == -1)
390     {
391 sysadm 1.75 log_error("setenv(TZ = %s) error %d", user_tz_env, errno);
392 sysadm 1.34 return -3;
393     }
394    
395     tzset();
396     }
397    
398 sysadm 1.44 cleanup:
399     mysql_free_result(rs);
400 sysadm 1.41 mysql_close(db);
401    
402 sysadm 1.44 return ret;
403 sysadm 1.1 }
404 sysadm 1.2
405 sysadm 1.40 int load_user_info(MYSQL *db, int BBS_uid)
406 sysadm 1.3 {
407 sysadm 1.44 MYSQL_RES *rs = NULL;
408 sysadm 1.11 MYSQL_ROW row;
409 sysadm 1.15 char sql[SQL_BUFFER_LEN];
410 sysadm 1.11 int life;
411     time_t last_login_dt;
412 sysadm 1.44 int ret = 0;
413 sysadm 1.11
414 sysadm 1.18 snprintf(sql, sizeof(sql),
415 sysadm 1.43 "SELECT life, UNIX_TIMESTAMP(last_login_dt), user_timezone, exp, nickname "
416 sysadm 1.40 "FROM user_pubinfo WHERE UID = %d",
417 sysadm 1.22 BBS_uid);
418 sysadm 1.11 if (mysql_query(db, sql) != 0)
419     {
420 sysadm 1.75 log_error("Query user_pubinfo error: %s", mysql_error(db));
421 sysadm 1.44 ret = -1;
422     goto cleanup;
423 sysadm 1.11 }
424     if ((rs = mysql_store_result(db)) == NULL)
425     {
426 sysadm 1.75 log_error("Get user_pubinfo data failed");
427 sysadm 1.44 ret = -1;
428     goto cleanup;
429 sysadm 1.11 }
430 sysadm 1.15 if ((row = mysql_fetch_row(rs)))
431 sysadm 1.11 {
432     life = atoi(row[0]);
433     last_login_dt = (time_t)atol(row[1]);
434 sysadm 1.34
435     strncpy(BBS_user_tz, row[2], sizeof(BBS_user_tz) - 1);
436     BBS_user_tz[sizeof(BBS_user_tz) - 1] = '\0';
437 sysadm 1.43
438     BBS_user_exp = atoi(row[3]);
439    
440     strncpy(BBS_nickname, row[4], sizeof(BBS_nickname));
441     BBS_nickname[sizeof(BBS_nickname) - 1] = '\0';
442 sysadm 1.11 }
443     else
444     {
445 sysadm 1.44 ret = -1; // Data not found
446     goto cleanup;
447 sysadm 1.11 }
448     mysql_free_result(rs);
449 sysadm 1.44 rs = NULL;
450 sysadm 1.3
451 sysadm 1.13 if (life != 333 && life != 365 && life != 666 && life != 999 && // Not immortal
452 sysadm 1.45 time(NULL) - last_login_dt > 60 * 60 * 24 * life)
453 sysadm 1.11 {
454 sysadm 1.44 ret = -3; // Dead
455     goto cleanup;
456 sysadm 1.11 }
457 sysadm 1.5
458 sysadm 1.15 if (load_priv(db, &BBS_priv, BBS_uid) != 0)
459     {
460 sysadm 1.74 ret = -1; // Data not found
461 sysadm 1.44 goto cleanup;
462 sysadm 1.15 }
463 sysadm 1.11
464 sysadm 1.73 if (last_login_dt < BBS_eula_tm)
465     {
466     ret = -2; // require update agreement first
467     goto cleanup;
468     }
469    
470 sysadm 1.44 cleanup:
471     mysql_free_result(rs);
472    
473     return ret;
474 sysadm 1.2 }
475 sysadm 1.5
476 sysadm 1.41 int load_guest_info(void)
477 sysadm 1.5 {
478 sysadm 1.44 MYSQL *db = NULL;
479     int ret = 0;
480 sysadm 1.41
481     db = db_open();
482     if (db == NULL)
483     {
484 sysadm 1.44 ret = -1;
485     goto cleanup;
486 sysadm 1.41 }
487    
488 sysadm 1.17 strncpy(BBS_username, "guest", sizeof(BBS_username) - 1);
489     BBS_username[sizeof(BBS_username) - 1] = '\0';
490 sysadm 1.5
491 sysadm 1.43 BBS_user_exp = 0;
492    
493     strncpy(BBS_nickname, "Guest", sizeof(BBS_nickname));
494     BBS_nickname[sizeof(BBS_nickname) - 1] = '\0';
495    
496 sysadm 1.15 if (load_priv(db, &BBS_priv, 0) != 0)
497     {
498 sysadm 1.44 ret = -1;
499     goto cleanup;
500 sysadm 1.15 }
501 sysadm 1.6
502 sysadm 1.15 if (user_online_add(db) != 0)
503     {
504 sysadm 1.44 ret = -1;
505     goto cleanup;
506 sysadm 1.15 }
507 sysadm 1.5
508 sysadm 1.45 BBS_last_access_tm = BBS_login_tm = time(NULL);
509 sysadm 1.5
510 sysadm 1.44 cleanup:
511 sysadm 1.41 mysql_close(db);
512 sysadm 1.44
513     return ret;
514 sysadm 1.5 }
515 sysadm 1.15
516     int user_online_add(MYSQL *db)
517     {
518     char sql[SQL_BUFFER_LEN];
519    
520 sysadm 1.60 snprintf(sql, sizeof(sql),
521     "INSERT INTO visit_log(dt, IP) VALUES(NOW(), '%s')",
522     hostaddr_client);
523     if (mysql_query(db, sql) != 0)
524     {
525 sysadm 1.75 log_error("Add visit log error: %s", mysql_error(db));
526 sysadm 1.60 return -1;
527     }
528    
529 sysadm 1.15 if (user_online_del(db) != 0)
530     {
531 sysadm 1.60 return -2;
532 sysadm 1.15 }
533    
534 sysadm 1.18 snprintf(sql, sizeof(sql),
535 sysadm 1.61 "INSERT INTO user_online(SID, UID, ip, current_action, login_tm, last_tm) "
536     "VALUES('Telnet_Process_%d', %d, '%s', 'LOGIN', NOW(), NOW())",
537 sysadm 1.22 getpid(), BBS_priv.uid, hostaddr_client);
538 sysadm 1.15 if (mysql_query(db, sql) != 0)
539     {
540 sysadm 1.75 log_error("Add user_online error: %s", mysql_error(db));
541 sysadm 1.60 return -3;
542 sysadm 1.15 }
543    
544     return 0;
545     }
546    
547     int user_online_del(MYSQL *db)
548     {
549     char sql[SQL_BUFFER_LEN];
550    
551 sysadm 1.57 snprintf(sql, sizeof(sql),
552     "DELETE FROM user_online WHERE SID = 'Telnet_Process_%d'",
553     getpid());
554     if (mysql_query(db, sql) != 0)
555     {
556 sysadm 1.75 log_error("Delete user_online error: %s", mysql_error(db));
557 sysadm 1.57 return -1;
558     }
559    
560     return 0;
561     }
562    
563     int user_online_exp(MYSQL *db)
564     {
565     char sql[SQL_BUFFER_LEN];
566    
567 sysadm 1.56 // +1 exp for every 5 minutes online since last logout
568     // but at most 24 hours worth of exp can be gained in Telnet session
569     snprintf(sql, sizeof(sql),
570 sysadm 1.60 "UPDATE user_pubinfo SET exp = exp + FLOOR(LEAST(TIMESTAMPDIFF("
571     "SECOND, GREATEST(last_login_dt, IF(last_logout_dt IS NULL, last_login_dt, last_logout_dt)), NOW()"
572     ") / 60 / 5, 12 * 24)), last_logout_dt = NOW() "
573     "WHERE UID = %d",
574     BBS_priv.uid);
575 sysadm 1.56 if (mysql_query(db, sql) != 0)
576     {
577 sysadm 1.75 log_error("Update user_pubinfo error: %s", mysql_error(db));
578 sysadm 1.56 return -1;
579     }
580 sysadm 1.15
581     return 0;
582     }
583 sysadm 1.47
584     int user_online_update(const char *action)
585     {
586     MYSQL *db = NULL;
587     char sql[SQL_BUFFER_LEN];
588    
589 sysadm 1.55 if ((action == NULL || strcmp(BBS_current_action, action) == 0) &&
590 sysadm 1.54 time(NULL) - BBS_current_action_tm < BBS_current_action_refresh_interval) // No change
591 sysadm 1.47 {
592     return 0;
593     }
594    
595 sysadm 1.55 if (action != NULL)
596     {
597     strncpy(BBS_current_action, action, sizeof(BBS_current_action) - 1);
598     BBS_current_action[sizeof(BBS_current_action) - 1] = '\0';
599     }
600    
601 sysadm 1.54 BBS_current_action_tm = time(NULL);
602 sysadm 1.47
603     db = db_open();
604     if (db == NULL)
605     {
606 sysadm 1.75 log_error("db_open() error: %s", mysql_error(db));
607 sysadm 1.47 return -1;
608     }
609    
610     snprintf(sql, sizeof(sql),
611 sysadm 1.62 "UPDATE user_online SET current_action = '%s', last_tm = NOW() "
612 sysadm 1.47 "WHERE SID = 'Telnet_Process_%d'",
613     BBS_current_action, getpid());
614     if (mysql_query(db, sql) != 0)
615     {
616 sysadm 1.75 log_error("Update user_online error: %s", mysql_error(db));
617 sysadm 1.47 return -2;
618     }
619    
620     mysql_close(db);
621    
622     return 1;
623     }
624 sysadm 1.74
625     int user_update_agreement(void)
626     {
627     MYSQL *db = NULL;
628     char sql[SQL_BUFFER_LEN];
629     int ch;
630     int ret = 0;
631    
632     clearscr();
633     moveto(2, 1);
634     prints("尊敬的用户:");
635     moveto(3, 1);
636     prints(" 本站的《用户许可协议》已更新,您必须在仔细阅读并接受后,才能继续使用本站提供的服务。");
637     press_any_key();
638    
639     clearscr();
640     display_file(DATA_EULA, 1);
641    
642     while (!SYS_server_exit)
643     {
644     clearscr();
645     moveto(2, 1);
646    
647     ch = press_any_key_ex("您是否接受本站的《用户许可协议》? (A)接受, (D)拒绝, (R)再看看协议 [D]", 60);
648     switch (toupper(ch))
649     {
650     case KEY_NULL:
651     return -1;
652     case KEY_TIMEOUT:
653     case CR:
654     case 'D':
655     moveto(3, 1);
656     prints("您已拒绝《用户许可协议》,再见!");
657     press_any_key();
658     return 0;
659     case 'R':
660     clearscr();
661     display_file(DATA_EULA, 1);
662     continue;
663     case 'A':
664     db = db_open();
665     if (db == NULL)
666     {
667     ret = -1;
668     goto cleanup;
669     }
670    
671     snprintf(sql, sizeof(sql),
672     "UPDATE user_pubinfo SET visit_count = visit_count + 1, "
673     "last_login_dt = NOW() WHERE UID = %d",
674     BBS_priv.uid);
675     if (mysql_query(db, sql) != 0)
676     {
677 sysadm 1.75 log_error("Update user_pubinfo error: %s", mysql_error(db));
678 sysadm 1.74 ret = -1;
679     goto cleanup;
680     }
681    
682     mysql_close(db);
683     db = NULL;
684    
685     moveto(3, 1);
686     prints("您已接受《用户许可协议》,请重新登陆。");
687     press_any_key();
688     return 1;
689     default:
690     continue;
691     }
692    
693     break;
694     }
695    
696     cleanup:
697     mysql_close(db);
698    
699     return ret;
700     }

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