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

Contents of /lbbs/src/section_list_display.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.81 - (show annotations)
Wed Dec 17 03:47:00 2025 UTC (2 months, 4 weeks ago) by sysadm
Branch: MAIN
Changes since 1.80: +4 -0 lines
Content type: text/x-csrc
Refine debug log

1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 /*
3 * section_list_display
4 * - user interactive feature of section articles list
5 *
6 * Copyright (C) 2004-2025 Leaflet <leaflet@leafok.com>
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "article_cache.h"
14 #include "article_favor.h"
15 #include "article_op.h"
16 #include "article_post.h"
17 #include "article_view_log.h"
18 #include "article_del.h"
19 #include "common.h"
20 #include "io.h"
21 #include "log.h"
22 #include "login.h"
23 #include "menu.h"
24 #include "menu_proc.h"
25 #include "section_list_display.h"
26 #include "section_list_loader.h"
27 #include "screen.h"
28 #include "str_process.h"
29 #include "user_info_display.h"
30 #include "user_list_display.h"
31 #include "user_priv.h"
32 #include <ctype.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <time.h>
36 #include <sys/param.h>
37
38 enum _section_list_display_constant_t
39 {
40 TITLE_SEARCH_MAX_LEN = 60,
41 };
42
43 static int32_t section_aid_locations[BBS_max_section] = {0};
44 static int section_topic_view_mode = 0;
45 static int section_topic_view_tid = -1;
46
47 enum select_cmd_t
48 {
49 EXIT_SECTION = 0,
50 VIEW_ARTICLE,
51 CHANGE_PAGE,
52 SHOW_HELP,
53 CHANGE_NAME_DISPLAY,
54 POST_ARTICLE,
55 EDIT_ARTICLE,
56 DELETE_ARTICLE,
57 QUERY_ARTICLE,
58 QUERY_USER,
59 SET_FAVOR_ARTICLE,
60 UNSET_FAVOR_ARTICLE,
61 FIRST_TOPIC_ARTICLE,
62 LAST_TOPIC_ARTICLE,
63 LAST_SECTION_ARTICLE,
64 SCAN_NEW_ARTICLE,
65 SCAN_ARTICLE_BACKWARD_BY_USER,
66 SCAN_ARTICLE_FORWARD_BY_USER,
67 SCAN_ARTICLE_BACKWARD_BY_TITLE,
68 SCAN_ARTICLE_FORWARD_BY_TITLE,
69 VIEW_EX_DIR,
70 SHOW_TOP10,
71 SEARCH_USER,
72 };
73
74 static int section_list_draw_items(int page_id, const ARTICLE *p_articles[], int article_count, int display_nickname, int ontop_start_offset)
75 {
76 char str_time[LINE_BUFFER_LEN];
77 struct tm tm_sub;
78 char title_f[BBS_article_title_max_len + 1];
79 int title_f_len;
80 int eol;
81 int len;
82 int i;
83 size_t j;
84 char article_flag;
85 int is_viewed;
86 int is_favor;
87 time_t tm_now;
88
89 time(&tm_now);
90
91 clrline(4, 23);
92
93 for (i = 0; i < article_count; i++)
94 {
95 if (p_articles[i]->uid == BBS_priv.uid)
96 {
97 is_viewed = 1;
98 }
99 else
100 {
101 is_viewed = article_view_log_is_viewed(p_articles[i]->aid, &BBS_article_view_log);
102 if (is_viewed < 0)
103 {
104 log_error("article_view_log_is_viewed(aid=%d) error\n", p_articles[i]->aid);
105 is_viewed = 0;
106 }
107 }
108
109 if (p_articles[i]->tid == 0)
110 {
111 is_favor = article_favor_check(p_articles[i]->aid, &BBS_article_favor);
112 if (is_favor < 0)
113 {
114 log_error("article_favor_check(aid=%d) error\n", p_articles[i]->aid);
115 is_favor = 0;
116 }
117 }
118 else
119 {
120 is_favor = 0;
121 }
122
123 if (p_articles[i]->excerption)
124 {
125 article_flag = (is_viewed ? 'm' : 'M');
126 }
127 else if (p_articles[i]->lock && is_viewed)
128 {
129 article_flag = 'x';
130 }
131 else
132 {
133 article_flag = (is_viewed ? ' ' : 'N');
134 }
135
136 localtime_r(&p_articles[i]->sub_dt, &tm_sub);
137 if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)
138 {
139 strftime(str_time, sizeof(str_time), "%b %e ", &tm_sub);
140 }
141 else
142 {
143 strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);
144 }
145
146 strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);
147 title_f[sizeof(title_f) - 1] = '\0';
148 strncat(title_f, (p_articles[i]->transship ? "[转载]" : ""), sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
149
150 // Rewrite title with "Re: Re: " prefix into "Re: ... "
151 j = 0;
152 if (p_articles[i]->tid != 0)
153 {
154 while (strncmp(p_articles[i]->title + j, "Re: ", strlen("Re: ")) == 0)
155 {
156 j += strlen("Re: ");
157 }
158 if (j >= strlen("Re: Re: "))
159 {
160 strncat(title_f, "Re: ... ", sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
161 }
162 else
163 {
164 j = 0;
165 }
166 }
167 strncat(title_f, p_articles[i]->title + j, sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
168
169 len = split_line(title_f, 59 - (display_nickname ? BBS_nickname_max_len / 2 : BBS_username_max_len), &eol, &title_f_len, 1);
170 if (title_f[len] != '\0')
171 {
172 title_f[len] = '\0';
173 }
174
175 moveto(4 + i, 1);
176 if (i >= ontop_start_offset)
177 {
178 prints(" \033[1;33m[提示]\033[m%c%c %s%*s %s %s%s\033[m",
179 (is_favor ? '@' : ' '),
180 article_flag,
181 (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
182 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
183 : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
184 "",
185 str_time,
186 (p_articles[i]->aid == section_topic_view_tid
187 ? "\033[1;33m"
188 : (p_articles[i]->tid == section_topic_view_tid
189 ? "\033[1;36m"
190 : "")),
191 title_f);
192 }
193 else
194 {
195 prints(" %s%7d\033[m%c%c %s%*s %s %s%s\033[m",
196 (p_articles[i]->aid == section_topic_view_tid
197 ? "\033[1;33m"
198 : (p_articles[i]->tid == section_topic_view_tid
199 ? "\033[1;36m"
200 : "")),
201 p_articles[i]->aid,
202 (is_favor ? '@' : ' '),
203 article_flag,
204 (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
205 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
206 : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
207 "",
208 str_time,
209 (p_articles[i]->aid == section_topic_view_tid
210 ? "\033[1;33m"
211 : (p_articles[i]->tid == section_topic_view_tid
212 ? "\033[1;36m"
213 : "")),
214 title_f);
215 }
216 }
217
218 return 0;
219 }
220
221 static int section_list_draw_screen(const char *sname, const char *stitle, const char *master_list, int display_nickname)
222 {
223 char str_section_master[LINE_BUFFER_LEN] = "诚征版主中";
224 char str_section_name[LINE_BUFFER_LEN];
225
226 if (master_list[0] != '\0')
227 {
228 snprintf(str_section_master, sizeof(str_section_master), "版主: %s", master_list);
229 }
230 snprintf(str_section_name, sizeof(str_section_name), "讨论区 [%s]", sname);
231
232 clearscr();
233 show_top(str_section_master, stitle, str_section_name);
234 moveto(2, 0);
235 prints("返回[\033[1;32m←\033[0;37m,\033[1;32mESC\033[0;37m] 选择[\033[1;32m↑\033[0;37m,\033[1;32m↓\033[0;37m] "
236 "阅读[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 发表[\033[1;32mCtrl-P\033[0;37m] "
237 "%s[\033[1;32mn\033[0;37m] 精华区[\033[1;32mx\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m",
238 (display_nickname ? "用户名" : "昵称"));
239 moveto(3, 0);
240 if (display_nickname)
241 {
242 prints("\033[44;37m \033[1;37m 编 号 发布者昵称 日 期 文章标题 \033[m");
243 }
244 else
245 {
246 prints("\033[44;37m \033[1;37m 编 号 发 布 者 日 期 文章标题 \033[m");
247 }
248
249 return 0;
250 }
251
252 static enum select_cmd_t section_list_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)
253 {
254 int old_page_id = *p_page_id;
255 int old_selected_index = *p_selected_index;
256 int ch;
257 time_t last_refresh_tm = time(NULL);
258
259 if (item_count > 0 && *p_selected_index >= 0)
260 {
261 moveto(4 + *p_selected_index, 1);
262 outc('>');
263 iflush();
264 }
265
266 while (!SYS_server_exit)
267 {
268 ch = igetch(100);
269
270 if (ch != KEY_NULL && ch != KEY_TIMEOUT)
271 {
272 BBS_last_access_tm = time(NULL);
273
274 // Refresh current action
275 if (user_online_update(NULL) < 0)
276 {
277 log_error("user_online_update(NULL) error\n");
278 }
279 }
280
281 switch (ch)
282 {
283 case KEY_NULL: // broken pipe
284 #ifdef _DEBUG
285 log_error("KEY_NULL\n");
286 #endif
287 return EXIT_SECTION;
288 case KEY_TIMEOUT:
289 if (time(NULL) - BBS_last_access_tm >= BBS_max_user_idle_time)
290 {
291 log_error("User input timeout\n");
292 return EXIT_SECTION;
293 }
294 continue;
295 case KEY_ESC:
296 case KEY_LEFT:
297 return EXIT_SECTION;
298 case 'n':
299 return CHANGE_NAME_DISPLAY;
300 case CR:
301 case 'r':
302 case KEY_RIGHT:
303 if (item_count > 0)
304 {
305 return VIEW_ARTICLE;
306 }
307 break;
308 case Ctrl('P'):
309 return POST_ARTICLE;
310 case 'E':
311 if (item_count > 0)
312 {
313 return EDIT_ARTICLE;
314 }
315 break;
316 case 'd':
317 if (item_count > 0)
318 {
319 return DELETE_ARTICLE;
320 }
321 break;
322 case Ctrl('Q'):
323 if (item_count > 0)
324 {
325 return QUERY_ARTICLE;
326 }
327 break;
328 case Ctrl('A'):
329 if (item_count > 0)
330 {
331 return QUERY_USER;
332 }
333 break;
334 case 'F':
335 if (item_count > 0)
336 {
337 return SET_FAVOR_ARTICLE;
338 }
339 break;
340 case '-':
341 if (item_count > 0)
342 {
343 return UNSET_FAVOR_ARTICLE;
344 }
345 break;
346 case KEY_HOME:
347 *p_page_id = 0;
348 case 'P':
349 case KEY_PGUP:
350 *p_selected_index = 0;
351 case 'k':
352 case KEY_UP:
353 if (*p_selected_index <= 0)
354 {
355 if (*p_page_id > 0)
356 {
357 (*p_page_id)--;
358 *p_selected_index = BBS_article_limit_per_page - 1;
359 }
360 else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of section list
361 {
362 if (total_page > 0)
363 {
364 *p_page_id = total_page - 1;
365 }
366 if (item_count > 0)
367 {
368 *p_selected_index = item_count - 1;
369 }
370 }
371 }
372 else
373 {
374 (*p_selected_index)--;
375 }
376 break;
377 case '$':
378 case KEY_END:
379 if (*p_page_id + 1 == total_page && *p_selected_index + 1 == item_count) // Press END at end of list
380 {
381 return LAST_SECTION_ARTICLE;
382 }
383 if (total_page > 0)
384 {
385 *p_page_id = total_page - 1;
386 }
387 case 'N':
388 case KEY_PGDN:
389 if (item_count > 0)
390 {
391 *p_selected_index = item_count - 1;
392 }
393 case 'j':
394 case KEY_DOWN:
395 if (*p_selected_index + 1 >= item_count) // next page
396 {
397 if (*p_page_id + 1 < total_page)
398 {
399 (*p_page_id)++;
400 *p_selected_index = 0;
401 }
402 else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of section list
403 {
404 *p_page_id = 0;
405 *p_selected_index = 0;
406 }
407 }
408 else
409 {
410 (*p_selected_index)++;
411 }
412 break;
413 case '=':
414 if (item_count > 0)
415 {
416 return FIRST_TOPIC_ARTICLE;
417 }
418 break;
419 case '\\':
420 if (item_count > 0)
421 {
422 return LAST_TOPIC_ARTICLE;
423 }
424 break;
425 case 'S':
426 if (item_count > 0)
427 {
428 return SCAN_NEW_ARTICLE;
429 }
430 break;
431 case 'A':
432 if (item_count > 0)
433 {
434 return SCAN_ARTICLE_BACKWARD_BY_USER;
435 }
436 break;
437 case 'a':
438 if (item_count > 0)
439 {
440 return SCAN_ARTICLE_FORWARD_BY_USER;
441 }
442 break;
443 case '?':
444 if (item_count > 0)
445 {
446 return SCAN_ARTICLE_BACKWARD_BY_TITLE;
447 }
448 break;
449 case '/':
450 if (item_count > 0)
451 {
452 return SCAN_ARTICLE_FORWARD_BY_TITLE;
453 }
454 break;
455 case 'u':
456 return SEARCH_USER;
457 case 'h':
458 return SHOW_HELP;
459 case 'x':
460 return VIEW_EX_DIR;
461 case 'H':
462 return SHOW_TOP10;
463 default:
464 break;
465 }
466
467 if (old_page_id != *p_page_id)
468 {
469 return CHANGE_PAGE;
470 }
471
472 if (item_count > 0 && old_selected_index != *p_selected_index)
473 {
474 if (old_selected_index >= 0)
475 {
476 moveto(4 + old_selected_index, 1);
477 outc(' ');
478 }
479 if (*p_selected_index >= 0)
480 {
481 moveto(4 + *p_selected_index, 1);
482 outc('>');
483 }
484 iflush();
485
486 old_selected_index = *p_selected_index;
487 }
488
489 if (BBS_last_access_tm - last_refresh_tm >= BBS_section_list_load_interval)
490 {
491 return CHANGE_PAGE; // force section list refresh
492 }
493 }
494
495 return EXIT_SECTION;
496 }
497
498 static int display_article_key_handler(int *p_key, DISPLAY_CTX *p_ctx)
499 {
500 switch (*p_key)
501 {
502 case 'p':
503 case Ctrl('X'):
504 section_topic_view_mode = !section_topic_view_mode;
505 case 0: // Set msg
506 if (section_topic_view_mode)
507 {
508 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
509 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
510 "同主题阅读[\033[32m↑\033[33m/\033[32m↓\033[33m] "
511 "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
512 }
513 else
514 {
515 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
516 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
517 "移动[\033[32m↑\033[33m/\033[32m↓\033[33m/\033[32mPgUp\033[33m/\033[32mPgDn\033[33m] "
518 "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
519 }
520 *p_key = 0;
521 break;
522 case 'r': // Reply article
523 return 1;
524 case '=': // First topic article
525 return 1;
526 case '\\': // Last topic article
527 return 1;
528 case KEY_UP:
529 case KEY_PGUP:
530 case KEY_HOME:
531 if (p_ctx->reach_begin)
532 {
533 if (section_topic_view_mode)
534 {
535 *p_key = KEY_PGUP;
536 }
537 else
538 {
539 *p_key = KEY_UP;
540 }
541 return 1;
542 }
543 break;
544 case 'k':
545 if (section_topic_view_mode)
546 {
547 *p_key = KEY_PGUP;
548 }
549 else
550 {
551 *p_key = KEY_UP;
552 }
553 return 1;
554 case KEY_DOWN:
555 case KEY_PGDN:
556 case KEY_END:
557 if (p_ctx->reach_end)
558 {
559 if (section_topic_view_mode)
560 {
561 *p_key = KEY_PGDN;
562 }
563 else
564 {
565 *p_key = KEY_DOWN;
566 }
567 return 1;
568 }
569 break;
570 case 'j':
571 if (section_topic_view_mode)
572 {
573 *p_key = KEY_PGDN;
574 }
575 else
576 {
577 *p_key = KEY_DOWN;
578 }
579 return 1;
580 }
581
582 return 0;
583 }
584
585 int section_list_display(const char *sname, int32_t aid)
586 {
587 static int display_nickname = 0;
588
589 SECTION_LIST *p_section;
590 int64_t section_index;
591 int32_t aid_location;
592 char stitle[BBS_section_title_max_len + 1];
593 char master_list[(BBS_username_max_len + 1) * 3 + 1];
594 char page_info_str[LINE_BUFFER_LEN];
595 const ARTICLE *p_articles[BBS_article_limit_per_page];
596 int article_count;
597 int page_count;
598 int ontop_start_offset;
599 int page_id = 0;
600 int selected_index = 0;
601 ARTICLE_CACHE cache;
602 int ret;
603 int loop;
604 int direction;
605 ARTICLE article_new;
606 int page_id_cur;
607 const ARTICLE *p_article_locate;
608 USER_INFO user_info;
609 char user_intro[BBS_user_intro_max_len + 1];
610 char username[BBS_username_max_len + 1];
611 char username_list[1][BBS_username_max_len + 1];
612 int32_t uid;
613 int i;
614 int ok;
615 char title[BBS_article_title_max_len + 1] = "\0";
616
617 p_section = section_list_find_by_name(sname);
618 if (p_section == NULL)
619 {
620 log_error("Section %s not found\n", sname);
621 return -1;
622 }
623
624 if (!checkpriv(&BBS_priv, p_section->sid, S_LIST))
625 {
626 log_error("Forbid access to unauthorized section, sid=%d, uid=%d\n",
627 p_section->sid, BBS_priv.uid);
628 return -1;
629 }
630
631 section_index = get_section_index(p_section);
632
633 if (get_section_info(p_section, NULL, stitle, master_list) < 0)
634 {
635 log_error("get_section_info(sid=%d) error\n", p_section->sid);
636 return -4;
637 }
638
639 if (aid == 0)
640 {
641 aid_location = section_aid_locations[section_index];
642 }
643 else
644 {
645 aid_location = aid;
646 }
647
648 // Locate at article with aid_locate
649 if (aid_location > 0)
650 {
651 p_article_locate = article_block_find_by_aid(aid_location);
652 if (p_article_locate == NULL)
653 {
654 log_error("article_block_find_by_aid(%d) error\n", aid_location);
655 return -3;
656 }
657
658 ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
659 &page_id, &selected_index, &article_count);
660 if (ret < 0)
661 {
662 log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
663 p_section->sid, p_article_locate->aid);
664 return -3;
665 }
666 }
667
668 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
669 {
670 log_error("section_list_draw_screen() error\n");
671 return -2;
672 }
673
674 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
675 if (ret < 0)
676 {
677 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
678 return -3;
679 }
680
681 section_topic_view_tid = -1;
682
683 if (article_count == 0) // empty section
684 {
685 selected_index = 0;
686 }
687 else if (aid > 0)
688 {
689 // Update current topic
690 section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
691
692 // Update current aid location
693 section_aid_locations[section_index] = p_articles[selected_index]->aid;
694 }
695
696 while (!SYS_server_exit)
697 {
698 ret = section_list_draw_items(page_id, p_articles, article_count, display_nickname, ontop_start_offset);
699 if (ret < 0)
700 {
701 log_error("section_list_draw_items(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
702 return -4;
703 }
704
705 snprintf(page_info_str, sizeof(page_info_str),
706 "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
707 page_id + 1, MAX(page_count, 1));
708
709 show_bottom(page_info_str);
710 iflush();
711
712 if (user_online_update(sname) < 0)
713 {
714 log_error("user_online_update(%s) error\n", sname);
715 }
716
717 ret = section_list_select(page_count, article_count, &page_id, &selected_index);
718
719 switch (ret)
720 {
721 case EXIT_SECTION:
722 // Update current aid location
723 if (selected_index < article_count && p_articles[selected_index] != NULL)
724 {
725 if (selected_index >= ontop_start_offset)
726 {
727 ret = last_article_in_section(p_section, &p_article_locate);
728 if (ret < 0)
729 {
730 log_error("last_article_in_section(sid=%d) error\n", p_section->sid);
731 return -3;
732 }
733 else if (ret == 0)
734 {
735 section_aid_locations[section_index] = 0;
736 }
737 else // ret > 0
738 {
739 section_aid_locations[section_index] = p_article_locate->aid;
740 }
741 }
742 else
743 {
744 section_aid_locations[section_index] = (p_articles[selected_index]->visible ? p_articles[selected_index]->aid : 0);
745 }
746 }
747 return 0;
748 case CHANGE_PAGE:
749 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
750 if (ret < 0)
751 {
752 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
753 return -3;
754 }
755 if (article_count == 0) // empty section
756 {
757 selected_index = 0;
758 }
759 else if (selected_index >= article_count)
760 {
761 selected_index = article_count - 1;
762 }
763 break;
764 case VIEW_ARTICLE:
765 do
766 {
767 loop = 0;
768
769 if (article_cache_load(&cache, VAR_ARTICLE_CACHE_DIR, p_articles[selected_index]) < 0)
770 {
771 log_error("article_cache_load(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
772 break;
773 }
774
775 if (user_online_update("VIEW_ARTICLE") < 0)
776 {
777 log_error("user_online_update(VIEW_ARTICLE) error\n");
778 }
779
780 ret = display_data(cache.p_data, cache.line_total, cache.line_offsets, 0,
781 display_article_key_handler, DATA_READ_HELP);
782
783 if (article_cache_unload(&cache) < 0)
784 {
785 log_error("article_cache_unload(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
786 break;
787 }
788
789 // Update article_view_log
790 if (article_view_log_set_viewed(p_articles[selected_index]->aid, &BBS_article_view_log) < 0)
791 {
792 log_error("article_view_log_set_viewed(aid=%d) error\n", p_articles[selected_index]->aid);
793 }
794
795 switch (ret)
796 {
797 case KEY_UP:
798 if (selected_index <= 0)
799 {
800 if (page_id > 0)
801 {
802 page_id--;
803 selected_index = BBS_article_limit_per_page - 1;
804
805 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
806 if (ret < 0)
807 {
808 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
809 return -3;
810 }
811
812 if (article_count != BBS_article_limit_per_page) // page is not full
813 {
814 selected_index = MAX(0, article_count - 1);
815 }
816 else
817 {
818 loop = 1;
819 }
820 }
821 }
822 else
823 {
824 selected_index--;
825 loop = 1;
826 }
827 break;
828 case KEY_DOWN:
829 if (selected_index + 1 >= article_count) // next page
830 {
831 if (page_id + 1 < page_count)
832 {
833 page_id++;
834 selected_index = 0;
835
836 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
837 if (ret < 0)
838 {
839 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
840 return -3;
841 }
842
843 if (article_count == 0) // empty page
844 {
845 selected_index = 0;
846 }
847 else
848 {
849 loop = 1;
850 }
851 }
852 }
853 else
854 {
855 selected_index++;
856 loop = 1;
857 }
858 break;
859 case KEY_PGUP:
860 case KEY_PGDN:
861 direction = (ret == KEY_PGUP ? -1 : 1);
862 ret = locate_article_in_section(p_section, p_articles[selected_index], direction, 1,
863 &page_id, &selected_index, &article_count);
864 if (ret < 0)
865 {
866 log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=1) error\n",
867 p_section->sid, p_articles[selected_index]->aid, direction);
868 return -3;
869 }
870 else if (ret > 0) // found
871 {
872 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
873 if (ret < 0)
874 {
875 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
876 return -3;
877 }
878 loop = 1;
879 }
880 break;
881 case 'r': // Reply article
882 if (user_online_update("REPLY_ARTICLE") < 0)
883 {
884 log_error("user_online_update(REPLY_ARTICLE) error\n");
885 }
886
887 if (article_reply(p_section, p_articles[selected_index], &article_new) < 0)
888 {
889 log_error("article_reply(aid=%d) error\n", p_articles[selected_index]->aid);
890 }
891 else if (ret > 0) // Article replied
892 {
893 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
894 if (ret < 0)
895 {
896 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
897 return -3;
898 }
899 }
900 loop = 1;
901 break;
902 case '=': // First topic article
903 case '\\': // Last topic article
904 page_id_cur = page_id;
905 direction = (ret == '=' ? -1 : 1);
906 ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
907 &page_id, &selected_index, &article_count);
908 if (ret < 0)
909 {
910 log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
911 p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
912 return -3;
913 }
914 else if (ret > 0) // found
915 {
916 if (page_id != page_id_cur) // page changed
917 {
918 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
919 if (ret < 0)
920 {
921 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
922 return -3;
923 }
924 }
925 loop = 1;
926 }
927 break;
928 }
929 } while (loop);
930
931 // Update current topic
932 section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
933
934 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
935 {
936 log_error("section_list_draw_screen() error\n");
937 return -2;
938 }
939 break;
940 case CHANGE_NAME_DISPLAY:
941 display_nickname = !display_nickname;
942 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
943 {
944 log_error("section_list_draw_screen() error\n");
945 return -2;
946 }
947 break;
948 case POST_ARTICLE:
949 if (user_online_update("POST_ARTICLE") < 0)
950 {
951 log_error("user_online_update(POST_ARTICLE) error\n");
952 }
953
954 if ((ret = article_post(p_section, &article_new)) < 0)
955 {
956 log_error("article_post(sid=%d) error\n", p_section->sid);
957 }
958 else if (ret > 0) // New article posted
959 {
960 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
961 if (ret < 0)
962 {
963 log_error("query_section_articles(sid=%d, page_id=%d) error: %d\n", p_section->sid, page_id, ret);
964 return -3;
965 }
966 }
967 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
968 {
969 log_error("section_list_draw_screen() error\n");
970 return -2;
971 }
972 break;
973 case EDIT_ARTICLE:
974 if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
975 p_articles[selected_index]->uid != BBS_priv.uid)
976 {
977 break; // No permission
978 }
979
980 if (user_online_update("EDIT_ARTICLE") < 0)
981 {
982 log_error("user_online_update() error\n");
983 }
984
985 if (article_modify(p_section, p_articles[selected_index], &article_new) < 0)
986 {
987 log_error("article_modify(aid=%d) error\n", p_articles[selected_index]->aid);
988 }
989 else if (ret > 0) // Article modified
990 {
991 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
992 if (ret < 0)
993 {
994 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
995 return -3;
996 }
997 }
998 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
999 {
1000 log_error("section_list_draw_screen() error\n");
1001 return -2;
1002 }
1003 break;
1004 case DELETE_ARTICLE:
1005 if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
1006 (!checkpriv(&BBS_priv, p_section->sid, S_MAN_S) && p_articles[selected_index]->uid != BBS_priv.uid))
1007 {
1008 break; // No permission
1009 }
1010 if ((ret = article_del(p_section, p_articles[selected_index])) < 0)
1011 {
1012 log_error("article_del(aid=%d) error\n", p_articles[selected_index]->aid);
1013 }
1014 else if (ret > 0) // Article deleted
1015 {
1016 do
1017 {
1018 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1019 if (ret >= 0 && selected_index > article_count - 1)
1020 {
1021 selected_index = article_count - 1;
1022 break;
1023 }
1024 else if (ret < 0 && page_id > 0)
1025 {
1026 page_id--;
1027 selected_index = BBS_article_limit_per_page - 1;
1028 }
1029 else if (ret < 0 && page_id <= 0)
1030 {
1031 selected_index = 0;
1032 break;
1033 }
1034 } while (ret < 0);
1035 }
1036 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1037 {
1038 log_error("section_list_draw_screen() error\n");
1039 return -2;
1040 }
1041 break;
1042 case QUERY_ARTICLE:
1043 if ((ret = display_article_meta(p_articles[selected_index]->aid)) < 0)
1044 {
1045 log_error("display_article_meta(aid=%d) error\n", p_articles[selected_index]->aid);
1046 }
1047 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1048 {
1049 log_error("section_list_draw_screen() error\n");
1050 return -2;
1051 }
1052 break;
1053 case QUERY_USER:
1054 if ((ret = query_user_info_by_uid(p_articles[selected_index]->uid, &user_info, user_intro, sizeof(user_intro))) < 0)
1055 {
1056 log_error("query_user_info_by_uid(uid=%d) error\n", p_articles[selected_index]->uid);
1057 return -2;
1058 }
1059 else if (ret == 0)
1060 {
1061 clearscr();
1062 prints("该用户已升天");
1063 press_any_key();
1064 }
1065 else if (user_info_display(&user_info) < 0) // && ret > 0
1066 {
1067 log_error("user_info_display(uid=%d) error\n", p_articles[selected_index]->uid);
1068 }
1069
1070 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1071 {
1072 log_error("section_list_draw_screen() error\n");
1073 return -2;
1074 }
1075 break;
1076 case SET_FAVOR_ARTICLE:
1077 ret = article_favor_set(p_articles[selected_index]->tid == 0
1078 ? p_articles[selected_index]->aid
1079 : p_articles[selected_index]->tid,
1080 &BBS_article_favor, 1);
1081 if (ret < 0)
1082 {
1083 log_error("article_favor_set(aid=%d, 1) error\n",
1084 p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
1085 }
1086 break;
1087 case UNSET_FAVOR_ARTICLE:
1088 ret = article_favor_set(p_articles[selected_index]->tid == 0
1089 ? p_articles[selected_index]->aid
1090 : p_articles[selected_index]->tid,
1091 &BBS_article_favor, 0);
1092 if (ret < 0)
1093 {
1094 log_error("article_favor_set(aid=%d, 0) error\n",
1095 p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
1096 }
1097 break;
1098 case FIRST_TOPIC_ARTICLE:
1099 case LAST_TOPIC_ARTICLE:
1100 page_id_cur = page_id;
1101 direction = (ret == FIRST_TOPIC_ARTICLE ? -1 : 1);
1102 ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
1103 &page_id, &selected_index, &article_count);
1104 if (ret < 0)
1105 {
1106 log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
1107 p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
1108 return -3;
1109 }
1110 else if (ret > 0 && page_id != page_id_cur) // found and page changed
1111 {
1112 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1113 if (ret < 0)
1114 {
1115 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1116 return -3;
1117 }
1118 }
1119 break;
1120 case LAST_SECTION_ARTICLE:
1121 page_id_cur = page_id;
1122 ret = last_article_in_section(p_section, &p_article_locate);
1123 if (ret < 0)
1124 {
1125 log_error("last_article_in_section(sid=%d) error\n", p_section->sid);
1126 return -3;
1127 }
1128 else if (ret == 0)
1129 {
1130 break;
1131 }
1132 ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
1133 &page_id, &selected_index, &article_count);
1134 if (ret < 0)
1135 {
1136 log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
1137 p_section->sid, p_article_locate->aid);
1138 return -3;
1139 }
1140 else if (ret > 0 && page_id != page_id_cur) // found and page changed
1141 {
1142 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1143 if (ret < 0)
1144 {
1145 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1146 return -3;
1147 }
1148 }
1149 break;
1150 case SCAN_NEW_ARTICLE:
1151 ret = scan_unread_article_in_section(p_section, p_articles[selected_index], &p_article_locate);
1152 if (ret < 0)
1153 {
1154 log_error("scan_unread_article_in_section(sid=%d, aid=%d) error\n",
1155 p_section->sid, p_articles[selected_index]->aid);
1156 return -3;
1157 }
1158 else if (ret == 0) // not found
1159 {
1160 break;
1161 }
1162 page_id_cur = page_id;
1163 ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
1164 &page_id, &selected_index, &article_count);
1165 if (ret < 0)
1166 {
1167 log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
1168 p_section->sid, p_article_locate->aid);
1169 return -3;
1170 }
1171 else if (ret > 0 && page_id != page_id_cur) // found and page changed
1172 {
1173 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1174 if (ret < 0)
1175 {
1176 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1177 return -3;
1178 }
1179 }
1180 break;
1181 case SCAN_ARTICLE_BACKWARD_BY_USER:
1182 case SCAN_ARTICLE_FORWARD_BY_USER:
1183 direction = (ret == SCAN_ARTICLE_FORWARD_BY_USER ? 1 : -1);
1184 strncpy(username, p_articles[selected_index]->username, sizeof(username) - 1);
1185 username[sizeof(username) - 1] = '\0';
1186 uid = 0;
1187
1188 moveto(SCREEN_ROWS, 1);
1189 clrtoeol();
1190 get_data(SCREEN_ROWS, 1,
1191 (direction == 1 ? "↓搜寻作者: " : "↑搜寻作者: "),
1192 username, sizeof(username), BBS_username_max_len);
1193
1194 if (username[0] == '\0')
1195 {
1196 break;
1197 }
1198
1199 // Verify format
1200 for (i = 0, ok = 1; ok && username[i] != '\0'; i++)
1201 {
1202 if (!(isalpha((int)username[i]) || (i > 0 && (isdigit((int)username[i]) || username[i] == '_'))))
1203 {
1204 ok = 0;
1205 }
1206 }
1207 if (ok && i > BBS_username_max_len)
1208 {
1209 ok = 0;
1210 }
1211 if (!ok)
1212 {
1213 break;
1214 }
1215
1216 ret = query_user_info_by_username(username, 1, &uid, username_list);
1217 if (ret < 0)
1218 {
1219 log_error("query_user_info_by_username(%s) error\n", username);
1220 break;
1221 }
1222
1223 if (uid > 0)
1224 {
1225 ret = scan_article_in_section_by_uid(p_section, p_articles[selected_index],
1226 direction, uid, &p_article_locate);
1227 if (ret < 0)
1228 {
1229 log_error("scan_article_in_section_by_uid(sid=%d, aid=%d, direction=%d, uid=%d) error\n",
1230 p_section->sid, p_articles[selected_index]->aid, direction, uid);
1231 return -3;
1232 }
1233 else if (ret == 0) // not found
1234 {
1235 break;
1236 }
1237 }
1238 else // uid == 0
1239 {
1240 ret = scan_article_in_section_by_username(p_section, p_articles[selected_index],
1241 direction, username, &p_article_locate);
1242 if (ret < 0)
1243 {
1244 log_error("scan_article_in_section_by_username(sid=%d, aid=%d, direction=%d, username=%s) error\n",
1245 p_section->sid, p_articles[selected_index]->aid, direction, username);
1246 return -3;
1247 }
1248 else if (ret == 0) // not found
1249 {
1250 break;
1251 }
1252 }
1253
1254 page_id_cur = page_id;
1255 ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
1256 &page_id, &selected_index, &article_count);
1257 if (ret < 0)
1258 {
1259 log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
1260 p_section->sid, p_article_locate->aid);
1261 return -3;
1262 }
1263 else if (ret > 0 && page_id != page_id_cur) // found and page changed
1264 {
1265 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1266 if (ret < 0)
1267 {
1268 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1269 return -3;
1270 }
1271 }
1272 break;
1273 case SCAN_ARTICLE_BACKWARD_BY_TITLE:
1274 case SCAN_ARTICLE_FORWARD_BY_TITLE:
1275 direction = (ret == SCAN_ARTICLE_FORWARD_BY_TITLE ? 1 : -1);
1276
1277 moveto(SCREEN_ROWS, 1);
1278 clrtoeol();
1279 get_data(SCREEN_ROWS, 1,
1280 (direction == 1 ? "↓搜寻标题: " : "↑搜寻标题: "),
1281 title, sizeof(title), TITLE_SEARCH_MAX_LEN);
1282
1283 if (title[0] == '\0')
1284 {
1285 break;
1286 }
1287
1288 ret = scan_article_in_section_by_title(p_section, p_articles[selected_index],
1289 direction, title, &p_article_locate);
1290 if (ret < 0)
1291 {
1292 log_error("scan_article_in_section_by_title(sid=%d, aid=%d, direction=%d, title=%s) error\n",
1293 p_section->sid, p_articles[selected_index]->aid, direction, title);
1294 return -3;
1295 }
1296 else if (ret == 0) // not found
1297 {
1298 break;
1299 }
1300
1301 page_id_cur = page_id;
1302 ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
1303 &page_id, &selected_index, &article_count);
1304 if (ret < 0)
1305 {
1306 log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
1307 p_section->sid, p_article_locate->aid);
1308 return -3;
1309 }
1310 else if (ret > 0 && page_id != page_id_cur) // found and page changed
1311 {
1312 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1313 if (ret < 0)
1314 {
1315 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1316 return -3;
1317 }
1318 }
1319 break;
1320 case SEARCH_USER:
1321 user_list_search();
1322 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1323 {
1324 log_error("section_list_draw_screen() error\n");
1325 return -2;
1326 }
1327 break;
1328 case SHOW_HELP:
1329 // Display help information
1330 display_file(DATA_READ_HELP, 1);
1331 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1332 {
1333 log_error("section_list_draw_screen() error\n");
1334 return -2;
1335 }
1336 break;
1337 case VIEW_EX_DIR:
1338 if (section_list_ex_dir_display(p_section) < 0)
1339 {
1340 log_error("section_list_ex_dir_display(sid=%d) error\n", p_section->sid);
1341 }
1342 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1343 {
1344 log_error("section_list_draw_screen() error\n");
1345 return -2;
1346 }
1347 break;
1348 case SHOW_TOP10:
1349 show_top10_menu(NULL);
1350 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1351 {
1352 log_error("section_list_draw_screen() error\n");
1353 return -2;
1354 }
1355 break;
1356 default:
1357 log_error("Unknown command %d\n", ret);
1358 }
1359 }
1360
1361 return 0;
1362 }
1363
1364 int section_list_ex_dir_display(SECTION_LIST *p_section)
1365 {
1366 MENU_SET ex_menu_set;
1367 int ch = 0;
1368 int loop;
1369
1370 if (p_section == NULL)
1371 {
1372 log_error("NULL pointer error\n");
1373 return -1;
1374 }
1375
1376 if (p_section->ex_menu_tm == 0) // N/A
1377 {
1378 moveto(2, 1);
1379 clrtoeol();
1380 prints("该版块精华区未开放");
1381 press_any_key();
1382 return 0;
1383 }
1384
1385 if (get_section_ex_menu_set(p_section, &ex_menu_set) < 0)
1386 {
1387 log_error("get_section_ex_menu_set(sid=%d) error\n", p_section->sid);
1388 return -3;
1389 }
1390 if (get_menu_shm_readonly(&ex_menu_set) < 0)
1391 {
1392 log_error("get_menu_shm_readonly(sid=%d) error\n", p_section->sid);
1393 return -3;
1394 }
1395
1396 clearscr();
1397 show_bottom("");
1398
1399 if (display_menu(&ex_menu_set) == 0)
1400 {
1401 for (loop = 1; !SYS_server_exit && loop;)
1402 {
1403 iflush();
1404 ch = igetch(100);
1405
1406 if (ch != KEY_NULL && ch != KEY_TIMEOUT)
1407 {
1408 BBS_last_access_tm = time(NULL);
1409
1410 // Refresh current action
1411 if (user_online_update(NULL) < 0)
1412 {
1413 log_error("user_online_update(NULL) error\n");
1414 }
1415 }
1416
1417 switch (ch)
1418 {
1419 case KEY_NULL: // broken pipe
1420 #ifdef _DEBUG
1421 log_error("KEY_NULL\n");
1422 #endif
1423 loop = 0;
1424 break;
1425 case KEY_TIMEOUT:
1426 if (time(NULL) - BBS_last_access_tm >= BBS_max_user_idle_time)
1427 {
1428 log_error("User input timeout\n");
1429 loop = 0;
1430 break;
1431 }
1432 continue;
1433 case CR:
1434 default:
1435 switch (menu_control(&ex_menu_set, ch))
1436 {
1437 case EXITMENU:
1438 loop = 0;
1439 break;
1440 case REDRAW:
1441 clearscr();
1442 show_bottom("");
1443 display_menu(&ex_menu_set);
1444 break;
1445 case NOREDRAW:
1446 case UNKNOWN_CMD:
1447 default:
1448 break;
1449 }
1450 }
1451 }
1452 }
1453
1454 detach_menu_shm(&ex_menu_set);
1455
1456 return 0;
1457 }
1458
1459 int section_aid_locations_save(int uid)
1460 {
1461 char filename[FILE_PATH_LEN];
1462 FILE *fp;
1463 int i;
1464 int ret = 0;
1465
1466 snprintf(filename, sizeof(filename), "%s/%d", VAR_SECTION_AID_LOC_DIR, uid);
1467
1468 if ((fp = fopen(filename, "wb")) == NULL)
1469 {
1470 log_error("fopen(%s, wb) error: %d\n", filename, errno);
1471 return -1;
1472 }
1473
1474 for (i = 0; i < p_section_list_pool->section_count; i++)
1475 {
1476 if (fwrite(&(p_section_list_pool->sections[i].sid), sizeof(p_section_list_pool->sections[i].sid), 1, fp) != 1)
1477 {
1478 log_error("fwrite(%s, sid) error\n", filename);
1479 ret = -2;
1480 break;
1481 }
1482
1483 if (fwrite(&(section_aid_locations[i]), sizeof(section_aid_locations[i]), 1, fp) != 1)
1484 {
1485 log_error("fwrite(%s, aid) error\n", filename);
1486 ret = -2;
1487 break;
1488 }
1489 }
1490
1491 if (fclose(fp) < 0)
1492 {
1493 log_error("fclose(%s) error: %d\n", filename, errno);
1494 ret = -1;
1495 }
1496
1497 return ret;
1498 }
1499
1500 int section_aid_locations_load(int uid)
1501 {
1502 char filename[FILE_PATH_LEN];
1503 FILE *fp;
1504 int i;
1505 int32_t sid;
1506 int32_t aid;
1507 SECTION_LIST *p_section;
1508 int ret = 0;
1509
1510 snprintf(filename, sizeof(filename), "%s/%d", VAR_SECTION_AID_LOC_DIR, uid);
1511
1512 if ((fp = fopen(filename, "rb")) == NULL)
1513 {
1514 if (errno == ENOENT) // file not exist
1515 {
1516 return 0;
1517 }
1518 log_error("fopen(%s, rb) error: %d\n", filename, errno);
1519 return -1;
1520 }
1521
1522 while (!feof(fp))
1523 {
1524 if (fread(&sid, sizeof(sid), 1, fp) != 1)
1525 {
1526 if (ferror(fp) == 0)
1527 {
1528 break;
1529 }
1530 log_error("fread(%s, sid) error: %d\n", filename, ferror(fp));
1531 ret = -2;
1532 break;
1533 }
1534
1535 if (fread(&aid, sizeof(aid), 1, fp) != 1)
1536 {
1537 if (ferror(fp) == 0)
1538 {
1539 break;
1540 }
1541 log_error("fread(%s, aid) error: %d\n", filename, ferror(fp));
1542 ret = -2;
1543 break;
1544 }
1545
1546 p_section = section_list_find_by_sid(sid);
1547 if (p_section == NULL)
1548 {
1549 continue; // skip section no longer exist
1550 }
1551
1552 i = get_section_index(p_section);
1553 if (i < 0)
1554 {
1555 log_error("get_section_index(sid=%d) error\n", sid);
1556 ret = -3;
1557 break;
1558 }
1559 section_aid_locations[i] = aid;
1560 }
1561
1562 if (fclose(fp) < 0)
1563 {
1564 log_error("fclose(%s) error: %d\n", filename, errno);
1565 ret = -1;
1566 }
1567
1568 return ret;
1569 }

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