/[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.22 - (show annotations)
Fri Oct 24 02:07:01 2025 UTC (4 months, 3 weeks ago) by sysadm
Branch: MAIN
Changes since 1.21: +9 -4 lines
Content type: text/x-csrc
Refine search algorithm

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

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