/[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.78 - (show annotations)
Sun Nov 23 04:28:24 2025 UTC (3 months, 3 weeks ago) by sysadm
Branch: MAIN
Changes since 1.77: +7 -9 lines
Content type: text/x-csrc
Fix bug: regard Ctrl-C as EXITMENU by mistake

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

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