/[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.40 - (show annotations)
Wed Jul 2 04:17:33 2025 UTC (8 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.39: +20 -20 lines
Content type: text/x-csrc
Support UTF8 instead of GBK

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

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