/[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.65 - (hide annotations)
Mon Nov 3 06:45:18 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.64: +1 -0 lines
Content type: text/x-csrc
Add required header file

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.53 #include "article_favor.h"
19 sysadm 1.41 #include "article_op.h"
20 sysadm 1.20 #include "article_post.h"
21 sysadm 1.34 #include "article_view_log.h"
22 sysadm 1.26 #include "article_del.h"
23 sysadm 1.1 #include "common.h"
24     #include "io.h"
25 sysadm 1.34 #include "log.h"
26     #include "login.h"
27 sysadm 1.37 #include "menu.h"
28 sysadm 1.48 #include "menu_proc.h"
29 sysadm 1.34 #include "section_list_display.h"
30     #include "section_list_loader.h"
31 sysadm 1.1 #include "screen.h"
32 sysadm 1.34 #include "str_process.h"
33 sysadm 1.57 #include "user_info_display.h"
34 sysadm 1.63 #include "user_list_display.h"
35 sysadm 1.18 #include "user_priv.h"
36 sysadm 1.65 #include <ctype.h>
37 sysadm 1.59 #include <errno.h>
38 sysadm 1.29 #include <string.h>
39 sysadm 1.1 #include <time.h>
40 sysadm 1.6 #include <sys/param.h>
41 sysadm 1.1
42 sysadm 1.59 static int32_t section_aid_locations[BBS_max_section] = {0};
43 sysadm 1.11 static int section_topic_view_mode = 0;
44 sysadm 1.13 static int section_topic_view_tid = -1;
45 sysadm 1.11
46 sysadm 1.1 enum select_cmd_t
47     {
48     EXIT_SECTION = 0,
49 sysadm 1.41 VIEW_ARTICLE,
50     CHANGE_PAGE,
51     SHOW_HELP,
52     CHANGE_NAME_DISPLAY,
53     POST_ARTICLE,
54     EDIT_ARTICLE,
55     DELETE_ARTICLE,
56     QUERY_ARTICLE,
57 sysadm 1.57 QUERY_USER,
58 sysadm 1.53 SET_FAVOR_ARTICLE,
59     UNSET_FAVOR_ARTICLE,
60 sysadm 1.41 FIRST_TOPIC_ARTICLE,
61     LAST_TOPIC_ARTICLE,
62 sysadm 1.45 SCAN_NEW_ARTICLE,
63 sysadm 1.64 SCAN_ARTICLE_BACKWARD_BY_USER,
64     SCAN_ARTICLE_FORWARD_BY_USER,
65 sysadm 1.41 VIEW_EX_DIR,
66 sysadm 1.48 SHOW_TOP10,
67 sysadm 1.63 SEARCH_USER,
68 sysadm 1.1 };
69    
70 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)
71 sysadm 1.1 {
72     char str_time[LINE_BUFFER_LEN];
73     struct tm tm_sub;
74     char title_f[BBS_article_title_max_len + 1];
75     int title_f_len;
76     int eol;
77     int len;
78     int i;
79 sysadm 1.42 size_t j;
80 sysadm 1.3 char article_flag;
81 sysadm 1.17 int is_viewed;
82 sysadm 1.53 int is_favor;
83 sysadm 1.3 time_t tm_now;
84    
85     time(&tm_now);
86 sysadm 1.1
87     clrline(4, 23);
88    
89     for (i = 0; i < article_count; i++)
90     {
91 sysadm 1.18 if (p_articles[i]->uid == BBS_priv.uid)
92 sysadm 1.17 {
93 sysadm 1.18 is_viewed = 1;
94     }
95     else
96     {
97     is_viewed = article_view_log_is_viewed(p_articles[i]->aid, &BBS_article_view_log);
98     if (is_viewed < 0)
99     {
100     log_error("article_view_log_is_viewed(aid=%d) error\n", p_articles[i]->aid);
101     is_viewed = 0;
102     }
103 sysadm 1.17 }
104    
105 sysadm 1.53 if (p_articles[i]->tid == 0)
106     {
107     is_favor = article_favor_check(p_articles[i]->aid, &BBS_article_favor);
108     if (is_favor < 0)
109     {
110     log_error("article_favor_check(aid=%d) error\n", p_articles[i]->aid);
111     is_favor = 0;
112     }
113     }
114     else
115     {
116     is_favor = 0;
117     }
118    
119 sysadm 1.3 if (p_articles[i]->excerption)
120     {
121 sysadm 1.17 article_flag = (is_viewed ? 'm' : 'M');
122 sysadm 1.3 }
123 sysadm 1.17 else if (p_articles[i]->lock && is_viewed)
124 sysadm 1.3 {
125     article_flag = 'x';
126     }
127 sysadm 1.35 else
128     {
129     article_flag = (is_viewed ? ' ' : 'N');
130     }
131 sysadm 1.3
132 sysadm 1.1 localtime_r(&p_articles[i]->sub_dt, &tm_sub);
133 sysadm 1.3 if (tm_now - p_articles[i]->sub_dt < 3600 * 24 * 365)
134     {
135     strftime(str_time, sizeof(str_time), "%b %e ", &tm_sub);
136     }
137     else
138     {
139     strftime(str_time, sizeof(str_time), "%m/%Y", &tm_sub);
140     }
141    
142 sysadm 1.40 strncpy(title_f, (p_articles[i]->tid == 0 ? "● " : ""), sizeof(title_f) - 1);
143 sysadm 1.1 title_f[sizeof(title_f) - 1] = '\0';
144 sysadm 1.40 strncat(title_f, (p_articles[i]->transship ? "[转载]" : ""), sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
145 sysadm 1.42
146     // Rewrite title with "Re: Re: " prefix into "Re: ... "
147     j = 0;
148     if (p_articles[i]->tid != 0)
149     {
150     while (strncmp(p_articles[i]->title + j, "Re: ", strlen("Re: ")) == 0)
151     {
152     j += strlen("Re: ");
153     }
154     if (j >= strlen("Re: Re: "))
155     {
156     strncat(title_f, "Re: ... ", sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
157     }
158     else
159     {
160     j = 0;
161     }
162     }
163     strncat(title_f, p_articles[i]->title + j, sizeof(title_f) - 1 - strnlen(title_f, sizeof(title_f)));
164    
165 sysadm 1.51 len = split_line(title_f, 59 - (display_nickname ? BBS_nickname_max_len / 2 : BBS_username_max_len), &eol, &title_f_len, 1);
166 sysadm 1.1 if (title_f[len] != '\0')
167     {
168     title_f[len] = '\0';
169     }
170    
171     moveto(4 + i, 1);
172 sysadm 1.36 if (i >= ontop_start_offset)
173     {
174 sysadm 1.53 prints(" \033[1;33m[提示]\033[m%c%c %s%*s %s %s%s\033[m",
175     (is_favor ? '@' : ' '),
176 sysadm 1.36 article_flag,
177     (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
178 sysadm 1.43 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
179     : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
180 sysadm 1.36 "",
181     str_time,
182     (p_articles[i]->aid == section_topic_view_tid
183     ? "\033[1;33m"
184     : (p_articles[i]->tid == section_topic_view_tid
185     ? "\033[1;36m"
186     : "")),
187     title_f);
188     }
189     else
190     {
191 sysadm 1.53 prints(" %s%7d\033[m%c%c %s%*s %s %s%s\033[m",
192 sysadm 1.36 (p_articles[i]->aid == section_topic_view_tid
193     ? "\033[1;33m"
194     : (p_articles[i]->tid == section_topic_view_tid
195     ? "\033[1;36m"
196     : "")),
197     p_articles[i]->aid,
198 sysadm 1.53 (is_favor ? '@' : ' '),
199 sysadm 1.36 article_flag,
200     (display_nickname ? p_articles[i]->nickname : p_articles[i]->username),
201 sysadm 1.43 (display_nickname ? BBS_nickname_max_len / 2 - str_length(p_articles[i]->nickname, 1)
202     : BBS_username_max_len - str_length(p_articles[i]->username, 1)),
203 sysadm 1.36 "",
204     str_time,
205     (p_articles[i]->aid == section_topic_view_tid
206     ? "\033[1;33m"
207     : (p_articles[i]->tid == section_topic_view_tid
208     ? "\033[1;36m"
209     : "")),
210     title_f);
211     }
212 sysadm 1.1 }
213    
214     return 0;
215     }
216    
217 sysadm 1.5 static int section_list_draw_screen(const char *sname, const char *stitle, const char *master_list, int display_nickname)
218 sysadm 1.1 {
219 sysadm 1.40 char str_section_master[LINE_BUFFER_LEN] = "诚征版主中";
220 sysadm 1.1 char str_section_name[LINE_BUFFER_LEN];
221    
222 sysadm 1.5 if (master_list[0] != '\0')
223 sysadm 1.1 {
224 sysadm 1.40 snprintf(str_section_master, sizeof(str_section_master), "版主:%s", master_list);
225 sysadm 1.1 }
226 sysadm 1.40 snprintf(str_section_name, sizeof(str_section_name), "讨论区 [%s]", sname);
227 sysadm 1.1
228     clearscr();
229 sysadm 1.5 show_top(str_section_master, stitle, str_section_name);
230 sysadm 1.1 moveto(2, 0);
231 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] "
232     "阅读[\033[1;32m→\033[0;37m,\033[1;32mENTER\033[0;37m] 发表[\033[1;32mCtrl-P\033[0;37m] "
233     "%s[\033[1;32mn\033[0;37m] 精华区[\033[1;32mx\033[0;37m] 帮助[\033[1;32mh\033[0;37m]\033[m",
234     (display_nickname ? "用户名" : "昵称"));
235 sysadm 1.1 moveto(3, 0);
236 sysadm 1.4 if (display_nickname)
237     {
238 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发布者昵称 日 期 文章标题 \033[m");
239 sysadm 1.4 }
240     else
241     {
242 sysadm 1.40 prints("\033[44;37m \033[1;37m 编 号 发 布 者 日 期 文章标题 \033[m");
243 sysadm 1.4 }
244 sysadm 1.1
245     return 0;
246     }
247    
248     static enum select_cmd_t section_list_select(int total_page, int item_count, int *p_page_id, int *p_selected_index)
249     {
250     int old_page_id = *p_page_id;
251     int old_selected_index = *p_selected_index;
252     int ch;
253 sysadm 1.30 time_t last_refresh_tm = time(NULL);
254 sysadm 1.1
255     if (item_count > 0 && *p_selected_index >= 0)
256     {
257     moveto(4 + *p_selected_index, 1);
258     outc('>');
259     iflush();
260     }
261    
262     while (!SYS_server_exit)
263     {
264     ch = igetch(100);
265    
266 sysadm 1.54 if (ch != KEY_NULL && ch != KEY_TIMEOUT)
267     {
268     BBS_last_access_tm = time(NULL);
269     }
270    
271 sysadm 1.1 switch (ch)
272     {
273 sysadm 1.57 case KEY_NULL: // broken pipe
274 sysadm 1.54 log_error("KEY_NULL\n");
275     return EXIT_SECTION;
276 sysadm 1.1 case KEY_TIMEOUT:
277 sysadm 1.30 if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
278 sysadm 1.1 {
279 sysadm 1.54 log_error("User input timeout\n");
280     return EXIT_SECTION;
281 sysadm 1.1 }
282     continue;
283 sysadm 1.54 case KEY_ESC:
284     case KEY_LEFT:
285     return EXIT_SECTION;
286 sysadm 1.4 case 'n':
287     return CHANGE_NAME_DISPLAY;
288 sysadm 1.1 case CR:
289 sysadm 1.28 case 'r':
290 sysadm 1.1 case KEY_RIGHT:
291     if (item_count > 0)
292     {
293     return VIEW_ARTICLE;
294     }
295     break;
296 sysadm 1.20 case Ctrl('P'):
297     return POST_ARTICLE;
298     case 'E':
299 sysadm 1.41 if (item_count > 0)
300     {
301     return EDIT_ARTICLE;
302     }
303     break;
304 sysadm 1.26 case 'd':
305 sysadm 1.41 if (item_count > 0)
306     {
307     return DELETE_ARTICLE;
308     }
309     break;
310     case Ctrl('Q'):
311     if (item_count > 0)
312     {
313     return QUERY_ARTICLE;
314     }
315     break;
316 sysadm 1.57 case Ctrl('A'):
317     if (item_count > 0)
318     {
319     return QUERY_USER;
320     }
321     break;
322 sysadm 1.53 case 'F':
323     if (item_count > 0)
324     {
325     return SET_FAVOR_ARTICLE;
326     }
327     break;
328     case '-':
329     if (item_count > 0)
330     {
331     return UNSET_FAVOR_ARTICLE;
332     }
333     break;
334 sysadm 1.1 case KEY_HOME:
335     *p_page_id = 0;
336 sysadm 1.28 case 'P':
337 sysadm 1.1 case KEY_PGUP:
338     *p_selected_index = 0;
339 sysadm 1.28 case 'k':
340 sysadm 1.1 case KEY_UP:
341     if (*p_selected_index <= 0)
342     {
343     if (*p_page_id > 0)
344     {
345     (*p_page_id)--;
346     *p_selected_index = BBS_article_limit_per_page - 1;
347     }
348 sysadm 1.44 else if (ch == KEY_UP || ch == 'k') // Rotate to the tail of section list
349     {
350     if (total_page > 0)
351     {
352     *p_page_id = total_page - 1;
353     }
354     if (item_count > 0)
355     {
356     *p_selected_index = item_count - 1;
357     }
358     }
359 sysadm 1.1 }
360     else
361     {
362     (*p_selected_index)--;
363     }
364     break;
365 sysadm 1.28 case '$':
366 sysadm 1.1 case KEY_END:
367     if (total_page > 0)
368     {
369     *p_page_id = total_page - 1;
370     }
371 sysadm 1.28 case 'N':
372 sysadm 1.1 case KEY_PGDN:
373     if (item_count > 0)
374     {
375     *p_selected_index = item_count - 1;
376     }
377 sysadm 1.28 case 'j':
378 sysadm 1.1 case KEY_DOWN:
379     if (*p_selected_index + 1 >= item_count) // next page
380     {
381     if (*p_page_id + 1 < total_page)
382     {
383     (*p_page_id)++;
384     *p_selected_index = 0;
385     }
386 sysadm 1.44 else if (ch == KEY_DOWN || ch == 'j') // Rotate to the head of section list
387 sysadm 1.25 {
388 sysadm 1.44 *p_page_id = 0;
389     *p_selected_index = 0;
390 sysadm 1.25 }
391 sysadm 1.1 }
392     else
393     {
394     (*p_selected_index)++;
395     }
396     break;
397 sysadm 1.31 case '=':
398 sysadm 1.41 if (item_count > 0)
399     {
400     return FIRST_TOPIC_ARTICLE;
401     }
402     break;
403 sysadm 1.31 case '\\':
404 sysadm 1.41 if (item_count > 0)
405     {
406     return LAST_TOPIC_ARTICLE;
407     }
408     break;
409 sysadm 1.45 case 'S':
410     if (item_count > 0)
411     {
412     return SCAN_NEW_ARTICLE;
413     }
414     break;
415 sysadm 1.64 case 'A':
416     if (item_count > 0)
417     {
418     return SCAN_ARTICLE_BACKWARD_BY_USER;
419     }
420     break;
421     case 'a':
422     if (item_count > 0)
423     {
424     return SCAN_ARTICLE_FORWARD_BY_USER;
425     }
426     break;
427 sysadm 1.63 case 'u':
428     return SEARCH_USER;
429 sysadm 1.28 case 'h':
430     return SHOW_HELP;
431 sysadm 1.37 case 'x':
432     return VIEW_EX_DIR;
433 sysadm 1.49 case 'H':
434 sysadm 1.48 return SHOW_TOP10;
435 sysadm 1.1 default:
436 sysadm 1.56 break;
437 sysadm 1.1 }
438    
439     if (old_page_id != *p_page_id)
440     {
441     return CHANGE_PAGE;
442     }
443    
444     if (item_count > 0 && old_selected_index != *p_selected_index)
445     {
446     if (old_selected_index >= 0)
447     {
448     moveto(4 + old_selected_index, 1);
449     outc(' ');
450     }
451     if (*p_selected_index >= 0)
452     {
453     moveto(4 + *p_selected_index, 1);
454     outc('>');
455     }
456     iflush();
457    
458     old_selected_index = *p_selected_index;
459     }
460    
461 sysadm 1.30 if (BBS_last_access_tm - last_refresh_tm >= BBS_section_list_load_interval)
462     {
463     return CHANGE_PAGE; // force section list refresh
464     }
465 sysadm 1.1 }
466    
467     return EXIT_SECTION;
468     }
469    
470 sysadm 1.11 static int display_article_key_handler(int *p_key, DISPLAY_CTX *p_ctx)
471 sysadm 1.10 {
472 sysadm 1.11 switch (*p_key)
473 sysadm 1.10 {
474 sysadm 1.11 case 'p':
475 sysadm 1.28 case Ctrl('X'):
476 sysadm 1.11 section_topic_view_mode = !section_topic_view_mode;
477 sysadm 1.10 case 0: // Set msg
478 sysadm 1.11 if (section_topic_view_mode)
479 sysadm 1.10 {
480 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
481 sysadm 1.40 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
482     "同主题阅读[\033[32m↑\033[33m/\033[32m↓\033[33m] "
483     "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
484 sysadm 1.10 }
485     else
486     {
487 sysadm 1.11 snprintf(p_ctx->msg, sizeof(p_ctx->msg),
488 sysadm 1.40 "| 返回[\033[32m←\033[33m,\033[32mESC\033[33m] "
489     "移动[\033[32m↑\033[33m/\033[32m↓\033[33m/\033[32mPgUp\033[33m/\033[32mPgDn\033[33m] "
490     "切换[\033[32mp\033[33m] 回复[\033[32mr\033[33m] 帮助[\033[32mh\033[33m] |");
491 sysadm 1.10 }
492 sysadm 1.11 *p_key = 0;
493 sysadm 1.10 break;
494 sysadm 1.20 case 'r': // Reply article
495     return 1;
496 sysadm 1.31 case '=': // First topic article
497     return 1;
498     case '\\': // Last topic article
499     return 1;
500 sysadm 1.12 case KEY_UP:
501 sysadm 1.16 case KEY_PGUP:
502     case KEY_HOME:
503 sysadm 1.12 if (p_ctx->reach_begin)
504     {
505     if (section_topic_view_mode)
506     {
507     *p_key = KEY_PGUP;
508     }
509 sysadm 1.16 else
510     {
511     *p_key = KEY_UP;
512     }
513 sysadm 1.12 return 1;
514     }
515     break;
516 sysadm 1.28 case 'k':
517     if (section_topic_view_mode)
518     {
519     *p_key = KEY_PGUP;
520     }
521     else
522     {
523     *p_key = KEY_UP;
524     }
525     return 1;
526 sysadm 1.12 case KEY_DOWN:
527 sysadm 1.16 case KEY_PGDN:
528     case KEY_END:
529 sysadm 1.12 if (p_ctx->reach_end)
530     {
531     if (section_topic_view_mode)
532     {
533     *p_key = KEY_PGDN;
534     }
535 sysadm 1.16 else
536     {
537     *p_key = KEY_DOWN;
538     }
539 sysadm 1.12 return 1;
540     }
541     break;
542 sysadm 1.28 case 'j':
543     if (section_topic_view_mode)
544     {
545     *p_key = KEY_PGDN;
546     }
547     else
548     {
549     *p_key = KEY_DOWN;
550     }
551     return 1;
552 sysadm 1.10 }
553    
554     return 0;
555     }
556    
557 sysadm 1.46 int section_list_display(const char *sname, int32_t aid)
558 sysadm 1.1 {
559 sysadm 1.4 static int display_nickname = 0;
560    
561 sysadm 1.1 SECTION_LIST *p_section;
562 sysadm 1.46 int64_t section_index;
563     int32_t aid_location;
564 sysadm 1.5 char stitle[BBS_section_title_max_len + 1];
565     char master_list[(BBS_username_max_len + 1) * 3 + 1];
566 sysadm 1.6 char page_info_str[LINE_BUFFER_LEN];
567 sysadm 1.1 ARTICLE *p_articles[BBS_article_limit_per_page];
568     int article_count;
569 sysadm 1.6 int page_count;
570 sysadm 1.36 int ontop_start_offset;
571 sysadm 1.1 int page_id = 0;
572     int selected_index = 0;
573 sysadm 1.10 ARTICLE_CACHE cache;
574 sysadm 1.1 int ret;
575 sysadm 1.12 int loop;
576     int direction;
577 sysadm 1.24 ARTICLE article_new;
578 sysadm 1.31 int page_id_cur;
579 sysadm 1.46 const ARTICLE *p_article_locate;
580 sysadm 1.57 USER_INFO user_info;
581 sysadm 1.61 char user_intro[BBS_user_intro_max_len];
582 sysadm 1.64 char username[BBS_username_max_len + 1];
583     char username_list[1][BBS_username_max_len + 1];
584     int32_t uid;
585     int i;
586     int ok;
587 sysadm 1.1
588 sysadm 1.50 p_section = section_list_find_by_name(sname);
589 sysadm 1.1 if (p_section == NULL)
590     {
591     log_error("Section %s not found\n", sname);
592     return -1;
593     }
594    
595 sysadm 1.52 if (!checkpriv(&BBS_priv, p_section->sid, S_LIST))
596     {
597     log_error("Forbid access to unauthorized section, sid=%d, uid=%d\n",
598     p_section->sid, BBS_priv.uid);
599     return -1;
600     }
601    
602 sysadm 1.50 section_index = get_section_index(p_section);
603    
604 sysadm 1.58 if (get_section_info(p_section, NULL, stitle, master_list) < 0)
605 sysadm 1.5 {
606 sysadm 1.58 log_error("get_section_info(sid=%d) error\n", p_section->sid);
607     return -4;
608 sysadm 1.5 }
609    
610 sysadm 1.46 if (aid == 0)
611     {
612     aid_location = section_aid_locations[section_index];
613     }
614     else
615     {
616     aid_location = aid;
617 sysadm 1.51 }
618 sysadm 1.46
619     // Locate at article with aid_locate
620     if (aid_location > 0)
621     {
622     p_article_locate = article_block_find_by_aid(aid_location);
623     if (p_article_locate == NULL)
624     {
625     log_error("article_block_find_by_aid(%d) error\n", aid_location);
626     return -3;
627     }
628    
629     ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
630     &page_id, &selected_index, &article_count);
631     if (ret < 0)
632     {
633     log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
634     p_section->sid, p_article_locate->aid);
635     return -3;
636     }
637     }
638    
639 sysadm 1.5 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
640 sysadm 1.1 {
641     log_error("section_list_draw_screen() error\n");
642     return -2;
643     }
644    
645 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
646 sysadm 1.5 if (ret < 0)
647 sysadm 1.1 {
648 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
649     return -3;
650 sysadm 1.1 }
651 sysadm 1.5
652 sysadm 1.46 section_topic_view_tid = -1;
653    
654 sysadm 1.5 if (article_count == 0) // empty section
655 sysadm 1.1 {
656     selected_index = 0;
657     }
658 sysadm 1.46 else if (aid > 0)
659     {
660     // Update current topic
661     section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
662    
663     // Update current aid location
664     section_aid_locations[section_index] = p_articles[selected_index]->aid;
665     }
666 sysadm 1.1
667     while (!SYS_server_exit)
668     {
669 sysadm 1.36 ret = section_list_draw_items(page_id, p_articles, article_count, display_nickname, ontop_start_offset);
670 sysadm 1.1 if (ret < 0)
671     {
672     log_error("section_list_draw_items(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
673     return -4;
674     }
675 sysadm 1.6
676 sysadm 1.7 snprintf(page_info_str, sizeof(page_info_str),
677 sysadm 1.40 "\033[33m[第\033[36m%d\033[33m/\033[36m%d\033[33m页]",
678 sysadm 1.7 page_id + 1, MAX(page_count, 1));
679 sysadm 1.8
680 sysadm 1.6 show_bottom(page_info_str);
681 sysadm 1.1 iflush();
682    
683 sysadm 1.33 if (user_online_update(sname) < 0)
684     {
685     log_error("user_online_update(%s) error\n", sname);
686     }
687    
688 sysadm 1.6 ret = section_list_select(page_count, article_count, &page_id, &selected_index);
689 sysadm 1.60
690 sysadm 1.1 switch (ret)
691     {
692     case EXIT_SECTION:
693 sysadm 1.62 // Update current aid location
694     if (p_articles[selected_index] != NULL)
695     {
696     section_aid_locations[section_index] = p_articles[selected_index]->aid;
697     }
698     else
699     {
700     log_error("p_articles[selected_index=%d] is NULL when exit section [%s]\n", selected_index, sname);
701     }
702 sysadm 1.1 return 0;
703     case CHANGE_PAGE:
704 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
705 sysadm 1.5 if (ret < 0)
706 sysadm 1.1 {
707 sysadm 1.5 log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
708     return -3;
709 sysadm 1.1 }
710 sysadm 1.5 if (article_count == 0) // empty section
711 sysadm 1.1 {
712     selected_index = 0;
713     }
714 sysadm 1.5 else if (selected_index >= article_count)
715 sysadm 1.1 {
716     selected_index = article_count - 1;
717     }
718     break;
719     case VIEW_ARTICLE:
720 sysadm 1.12 do
721 sysadm 1.9 {
722 sysadm 1.12 loop = 0;
723 sysadm 1.9
724 sysadm 1.12 if (article_cache_load(&cache, VAR_ARTICLE_CACHE_DIR, p_articles[selected_index]) < 0)
725     {
726     log_error("article_cache_load(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
727     break;
728     }
729    
730 sysadm 1.33 if (user_online_update("VIEW_ARTICLE") < 0)
731     {
732     log_error("user_online_update(VIEW_ARTICLE) error\n");
733     }
734    
735 sysadm 1.19 ret = display_data(cache.p_data, cache.line_total, cache.line_offsets, 0,
736 sysadm 1.12 display_article_key_handler, DATA_READ_HELP);
737    
738     if (article_cache_unload(&cache) < 0)
739     {
740     log_error("article_cache_unload(aid=%d, cid=%d) error\n", p_articles[selected_index]->aid, p_articles[selected_index]->cid);
741     break;
742     }
743    
744 sysadm 1.17 // Update article_view_log
745     if (article_view_log_set_viewed(p_articles[selected_index]->aid, &BBS_article_view_log) < 0)
746     {
747     log_error("article_view_log_set_viewed(aid=%d) error\n", p_articles[selected_index]->aid);
748     }
749    
750 sysadm 1.12 switch (ret)
751     {
752     case KEY_UP:
753     if (selected_index <= 0)
754     {
755     if (page_id > 0)
756     {
757     page_id--;
758     selected_index = BBS_article_limit_per_page - 1;
759    
760 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
761 sysadm 1.12 if (ret < 0)
762     {
763     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
764     return -3;
765     }
766    
767     if (article_count != BBS_article_limit_per_page) // page is not full
768     {
769     selected_index = MAX(0, article_count - 1);
770     }
771     else
772     {
773     loop = 1;
774     }
775     }
776     }
777     else
778     {
779     selected_index--;
780     loop = 1;
781     }
782     break;
783     case KEY_DOWN:
784     if (selected_index + 1 >= article_count) // next page
785     {
786     if (page_id + 1 < page_count)
787     {
788     page_id++;
789     selected_index = 0;
790    
791 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
792 sysadm 1.12 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     if (article_count == 0) // empty page
799     {
800     selected_index = 0;
801     }
802     else
803     {
804     loop = 1;
805     }
806     }
807     }
808     else
809     {
810     selected_index++;
811     loop = 1;
812     }
813     break;
814     case KEY_PGUP:
815     case KEY_PGDN:
816     direction = (ret == KEY_PGUP ? -1 : 1);
817 sysadm 1.31 ret = locate_article_in_section(p_section, p_articles[selected_index], direction, 1,
818     &page_id, &selected_index, &article_count);
819 sysadm 1.12 if (ret < 0)
820     {
821 sysadm 1.31 log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=1) error\n",
822 sysadm 1.12 p_section->sid, p_articles[selected_index]->aid, direction);
823     return -3;
824     }
825 sysadm 1.31 else if (ret > 0) // found
826 sysadm 1.12 {
827 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
828 sysadm 1.12 if (ret < 0)
829     {
830     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
831     return -3;
832     }
833     loop = 1;
834     }
835     break;
836 sysadm 1.20 case 'r': // Reply article
837 sysadm 1.33 if (user_online_update("REPLY_ARTICLE") < 0)
838     {
839     log_error("user_online_update(REPLY_ARTICLE) error\n");
840     }
841    
842 sysadm 1.24 if (article_reply(p_section, p_articles[selected_index], &article_new) < 0)
843 sysadm 1.20 {
844 sysadm 1.33 log_error("article_reply(aid=%d) error\n", p_articles[selected_index]->aid);
845 sysadm 1.20 }
846     loop = 1;
847     break;
848 sysadm 1.31 case '=': // First topic article
849     case '\\': // Last topic article
850     page_id_cur = page_id;
851     direction = (ret == '=' ? -1 : 1);
852     ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
853     &page_id, &selected_index, &article_count);
854     if (ret < 0)
855     {
856     log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
857     p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
858     return -3;
859     }
860     else if (ret > 0) // found
861     {
862     if (page_id != page_id_cur) // page changed
863     {
864 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
865 sysadm 1.31 if (ret < 0)
866     {
867     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
868     return -3;
869     }
870     }
871     loop = 1;
872     }
873     break;
874 sysadm 1.12 }
875     } while (loop);
876 sysadm 1.13
877     // Update current topic
878     section_topic_view_tid = (p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
879 sysadm 1.46
880 sysadm 1.35 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
881     {
882     log_error("section_list_draw_screen() error\n");
883     return -2;
884     }
885     break;
886 sysadm 1.4 case CHANGE_NAME_DISPLAY:
887     display_nickname = !display_nickname;
888 sysadm 1.5 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
889 sysadm 1.1 {
890     log_error("section_list_draw_screen() error\n");
891     return -2;
892     }
893     break;
894 sysadm 1.20 case POST_ARTICLE:
895 sysadm 1.33 if (user_online_update("POST_ARTICLE") < 0)
896     {
897     log_error("user_online_update(POST_ARTICLE) error\n");
898     }
899    
900 sysadm 1.30 if ((ret = article_post(p_section, &article_new)) < 0)
901 sysadm 1.20 {
902 sysadm 1.26 log_error("article_post(sid=%d) error\n", p_section->sid);
903 sysadm 1.20 }
904 sysadm 1.24 else if (ret > 0) // New article posted
905     {
906 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
907 sysadm 1.24 if (ret < 0)
908     {
909     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
910     return -3;
911     }
912     }
913 sysadm 1.20 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
914     {
915     log_error("section_list_draw_screen() error\n");
916     return -2;
917     }
918     break;
919     case EDIT_ARTICLE:
920 sysadm 1.26 if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
921     p_articles[selected_index]->uid != BBS_priv.uid)
922 sysadm 1.20 {
923 sysadm 1.26 break; // No permission
924 sysadm 1.20 }
925 sysadm 1.33
926     if (user_online_update("EDIT_ARTICLE") < 0)
927     {
928     log_error("user_online_update() error\n");
929     }
930    
931 sysadm 1.24 if (article_modify(p_section, p_articles[selected_index], &article_new) < 0)
932 sysadm 1.20 {
933 sysadm 1.26 log_error("article_modify(aid=%d) error\n", p_articles[selected_index]->aid);
934     }
935     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
936     {
937     log_error("section_list_draw_screen() error\n");
938     return -2;
939     }
940     break;
941     case DELETE_ARTICLE:
942     if (!checkpriv(&BBS_priv, p_section->sid, S_POST) ||
943     (!checkpriv(&BBS_priv, p_section->sid, S_MAN_S) && p_articles[selected_index]->uid != BBS_priv.uid))
944     {
945     break; // No permission
946     }
947 sysadm 1.30 if ((ret = article_del(p_section, p_articles[selected_index])) < 0)
948 sysadm 1.26 {
949     log_error("article_del(aid=%d) error\n", p_articles[selected_index]->aid);
950 sysadm 1.20 }
951 sysadm 1.30 else if (ret > 0) // Article deleted
952     {
953 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
954 sysadm 1.30 if (ret < 0)
955     {
956     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
957     return -3;
958     }
959     }
960 sysadm 1.20 if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
961     {
962     log_error("section_list_draw_screen() error\n");
963     return -2;
964     }
965     break;
966 sysadm 1.41 case QUERY_ARTICLE:
967     if ((ret = display_article_meta(p_articles[selected_index]->aid)) < 0)
968     {
969     log_error("display_article_meta(aid=%d) error\n", p_articles[selected_index]->aid);
970     }
971     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
972     {
973     log_error("section_list_draw_screen() error\n");
974     return -2;
975     }
976     break;
977 sysadm 1.57 case QUERY_USER:
978 sysadm 1.61 if ((ret = query_user_info_by_uid(p_articles[selected_index]->uid, &user_info, user_intro, sizeof(user_intro))) < 0)
979 sysadm 1.57 {
980     log_error("query_user_info_by_uid(uid=%d) error\n", p_articles[selected_index]->uid);
981     return -2;
982     }
983     else if (ret == 0)
984     {
985     clearscr();
986     prints("该用户已升天");
987     press_any_key();
988     }
989     else if (user_info_display(&user_info) < 0) // && ret > 0
990     {
991     log_error("user_info_display(uid=%d) error\n", p_articles[selected_index]->uid);
992     }
993    
994     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
995     {
996     log_error("section_list_draw_screen() error\n");
997     return -2;
998     }
999     break;
1000 sysadm 1.53 case SET_FAVOR_ARTICLE:
1001     ret = article_favor_set(p_articles[selected_index]->tid == 0
1002     ? p_articles[selected_index]->aid
1003     : p_articles[selected_index]->tid,
1004     &BBS_article_favor, 1);
1005     if (ret < 0)
1006     {
1007     log_error("article_favor_set(aid=%d, 1) error\n",
1008     p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
1009     }
1010     break;
1011     case UNSET_FAVOR_ARTICLE:
1012     ret = article_favor_set(p_articles[selected_index]->tid == 0
1013     ? p_articles[selected_index]->aid
1014     : p_articles[selected_index]->tid,
1015     &BBS_article_favor, 0);
1016     if (ret < 0)
1017     {
1018     log_error("article_favor_set(aid=%d, 0) error\n",
1019     p_articles[selected_index]->tid == 0 ? p_articles[selected_index]->aid : p_articles[selected_index]->tid);
1020     }
1021     break;
1022 sysadm 1.31 case FIRST_TOPIC_ARTICLE:
1023     case LAST_TOPIC_ARTICLE:
1024     page_id_cur = page_id;
1025     direction = (ret == FIRST_TOPIC_ARTICLE ? -1 : 1);
1026     ret = locate_article_in_section(p_section, p_articles[selected_index], direction, BBS_article_limit_per_section,
1027     &page_id, &selected_index, &article_count);
1028     if (ret < 0)
1029     {
1030     log_error("locate_article_in_section(sid=%d, aid=%d, direction=%d, step=%d) error\n",
1031     p_section->sid, p_articles[selected_index]->aid, direction, BBS_article_limit_per_section);
1032     return -3;
1033     }
1034     else if (ret > 0 && page_id != page_id_cur) // found and page changed
1035     {
1036 sysadm 1.36 ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1037 sysadm 1.31 if (ret < 0)
1038     {
1039     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1040     return -3;
1041     }
1042     }
1043     break;
1044 sysadm 1.45 case SCAN_NEW_ARTICLE:
1045 sysadm 1.46 ret = scan_unread_article_in_section(p_section, p_articles[selected_index], &p_article_locate);
1046 sysadm 1.45 if (ret < 0)
1047     {
1048     log_error("scan_unread_article_in_section(sid=%d, aid=%d) error\n",
1049     p_section->sid, p_articles[selected_index]->aid);
1050     return -3;
1051     }
1052     else if (ret == 0) // not found
1053     {
1054     break;
1055     }
1056     page_id_cur = page_id;
1057 sysadm 1.46 ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
1058 sysadm 1.45 &page_id, &selected_index, &article_count);
1059     if (ret < 0)
1060     {
1061     log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
1062 sysadm 1.46 p_section->sid, p_article_locate->aid);
1063 sysadm 1.45 return -3;
1064     }
1065     else if (ret > 0 && page_id != page_id_cur) // found and page changed
1066     {
1067     ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1068     if (ret < 0)
1069     {
1070     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1071     return -3;
1072     }
1073     }
1074     break;
1075 sysadm 1.64 case SCAN_ARTICLE_BACKWARD_BY_USER:
1076     case SCAN_ARTICLE_FORWARD_BY_USER:
1077     direction = (ret == SCAN_ARTICLE_FORWARD_BY_USER ? 1 : -1);
1078     strncpy(username, p_articles[selected_index]->username, sizeof(username) - 1);
1079     username[sizeof(username) - 1] = '\0';
1080     uid = 0;
1081    
1082     moveto(SCREEN_ROWS, 1);
1083     clrtoeol();
1084     get_data(SCREEN_ROWS, 1,
1085     (direction == 1 ? "向下搜寻作者: " : "向上搜寻作者: "),
1086     username, sizeof(username), BBS_username_max_len);
1087    
1088     if (username[0] == '\0')
1089     {
1090     break;
1091     }
1092    
1093     // Verify format
1094     for (i = 0, ok = 1; ok && username[i] != '\0'; i++)
1095     {
1096     if (!(isalpha(username[i]) || (i > 0 && (isdigit(username[i]) || username[i] == '_'))))
1097     {
1098     ok = 0;
1099     }
1100     }
1101     if (ok && i > BBS_username_max_len)
1102     {
1103     ok = 0;
1104     }
1105     if (!ok)
1106     {
1107     break;
1108     }
1109    
1110     ret = query_user_info_by_username(username, 1, &uid, username_list);
1111     if (ret < 0)
1112     {
1113     log_error("query_user_info_by_username(%s) error\n", username);
1114     break;
1115     }
1116    
1117     if (uid > 0)
1118     {
1119     ret = scan_article_in_section_by_uid(p_section, p_articles[selected_index],
1120     direction, uid, &p_article_locate);
1121     if (ret < 0)
1122     {
1123     log_error("scan_article_in_section_by_uid(sid=%d, aid=%d, direction=%d, uid=%d) error\n",
1124     p_section->sid, p_articles[selected_index]->aid, direction, uid);
1125     return -3;
1126     }
1127     else if (ret == 0) // not found
1128     {
1129     break;
1130     }
1131     }
1132     else // uid == 0
1133     {
1134     ret = scan_article_in_section_by_username(p_section, p_articles[selected_index],
1135     direction, username, &p_article_locate);
1136     if (ret < 0)
1137     {
1138     log_error("scan_article_in_section_by_username(sid=%d, aid=%d, direction=%d, username=%s) error\n",
1139     p_section->sid, p_articles[selected_index]->aid, direction, username);
1140     return -3;
1141     }
1142     else if (ret == 0) // not found
1143     {
1144     break;
1145     }
1146     }
1147    
1148     page_id_cur = page_id;
1149     ret = locate_article_in_section(p_section, p_article_locate, 0, 0,
1150     &page_id, &selected_index, &article_count);
1151     if (ret < 0)
1152     {
1153     log_error("locate_article_in_section(sid=%d, aid=%d, direction=0, step=0) error\n",
1154     p_section->sid, p_article_locate->aid);
1155     return -3;
1156     }
1157     else if (ret > 0 && page_id != page_id_cur) // found and page changed
1158     {
1159     ret = query_section_articles(p_section, page_id, p_articles, &article_count, &page_count, &ontop_start_offset);
1160     if (ret < 0)
1161     {
1162     log_error("query_section_articles(sid=%d, page_id=%d) error\n", p_section->sid, page_id);
1163     return -3;
1164     }
1165     }
1166     break;
1167 sysadm 1.63 case SEARCH_USER:
1168     user_list_search();
1169     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1170     {
1171     log_error("section_list_draw_screen() error\n");
1172     return -2;
1173     }
1174     break;
1175 sysadm 1.28 case SHOW_HELP:
1176     // Display help information
1177     display_file(DATA_READ_HELP, 1);
1178     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1179     {
1180     log_error("section_list_draw_screen() error\n");
1181     return -2;
1182     }
1183     break;
1184 sysadm 1.37 case VIEW_EX_DIR:
1185     if (section_list_ex_dir_display(p_section) < 0)
1186     {
1187     log_error("section_list_ex_dir_display(sid=%d) error\n", p_section->sid);
1188     }
1189     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1190     {
1191     log_error("section_list_draw_screen() error\n");
1192     return -2;
1193     }
1194     break;
1195 sysadm 1.48 case SHOW_TOP10:
1196     show_top10_menu(NULL);
1197     if (section_list_draw_screen(sname, stitle, master_list, display_nickname) < 0)
1198     {
1199     log_error("section_list_draw_screen() error\n");
1200     return -2;
1201     }
1202     break;
1203 sysadm 1.1 default:
1204     log_error("Unknown command %d\n", ret);
1205     }
1206     }
1207    
1208     return 0;
1209     }
1210 sysadm 1.37
1211     int section_list_ex_dir_display(SECTION_LIST *p_section)
1212     {
1213     MENU_SET ex_menu_set;
1214     int ch = 0;
1215    
1216     if (p_section == NULL)
1217     {
1218     log_error("NULL pointer error\n");
1219     return -1;
1220     }
1221    
1222 sysadm 1.39 if (p_section->ex_menu_tm == 0) // N/A
1223     {
1224     moveto(2, 1);
1225     clrtoeol();
1226 sysadm 1.40 prints("该版块精华区未开放");
1227 sysadm 1.39 press_any_key();
1228     return 0;
1229     }
1230    
1231 sysadm 1.37 if (get_section_ex_menu_set(p_section, &ex_menu_set) < 0)
1232     {
1233     log_error("get_section_ex_menu_set(sid=%d) error\n", p_section->sid);
1234     return -3;
1235     }
1236     if (get_menu_shm_readonly(&ex_menu_set) < 0)
1237     {
1238 sysadm 1.39 log_error("get_menu_shm_readonly(sid=%d) error\n", p_section->sid);
1239 sysadm 1.37 return -3;
1240     }
1241    
1242     clearscr();
1243 sysadm 1.38 show_bottom("");
1244 sysadm 1.37
1245     if (display_menu(&ex_menu_set) == 0)
1246     {
1247     while (!SYS_server_exit)
1248     {
1249     iflush();
1250     ch = igetch(100);
1251 sysadm 1.54
1252     if (ch != KEY_NULL && ch != KEY_TIMEOUT)
1253     {
1254     BBS_last_access_tm = time(NULL);
1255     }
1256    
1257 sysadm 1.37 switch (ch)
1258     {
1259     case KEY_NULL: // broken pipe
1260 sysadm 1.54 log_error("KEY_NULL\n");
1261 sysadm 1.37 return 0;
1262     case KEY_TIMEOUT:
1263     if (time(NULL) - BBS_last_access_tm >= MAX_DELAY_TIME)
1264     {
1265 sysadm 1.54 log_error("User input timeout\n");
1266 sysadm 1.37 return 0;
1267     }
1268     continue;
1269     case CR:
1270     default:
1271     switch (menu_control(&ex_menu_set, ch))
1272     {
1273     case EXITMENU:
1274     ch = EXITMENU;
1275     break;
1276     case REDRAW:
1277     clearscr();
1278 sysadm 1.38 show_bottom("");
1279 sysadm 1.37 display_menu(&ex_menu_set);
1280     break;
1281     case NOREDRAW:
1282     case UNKNOWN_CMD:
1283     default:
1284     break;
1285     }
1286     }
1287    
1288     if (ch == EXITMENU)
1289     {
1290     break;
1291     }
1292     }
1293     }
1294    
1295     detach_menu_shm(&ex_menu_set);
1296    
1297     return 0;
1298     }
1299 sysadm 1.59
1300     int section_aid_locations_save(int uid)
1301     {
1302     char filename[FILE_PATH_LEN];
1303     FILE *fp;
1304     int i;
1305     int ret = 0;
1306    
1307     snprintf(filename, sizeof(filename), "%s/%d", VAR_SECTION_AID_LOC_DIR, uid);
1308    
1309     if ((fp = fopen(filename, "wb")) == NULL)
1310     {
1311     log_error("fopen(%s, wb) error: %d\n", filename, errno);
1312     return -1;
1313     }
1314    
1315     for (i = 0; i < p_section_list_pool->section_count; i++)
1316     {
1317     if (fwrite(&(p_section_list_pool->sections[i].sid), sizeof(p_section_list_pool->sections[i].sid), 1, fp) != 1)
1318     {
1319     log_error("fwrite(%s, sid) error\n", filename);
1320     ret = -2;
1321     break;
1322     }
1323    
1324     if (fwrite(&(section_aid_locations[i]), sizeof(section_aid_locations[i]), 1, fp) != 1)
1325     {
1326     log_error("fwrite(%s, aid) error\n", filename);
1327     ret = -2;
1328     break;
1329     }
1330     }
1331    
1332     if (fclose(fp) < 0)
1333     {
1334     log_error("fclose(%s) error: %d\n", filename, errno);
1335     ret = -1;
1336     }
1337    
1338     return ret;
1339     }
1340    
1341     int section_aid_locations_load(int uid)
1342     {
1343     char filename[FILE_PATH_LEN];
1344     FILE *fp;
1345     int i;
1346     int32_t sid;
1347     int32_t aid;
1348     SECTION_LIST *p_section;
1349     int ret = 0;
1350    
1351     snprintf(filename, sizeof(filename), "%s/%d", VAR_SECTION_AID_LOC_DIR, uid);
1352    
1353     if ((fp = fopen(filename, "rb")) == NULL)
1354     {
1355     if (errno == ENOENT) // file not exist
1356     {
1357     return 0;
1358     }
1359     log_error("fopen(%s, rb) error: %d\n", filename, errno);
1360     return -1;
1361     }
1362    
1363     while (!feof(fp))
1364     {
1365     if (fread(&sid, sizeof(sid), 1, fp) != 1)
1366     {
1367     if (ferror(fp) == 0)
1368     {
1369     break;
1370     }
1371     log_error("fread(%s, sid) error: %d\n", filename, ferror(fp));
1372     ret = -2;
1373     break;
1374     }
1375    
1376     if (fread(&aid, sizeof(aid), 1, fp) != 1)
1377     {
1378     if (ferror(fp) == 0)
1379     {
1380     break;
1381     }
1382     log_error("fread(%s, aid) error: %d\n", filename, ferror(fp));
1383     ret = -2;
1384     break;
1385     }
1386    
1387     p_section = section_list_find_by_sid(sid);
1388     if (p_section == NULL)
1389     {
1390     continue; // skip section no longer exist
1391     }
1392    
1393     i = get_section_index(p_section);
1394     if (i < 0)
1395     {
1396     log_error("get_section_index(sid=%d) error\n", sid);
1397     ret = -3;
1398     break;
1399     }
1400     section_aid_locations[i] = aid;
1401     }
1402    
1403     if (fclose(fp) < 0)
1404     {
1405     log_error("fclose(%s) error: %d\n", filename, errno);
1406     ret = -1;
1407     }
1408    
1409     return ret;
1410     }

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