/[LeafOK_CVS]/lbbs/src/section_list_display.c
ViewVC logotype

Annotation of /lbbs/src/section_list_display.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.67 - (hide annotations)
Mon Nov 3 15:06:46 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.66: +38 -11 lines
Content type: text/x-csrc
query_section_articles after article reply / delete / edit

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

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