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

Diff of /lbbs/src/user_list.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.8 by sysadm, Wed Oct 22 07:16:48 2025 UTC Revision 1.14 by sysadm, Wed Oct 22 16:12:50 2025 UTC
# Line 106  static int user_info_index_uid_comp(cons Line 106  static int user_info_index_uid_comp(cons
106          {          {
107                  return 1;                  return 1;
108          }          }
109            else if (p1->id < p2->id)
110            {
111                    return -1;
112            }
113            else if (p1->id > p2->id)
114            {
115                    return 1;
116            }
117          return 0;          return 0;
118  }  }
119    
120  int user_list_load(MYSQL *db, USER_LIST *p_list)  int user_list_load(MYSQL *db, USER_LIST *p_list)
121  {  {
122            USER_INFO_INDEX_UID index_uid[BBS_max_user_count];
123          MYSQL_RES *rs = NULL;          MYSQL_RES *rs = NULL;
124          MYSQL_ROW row;          MYSQL_ROW row;
125          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
126          int ret = 0;          int ret = 0;
127          int i;          int i = 0;
128            int32_t last_uid = -1;
129            size_t intro_buf_offset = 0L;
130            size_t intro_len;
131    
132          if (db == NULL || p_list == NULL)          if (db == NULL || p_list == NULL)
133          {          {
# Line 123  int user_list_load(MYSQL *db, USER_LIST Line 135  int user_list_load(MYSQL *db, USER_LIST
135                  return -1;                  return -1;
136          }          }
137    
138            if (p_list->user_count > 0)
139            {
140                    last_uid = p_list->users[p_list->user_count - 1].uid;
141            }
142    
143          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
144                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, "                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, visit_count, "
145                           "UNIX_TIMESTAMP(signup_dt), UNIX_TIMESTAMP(last_login_dt), UNIX_TIMESTAMP(birthday) "                           "UNIX_TIMESTAMP(signup_dt), UNIX_TIMESTAMP(last_login_dt), UNIX_TIMESTAMP(birthday), `introduction` "
146                           "FROM user_list INNER JOIN user_pubinfo ON user_list.UID = user_pubinfo.UID "                           "FROM user_list INNER JOIN user_pubinfo ON user_list.UID = user_pubinfo.UID "
147                           "INNER JOIN user_reginfo ON user_list.UID = user_reginfo.UID "                           "INNER JOIN user_reginfo ON user_list.UID = user_reginfo.UID "
148                           "WHERE enable ORDER BY username");                           "WHERE enable ORDER BY username");
# Line 144  int user_list_load(MYSQL *db, USER_LIST Line 161  int user_list_load(MYSQL *db, USER_LIST
161                  goto cleanup;                  goto cleanup;
162          }          }
163    
164            intro_buf_offset = 0;
165          i = 0;          i = 0;
166          while ((row = mysql_fetch_row(rs)))          while ((row = mysql_fetch_row(rs)))
167          {          {
# Line 158  int user_list_load(MYSQL *db, USER_LIST Line 176  int user_list_load(MYSQL *db, USER_LIST
176                  p_list->users[i].gender_pub = (int8_t)(row[4] == NULL ? 0 : atoi(row[4]));                  p_list->users[i].gender_pub = (int8_t)(row[4] == NULL ? 0 : atoi(row[4]));
177                  p_list->users[i].life = (row[5] == NULL ? 0 : atoi(row[5]));                  p_list->users[i].life = (row[5] == NULL ? 0 : atoi(row[5]));
178                  p_list->users[i].exp = (row[6] == NULL ? 0 : atoi(row[6]));                  p_list->users[i].exp = (row[6] == NULL ? 0 : atoi(row[6]));
179                  p_list->users[i].signup_dt = (row[7] == NULL ? 0 : atol(row[7]));                  p_list->users[i].visit_count = (row[7] == NULL ? 0 : atoi(row[7]));
180                  p_list->users[i].last_login_dt = (row[8] == NULL ? 0 : atol(row[8]));                  p_list->users[i].signup_dt = (row[8] == NULL ? 0 : atol(row[8]));
181                  p_list->users[i].birthday = (row[9] == NULL ? 0 : atol(row[9]));                  p_list->users[i].last_login_dt = (row[9] == NULL ? 0 : atol(row[9]));
182                    p_list->users[i].birthday = (row[10] == NULL ? 0 : atol(row[10]));
183                    intro_len = strlen((row[11] == NULL ? "" : row[11]));
184                    if (intro_len >= sizeof(p_list->user_intro_buf) - 1 - intro_buf_offset)
185                    {
186                            log_error("OOM for user introduction: len=%d, i=%d\n", intro_len, i);
187                            break;
188                    }
189                    memcpy(p_list->user_intro_buf + intro_buf_offset,
190                               (row[11] == NULL ? "" : row[11]),
191                               intro_len + 1);
192                    p_list->users[i].intro = p_list->user_intro_buf + intro_buf_offset;
193                    intro_buf_offset += (intro_len + 1);
194    
195                  // index                  // index
196                  p_list->index_uid[i].uid = p_list->users[i].uid;                  index_uid[i].uid = p_list->users[i].uid;
197                  p_list->index_uid[i].id = i;                  index_uid[i].id = i;
198    
199                  i++;                  i++;
200                  if (i >= BBS_max_user_count)                  if (i >= BBS_max_user_count)
# Line 176  int user_list_load(MYSQL *db, USER_LIST Line 206  int user_list_load(MYSQL *db, USER_LIST
206          mysql_free_result(rs);          mysql_free_result(rs);
207          rs = NULL;          rs = NULL;
208    
         p_list->user_count = i;  
   
209          // Sort index          // Sort index
210          qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);          if (i != p_list->user_count || p_list->users[i - 1].uid != last_uid) // Count of users changed
211            {
212                    qsort(index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
213                    memcpy(p_list->index_uid, index_uid, sizeof(USER_INFO_INDEX_UID) * (size_t)i);
214    
215    #ifdef _DEBUG
216                    log_error("Rebuild index of %d users, last_uid=%d\n", i, p_list->users[i - 1].uid);
217    #endif
218            }
219    
220            p_list->user_count = i;
221    
222  #ifdef _DEBUG  #ifdef _DEBUG
223          log_error("Loaded %d users\n", p_list->user_count);          log_error("Loaded %d users\n", p_list->user_count);
# Line 208  int user_online_list_load(MYSQL *db, USE Line 246  int user_online_list_load(MYSQL *db, USE
246          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
247                           "SELECT SID, UID, ip, current_action, UNIX_TIMESTAMP(login_tm), "                           "SELECT SID, UID, ip, current_action, UNIX_TIMESTAMP(login_tm), "
248                           "UNIX_TIMESTAMP(last_tm) FROM user_online "                           "UNIX_TIMESTAMP(last_tm) FROM user_online "
249                           "WHERE last_tm >= SUBDATE(NOW(), INTERVAL %d SECOND) "                           "WHERE last_tm >= SUBDATE(NOW(), INTERVAL %d SECOND) AND UID <> 0 "
250                           "ORDER BY last_tm DESC",                           "ORDER BY last_tm DESC",
251                           BBS_user_off_line);                           BBS_user_off_line);
252    
# Line 233  int user_online_list_load(MYSQL *db, USE Line 271  int user_online_list_load(MYSQL *db, USE
271                  strncpy(p_list->users[i].session_id, row[0], sizeof(p_list->users[i].session_id) - 1);                  strncpy(p_list->users[i].session_id, row[0], sizeof(p_list->users[i].session_id) - 1);
272                  p_list->users[i].session_id[sizeof(p_list->users[i].session_id) - 1] = '\0';                  p_list->users[i].session_id[sizeof(p_list->users[i].session_id) - 1] = '\0';
273    
274                  if ((ret = query_user_info_by_uid(atoi(row[1]), &(p_list->users[i].user_info))) < 0)                  if ((ret = query_user_info_by_uid(atoi(row[1]), &(p_list->users[i].user_info))) <= 0)
275                  {                  {
276                          log_error("query_user_info(%d) error\n", atoi(row[1]));                          log_error("query_user_info_by_uid(%d) error\n", atoi(row[1]));
277                          continue;                          continue;
278                  }                  }
                 else if (ret == 0) // Guest  
                 {  
                         p_list->users[i].user_info.id = -1;  
                         p_list->users[i].user_info.uid = 0;  
                         strncpy(p_list->users[i].user_info.username, "guest", sizeof(p_list->users[i].user_info.username) - 1);  
                         p_list->users[i].user_info.username[sizeof(p_list->users[i].user_info.username) - 1] = '\0';  
                         strncpy(p_list->users[i].user_info.nickname, "Guest", sizeof(p_list->users[i].user_info.nickname) - 1);  
                         p_list->users[i].user_info.nickname[sizeof(p_list->users[i].user_info.nickname) - 1] = '\0';  
                         p_list->users[i].user_info.gender = 'M';  
                         p_list->users[i].user_info.gender_pub = 0;  
                         p_list->users[i].user_info.life = 150;  
                         p_list->users[i].user_info.exp = 0;  
                         p_list->users[i].user_info.signup_dt = 0;  
                         p_list->users[i].user_info.last_login_dt = 0;  
                         p_list->users[i].user_info.birthday = 0;  
                 }  
279    
280                  strncpy(p_list->users[i].ip, row[2], sizeof(p_list->users[i].ip) - 1);                  strncpy(p_list->users[i].ip, row[2], sizeof(p_list->users[i].ip) - 1);
281                  p_list->users[i].ip[sizeof(p_list->users[i].ip) - 1] = '\0';                  p_list->users[i].ip[sizeof(p_list->users[i].ip) - 1] = '\0';
# Line 275  int user_online_list_load(MYSQL *db, USE Line 297  int user_online_list_load(MYSQL *db, USE
297                  p_list->users[i].login_tm = (row[4] == NULL ? 0 : atol(row[4]));                  p_list->users[i].login_tm = (row[4] == NULL ? 0 : atol(row[4]));
298                  p_list->users[i].last_tm = (row[5] == NULL ? 0 : atol(row[5]));                  p_list->users[i].last_tm = (row[5] == NULL ? 0 : atol(row[5]));
299    
300                    // index
301                    p_list->index_uid[i].uid = p_list->users[i].user_info.uid;
302                    p_list->index_uid[i].id = i;
303    
304                  i++;                  i++;
305                  if (i >= BBS_max_user_online_count)                  if (i >= BBS_max_user_online_count)
306                  {                  {
# Line 285  int user_online_list_load(MYSQL *db, USE Line 311  int user_online_list_load(MYSQL *db, USE
311          mysql_free_result(rs);          mysql_free_result(rs);
312          rs = NULL;          rs = NULL;
313    
314            // Sort index
315            if (i > 0)
316            {
317                    qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
318    #ifdef _DEBUG
319                    log_error("Rebuild index of %d online users\n", i);
320    #endif
321            }
322    
323          p_list->user_count = i;          p_list->user_count = i;
324    
325  #ifdef _DEBUG  #ifdef _DEBUG
326          log_error("Loaded %d users\n", p_list->user_count);          log_error("Loaded %d online users\n", p_list->user_count);
327  #endif  #endif
328    
329  cleanup:  cleanup:
# Line 470  int user_list_pool_reload(int online_use Line 505  int user_list_pool_reload(int online_use
505          MYSQL *db = NULL;          MYSQL *db = NULL;
506          USER_LIST *p_tmp;          USER_LIST *p_tmp;
507          USER_ONLINE_LIST *p_online_tmp;          USER_ONLINE_LIST *p_online_tmp;
508            int ret = 0;
509    
510          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
511          {          {
# Line 489  int user_list_pool_reload(int online_use Line 525  int user_list_pool_reload(int online_use
525                  if (user_online_list_load(db, p_user_list_pool->p_online_new) < 0)                  if (user_online_list_load(db, p_user_list_pool->p_online_new) < 0)
526                  {                  {
527                          log_error("user_online_list_load() error\n");                          log_error("user_online_list_load() error\n");
528                          return -2;                          ret = -2;
529                            goto cleanup;
530                  }                  }
531          }          }
532          else          else
# Line 497  int user_list_pool_reload(int online_use Line 534  int user_list_pool_reload(int online_use
534                  if (user_list_load(db, p_user_list_pool->p_new) < 0)                  if (user_list_load(db, p_user_list_pool->p_new) < 0)
535                  {                  {
536                          log_error("user_list_load() error\n");                          log_error("user_list_load() error\n");
537                          return -2;                          ret = -2;
538                            goto cleanup;
539                  }                  }
540          }          }
541    
542          mysql_close(db);          mysql_close(db);
543            db = NULL;
544    
545          if (user_list_rw_lock(p_user_list_pool->semid) < 0)          if (user_list_rw_lock(p_user_list_pool->semid) < 0)
546          {          {
547                  log_error("user_list_rw_lock() error\n");                  log_error("user_list_rw_lock() error\n");
548                  return -3;                  ret = -3;
549                    goto cleanup;
550          }          }
551    
552          if (online_user)          if (online_user)
# Line 527  int user_list_pool_reload(int online_use Line 567  int user_list_pool_reload(int online_use
567          if (user_list_rw_unlock(p_user_list_pool->semid) < 0)          if (user_list_rw_unlock(p_user_list_pool->semid) < 0)
568          {          {
569                  log_error("user_list_rw_unlock() error\n");                  log_error("user_list_rw_unlock() error\n");
570                  return -3;                  ret = -3;
571                    goto cleanup;
572          }          }
573    
574          return 0;  cleanup:
575            mysql_close(db);
576    
577            return ret;
578  }  }
579    
580  int user_list_try_rd_lock(int semid, int wait_sec)  int user_list_try_rd_lock(int semid, int wait_sec)
# Line 695  int query_user_list(int page_id, USER_IN Line 739  int query_user_list(int page_id, USER_IN
739                  return -1;                  return -1;
740          }          }
741    
742            *p_user_count = 0;
743            *p_page_count = 0;
744    
745          // acquire lock of user list          // acquire lock of user list
746          if (user_list_rd_lock(p_user_list_pool->semid) < 0)          if (user_list_rd_lock(p_user_list_pool->semid) < 0)
747          {          {
# Line 748  int query_user_online_list(int page_id, Line 795  int query_user_online_list(int page_id,
795                  return -1;                  return -1;
796          }          }
797    
798            *p_user_count = 0;
799            *p_page_count = 0;
800    
801          // acquire lock of user list          // acquire lock of user list
802          if (user_list_rd_lock(p_user_list_pool->semid) < 0)          if (user_list_rd_lock(p_user_list_pool->semid) < 0)
803          {          {
# Line 869  int query_user_info_by_uid(int32_t uid, Line 919  int query_user_info_by_uid(int32_t uid,
919          if (uid == p_user_list_pool->p_current->index_uid[left].uid) // Found          if (uid == p_user_list_pool->p_current->index_uid[left].uid) // Found
920          {          {
921                  id = p_user_list_pool->p_current->index_uid[left].id;                  id = p_user_list_pool->p_current->index_uid[left].id;
922                  if ((ret = query_user_info(id, p_user)) <= 0)                  *p_user = p_user_list_pool->p_current->users[id];
923                  {                  ret = 1;
                         log_error("query_user_info(id=%d) error: %d\n", id, ret);  
                 }  
                 else  
                 {  
                         ret = 1;  
                 }  
924          }          }
925    
926          // release lock of user list          // release lock of user list
# Line 913  int query_user_online_info(int32_t id, U Line 957  int query_user_online_info(int32_t id, U
957          }          }
958    
959          // release lock of user list          // release lock of user list
960            if (user_list_rd_unlock(p_user_list_pool->semid) < 0)
961            {
962                    log_error("user_list_rd_unlock() error\n");
963                    ret = -1;
964            }
965    
966            return ret;
967    }
968    
969    int query_user_online_info_by_uid(int32_t uid, USER_ONLINE_INFO *p_users, int *p_user_cnt, int start_id)
970    {
971            int left;
972            int right;
973            int mid;
974            int32_t id;
975            int ret = 0;
976            int i;
977    
978            if (p_users == NULL || p_user_cnt == NULL)
979            {
980                    log_error("NULL pointer error\n");
981                    return -1;
982            }
983    
984            // acquire lock of user list
985            if (user_list_rd_lock(p_user_list_pool->semid) < 0)
986            {
987                    log_error("user_list_rd_lock() error\n");
988                    return -2;
989            }
990    
991            left = start_id;
992            right = p_user_list_pool->p_online_current->user_count - 1;
993    
994            while (left < right)
995            {
996                    mid = (left + right) / 2;
997                    if (uid < p_user_list_pool->p_online_current->index_uid[mid].uid)
998                    {
999                            right = mid;
1000                    }
1001                    else if (uid > p_user_list_pool->p_online_current->index_uid[mid].uid)
1002                    {
1003                            left = mid + 1;
1004                    }
1005                    else // if (uid == p_user_list_pool->p_online_current->index_uid[mid].uid)
1006                    {
1007                            left = mid;
1008                            break;
1009                    }
1010            }
1011    
1012            if (uid == p_user_list_pool->p_online_current->index_uid[left].uid)
1013            {
1014                    right = left;
1015                    left = start_id;
1016    
1017                    while (left < right)
1018                    {
1019                            mid = (left + right) / 2;
1020                            if (uid - 1 < p_user_list_pool->p_online_current->index_uid[mid].uid)
1021                            {
1022                                    right = mid;
1023                            }
1024                            else // if (uid - 1 >= p_user_list_pool->p_online_current->index_uid[mid].uid)
1025                            {
1026                                    left = mid + 1;
1027                            }
1028                    }
1029    
1030                    for (i = 0;
1031                             left < p_user_list_pool->p_online_current->user_count && i < *p_user_cnt &&
1032                             uid == p_user_list_pool->p_online_current->index_uid[left].uid;
1033                             left++, i++)
1034                    {
1035                            id = p_user_list_pool->p_online_current->index_uid[left].id;
1036                            p_users[i] = p_user_list_pool->p_online_current->users[id];
1037                    }
1038    
1039                    if (i > 0)
1040                    {
1041                            *p_user_cnt = i;
1042                            ret = 1;
1043                    }
1044            }
1045    
1046            // release lock of user list
1047          if (user_list_rd_unlock(p_user_list_pool->semid) < 0)          if (user_list_rd_unlock(p_user_list_pool->semid) < 0)
1048          {          {
1049                  log_error("user_list_rd_unlock() error\n");                  log_error("user_list_rd_unlock() error\n");


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

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