/[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.42 - (show annotations)
Tue Sep 30 14:56:51 2025 UTC (5 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.41: +21 -1 lines
Content type: text/x-csrc
Rewrite title with "Re: Re: " prefix into "Re: ... "

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

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