/[LeafOK_CVS]/lbbs/src/menu.c
ViewVC logotype

Annotation of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.39 - (hide annotations)
Wed May 14 04:22:45 2025 UTC (10 months ago) by sysadm
Branch: MAIN
Changes since 1.38: +17 -6 lines
Content type: text/x-csrc
Refine menu with trie_dict

1 sysadm 1.1 /***************************************************************************
2 sysadm 1.21 menu.c - description
3     -------------------
4 sysadm 1.30 Copyright : (C) 2004-2025 by Leaflet
5     Email : leaflet@leafok.com
6 sysadm 1.1 ***************************************************************************/
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 sysadm 1.30 * the Free Software Foundation; either version 3 of the License, or *
13 sysadm 1.1 * (at your option) any later version. *
14     * *
15     ***************************************************************************/
16    
17 sysadm 1.3 #include "bbs.h"
18 sysadm 1.17 #include "bbs_cmd.h"
19 sysadm 1.22 #include "user_priv.h"
20     #include "bbs_cmd.h"
21 sysadm 1.1 #include "menu.h"
22 sysadm 1.22 #include "log.h"
23 sysadm 1.1 #include "io.h"
24 sysadm 1.22 #include "screen.h"
25 sysadm 1.2 #include "common.h"
26 sysadm 1.22 #include <string.h>
27 sysadm 1.1 #include <stdio.h>
28     #include <ctype.h>
29 sysadm 1.6 #include <stdlib.h>
30 sysadm 1.1
31 sysadm 1.31 #define MENU_SCREEN_PATH_PREFIX "var/MENU_SCR_"
32     #define MENU_CONF_DELIM_WITH_SPACE " ,\t\r\n"
33     #define MENU_CONF_DELIM_WITHOUT_SPACE "\r\n"
34 sysadm 1.25
35 sysadm 1.2 MENU_SET bbs_menu;
36 sysadm 1.1
37 sysadm 1.21 int load_menu(MENU_SET *p_menu_set, const char *conf_file)
38 sysadm 1.1 {
39 sysadm 1.21 FILE *fin, *fout;
40 sysadm 1.31 int fin_line = 0;
41     int i = 0;
42     int j = 0;
43 sysadm 1.23 char buffer[LINE_BUFFER_LEN];
44 sysadm 1.33 char temp[LINE_BUFFER_LEN];
45 sysadm 1.25 char screen_filename[FILE_PATH_LEN];
46 sysadm 1.31 char *p = NULL;
47     char *q = NULL;
48     char *saveptr = NULL;
49     MENU *p_menu = NULL;
50     MENU_ITEM *p_item = NULL;
51    
52     p_menu_set->menu_count = 0;
53 sysadm 1.39 p_menu_set->p_menu_name_dict = trie_dict_create();
54 sysadm 1.21
55     if ((fin = fopen(conf_file, "r")) == NULL)
56     {
57     log_error("Open %s failed", conf_file);
58 sysadm 1.31 return -2;
59 sysadm 1.21 }
60    
61 sysadm 1.27 strncpy(p_menu_set->conf_file, conf_file, sizeof(p_menu_set->conf_file) - 1);
62     p_menu_set->conf_file[sizeof(p_menu_set->conf_file) - 1] = '\0';
63 sysadm 1.21
64 sysadm 1.23 while (fgets(buffer, sizeof(buffer), fin))
65 sysadm 1.3 {
66 sysadm 1.31 fin_line++;
67    
68     p = strtok_r(buffer, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
69     if (p == NULL) // Blank line
70 sysadm 1.21 {
71 sysadm 1.31 continue;
72     }
73    
74     if (*p == '#' || *p == '\r' || *p == '\n') // Comment or blank line
75     {
76     continue;
77     }
78    
79     if (*p == '%')
80     {
81     p++;
82    
83     if (strcmp(p, "menu") == 0) // BEGIN of sub-menu
84 sysadm 1.21 {
85 sysadm 1.31 if (p_menu != NULL)
86     {
87 sysadm 1.33 log_error("Incomplete menu definition in menu config line %d\n", fin_line);
88 sysadm 1.31 return -1;
89     }
90     p_menu = (MENU *)malloc(sizeof(MENU));
91     if (p_menu == NULL)
92     {
93     log_error("Unable to allocate memory for menu\n");
94     return -3;
95     }
96     p_menu_set->p_menu[i] = p_menu;
97     i++;
98     p_menu_set->menu_count = i;
99 sysadm 1.21
100 sysadm 1.31 j = 0; // Menu item counter
101     p_menu->item_count = 0;
102     p_menu->item_cur_pos = 0;
103     p_menu->title.show = 0;
104     p_menu->screen.show = 0;
105    
106     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
107     if (q == NULL)
108     {
109     log_error("Error menu name in menu config line %d\n", fin_line);
110     return -1;
111     }
112     p = q;
113     while (isalnum(*q) || *q == '_')
114     {
115     q++;
116     }
117     if (*q != '\0')
118 sysadm 1.21 {
119 sysadm 1.31 log_error("Error menu name in menu config line %d\n", fin_line);
120     return -1;
121 sysadm 1.21 }
122    
123 sysadm 1.31 if (q - p > sizeof(p_menu->name) - 1)
124 sysadm 1.21 {
125 sysadm 1.31 log_error("Too longer menu name in menu config line %d\n", fin_line);
126     return -1;
127 sysadm 1.21 }
128 sysadm 1.31 strncpy(p_menu->name, p, sizeof(p_menu->name) - 1);
129     p_menu->name[sizeof(p_menu->name) - 1] = '\0';
130 sysadm 1.39 if (trie_dict_set(p_menu_set->p_menu_name_dict, p_menu->name, (int64_t)p_menu) != 1)
131     {
132     log_error("Error set menu dict [%s]\n", p_menu->name);
133     }
134 sysadm 1.21
135 sysadm 1.31 // Check syntax
136     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
137     if (q != NULL)
138     {
139     log_error("Unknown extra content in menu config line %d\n", fin_line);
140     return -1;
141     }
142 sysadm 1.21
143 sysadm 1.31 while (fgets(buffer, sizeof(buffer), fin))
144     {
145     fin_line++;
146 sysadm 1.21
147 sysadm 1.31 p = strtok_r(buffer, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
148     if (p == NULL) // Blank line
149     {
150     continue;
151     }
152 sysadm 1.21
153 sysadm 1.31 if (*p == '#' || *p == '\r' || *p == '\n') // Comment or blank line
154 sysadm 1.21 {
155     continue;
156     }
157 sysadm 1.31
158     if (*p == '%') // END of sub-menu
159 sysadm 1.21 {
160 sysadm 1.31 p_menu = NULL;
161 sysadm 1.21 break;
162     }
163 sysadm 1.31 else if (*p == '!' || *p == '@')
164 sysadm 1.21 {
165 sysadm 1.31 // BEGIN of menu item
166     p_item = (MENU_ITEM *)malloc(sizeof(MENU_ITEM));
167     if (p_item == NULL)
168     {
169     log_error("Unable to allocate memory for menu item\n");
170     return -3;
171     }
172     p_menu->items[j] = p_item;
173 sysadm 1.21 j++;
174 sysadm 1.31 p_menu->item_count = j;
175    
176     p_item->submenu = (*p == '!' ? 1 : 0);
177    
178     // Menu item action
179     p++;
180     if (strcmp(p, "..") == 0) // Return to parent menu
181     {
182     q = p + 2; // strlen("..")
183     }
184     else
185     {
186     q = p;
187     while (isalnum(*q) || *q == '_')
188     {
189     q++;
190     }
191     if (*q != '\0')
192     {
193     log_error("Error menu item action in menu config line %d\n", fin_line);
194     return -1;
195     }
196     }
197    
198     if (q - p > sizeof(p_item->action) - 1)
199     {
200     log_error("Too longer menu action in menu config line %d\n", fin_line);
201     return -1;
202     }
203     strncpy(p_item->action, p, sizeof(p_item->action) - 1);
204     p_item->action[sizeof(p_item->action) - 1] = '\0';
205    
206     // Menu item row
207     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
208     if (q == NULL)
209     {
210     log_error("Error menu item row in menu config line %d\n", fin_line);
211     return -1;
212     }
213     p = q;
214     while (isdigit(*q))
215     {
216     q++;
217     }
218     if (*q != '\0')
219     {
220     log_error("Error menu item row in menu config line %d\n", fin_line);
221     return -1;
222     }
223     p_item->row = atoi(p);
224    
225     // Menu item col
226     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
227     if (q == NULL)
228     {
229     log_error("Error menu item col in menu config line %d\n", fin_line);
230     return -1;
231     }
232     p = q;
233     while (isdigit(*q))
234     {
235     q++;
236     }
237     if (*q != '\0')
238     {
239     log_error("Error menu item col in menu config line %d\n", fin_line);
240     return -1;
241     }
242     p_item->col = atoi(p);
243    
244     // Menu item priv
245     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
246     if (q == NULL)
247     {
248     log_error("Error menu item priv in menu config line %d\n", fin_line);
249     return -1;
250     }
251     p = q;
252     while (isdigit(*q))
253     {
254     q++;
255     }
256     if (*q != '\0')
257     {
258     log_error("Error menu item priv in menu config line %d\n", fin_line);
259     return -1;
260     }
261     p_item->priv = atoi(p);
262    
263     // Menu item level
264     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
265     if (q == NULL)
266     {
267     log_error("Error menu item level in menu config line %d\n", fin_line);
268     return -1;
269     }
270     p = q;
271     while (isdigit(*q))
272     {
273     q++;
274     }
275     if (*q != '\0')
276     {
277     log_error("Error menu item level in menu config line %d\n", fin_line);
278     return -1;
279     }
280     p_item->level = atoi(p);
281    
282     // Menu item name
283     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
284     if (q == NULL || *q != '\"')
285     {
286     log_error("Error menu item name in menu config line %d\n", fin_line);
287     return -1;
288     }
289     q++;
290     p = q;
291     while (*q != '\0' && *q != '\"')
292     {
293     q++;
294     }
295     if (*q != '\"' || *(q + 1) != '\0')
296     {
297     log_error("Error menu item name in menu config line %d\n", fin_line);
298     return -1;
299     }
300     *q = '\0';
301    
302     if (q - p > sizeof(p_item->name) - 1)
303     {
304     log_error("Too longer menu name in menu config line %d\n", fin_line);
305     return -1;
306     }
307     strncpy(p_item->name, p, sizeof(p_item->name) - 1);
308     p_item->name[sizeof(p_item->name) - 1] = '\0';
309    
310     // Menu item text
311     q = strtok_r(NULL, MENU_CONF_DELIM_WITHOUT_SPACE, &saveptr);
312     if (q == NULL || (q = strchr(q, '\"')) == NULL)
313     {
314 sysadm 1.32 log_error("Error menu item text in menu config line %d\n", fin_line);
315 sysadm 1.31 return -1;
316     }
317     q++;
318     p = q;
319     while (*q != '\0' && *q != '\"')
320     {
321     q++;
322     }
323     if (*q != '\"')
324     {
325     log_error("Error menu item text in menu config line %d\n", fin_line);
326     return -1;
327     }
328     *q = '\0';
329    
330     if (q - p > sizeof(p_item->text) - 1)
331     {
332     log_error("Too longer menu item text in menu config line %d\n", fin_line);
333     return -1;
334     }
335     strncpy(p_item->text, p, sizeof(p_item->text) - 1);
336     p_item->text[sizeof(p_item->text) - 1] = '\0';
337    
338     // Check syntax
339     q = strtok_r(q + 1, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
340     if (q != NULL)
341     {
342     log_error("Unknown extra content in menu config line %d\n", fin_line);
343     return -1;
344     }
345     }
346     else if (strcmp(p, "title") == 0)
347     {
348     p_menu->title.show = 1;
349    
350     // Menu title row
351     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
352     if (q == NULL)
353     {
354     log_error("Error menu title row in menu config line %d\n", fin_line);
355     return -1;
356     }
357     p = q;
358     while (isdigit(*q))
359     {
360     q++;
361     }
362     if (*q != '\0')
363     {
364     log_error("Error menu title row in menu config line %d\n", fin_line);
365     return -1;
366     }
367     p_menu->title.row = atoi(p);
368    
369     // Menu title col
370     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
371     if (q == NULL)
372     {
373     log_error("Error menu title col in menu config line %d\n", fin_line);
374     return -1;
375     }
376     p = q;
377     while (isdigit(*q))
378     {
379     q++;
380     }
381     if (*q != '\0')
382     {
383     log_error("Error menu title col in menu config line %d\n", fin_line);
384     return -1;
385     }
386     p_menu->title.col = atoi(p);
387    
388     // Menu title text
389     q = strtok_r(NULL, MENU_CONF_DELIM_WITHOUT_SPACE, &saveptr);
390     if (q == NULL || (q = strchr(q, '\"')) == NULL)
391     {
392     log_error("Error menu title text in menu config line %d\n", fin_line);
393     return -1;
394     }
395     q++;
396     p = q;
397     while (*q != '\0' && *q != '\"')
398     {
399     q++;
400     }
401     if (*q != '\"')
402     {
403     log_error("Error menu title text in menu config line %d\n", fin_line);
404     return -1;
405     }
406     *q = '\0';
407    
408     if (q - p > sizeof(p_item->text) - 1)
409     {
410     log_error("Too longer menu title text in menu config line %d\n", fin_line);
411     return -1;
412     }
413     strncpy(p_menu->title.text, p, sizeof(p_menu->title.text) - 1);
414     p_menu->title.text[sizeof(p_menu->title.text) - 1] = '\0';
415    
416     // Check syntax
417     q = strtok_r(q + 1, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
418     if (q != NULL)
419     {
420     log_error("Unknown extra content in menu config line %d\n", fin_line);
421     return -1;
422     }
423 sysadm 1.21 }
424 sysadm 1.31 else if (strcmp(p, "screen") == 0)
425 sysadm 1.21 {
426 sysadm 1.31 p_menu->screen.show = 1;
427    
428     // Menu screen row
429     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
430     if (q == NULL)
431     {
432     log_error("Error menu screen row in menu config line %d\n", fin_line);
433     return -1;
434     }
435     p = q;
436     while (isdigit(*q))
437     {
438     q++;
439     }
440     if (*q != '\0')
441     {
442     log_error("Error menu screen row in menu config line %d\n", fin_line);
443     return -1;
444     }
445     p_menu->screen.row = atoi(p);
446    
447     // Menu screen col
448     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
449     if (q == NULL)
450     {
451     log_error("Error menu screen col in menu config line %d\n", fin_line);
452     return -1;
453     }
454     p = q;
455     while (isdigit(*q))
456     {
457     q++;
458     }
459     if (*q != '\0')
460     {
461     log_error("Error menu screen col in menu config line %d\n", fin_line);
462     return -1;
463     }
464     p_menu->screen.col = atoi(p);
465    
466     // Menu screen name
467     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
468     if (q == NULL)
469     {
470     log_error("Error menu screen name in menu config line %d\n", fin_line);
471     return -1;
472     }
473     p = q;
474     while (isalnum(*q) || *q == '_')
475     {
476     q++;
477     }
478     if (*q != '\0')
479     {
480     log_error("Error menu screen name in menu config line %d\n", fin_line);
481     return -1;
482     }
483    
484     snprintf(p_menu->screen.filename, sizeof(p_menu->screen.filename), "%s%s", MENU_SCREEN_PATH_PREFIX, p);
485    
486     // Check syntax
487     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
488     if (q != NULL)
489     {
490     log_error("Unknown extra content in menu config line %d\n", fin_line);
491     return -1;
492     }
493 sysadm 1.21 }
494 sysadm 1.31 }
495     }
496     else // BEGIN of menu screen
497     {
498     q = p;
499     while (isalnum(*q) || *q == '_')
500     {
501     q++;
502     }
503     if (*q != '\0')
504     {
505     log_error("Error menu screen name in menu config line %d\n", fin_line);
506     return -1;
507     }
508    
509     snprintf(screen_filename, sizeof(screen_filename), "%s%s", MENU_SCREEN_PATH_PREFIX, p);
510    
511     // Check syntax
512     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
513     if (q != NULL)
514     {
515     log_error("Unknown extra content in menu config line %d\n", fin_line);
516     return -1;
517     }
518    
519     if ((fout = fopen(screen_filename, "w")) == NULL)
520     {
521     log_error("Open %s failed", screen_filename);
522     return -2;
523     }
524    
525     while (fgets(buffer, sizeof(buffer), fin))
526     {
527     fin_line++;
528    
529 sysadm 1.34 strncpy(temp, buffer, sizeof(temp)); // Duplicate line for strtok_r
530 sysadm 1.33 p = strtok_r(temp, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
531 sysadm 1.31 if (p != NULL && *p == '%') // END of menu screen
532 sysadm 1.21 {
533 sysadm 1.31 break;
534 sysadm 1.21 }
535 sysadm 1.31
536     if (fputs(buffer, fout) < 0)
537 sysadm 1.21 {
538 sysadm 1.31 log_error("Write %s failed", screen_filename);
539     return -2;
540 sysadm 1.21 }
541     }
542 sysadm 1.31
543     fclose(fout);
544 sysadm 1.21 }
545 sysadm 1.31 }
546     else // Invalid prefix
547     {
548     log_error("Error in menu config line %d\n", fin_line);
549     return -1;
550 sysadm 1.10 }
551 sysadm 1.3 }
552 sysadm 1.21 fclose(fin);
553 sysadm 1.3
554 sysadm 1.21 p_menu_set->menu_count = i;
555     p_menu_set->menu_select_depth = 0;
556     p_menu_set->p_menu_select[p_menu_set->menu_select_depth] = (i == 0 ? NULL : p_menu_set->p_menu[0]);
557 sysadm 1.2
558 sysadm 1.21 return 0;
559 sysadm 1.1 }
560    
561 sysadm 1.31 MENU *get_menu(MENU_SET *p_menu_set, const char *menu_name)
562 sysadm 1.3 {
563 sysadm 1.39 int ret;
564     int64_t value = 0;
565    
566     ret = trie_dict_get(p_menu_set->p_menu_name_dict, menu_name, &value);
567 sysadm 1.5
568 sysadm 1.39 if (ret == 1) // found
569 sysadm 1.10 {
570 sysadm 1.39 return ((MENU *)value);
571 sysadm 1.10 }
572 sysadm 1.5
573 sysadm 1.21 return NULL;
574 sysadm 1.3 }
575    
576 sysadm 1.22 static void display_menu_cursor(MENU *p_menu, int show)
577 sysadm 1.1 {
578 sysadm 1.21 moveto((p_menu->items[p_menu->item_cur_pos])->r_row,
579     (p_menu->items[p_menu->item_cur_pos])->r_col - 2);
580 sysadm 1.26 outc(show ? '>' : ' ');
581 sysadm 1.21 iflush();
582 sysadm 1.1 }
583    
584 sysadm 1.21 int display_menu(MENU *p_menu)
585 sysadm 1.1 {
586 sysadm 1.26 int row = 0;
587     int col = 0;
588     int menu_selectable = 0;
589 sysadm 1.3
590 sysadm 1.21 if (p_menu == NULL)
591 sysadm 1.26 {
592 sysadm 1.21 return -1;
593 sysadm 1.26 }
594 sysadm 1.5
595 sysadm 1.35 if (p_menu->item_cur_pos > 0 &&
596     checkpriv(&BBS_priv, 0, p_menu->items[p_menu->item_cur_pos]->priv) != 0 &&
597     checklevel(&BBS_priv, p_menu->items[p_menu->item_cur_pos]->level) != 0)
598     {
599     menu_selectable = 1;
600     }
601    
602 sysadm 1.21 if (p_menu->title.show)
603 sysadm 1.26 {
604 sysadm 1.21 show_top(p_menu->title.text);
605 sysadm 1.26 }
606 sysadm 1.3
607 sysadm 1.21 if (p_menu->screen.show)
608 sysadm 1.10 {
609 sysadm 1.21 moveto(p_menu->screen.row, p_menu->screen.col);
610     if (display_file(p_menu->screen.filename) != 0)
611 sysadm 1.26 {
612 sysadm 1.21 log_error("Display menu screen <%s> failed!\n",
613     p_menu->screen.filename);
614 sysadm 1.26 }
615 sysadm 1.10 }
616 sysadm 1.21
617 sysadm 1.26 for (int i = 0; i < p_menu->item_count; i++)
618     {
619     if (p_menu->items[i]->row != 0)
620     {
621     row = p_menu->items[i]->row;
622     }
623     if (p_menu->items[i]->col != 0)
624     {
625     col = p_menu->items[i]->col;
626     }
627 sysadm 1.21
628     if (checkpriv(&BBS_priv, 0, p_menu->items[i]->priv) == 0 || checklevel(&BBS_priv, p_menu->items[i]->level) == 0)
629     {
630     p_menu->items[i]->display = 0;
631 sysadm 1.26 p_menu->items[i]->r_row = 0;
632     p_menu->items[i]->r_col = 0;
633 sysadm 1.21 }
634     else
635     {
636     p_menu->items[i]->display = 1;
637 sysadm 1.10
638 sysadm 1.26 if (!menu_selectable)
639     {
640     p_menu->item_cur_pos = i;
641     menu_selectable = 1;
642     }
643 sysadm 1.3
644 sysadm 1.21 p_menu->items[i]->r_row = row;
645     p_menu->items[i]->r_col = col;
646 sysadm 1.26
647 sysadm 1.21 moveto(row, col);
648 sysadm 1.26 prints("%s", p_menu->items[i]->text);
649    
650     row++;
651 sysadm 1.21 }
652 sysadm 1.10 }
653    
654 sysadm 1.21 if (!menu_selectable)
655 sysadm 1.26 {
656 sysadm 1.21 return -1;
657 sysadm 1.26 }
658 sysadm 1.3
659 sysadm 1.21 display_menu_cursor(p_menu, 1);
660 sysadm 1.1
661 sysadm 1.21 return 0;
662 sysadm 1.1 }
663    
664 sysadm 1.21 int display_current_menu(MENU_SET *p_menu_set)
665 sysadm 1.12 {
666 sysadm 1.21 MENU *p_menu;
667 sysadm 1.12
668 sysadm 1.21 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
669 sysadm 1.12
670 sysadm 1.21 return display_menu(p_menu);
671 sysadm 1.12 }
672    
673 sysadm 1.21 int menu_control(MENU_SET *p_menu_set, int key)
674 sysadm 1.1 {
675 sysadm 1.21 int i;
676     MENU *p_menu;
677 sysadm 1.3
678 sysadm 1.21 if (p_menu_set->menu_count == 0)
679 sysadm 1.26 {
680 sysadm 1.21 return 0;
681 sysadm 1.26 }
682 sysadm 1.3
683 sysadm 1.21 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
684 sysadm 1.3
685 sysadm 1.21 switch (key)
686 sysadm 1.10 {
687 sysadm 1.21 case CR:
688     case KEY_RIGHT:
689     if (p_menu->items[p_menu->item_cur_pos]->submenu)
690     {
691     if (strcmp(p_menu->items[p_menu->item_cur_pos]->action, "..") == 0)
692 sysadm 1.26 {
693 sysadm 1.21 return menu_control(p_menu_set, KEY_LEFT);
694 sysadm 1.26 }
695 sysadm 1.21 p_menu_set->menu_select_depth++;
696 sysadm 1.26 p_menu = get_menu(p_menu_set, p_menu->items[p_menu->item_cur_pos]->action);
697     p_menu_set->p_menu_select[p_menu_set->menu_select_depth] = p_menu;
698    
699 sysadm 1.21 if (display_menu(p_menu) != 0)
700 sysadm 1.26 {
701 sysadm 1.21 return menu_control(p_menu_set, KEY_LEFT);
702 sysadm 1.26 }
703 sysadm 1.21 }
704     else
705     {
706     return (exec_cmd(p_menu->items[p_menu->item_cur_pos]->action,
707     p_menu->items[p_menu->item_cur_pos]->name));
708     }
709 sysadm 1.38 break;
710 sysadm 1.21 case KEY_LEFT:
711     if (p_menu_set->menu_select_depth > 0)
712     {
713     p_menu_set->menu_select_depth--;
714     if (display_current_menu(p_menu_set) != 0)
715 sysadm 1.26 {
716 sysadm 1.21 return menu_control(p_menu_set, KEY_LEFT);
717 sysadm 1.26 }
718 sysadm 1.21 }
719     else
720     {
721     display_menu_cursor(p_menu, 0);
722     p_menu->item_cur_pos = p_menu->item_count - 1;
723 sysadm 1.36 while (p_menu->item_cur_pos >= 0 && (!p_menu->items[p_menu->item_cur_pos]->display ||
724     p_menu->items[p_menu->item_cur_pos]->priv != 0 ||
725     p_menu->items[p_menu->item_cur_pos]->level != 0))
726 sysadm 1.26 {
727 sysadm 1.21 p_menu->item_cur_pos--;
728 sysadm 1.26 }
729 sysadm 1.21 display_menu_cursor(p_menu, 1);
730     }
731 sysadm 1.38 break;
732 sysadm 1.21 case KEY_UP:
733     display_menu_cursor(p_menu, 0);
734     do
735     {
736     p_menu->item_cur_pos--;
737     if (p_menu->item_cur_pos < 0)
738 sysadm 1.26 {
739 sysadm 1.21 p_menu->item_cur_pos = p_menu->item_count - 1;
740 sysadm 1.26 }
741 sysadm 1.21 } while (!p_menu->items[p_menu->item_cur_pos]->display);
742     display_menu_cursor(p_menu, 1);
743     break;
744     case KEY_DOWN:
745     display_menu_cursor(p_menu, 0);
746     do
747     {
748     p_menu->item_cur_pos++;
749     if (p_menu->item_cur_pos >= p_menu->item_count)
750 sysadm 1.26 {
751 sysadm 1.21 p_menu->item_cur_pos = 0;
752 sysadm 1.26 }
753 sysadm 1.21 } while (!p_menu->items[p_menu->item_cur_pos]->display);
754     display_menu_cursor(p_menu, 1);
755     break;
756     default:
757 sysadm 1.31 if (isalnum(key))
758 sysadm 1.21 {
759     for (i = 0; i < p_menu->item_count; i++)
760     {
761     if (toupper(key) == toupper(p_menu->items[i]->name[0]) &&
762     p_menu->items[i]->display)
763     {
764     display_menu_cursor(p_menu, 0);
765     p_menu->item_cur_pos = i;
766     display_menu_cursor(p_menu, 1);
767     return 0;
768     }
769     }
770 sysadm 1.16 }
771 sysadm 1.38 break;
772 sysadm 1.3 }
773 sysadm 1.1
774 sysadm 1.21 return 0;
775 sysadm 1.1 }
776 sysadm 1.15
777 sysadm 1.21 void unload_menu(MENU_SET *p_menu_set)
778 sysadm 1.15 {
779 sysadm 1.21 MENU *p_menu;
780     int i, j;
781    
782 sysadm 1.39 if (p_menu_set->p_menu_name_dict != NULL)
783     {
784     trie_dict_destroy(p_menu_set->p_menu_name_dict);
785     p_menu_set->p_menu_name_dict = NULL;
786     }
787    
788 sysadm 1.21 for (i = 0; i < p_menu_set->menu_count; i++)
789 sysadm 1.16 {
790 sysadm 1.21 p_menu = p_menu_set->p_menu[i];
791     for (j = 0; j < p_menu->item_count; j++)
792     {
793     free(p_menu->items[j]);
794     }
795     free(p_menu);
796 sysadm 1.16 }
797    
798 sysadm 1.21 p_menu_set->menu_count = 0;
799     p_menu_set->menu_select_depth = 0;
800 sysadm 1.15 }
801 sysadm 1.18
802 sysadm 1.21 int reload_menu(MENU_SET *p_menu_set)
803 sysadm 1.18 {
804 sysadm 1.21 int result;
805 sysadm 1.23 char conf_file[FILE_PATH_LEN];
806 sysadm 1.21
807 sysadm 1.27 strncpy(conf_file, p_menu_set->conf_file, sizeof(conf_file) - 1);
808     conf_file[sizeof(conf_file) - 1] = '\0';
809    
810 sysadm 1.21 unload_menu(p_menu_set);
811     result = load_menu(p_menu_set, conf_file);
812 sysadm 1.18
813 sysadm 1.21 return result;
814 sysadm 1.18 }

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