/[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.86 - (show annotations)
Sat Jan 3 10:27:14 2026 UTC (2 months, 1 week ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.85: +1 -1 lines
Content type: text/x-csrc
Update copyright info

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

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