/[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.48 - (hide annotations)
Mon Oct 13 07:35:48 2025 UTC (5 months ago) by sysadm
Branch: MAIN
Changes since 1.47: +12 -0 lines
Content type: text/x-csrc
Use Ctrl-H in section list to invoke top10 menu
Prevent recursive call to show_top10()

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.41 #include "article_op.h"
19 sysadm 1.20 #include "article_post.h"
20 sysadm 1.34 #include "article_view_log.h"
21 sysadm 1.26 #include "article_del.h"
22 sysadm 1.1 #include "common.h"
23     #include "io.h"
24 sysadm 1.34 #include "log.h"
25     #include "login.h"
26 sysadm 1.37 #include "menu.h"
27 sysadm 1.48 #include "menu_proc.h"
28 sysadm 1.34 #include "section_list_display.h"
29     #include "section_list_loader.h"
30 sysadm 1.1 #include "screen.h"
31 sysadm 1.34 #include "str_process.h"
32 sysadm 1.18 #include "user_priv.h"
33 sysadm 1.29 #include <string.h>
34 sysadm 1.1 #include <time.h>
35 sysadm 1.6 #include <sys/param.h>
36 sysadm 1.1
37 sysadm 1.46 static int section_aid_locations[BBS_max_section] = {0};
38 sysadm 1.11 static int section_topic_view_mode = 0;
39 sysadm 1.13 static int section_topic_view_tid = -1;
40 sysadm 1.11
41 sysadm 1.1 enum select_cmd_t
42     {
43     EXIT_SECTION = 0,
44 sysadm 1.41 VIEW_ARTICLE,
45     CHANGE_PAGE,
46     SHOW_HELP,
47     CHANGE_NAME_DISPLAY,
48     POST_ARTICLE,
49     EDIT_ARTICLE,
50     DELETE_ARTICLE,
51     QUERY_ARTICLE,
52     FIRST_TOPIC_ARTICLE,
53     LAST_TOPIC_ARTICLE,
54 sysadm 1.45 SCAN_NEW_ARTICLE,
55 sysadm 1.41 VIEW_EX_DIR,
56 sysadm 1.48 SHOW_TOP10,
57 sysadm 1.1 };
58    
59 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)
60 sysadm 1.1 {
61     char str_time[LINE_BUFFER_LEN];
62     struct tm tm_sub;
63     char title_f[BBS_article_title_max_len + 1];
64     int title_f_len;
65     int eol;
66     int len;
67     int i;
68 sysadm 1.42 size_t j;
69 sysadm 1.3 char article_flag;
70 sysadm 1.17 int is_viewed;
71 sysadm 1.3 time_t tm_now;
72    
73     time(&tm_now);
74 sysadm 1.1
75     clrline(4, 23);
76    
77     for (i = 0; i < article_count; i++)
78     {
79 sysadm 1.18 if (p_articles[i]->uid == BBS_priv.uid)
80 sysadm 1.17 {
81 sysadm 1.18 is_viewed = 1;
82     }
83     else
84     {
85     is_viewed = article_view_log_is_viewed(p_articles[i]->aid, &BBS_article_view_log);
86     if (is_viewed < 0)
87     {
88     log_error("article_view_log_is_viewed(aid=%d) error\n", p_articles[i]->aid);
89     is_viewed = 0;
90     }
91 sysadm 1.17 }
92    
93 sysadm 1.3 if (p_articles[i]->excerption)
94     {
95 sysadm 1.17 article_flag = (is_viewed ? 'm' : 'M');
96 sysadm 1.3 }
97 sysadm 1.17 else if (p_articles[i]->lock && is_viewed)
98 sysadm 1.3 {
99     article_flag = 'x';
100     }
101 sysadm 1.35 else
102     {
103     article_flag = (is_viewed ? ' ' : 'N');
104     }
105 sysadm 1.3
106 sysadm 1.1 localtime_r(&p_articles[i]->sub_dt, &tm_sub);
107 sysadm 1.3 if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)
108     {
109     strftime(str_time, sizeof(str_time), "%b %e ", &tm_sub);
110     }
111     else
112     {
113     strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);
114     }
115    
116 sysadm 1.40 strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);
117 sysadm 1.1 title_f[sizeof(title_f) - 1] = '\0';
118 sysadm 1.40 strncat(title_f, (p_articles[i]->transship ? "[转载]" : ""), sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
119 sysadm 1.42
120     // Rewrite title with "Re: Re: " prefix into "Re: ... "
121     j = 0;
122     if (p_articles[i]->tid != 0)
123     {
124     while (strncmp(p_articles[i]->title + j, "Re: ", strlen("Re: ")) == 0)
125     {
126     j += strlen("Re: ");
127     }
128     if (j >= strlen("Re: Re: "))
129     {
130     strncat(title_f, "Re: ... ", sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
131     }
132     else
133     {
134     j = 0;
135     }
136     }
137     strncat(title_f, p_articles[i]->title + j, sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
138    
139 sysadm 1.27 len = split_line(title_f, 47 - (display_nickname ? 8 : 0), &eol, &title_f_len, 1);
140 sysadm 1.1 if (title_f[len] != '\0')
141     {
142     title_f[len] = '\0';
143     }
144    
145     moveto(4 + i, 1);
146 sysadm 1.36 if (i >= ontop_start_offset)
147     {
148 sysadm 1.40 prints(" \033[1;33m[提示]\033[m %c %s%*s %s %s%s\033[m",
149 sysadm 1.36 article_flag,
150     (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
151 sysadm 1.43 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
152     : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
153 sysadm 1.36 "",
154     str_time,
155     (p_articles[i]->aid == section_topic_view_tid
156     ? "\033[1;33m"
157     : (p_articles[i]->tid == section_topic_view_tid
158     ? "\033[1;36m"
159     : "")),
160     title_f);
161     }
162     else
163     {
164     prints(" %s%7d\033[m %c %s%*s %s %s%s\033[m",
165     (p_articles[i]->aid == section_topic_view_tid
166     ? "\033[1;33m"
167     : (p_articles[i]->tid == section_topic_view_tid
168     ? "\033[1;36m"
169     : "")),
170     p_articles[i]->aid,
171     article_flag,
172     (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
173 sysadm 1.43 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
174     : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
175 sysadm 1.36 "",
176     str_time,
177     (p_articles[i]->aid == section_topic_view_tid
178     ? "\033[1;33m"
179     : (p_articles[i]->tid == section_topic_view_tid
180     ? "\033[1;36m"
181     : "")),
182     title_f);
183     }
184 sysadm 1.1 }
185    
186     return 0;
187     }
188    
189 sysadm 1.5 static int section_list_draw_screen(const char *sname, const char *stitle, const char *master_list, int display_nickname)
190 sysadm 1.1 {
191 sysadm 1.40 char str_section_master[LINE_BUFFER_LEN] = "诚征版主中";
192 sysadm 1.1 char str_section_name[LINE_BUFFER_LEN];
193    
194 sysadm 1.5 if (master_list[0] != '\0')
195 sysadm 1.1 {
196 sysadm 1.40 snprintf(str_section_master, sizeof(str_section_master), "版主:%s", master_list);
197 sysadm 1.1 }
198 sysadm 1.40 snprintf(str_section_name, sizeof(str_section_name), "讨论区 [%s]", sname);
199 sysadm 1.1
200     clearscr();
201 sysadm 1.5 show_top(str_section_master, stitle, str_section_name);
202 sysadm 1.1 moveto(2, 0);
203 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] "
204     "阅读[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 发表[\033[1;32mCtrl-P\033[0;37m] "
205     "%s[\033[1;32mn\033[0;37m] 精华区[\033[1;32mx\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m",
206     (display_nickname ? "用户名" : "昵称"));
207 sysadm 1.1 moveto(3, 0);
208 sysadm 1.4 if (display_nickname)
209     {
210 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发布者昵称 日 期 文章标题 \033[m");
211 sysadm 1.4 }
212     else
213     {
214 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发 布 者 日 期 文章标题 \033[m");
215 sysadm 1.4 }
216 sysadm 1.1
217     return 0;
218     }
219    
220     static enum select_cmd_t section_list_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)
221     {
222     int old_page_id = *p_page_id;
223     int old_selected_index = *p_selected_index;
224     int ch;
225 sysadm 1.30 time_t last_refresh_tm = time(NULL);
226 sysadm 1.1
227     if (item_count > 0 && *p_selected_index >= 0)
228     {
229     moveto(4 + *p_selected_index, 1);
230     outc('>');
231     iflush();
232     }
233    
234     while (!SYS_server_exit)
235     {
236     ch = igetch(100);
237    
238     switch (ch)
239     {
240     case KEY_ESC:
241     case KEY_LEFT:
242 sysadm 1.30 BBS_last_access_tm = time(NULL);
243     case KEY_NULL: // broken pipe
244 sysadm 1.1 return EXIT_SECTION; // exit section
245     case KEY_TIMEOUT:
246 sysadm 1.30 if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
247 sysadm 1.1 {
248     return EXIT_SECTION; // exit section
249     }
250     continue;
251 sysadm 1.4 case 'n':
252 sysadm 1.30 BBS_last_access_tm = time(NULL);
253 sysadm 1.4 return CHANGE_NAME_DISPLAY;
254 sysadm 1.1 case CR:
255     igetch_reset();
256 sysadm 1.28 case 'r':
257 sysadm 1.1 case KEY_RIGHT:
258     if (item_count > 0)
259     {
260 sysadm 1.30 BBS_last_access_tm = time(NULL);
261 sysadm 1.1 return VIEW_ARTICLE;
262     }
263     break;
264 sysadm 1.20 case Ctrl('P'):
265     return POST_ARTICLE;
266     case 'E':
267 sysadm 1.41 if (item_count > 0)
268     {
269     return EDIT_ARTICLE;
270     }
271     break;
272 sysadm 1.26 case 'd':
273 sysadm 1.41 if (item_count > 0)
274     {
275     return DELETE_ARTICLE;
276     }
277     break;
278     case Ctrl('Q'):
279     if (item_count > 0)
280     {
281     return QUERY_ARTICLE;
282     }
283     break;
284 sysadm 1.1 case KEY_HOME:
285     *p_page_id = 0;
286 sysadm 1.28 case 'P':
287 sysadm 1.1 case KEY_PGUP:
288     *p_selected_index = 0;
289 sysadm 1.28 case 'k':
290 sysadm 1.1 case KEY_UP:
291     if (*p_selected_index <= 0)
292     {
293     if (*p_page_id > 0)
294     {
295     (*p_page_id)--;
296     *p_selected_index = BBS_article_limit_per_page - 1;
297     }
298 sysadm 1.44 else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of section list
299     {
300     if (total_page > 0)
301     {
302     *p_page_id = total_page - 1;
303     }
304     if (item_count > 0)
305     {
306     *p_selected_index = item_count - 1;
307     }
308     }
309 sysadm 1.1 }
310     else
311     {
312     (*p_selected_index)--;
313     }
314     break;
315 sysadm 1.28 case '$':
316 sysadm 1.1 case KEY_END:
317     if (total_page > 0)
318     {
319     *p_page_id = total_page - 1;
320     }
321 sysadm 1.28 case 'N':
322 sysadm 1.1 case KEY_PGDN:
323     if (item_count > 0)
324     {
325     *p_selected_index = item_count - 1;
326     }
327 sysadm 1.28 case 'j':
328 sysadm 1.1 case KEY_DOWN:
329     if (*p_selected_index + 1 >= item_count) // next page
330     {
331     if (*p_page_id + 1 < total_page)
332     {
333     (*p_page_id)++;
334     *p_selected_index = 0;
335     }
336 sysadm 1.44 else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of section list
337 sysadm 1.25 {
338 sysadm 1.44 *p_page_id = 0;
339     *p_selected_index = 0;
340 sysadm 1.25 }
341 sysadm 1.1 }
342     else
343     {
344     (*p_selected_index)++;
345     }
346     break;
347 sysadm 1.31 case '=':
348 sysadm 1.41 if (item_count > 0)
349     {
350     return FIRST_TOPIC_ARTICLE;
351     }
352     break;
353 sysadm 1.31 case '\\':
354 sysadm 1.41 if (item_count > 0)
355     {
356     return LAST_TOPIC_ARTICLE;
357     }
358     break;
359 sysadm 1.45 case 'S':
360     if (item_count > 0)
361     {
362     return SCAN_NEW_ARTICLE;
363     }
364     break;
365 sysadm 1.28 case 'h':
366     return SHOW_HELP;
367 sysadm 1.37 case 'x':
368     return VIEW_EX_DIR;
369 sysadm 1.48 case Ctrl('H'):
370     return SHOW_TOP10;
371 sysadm 1.1 default:
372     }
373    
374     if (old_page_id != *p_page_id)
375     {
376     return CHANGE_PAGE;
377     }
378    
379     if (item_count > 0 && old_selected_index != *p_selected_index)
380     {
381     if (old_selected_index >= 0)
382     {
383     moveto(4 + old_selected_index, 1);
384     outc(' ');
385     }
386     if (*p_selected_index >= 0)
387     {
388     moveto(4 + *p_selected_index, 1);
389     outc('>');
390     }
391     iflush();
392    
393     old_selected_index = *p_selected_index;
394     }
395    
396 sysadm 1.30 BBS_last_access_tm = time(NULL);
397     if (BBS_last_access_tm - last_refresh_tm >= BBS_section_list_load_interval)
398     {
399     return CHANGE_PAGE; // force section list refresh
400     }
401 sysadm 1.1 }
402    
403     return EXIT_SECTION;
404     }
405    
406 sysadm 1.11 static int display_article_key_handler(int *p_key, DISPLAY_CTX *p_ctx)
407 sysadm 1.10 {
408 sysadm 1.11 switch (*p_key)
409 sysadm 1.10 {
410 sysadm 1.11 case 'p':
411 sysadm 1.28 case Ctrl('X'):
412 sysadm 1.11 section_topic_view_mode = !section_topic_view_mode;
413 sysadm 1.10 case 0: // Set msg
414 sysadm 1.11 if (section_topic_view_mode)
415 sysadm 1.10 {
416 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
417 sysadm 1.40 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
418     "同主题阅读[\033[32m↑\033[33m/\033[32m↓\033[33m] "
419     "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
420 sysadm 1.10 }
421     else
422     {
423 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
424 sysadm 1.40 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
425     "移动[\033[32m↑\033[33m/\033[32m↓\033[33m/\033[32mPgUp\033[33m/\033[32mPgDn\033[33m] "
426     "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
427 sysadm 1.10 }
428 sysadm 1.11 *p_key = 0;
429 sysadm 1.10 break;
430 sysadm 1.20 case 'r': // Reply article
431     return 1;
432 sysadm 1.31 case '=': // First topic article
433     return 1;
434     case '\\': // Last topic article
435     return 1;
436 sysadm 1.12 case KEY_UP:
437 sysadm 1.16 case KEY_PGUP:
438     case KEY_HOME:
439 sysadm 1.12 if (p_ctx->reach_begin)
440     {
441     if (section_topic_view_mode)
442     {
443     *p_key = KEY_PGUP;
444     }
445 sysadm 1.16 else
446     {
447     *p_key = KEY_UP;
448     }
449 sysadm 1.12 return 1;
450     }
451     break;
452 sysadm 1.28 case 'k':
453     if (section_topic_view_mode)
454     {
455     *p_key = KEY_PGUP;
456     }
457     else
458     {
459     *p_key = KEY_UP;
460     }
461     return 1;
462 sysadm 1.12 case KEY_DOWN:
463 sysadm 1.16 case KEY_PGDN:
464     case KEY_END:
465 sysadm 1.12 if (p_ctx->reach_end)
466     {
467     if (section_topic_view_mode)
468     {
469     *p_key = KEY_PGDN;
470     }
471 sysadm 1.16 else
472     {
473     *p_key = KEY_DOWN;
474     }
475 sysadm 1.12 return 1;
476     }
477     break;
478 sysadm 1.28 case 'j':
479     if (section_topic_view_mode)
480     {
481     *p_key = KEY_PGDN;
482     }
483     else
484     {
485     *p_key = KEY_DOWN;
486     }
487     return 1;
488 sysadm 1.10 }
489    
490     return 0;
491     }
492    
493 sysadm 1.46 int section_list_display(const char *sname, int32_t aid)
494 sysadm 1.1 {
495 sysadm 1.4 static int display_nickname = 0;
496    
497 sysadm 1.1 SECTION_LIST *p_section;
498 sysadm 1.46 int64_t section_index;
499     int32_t aid_location;
500 sysadm 1.5 char stitle[BBS_section_title_max_len + 1];
501     char master_list[(BBS_username_max_len + 1) * 3 + 1];
502 sysadm 1.6 char page_info_str[LINE_BUFFER_LEN];
503 sysadm 1.1 ARTICLE *p_articles[BBS_article_limit_per_page];
504     int article_count;
505 sysadm 1.6 int page_count;
506 sysadm 1.36 int ontop_start_offset;
507 sysadm 1.1 int page_id = 0;
508     int selected_index = 0;
509 sysadm 1.10 ARTICLE_CACHE cache;
510 sysadm 1.1 int ret;
511 sysadm 1.12 int loop;
512     int direction;
513 sysadm 1.24 ARTICLE article_new;
514 sysadm 1.31 int page_id_cur;
515 sysadm 1.46 const ARTICLE *p_article_locate;
516 sysadm 1.1
517 sysadm 1.46 p_section = section_list_find_by_name(sname, &section_index);
518 sysadm 1.1 if (p_section == NULL)
519     {
520     log_error("Section %s not found\n", sname);
521     return -1;
522     }
523    
524 sysadm 1.5 if ((ret = section_list_rd_lock(p_section)) < 0)
525     {
526     log_error("section_list_rd_lock(sid = 0) error\n");
527     return -2;
528     }
529    
530     strncpy(stitle, p_section->stitle, sizeof(stitle) - 1);
531     stitle[sizeof(stitle) - 1] = '\0';
532     strncpy(master_list, p_section->master_list, sizeof(master_list) - 1);
533     master_list[sizeof(master_list) - 1] = '\0';
534    
535     if ((ret = section_list_rd_unlock(p_section)) < 0)
536     {
537     log_error("section_list_rd_unlock(sid = 0) error\n");
538     return -2;
539     }
540    
541 sysadm 1.46 if (aid == 0)
542     {
543     aid_location = section_aid_locations[section_index];
544     }
545     else
546     {
547     aid_location = aid;
548     }
549    
550     // Locate at article with aid_locate
551     if (aid_location > 0)
552     {
553     p_article_locate = article_block_find_by_aid(aid_location);
554     if (p_article_locate == NULL)
555     {
556     log_error("article_block_find_by_aid(%d) error\n", aid_location);
557     return -3;
558     }
559    
560     ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
561     &page_id, &selected_index, &article_count);
562     if (ret < 0)
563     {
564     log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
565     p_section->sid, p_article_locate->aid);
566     return -3;
567     }
568     }
569    
570 sysadm 1.5 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
571 sysadm 1.1 {
572     log_error("section_list_draw_screen() error\n");
573     return -2;
574     }
575    
576 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
577 sysadm 1.5 if (ret < 0)
578 sysadm 1.1 {
579 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
580     return -3;
581 sysadm 1.1 }
582 sysadm 1.5
583 sysadm 1.46 section_topic_view_tid = -1;
584    
585 sysadm 1.5 if (article_count == 0) // empty section
586 sysadm 1.1 {
587     selected_index = 0;
588     }
589 sysadm 1.46 else if (aid > 0)
590     {
591     // Update current topic
592     section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
593    
594     // Update current aid location
595     section_aid_locations[section_index] = p_articles[selected_index]->aid;
596     }
597 sysadm 1.1
598     while (!SYS_server_exit)
599     {
600 sysadm 1.36 ret = section_list_draw_items(page_id, p_articles, article_count, display_nickname, ontop_start_offset);
601 sysadm 1.1 if (ret < 0)
602     {
603     log_error("section_list_draw_items(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
604     return -4;
605     }
606 sysadm 1.6
607 sysadm 1.7 snprintf(page_info_str, sizeof(page_info_str),
608 sysadm 1.40 "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
609 sysadm 1.7 page_id + 1, MAX(page_count, 1));
610 sysadm 1.8
611 sysadm 1.6 show_bottom(page_info_str);
612 sysadm 1.1 iflush();
613    
614 sysadm 1.33 if (user_online_update(sname) < 0)
615     {
616     log_error("user_online_update(%s) error\n", sname);
617     }
618    
619 sysadm 1.6 ret = section_list_select(page_count, article_count, &page_id, &selected_index);
620 sysadm 1.1 switch (ret)
621     {
622     case EXIT_SECTION:
623     return 0;
624     case CHANGE_PAGE:
625 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
626 sysadm 1.5 if (ret < 0)
627 sysadm 1.1 {
628 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
629     return -3;
630 sysadm 1.1 }
631 sysadm 1.5 if (article_count == 0) // empty section
632 sysadm 1.1 {
633     selected_index = 0;
634     }
635 sysadm 1.5 else if (selected_index >= article_count)
636 sysadm 1.1 {
637     selected_index = article_count - 1;
638     }
639     break;
640     case VIEW_ARTICLE:
641 sysadm 1.12 do
642 sysadm 1.9 {
643 sysadm 1.12 loop = 0;
644 sysadm 1.9
645 sysadm 1.12 if (article_cache_load(&cache, VAR_ARTICLE_CACHE_DIR, p_articles[selected_index]) < 0)
646     {
647     log_error("article_cache_load(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
648     break;
649     }
650    
651 sysadm 1.33 if (user_online_update("VIEW_ARTICLE") < 0)
652     {
653     log_error("user_online_update(VIEW_ARTICLE) error\n");
654     }
655    
656 sysadm 1.19 ret = display_data(cache.p_data, cache.line_total, cache.line_offsets, 0,
657 sysadm 1.12 display_article_key_handler, DATA_READ_HELP);
658    
659     if (article_cache_unload(&cache) < 0)
660     {
661     log_error("article_cache_unload(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
662     break;
663     }
664    
665 sysadm 1.17 // Update article_view_log
666     if (article_view_log_set_viewed(p_articles[selected_index]->aid, &BBS_article_view_log) < 0)
667     {
668     log_error("article_view_log_set_viewed(aid=%d) error\n", p_articles[selected_index]->aid);
669     }
670    
671 sysadm 1.12 switch (ret)
672     {
673     case KEY_UP:
674     if (selected_index <= 0)
675     {
676     if (page_id > 0)
677     {
678     page_id--;
679     selected_index = BBS_article_limit_per_page - 1;
680    
681 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
682 sysadm 1.12 if (ret < 0)
683     {
684     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
685     return -3;
686     }
687    
688     if (article_count != BBS_article_limit_per_page) // page is not full
689     {
690     selected_index = MAX(0, article_count - 1);
691     }
692     else
693     {
694     loop = 1;
695     }
696     }
697     }
698     else
699     {
700     selected_index--;
701     loop = 1;
702     }
703     break;
704     case KEY_DOWN:
705     if (selected_index + 1 >= article_count) // next page
706     {
707     if (page_id + 1 < page_count)
708     {
709     page_id++;
710     selected_index = 0;
711    
712 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
713 sysadm 1.12 if (ret < 0)
714     {
715     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
716     return -3;
717     }
718    
719     if (article_count == 0) // empty page
720     {
721     selected_index = 0;
722     }
723     else
724     {
725     loop = 1;
726     }
727     }
728     }
729     else
730     {
731     selected_index++;
732     loop = 1;
733     }
734     break;
735     case KEY_PGUP:
736     case KEY_PGDN:
737     direction = (ret == KEY_PGUP ? -1 : 1);
738 sysadm 1.31 ret = locate_article_in_section(p_section, p_articles[selected_index], direction, 1,
739     &page_id, &selected_index, &article_count);
740 sysadm 1.12 if (ret < 0)
741     {
742 sysadm 1.31 log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=1) error\n",
743 sysadm 1.12 p_section->sid, p_articles[selected_index]->aid, direction);
744     return -3;
745     }
746 sysadm 1.31 else if (ret > 0) // found
747 sysadm 1.12 {
748 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
749 sysadm 1.12 if (ret < 0)
750     {
751     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
752     return -3;
753     }
754     loop = 1;
755     }
756     break;
757 sysadm 1.20 case 'r': // Reply article
758 sysadm 1.33 if (user_online_update("REPLY_ARTICLE") < 0)
759     {
760     log_error("user_online_update(REPLY_ARTICLE) error\n");
761     }
762    
763 sysadm 1.24 if (article_reply(p_section, p_articles[selected_index], &article_new) < 0)
764 sysadm 1.20 {
765 sysadm 1.33 log_error("article_reply(aid=%d) error\n", p_articles[selected_index]->aid);
766 sysadm 1.20 }
767     loop = 1;
768     break;
769 sysadm 1.31 case '=': // First topic article
770     case '\\': // Last topic article
771     page_id_cur = page_id;
772     direction = (ret == '=' ? -1 : 1);
773     ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
774     &page_id, &selected_index, &article_count);
775     if (ret < 0)
776     {
777     log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
778     p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
779     return -3;
780     }
781     else if (ret > 0) // found
782     {
783     if (page_id != page_id_cur) // page changed
784     {
785 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
786 sysadm 1.31 if (ret < 0)
787     {
788     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
789     return -3;
790     }
791     }
792     loop = 1;
793     }
794     break;
795 sysadm 1.12 }
796     } while (loop);
797 sysadm 1.13
798     // Update current topic
799     section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
800 sysadm 1.46
801     // Update current aid location
802     section_aid_locations[section_index] = p_articles[selected_index]->aid;
803 sysadm 1.35
804     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
805     {
806     log_error("section_list_draw_screen() error\n");
807     return -2;
808     }
809     break;
810 sysadm 1.4 case CHANGE_NAME_DISPLAY:
811     display_nickname = !display_nickname;
812 sysadm 1.5 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
813 sysadm 1.1 {
814     log_error("section_list_draw_screen() error\n");
815     return -2;
816     }
817     break;
818 sysadm 1.20 case POST_ARTICLE:
819 sysadm 1.33 if (user_online_update("POST_ARTICLE") < 0)
820     {
821     log_error("user_online_update(POST_ARTICLE) error\n");
822     }
823    
824 sysadm 1.30 if ((ret = article_post(p_section, &article_new)) < 0)
825 sysadm 1.20 {
826 sysadm 1.26 log_error("article_post(sid=%d) error\n", p_section->sid);
827 sysadm 1.20 }
828 sysadm 1.24 else if (ret > 0) // New article posted
829     {
830 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
831 sysadm 1.24 if (ret < 0)
832     {
833     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
834     return -3;
835     }
836     }
837 sysadm 1.20 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
838     {
839     log_error("section_list_draw_screen() error\n");
840     return -2;
841     }
842     break;
843     case EDIT_ARTICLE:
844 sysadm 1.26 if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
845     p_articles[selected_index]->uid != BBS_priv.uid)
846 sysadm 1.20 {
847 sysadm 1.26 break; // No permission
848 sysadm 1.20 }
849 sysadm 1.33
850     if (user_online_update("EDIT_ARTICLE") < 0)
851     {
852     log_error("user_online_update() error\n");
853     }
854    
855 sysadm 1.24 if (article_modify(p_section, p_articles[selected_index], &article_new) < 0)
856 sysadm 1.20 {
857 sysadm 1.26 log_error("article_modify(aid=%d) error\n", p_articles[selected_index]->aid);
858     }
859     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
860     {
861     log_error("section_list_draw_screen() error\n");
862     return -2;
863     }
864     break;
865     case DELETE_ARTICLE:
866     if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
867     (!checkpriv(&BBS_priv, p_section->sid, S_MAN_S) && p_articles[selected_index]->uid != BBS_priv.uid))
868     {
869     break; // No permission
870     }
871 sysadm 1.30 if ((ret = article_del(p_section, p_articles[selected_index])) < 0)
872 sysadm 1.26 {
873     log_error("article_del(aid=%d) error\n", p_articles[selected_index]->aid);
874 sysadm 1.20 }
875 sysadm 1.30 else if (ret > 0) // Article deleted
876     {
877 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
878 sysadm 1.30 if (ret < 0)
879     {
880     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
881     return -3;
882     }
883     }
884 sysadm 1.20 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
885     {
886     log_error("section_list_draw_screen() error\n");
887     return -2;
888     }
889     break;
890 sysadm 1.41 case QUERY_ARTICLE:
891     if ((ret = display_article_meta(p_articles[selected_index]->aid)) < 0)
892     {
893     log_error("display_article_meta(aid=%d) error\n", p_articles[selected_index]->aid);
894     }
895     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
896     {
897     log_error("section_list_draw_screen() error\n");
898     return -2;
899     }
900     break;
901 sysadm 1.31 case FIRST_TOPIC_ARTICLE:
902     case LAST_TOPIC_ARTICLE:
903     page_id_cur = page_id;
904     direction = (ret == FIRST_TOPIC_ARTICLE ? -1 : 1);
905     ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
906     &page_id, &selected_index, &article_count);
907     if (ret < 0)
908     {
909     log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
910     p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
911     return -3;
912     }
913     else if (ret > 0 && page_id != page_id_cur) // found and page changed
914     {
915 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
916 sysadm 1.31 if (ret < 0)
917     {
918     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
919     return -3;
920     }
921     }
922     break;
923 sysadm 1.45 case SCAN_NEW_ARTICLE:
924 sysadm 1.46 ret = scan_unread_article_in_section(p_section, p_articles[selected_index], &p_article_locate);
925 sysadm 1.45 if (ret < 0)
926     {
927     log_error("scan_unread_article_in_section(sid=%d, aid=%d) error\n",
928     p_section->sid, p_articles[selected_index]->aid);
929     return -3;
930     }
931     else if (ret == 0) // not found
932     {
933     break;
934     }
935     page_id_cur = page_id;
936 sysadm 1.46 ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
937 sysadm 1.45 &page_id, &selected_index, &article_count);
938     if (ret < 0)
939     {
940     log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
941 sysadm 1.46 p_section->sid, p_article_locate->aid);
942 sysadm 1.45 return -3;
943     }
944     else if (ret > 0 && page_id != page_id_cur) // found and page changed
945     {
946     ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
947     if (ret < 0)
948     {
949     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
950     return -3;
951     }
952     }
953     break;
954 sysadm 1.28 case SHOW_HELP:
955     // Display help information
956     display_file(DATA_READ_HELP, 1);
957     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
958     {
959     log_error("section_list_draw_screen() error\n");
960     return -2;
961     }
962     break;
963 sysadm 1.37 case VIEW_EX_DIR:
964     if (section_list_ex_dir_display(p_section) < 0)
965     {
966     log_error("section_list_ex_dir_display(sid=%d) error\n", p_section->sid);
967     }
968     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
969     {
970     log_error("section_list_draw_screen() error\n");
971     return -2;
972     }
973     break;
974 sysadm 1.48 case SHOW_TOP10:
975     show_top10_menu(NULL);
976     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
977     {
978     log_error("section_list_draw_screen() error\n");
979     return -2;
980     }
981     break;
982 sysadm 1.1 default:
983     log_error("Unknown command %d\n", ret);
984     }
985     }
986    
987     return 0;
988     }
989 sysadm 1.37
990     int section_list_ex_dir_display(SECTION_LIST *p_section)
991     {
992     MENU_SET ex_menu_set;
993     int ch = 0;
994    
995     if (p_section == NULL)
996     {
997     log_error("NULL pointer error\n");
998     return -1;
999     }
1000    
1001 sysadm 1.39 if (p_section->ex_menu_tm == 0) // N/A
1002     {
1003     moveto(2, 1);
1004     clrtoeol();
1005 sysadm 1.40 prints("该版块精华区未开放");
1006 sysadm 1.39 press_any_key();
1007     return 0;
1008     }
1009    
1010 sysadm 1.37 if (get_section_ex_menu_set(p_section, &ex_menu_set) < 0)
1011     {
1012     log_error("get_section_ex_menu_set(sid=%d) error\n", p_section->sid);
1013     return -3;
1014     }
1015     if (get_menu_shm_readonly(&ex_menu_set) < 0)
1016     {
1017 sysadm 1.39 log_error("get_menu_shm_readonly(sid=%d) error\n", p_section->sid);
1018 sysadm 1.37 return -3;
1019     }
1020    
1021     clearscr();
1022 sysadm 1.38 show_bottom("");
1023 sysadm 1.37
1024     if (display_menu(&ex_menu_set) == 0)
1025     {
1026     while (!SYS_server_exit)
1027     {
1028     iflush();
1029     ch = igetch(100);
1030     switch (ch)
1031     {
1032     case KEY_NULL: // broken pipe
1033     return 0;
1034     case KEY_TIMEOUT:
1035     if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
1036     {
1037     return 0;
1038     }
1039     continue;
1040     case CR:
1041     igetch_reset();
1042     default:
1043     switch (menu_control(&ex_menu_set, ch))
1044     {
1045     case EXITMENU:
1046     ch = EXITMENU;
1047     break;
1048     case REDRAW:
1049     clearscr();
1050 sysadm 1.38 show_bottom("");
1051 sysadm 1.37 display_menu(&ex_menu_set);
1052     break;
1053     case NOREDRAW:
1054     case UNKNOWN_CMD:
1055     default:
1056     break;
1057     }
1058     }
1059    
1060     BBS_last_access_tm = time(NULL);
1061    
1062     if (ch == EXITMENU)
1063     {
1064     break;
1065     }
1066     }
1067     }
1068    
1069     detach_menu_shm(&ex_menu_set);
1070    
1071     return 0;
1072     }

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