/[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.64 - (hide annotations)
Mon Nov 3 06:43:55 2025 UTC (4 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.63: +111 -0 lines
Content type: text/x-csrc
Add scan_article_in_section_by_uid() and scan_article_in_section_by_username()
Support search prior / next article of the user matching the specific name prefix

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

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