/[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.41 - (show annotations)
Tue Sep 30 04:56:16 2025 UTC (5 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.40: +49 -14 lines
Content type: text/x-csrc
Add display_article_meta()
Fix bug of edit / delete article in empty section

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

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