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

Contents of /lbbs/src/user_priv.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.29 - (show annotations)
Fri Feb 13 12:38:09 2026 UTC (4 weeks, 4 days ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.28: +6 -0 lines
Content type: text/x-csrc
Fix build error caused by inline function under Debug mode with CMake

1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 /*
3 * user_priv
4 * - basic operations of user privilege
5 *
6 * Copyright (C) 2004-2026 Leaflet <leaflet@leafok.com>
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "bbs.h"
14 #include "common.h"
15 #include "database.h"
16 #include "log.h"
17 #include "user_priv.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <mysql.h>
21
22 BBS_user_priv BBS_priv;
23
24 // External definitions for inline functions
25 extern inline int checklevel(BBS_user_priv *p_priv, int level);
26 extern inline int checklevel2(BBS_user_priv *p_priv, int level);
27 extern inline int checkpriv(BBS_user_priv *p_priv, int sid, int priv);
28 extern inline int is_favor(BBS_user_priv *p_priv, int sid);
29
30 inline static int search_priv(BBS_user_priv *p_priv, int sid, int *p_offset)
31 {
32 int left = 0;
33 int right = p_priv->s_count - 1;
34 int mid = 0;
35
36 while (left < right)
37 {
38 mid = (left + right) / 2;
39
40 if (sid < p_priv->s_priv_list[mid].sid)
41 {
42 right = mid - 1;
43 }
44 else if (sid > p_priv->s_priv_list[mid].sid)
45 {
46 left = mid + 1;
47 }
48 else // if (sid == p_priv->s_priv_list[mid].sid)
49 {
50 left = mid;
51 break;
52 }
53 }
54
55 *p_offset = left;
56
57 return (sid == p_priv->s_priv_list[left].sid);
58 }
59
60 int setpriv(BBS_user_priv *p_priv, int sid, int priv, int is_favor)
61 {
62 int offset;
63 int i;
64
65 if (sid == 0)
66 {
67 p_priv->g_priv = priv;
68 return 0;
69 }
70
71 if (search_priv(p_priv, sid, &offset)) // found
72 {
73 p_priv->s_priv_list[offset].s_priv = priv;
74 p_priv->s_priv_list[offset].is_favor = is_favor;
75 return 0;
76 }
77
78 // not found
79 if (p_priv->s_count >= BBS_max_section)
80 {
81 return -1;
82 }
83
84 // move items at [left, p_priv->s_count - 1] to [left + 1, p_priv->s_count]
85 for (i = p_priv->s_count - 1; i >= offset; i--)
86 {
87 p_priv->s_priv_list[i + 1] = p_priv->s_priv_list[i];
88 }
89 p_priv->s_count++;
90
91 // insert new item at offset left
92 p_priv->s_priv_list[offset].sid = sid;
93 p_priv->s_priv_list[offset].s_priv = priv;
94 p_priv->s_priv_list[offset].is_favor = is_favor;
95
96 return 0;
97 }
98
99 int getpriv(BBS_user_priv *p_priv, int sid, int *p_is_favor)
100 {
101 int offset;
102
103 if (search_priv(p_priv, sid, &offset)) // found
104 {
105 *p_is_favor = p_priv->s_priv_list[offset].is_favor;
106 return p_priv->s_priv_list[offset].s_priv;
107 }
108
109 *p_is_favor = 0;
110 return (sid >= 0 ? p_priv->g_priv : S_NONE);
111 }
112
113 int load_priv(MYSQL *db, BBS_user_priv *p_priv, int uid)
114 {
115 MYSQL_RES *rs;
116 MYSQL_ROW row;
117 char sql[SQL_BUFFER_LEN];
118 int priv;
119 int is_favor;
120
121 p_priv->uid = uid;
122 p_priv->level = (uid == 0 ? P_GUEST : P_USER);
123 p_priv->g_priv = S_DEFAULT;
124 p_priv->s_count = 0;
125
126 if (db == NULL)
127 return 1;
128
129 // Permission
130 snprintf(sql, sizeof(sql),
131 "SELECT p_post, p_msg FROM user_list WHERE UID = %d AND verified",
132 uid);
133 if (mysql_query(db, sql) != 0)
134 {
135 log_error("Query user_list error: %s", mysql_error(db));
136 return -1;
137 }
138 if ((rs = mysql_store_result(db)) == NULL)
139 {
140 log_error("Get user_list data failed");
141 return -1;
142 }
143 if ((row = mysql_fetch_row(rs)))
144 {
145 p_priv->g_priv |= (atoi(row[0]) ? S_POST : 0);
146 p_priv->g_priv |= (atoi(row[1]) ? S_MSG : 0);
147 }
148 mysql_free_result(rs);
149
150 // Admin
151 snprintf(sql, sizeof(sql),
152 "SELECT major FROM admin_config WHERE UID = %d "
153 "AND enable AND (NOW() BETWEEN begin_dt AND end_dt)",
154 uid);
155 if (mysql_query(db, sql) != 0)
156 {
157 log_error("Query admin_config error: %s", mysql_error(db));
158 return -1;
159 }
160 if ((rs = mysql_store_result(db)) == NULL)
161 {
162 log_error("Get admin_config data failed");
163 return -1;
164 }
165 if ((row = mysql_fetch_row(rs)))
166 {
167 p_priv->level |= (atoi(row[0]) ? P_ADMIN_M : P_ADMIN_S);
168 p_priv->g_priv |= (atoi(row[0]) ? S_ALL : S_ADMIN);
169 }
170 mysql_free_result(rs);
171
172 // Section Master
173 snprintf(sql, sizeof(sql),
174 "SELECT section_master.SID, major FROM section_master "
175 "INNER JOIN section_config ON section_master.SID = section_config.SID "
176 "WHERE UID = %d AND section_master.enable AND section_config.enable "
177 "AND (NOW() BETWEEN begin_dt AND end_dt)",
178 uid);
179 if (mysql_query(db, sql) != 0)
180 {
181 log_error("Query section_master error: %s", mysql_error(db));
182 return -1;
183 }
184 if ((rs = mysql_store_result(db)) == NULL)
185 {
186 log_error("Get section_master data failed");
187 return -1;
188 }
189 while ((row = mysql_fetch_row(rs)))
190 {
191 p_priv->level |= (atoi(row[1]) ? P_MAN_M : P_MAN_S);
192 priv = (getpriv(p_priv, atoi(row[0]), &is_favor) | (atoi(row[1]) ? S_MAN_M : S_MAN_S));
193 setpriv(p_priv, atoi(row[0]), priv, is_favor);
194 }
195 mysql_free_result(rs);
196
197 // Section status
198 snprintf(sql, sizeof(sql),
199 "SELECT SID, exp_get, read_user_level, write_user_level FROM section_config "
200 "INNER JOIN section_class ON section_config.CID = section_class.CID "
201 "WHERE section_config.enable AND section_class.enable "
202 "ORDER BY SID");
203 if (mysql_query(db, sql) != 0)
204 {
205 log_error("Query section_config error: %s", mysql_error(db));
206 return -1;
207 }
208 if ((rs = mysql_store_result(db)) == NULL)
209 {
210 log_error("Get section_config data failed");
211 return -1;
212 }
213 while ((row = mysql_fetch_row(rs)))
214 {
215 int priv = getpriv(p_priv, atoi(row[0]), &is_favor);
216 if (p_priv->level < atoi(row[2]))
217 {
218 priv &= (~S_LIST);
219 }
220 if (p_priv->level < atoi(row[3]))
221 {
222 priv &= (~S_POST);
223 }
224 if (!atoi(row[1]))
225 {
226 priv &= (~S_GETEXP);
227 }
228 setpriv(p_priv, atoi(row[0]), priv, is_favor);
229 }
230 mysql_free_result(rs);
231
232 // Section ban
233 snprintf(sql, sizeof(sql),
234 "SELECT SID FROM ban_user_list WHERE UID = %d AND enable "
235 "AND (NOW() BETWEEN ban_dt AND unban_dt)",
236 uid);
237 if (mysql_query(db, sql) != 0)
238 {
239 log_error("Query ban_user_list error: %s", mysql_error(db));
240 return -1;
241 }
242 if ((rs = mysql_store_result(db)) == NULL)
243 {
244 log_error("Get ban_user_list data failed");
245 return -1;
246 }
247 while ((row = mysql_fetch_row(rs)))
248 {
249 priv = getpriv(p_priv, atoi(row[0]), &is_favor) & (~S_POST);
250 setpriv(p_priv, atoi(row[0]), priv, is_favor);
251 }
252 mysql_free_result(rs);
253
254 // User favor section
255 snprintf(sql, sizeof(sql),
256 "SELECT SID FROM section_favorite WHERE UID = %d",
257 uid);
258 if (mysql_query(db, sql) != 0)
259 {
260 log_error("Query section_favorite error: %s", mysql_error(db));
261 return -1;
262 }
263 if ((rs = mysql_store_result(db)) == NULL)
264 {
265 log_error("Get section_favorite data failed");
266 return -1;
267 }
268 while ((row = mysql_fetch_row(rs)))
269 {
270 priv = getpriv(p_priv, atoi(row[0]), &is_favor);
271 if (!is_favor)
272 {
273 setpriv(p_priv, atoi(row[0]), priv, 1);
274 priv = getpriv(p_priv, atoi(row[0]), &is_favor);
275 }
276 }
277 mysql_free_result(rs);
278
279 return 0;
280 }

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