/[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.68 - (show annotations)
Tue Nov 4 06:36:52 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.67: +56 -1 lines
Content type: text/x-csrc
Locate at the last visible article of the section by pressing END at the bottom of section article list.
When exiting the section, set the last selected article to the last visible article if the selected one was pinned.

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

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