/[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.70 - (show annotations)
Tue Nov 4 14:58:56 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.69: +1 -1 lines
Content type: text/x-csrc
Refine file header information comments

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

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