/[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.74 - (show annotations)
Mon Nov 10 14:24:37 2025 UTC (4 months ago) by sysadm
Branch: MAIN
Changes since 1.73: +1 -1 lines
Content type: text/x-csrc
Replace ":" with ":"

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

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