/[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.41 - (hide 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 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.34 #include "section_list_display.h"
28     #include "section_list_loader.h"
29 sysadm 1.1 #include "screen.h"
30 sysadm 1.34 #include "str_process.h"
31 sysadm 1.18 #include "user_priv.h"
32 sysadm 1.29 #include <string.h>
33 sysadm 1.1 #include <time.h>
34 sysadm 1.6 #include <sys/param.h>
35 sysadm 1.1
36 sysadm 1.11 static int section_topic_view_mode = 0;
37 sysadm 1.13 static int section_topic_view_tid = -1;
38 sysadm 1.11
39 sysadm 1.1 enum select_cmd_t
40     {
41     EXIT_SECTION = 0,
42 sysadm 1.41 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 sysadm 1.1 };
54    
55 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)
56 sysadm 1.1 {
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 sysadm 1.3 char article_flag;
65 sysadm 1.17 int is_viewed;
66 sysadm 1.3 time_t tm_now;
67    
68     time(&tm_now);
69 sysadm 1.1
70     clrline(4, 23);
71    
72     for (i = 0; i < article_count; i++)
73     {
74 sysadm 1.18 if (p_articles[i]->uid == BBS_priv.uid)
75 sysadm 1.17 {
76 sysadm 1.18 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 sysadm 1.17 }
87    
88 sysadm 1.3 if (p_articles[i]->excerption)
89     {
90 sysadm 1.17 article_flag = (is_viewed ? 'm' : 'M');
91 sysadm 1.3 }
92 sysadm 1.17 else if (p_articles[i]->lock && is_viewed)
93 sysadm 1.3 {
94     article_flag = 'x';
95     }
96 sysadm 1.35 else
97     {
98     article_flag = (is_viewed ? ' ' : 'N');
99     }
100 sysadm 1.3
101 sysadm 1.1 localtime_r(&p_articles[i]->sub_dt, &tm_sub);
102 sysadm 1.3 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 sysadm 1.40 strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);
112 sysadm 1.1 title_f[sizeof(title_f) - 1] = '\0';
113 sysadm 1.40 strncat(title_f, (p_articles[i]->transship ? "[转载]" : ""), sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
114 sysadm 1.3 strncat(title_f, p_articles[i]->title, sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
115 sysadm 1.27 len = split_line(title_f, 47 - (display_nickname ? 8 : 0), &eol, &title_f_len, 1);
116 sysadm 1.1 if (title_f[len] != '\0')
117     {
118     title_f[len] = '\0';
119     }
120    
121     moveto(4 + i, 1);
122 sysadm 1.36 if (i >= ontop_start_offset)
123     {
124 sysadm 1.40 prints(" \033[1;33m[提示]\033[m %c %s%*s %s %s%s\033[m",
125 sysadm 1.36 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 sysadm 1.1 }
161    
162     return 0;
163     }
164    
165 sysadm 1.5 static int section_list_draw_screen(const char *sname, const char *stitle, const char *master_list, int display_nickname)
166 sysadm 1.1 {
167 sysadm 1.40 char str_section_master[LINE_BUFFER_LEN] = "诚征版主中";
168 sysadm 1.1 char str_section_name[LINE_BUFFER_LEN];
169    
170 sysadm 1.5 if (master_list[0] != '\0')
171 sysadm 1.1 {
172 sysadm 1.40 snprintf(str_section_master, sizeof(str_section_master), "版主:%s", master_list);
173 sysadm 1.1 }
174 sysadm 1.40 snprintf(str_section_name, sizeof(str_section_name), "讨论区 [%s]", sname);
175 sysadm 1.1
176     clearscr();
177 sysadm 1.5 show_top(str_section_master, stitle, str_section_name);
178 sysadm 1.1 moveto(2, 0);
179 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] "
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 sysadm 1.1 moveto(3, 0);
184 sysadm 1.4 if (display_nickname)
185     {
186 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发布者昵称 日 期 文章标题 \033[m");
187 sysadm 1.4 }
188     else
189     {
190 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发 布 者 日 期 文章标题 \033[m");
191 sysadm 1.4 }
192 sysadm 1.1
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 sysadm 1.30 time_t last_refresh_tm = time(NULL);
202 sysadm 1.1
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 sysadm 1.30 BBS_last_access_tm = time(NULL);
219     case KEY_NULL: // broken pipe
220 sysadm 1.1 return EXIT_SECTION; // exit section
221     case KEY_TIMEOUT:
222 sysadm 1.30 if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
223 sysadm 1.1 {
224     return EXIT_SECTION; // exit section
225     }
226     continue;
227 sysadm 1.4 case 'n':
228 sysadm 1.30 BBS_last_access_tm = time(NULL);
229 sysadm 1.4 return CHANGE_NAME_DISPLAY;
230 sysadm 1.1 case CR:
231     igetch_reset();
232 sysadm 1.28 case 'r':
233 sysadm 1.1 case KEY_RIGHT:
234     if (item_count > 0)
235     {
236 sysadm 1.30 BBS_last_access_tm = time(NULL);
237 sysadm 1.1 return VIEW_ARTICLE;
238     }
239     break;
240 sysadm 1.20 case Ctrl('P'):
241     return POST_ARTICLE;
242     case 'E':
243 sysadm 1.41 if (item_count > 0)
244     {
245     return EDIT_ARTICLE;
246     }
247     break;
248 sysadm 1.26 case 'd':
249 sysadm 1.41 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 sysadm 1.1 case KEY_HOME:
261     *p_page_id = 0;
262 sysadm 1.28 case 'P':
263 sysadm 1.1 case KEY_PGUP:
264     *p_selected_index = 0;
265 sysadm 1.28 case 'k':
266 sysadm 1.1 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 sysadm 1.28 case '$':
281 sysadm 1.1 case KEY_END:
282     if (total_page > 0)
283     {
284     *p_page_id = total_page - 1;
285     }
286 sysadm 1.28 case 'N':
287 sysadm 1.1 case KEY_PGDN:
288     if (item_count > 0)
289     {
290     *p_selected_index = item_count - 1;
291     }
292 sysadm 1.28 case 'j':
293 sysadm 1.1 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 sysadm 1.25 else // end of last page
302     {
303     return CHANGE_PAGE; // force refresh pages
304     }
305 sysadm 1.1 }
306     else
307     {
308     (*p_selected_index)++;
309     }
310     break;
311 sysadm 1.31 case '=':
312 sysadm 1.41 if (item_count > 0)
313     {
314     return FIRST_TOPIC_ARTICLE;
315     }
316     break;
317 sysadm 1.31 case '\\':
318 sysadm 1.41 if (item_count > 0)
319     {
320     return LAST_TOPIC_ARTICLE;
321     }
322     break;
323 sysadm 1.28 case 'h':
324     return SHOW_HELP;
325 sysadm 1.37 case 'x':
326     return VIEW_EX_DIR;
327 sysadm 1.1 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 sysadm 1.30 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 sysadm 1.1 }
358    
359     return EXIT_SECTION;
360     }
361    
362 sysadm 1.11 static int display_article_key_handler(int *p_key, DISPLAY_CTX *p_ctx)
363 sysadm 1.10 {
364 sysadm 1.11 switch (*p_key)
365 sysadm 1.10 {
366 sysadm 1.11 case 'p':
367 sysadm 1.28 case Ctrl('X'):
368 sysadm 1.11 section_topic_view_mode = !section_topic_view_mode;
369 sysadm 1.10 case 0: // Set msg
370 sysadm 1.11 if (section_topic_view_mode)
371 sysadm 1.10 {
372 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
373 sysadm 1.40 "| 返回[\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 sysadm 1.10 }
377     else
378     {
379 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
380 sysadm 1.40 "| 返回[\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 sysadm 1.10 }
384 sysadm 1.11 *p_key = 0;
385 sysadm 1.10 break;
386 sysadm 1.20 case 'r': // Reply article
387     return 1;
388 sysadm 1.31 case '=': // First topic article
389     return 1;
390     case '\\': // Last topic article
391     return 1;
392 sysadm 1.12 case KEY_UP:
393 sysadm 1.16 case KEY_PGUP:
394     case KEY_HOME:
395 sysadm 1.12 if (p_ctx->reach_begin)
396     {
397     if (section_topic_view_mode)
398     {
399     *p_key = KEY_PGUP;
400     }
401 sysadm 1.16 else
402     {
403     *p_key = KEY_UP;
404     }
405 sysadm 1.12 return 1;
406     }
407     break;
408 sysadm 1.28 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 sysadm 1.12 case KEY_DOWN:
419 sysadm 1.16 case KEY_PGDN:
420     case KEY_END:
421 sysadm 1.12 if (p_ctx->reach_end)
422     {
423     if (section_topic_view_mode)
424     {
425     *p_key = KEY_PGDN;
426     }
427 sysadm 1.16 else
428     {
429     *p_key = KEY_DOWN;
430     }
431 sysadm 1.12 return 1;
432     }
433     break;
434 sysadm 1.28 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 sysadm 1.10 }
445    
446     return 0;
447     }
448    
449 sysadm 1.1 int section_list_display(const char *sname)
450     {
451 sysadm 1.4 static int display_nickname = 0;
452    
453 sysadm 1.1 SECTION_LIST *p_section;
454 sysadm 1.5 char stitle[BBS_section_title_max_len + 1];
455     char master_list[(BBS_username_max_len + 1) * 3 + 1];
456 sysadm 1.6 char page_info_str[LINE_BUFFER_LEN];
457 sysadm 1.1 ARTICLE *p_articles[BBS_article_limit_per_page];
458     int article_count;
459 sysadm 1.6 int page_count;
460 sysadm 1.36 int ontop_start_offset;
461 sysadm 1.1 int page_id = 0;
462     int selected_index = 0;
463 sysadm 1.10 ARTICLE_CACHE cache;
464 sysadm 1.1 int ret;
465 sysadm 1.12 int loop;
466     int direction;
467 sysadm 1.24 ARTICLE article_new;
468 sysadm 1.31 int page_id_cur;
469 sysadm 1.1
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 sysadm 1.5 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 sysadm 1.1 {
496     log_error("section_list_draw_screen() error\n");
497     return -2;
498     }
499    
500 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
501 sysadm 1.5 if (ret < 0)
502 sysadm 1.1 {
503 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
504     return -3;
505 sysadm 1.1 }
506 sysadm 1.5
507     if (article_count == 0) // empty section
508 sysadm 1.1 {
509     selected_index = 0;
510     }
511    
512     while (!SYS_server_exit)
513     {
514 sysadm 1.36 ret = section_list_draw_items(page_id, p_articles, article_count, display_nickname, ontop_start_offset);
515 sysadm 1.1 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 sysadm 1.6
521 sysadm 1.7 snprintf(page_info_str, sizeof(page_info_str),
522 sysadm 1.40 "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
523 sysadm 1.7 page_id + 1, MAX(page_count, 1));
524 sysadm 1.8
525 sysadm 1.6 show_bottom(page_info_str);
526 sysadm 1.1 iflush();
527    
528 sysadm 1.33 if (user_online_update(sname) < 0)
529     {
530     log_error("user_online_update(%s) error\n", sname);
531     }
532    
533 sysadm 1.6 ret = section_list_select(page_count, article_count, &page_id, &selected_index);
534 sysadm 1.1 switch (ret)
535     {
536     case EXIT_SECTION:
537     return 0;
538     case CHANGE_PAGE:
539 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
540 sysadm 1.5 if (ret < 0)
541 sysadm 1.1 {
542 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
543     return -3;
544 sysadm 1.1 }
545 sysadm 1.5 if (article_count == 0) // empty section
546 sysadm 1.1 {
547     selected_index = 0;
548     }
549 sysadm 1.5 else if (selected_index >= article_count)
550 sysadm 1.1 {
551     selected_index = article_count - 1;
552     }
553     break;
554     case VIEW_ARTICLE:
555 sysadm 1.12 do
556 sysadm 1.9 {
557 sysadm 1.12 loop = 0;
558 sysadm 1.9
559 sysadm 1.12 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 sysadm 1.33 if (user_online_update("VIEW_ARTICLE") < 0)
566     {
567     log_error("user_online_update(VIEW_ARTICLE) error\n");
568     }
569    
570 sysadm 1.19 ret = display_data(cache.p_data, cache.line_total, cache.line_offsets, 0,
571 sysadm 1.12 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 sysadm 1.17 // 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 sysadm 1.12 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 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
596 sysadm 1.12 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 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
627 sysadm 1.12 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 sysadm 1.31 ret = locate_article_in_section(p_section, p_articles[selected_index], direction, 1,
653     &page_id, &selected_index, &article_count);
654 sysadm 1.12 if (ret < 0)
655     {
656 sysadm 1.31 log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=1) error\n",
657 sysadm 1.12 p_section->sid, p_articles[selected_index]->aid, direction);
658     return -3;
659     }
660 sysadm 1.31 else if (ret > 0) // found
661 sysadm 1.12 {
662 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
663 sysadm 1.12 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 sysadm 1.20 case 'r': // Reply article
672 sysadm 1.33 if (user_online_update("REPLY_ARTICLE") < 0)
673     {
674     log_error("user_online_update(REPLY_ARTICLE) error\n");
675     }
676    
677 sysadm 1.24 if (article_reply(p_section, p_articles[selected_index], &article_new) < 0)
678 sysadm 1.20 {
679 sysadm 1.33 log_error("article_reply(aid=%d) error\n", p_articles[selected_index]->aid);
680 sysadm 1.20 }
681     loop = 1;
682     break;
683 sysadm 1.31 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 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
700 sysadm 1.31 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 sysadm 1.12 }
710     } while (loop);
711 sysadm 1.13
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 sysadm 1.35
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 sysadm 1.4 case CHANGE_NAME_DISPLAY:
722     display_nickname = !display_nickname;
723 sysadm 1.5 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
724 sysadm 1.1 {
725     log_error("section_list_draw_screen() error\n");
726     return -2;
727     }
728     break;
729 sysadm 1.20 case POST_ARTICLE:
730 sysadm 1.33 if (user_online_update("POST_ARTICLE") < 0)
731     {
732     log_error("user_online_update(POST_ARTICLE) error\n");
733     }
734    
735 sysadm 1.30 if ((ret = article_post(p_section, &article_new)) < 0)
736 sysadm 1.20 {
737 sysadm 1.26 log_error("article_post(sid=%d) error\n", p_section->sid);
738 sysadm 1.20 }
739 sysadm 1.24 else if (ret > 0) // New article posted
740     {
741 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
742 sysadm 1.24 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 sysadm 1.20 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 sysadm 1.26 if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
756     p_articles[selected_index]->uid != BBS_priv.uid)
757 sysadm 1.20 {
758 sysadm 1.26 break; // No permission
759 sysadm 1.20 }
760 sysadm 1.33
761     if (user_online_update("EDIT_ARTICLE") < 0)
762     {
763     log_error("user_online_update() error\n");
764     }
765    
766 sysadm 1.24 if (article_modify(p_section, p_articles[selected_index], &article_new) < 0)
767 sysadm 1.20 {
768 sysadm 1.26 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 sysadm 1.30 if ((ret = article_del(p_section, p_articles[selected_index])) < 0)
783 sysadm 1.26 {
784     log_error("article_del(aid=%d) error\n", p_articles[selected_index]->aid);
785 sysadm 1.20 }
786 sysadm 1.30 else if (ret > 0) // Article deleted
787     {
788 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
789 sysadm 1.30 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 sysadm 1.20 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 sysadm 1.41 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 sysadm 1.31 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 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
827 sysadm 1.31 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 sysadm 1.28 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 sysadm 1.37 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 sysadm 1.1 default:
855     log_error("Unknown command %d\n", ret);
856     }
857     }
858    
859     return 0;
860     }
861 sysadm 1.37
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 sysadm 1.39 if (p_section->ex_menu_tm == 0) // N/A
874     {
875     moveto(2, 1);
876     clrtoeol();
877 sysadm 1.40 prints("该版块精华区未开放");
878 sysadm 1.39 press_any_key();
879     return 0;
880     }
881    
882 sysadm 1.37 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 sysadm 1.39 log_error("get_menu_shm_readonly(sid=%d) error\n", p_section->sid);
890 sysadm 1.37 return -3;
891     }
892    
893     clearscr();
894 sysadm 1.38 show_bottom("");
895 sysadm 1.37
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 sysadm 1.38 show_bottom("");
923 sysadm 1.37 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