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

Annotation of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.23 - (hide annotations)
Fri May 2 03:34:58 2025 UTC (10 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.22: +8 -6 lines
Content type: text/x-csrc
Refine

1 sysadm 1.1 /***************************************************************************
2 sysadm 1.21 menu.c - description
3     -------------------
4     begin : Wed Mar 16 2004
5     copyright : (C) 2005 by Leaflet
6     email : leaflet@leafok.com
7 sysadm 1.1 ***************************************************************************/
8    
9     /***************************************************************************
10     * *
11     * This program is free software; you can redistribute it and/or modify *
12     * it under the terms of the GNU General Public License as published by *
13     * the Free Software Foundation; either version 2 of the License, or *
14     * (at your option) any later version. *
15     * *
16     ***************************************************************************/
17    
18 sysadm 1.3 #include "bbs.h"
19 sysadm 1.17 #include "bbs_cmd.h"
20 sysadm 1.22 #include "user_priv.h"
21     #include "reg_ex.h"
22     #include "bbs_cmd.h"
23 sysadm 1.1 #include "menu.h"
24 sysadm 1.22 #include "log.h"
25 sysadm 1.1 #include "io.h"
26 sysadm 1.22 #include "screen.h"
27 sysadm 1.2 #include "common.h"
28 sysadm 1.22 #include <string.h>
29 sysadm 1.1 #include <stdio.h>
30     #include <ctype.h>
31 sysadm 1.2 #include <regex.h>
32 sysadm 1.6 #include <stdlib.h>
33 sysadm 1.1
34 sysadm 1.2 MENU_SET bbs_menu;
35 sysadm 1.1
36 sysadm 1.21 int load_menu(MENU_SET *p_menu_set, const char *conf_file)
37 sysadm 1.1 {
38 sysadm 1.21 FILE *fin, *fout;
39     int i = 0, j;
40 sysadm 1.23 char buffer[LINE_BUFFER_LEN];
41     char screen_filename[LINE_BUFFER_LEN];
42     char temp[LINE_BUFFER_LEN];
43 sysadm 1.21 regmatch_t pmatch[10];
44    
45     if ((fin = fopen(conf_file, "r")) == NULL)
46     {
47     log_error("Open %s failed", conf_file);
48     return -1;
49     }
50    
51     strcpy(p_menu_set->conf_file, conf_file);
52    
53 sysadm 1.23 while (fgets(buffer, sizeof(buffer), fin))
54 sysadm 1.3 {
55 sysadm 1.21 switch (buffer[0])
56     {
57     case '#':
58     break;
59     case '%':
60     if (ireg("^%S_([A-Za-z0-9_]+)", buffer, 2, pmatch) == 0)
61     {
62     strncpy(temp, buffer + pmatch[1].rm_so,
63     pmatch[1].rm_eo - pmatch[1].rm_so);
64     temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
65     sprintf(screen_filename, "%sMENU_SCR_%s", app_temp_dir, temp);
66    
67     if ((fout = fopen(screen_filename, "w")) == NULL)
68     {
69     log_error("Open %s failed", screen_filename);
70     return -2;
71     }
72    
73 sysadm 1.23 while (fgets(buffer, sizeof(buffer), fin))
74 sysadm 1.21 {
75     if (buffer[0] != '%')
76     fputs(buffer, fout);
77     else
78     break;
79     }
80    
81     fclose(fout);
82     break;
83     }
84    
85     if (ireg("^%menu ([A-Za-z0-9_]+)", buffer, 2, pmatch) == 0)
86     {
87     p_menu_set->p_menu[i] = malloc(sizeof(MENU));
88     p_menu_set->p_menu[i]->title.show = 0;
89     p_menu_set->p_menu[i]->screen.show = 0;
90    
91     strncpy(p_menu_set->p_menu[i]->name,
92     buffer + pmatch[1].rm_so,
93     pmatch[1].rm_eo - pmatch[1].rm_so);
94     p_menu_set->p_menu[i]->name[pmatch[1].rm_eo - pmatch[1].rm_so] =
95     '\0';
96    
97     j = 0;
98    
99 sysadm 1.23 while (fgets(buffer, sizeof(buffer), fin))
100 sysadm 1.21 {
101     if (buffer[0] == '#')
102     {
103     continue;
104     }
105     if (buffer[0] == '%')
106     {
107     p_menu_set->p_menu[i]->item_count = j;
108     p_menu_set->p_menu[i]->item_cur_pos = 0;
109     i++;
110     break;
111     }
112     if (ireg("^!([A-Za-z0-9_.]+)[[:space:]]*([0-9]+),"
113     "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
114     "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\","
115     "[[:space:]]*\"([^\"]+)\"",
116     buffer, 8, pmatch) == 0)
117     {
118     p_menu_set->p_menu[i]->items[j] =
119     malloc(sizeof(MENU_ITEM));
120     p_menu_set->p_menu[i]->items[j]->submenu = 1;
121     strncpy(p_menu_set->p_menu[i]->items[j]->action,
122     buffer + pmatch[1].rm_so,
123     pmatch[1].rm_eo - pmatch[1].rm_so);
124     p_menu_set->p_menu[i]->items[j]->action[pmatch[1].rm_eo -
125     pmatch[1].rm_so] = '\0';
126     strncpy(temp, buffer + pmatch[2].rm_so,
127     pmatch[2].rm_eo - pmatch[2].rm_so);
128     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
129     p_menu_set->p_menu[i]->items[j]->row = atoi(temp);
130     strncpy(temp,
131     buffer + pmatch[3].rm_so,
132     pmatch[3].rm_eo - pmatch[3].rm_so);
133     temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
134     p_menu_set->p_menu[i]->items[j]->col = atoi(temp);
135     strncpy(temp,
136     buffer + pmatch[4].rm_so,
137     pmatch[4].rm_eo - pmatch[4].rm_so);
138     temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
139     p_menu_set->p_menu[i]->items[j]->priv = atoi(temp);
140     strncpy(temp,
141     buffer + pmatch[5].rm_so,
142     pmatch[5].rm_eo - pmatch[5].rm_so);
143     temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
144     p_menu_set->p_menu[i]->items[j]->level = atoi(temp);
145     strncpy(p_menu_set->p_menu[i]->items[j]->name,
146     buffer + pmatch[6].rm_so,
147     pmatch[6].rm_eo - pmatch[6].rm_so);
148     p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
149     pmatch[6].rm_so] =
150     '\0';
151     strncpy(p_menu_set->p_menu[i]->items[j]->text,
152     buffer + pmatch[7].rm_so,
153     pmatch[7].rm_eo - pmatch[7].rm_so);
154     p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
155     pmatch[7].rm_so] =
156     '\0';
157     j++;
158     continue;
159     }
160     if (ireg("^@([A-Za-z0-9_]+)[[:space:]]*([0-9]+),"
161     "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
162     "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\","
163     "[[:space:]]*\"([^\"]+)\"",
164     buffer, 8, pmatch) == 0)
165     {
166     p_menu_set->p_menu[i]->items[j] =
167     malloc(sizeof(MENU_ITEM));
168     p_menu_set->p_menu[i]->items[j]->submenu = 0;
169     strncpy(p_menu_set->p_menu[i]->items[j]->action,
170     buffer + pmatch[1].rm_so,
171     pmatch[1].rm_eo - pmatch[1].rm_so);
172     p_menu_set->p_menu[i]->items[j]->action[pmatch[1].rm_eo -
173     pmatch[1].rm_so] = '\0';
174     strncpy(temp, buffer + pmatch[2].rm_so,
175     pmatch[2].rm_eo - pmatch[2].rm_so);
176     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
177     p_menu_set->p_menu[i]->items[j]->row = atoi(temp);
178     strncpy(temp,
179     buffer + pmatch[3].rm_so,
180     pmatch[3].rm_eo - pmatch[3].rm_so);
181     temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
182     p_menu_set->p_menu[i]->items[j]->col = atoi(temp);
183     strncpy(temp,
184     buffer + pmatch[4].rm_so,
185     pmatch[4].rm_eo - pmatch[4].rm_so);
186     temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
187     p_menu_set->p_menu[i]->items[j]->priv = atoi(temp);
188     strncpy(temp,
189     buffer + pmatch[5].rm_so,
190     pmatch[5].rm_eo - pmatch[5].rm_so);
191     temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
192     p_menu_set->p_menu[i]->items[j]->level = atoi(temp);
193     strncpy(p_menu_set->p_menu[i]->items[j]->name,
194     buffer + pmatch[6].rm_so,
195     pmatch[6].rm_eo - pmatch[6].rm_so);
196     p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
197     pmatch[6].rm_so] =
198     '\0';
199     strncpy(p_menu_set->p_menu[i]->items[j]->text,
200     buffer + pmatch[7].rm_so,
201     pmatch[7].rm_eo - pmatch[7].rm_so);
202     p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
203     pmatch[7].rm_so] =
204     '\0';
205     j++;
206     continue;
207     }
208     if (ireg("^title[[:space:]]*([0-9]+),"
209     "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\"",
210     buffer, 4, pmatch) == 0)
211     {
212     p_menu_set->p_menu[i]->title.show = 1;
213     strncpy(temp,
214     buffer + pmatch[1].rm_so,
215     pmatch[1].rm_eo - pmatch[1].rm_so);
216     temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
217     p_menu_set->p_menu[i]->title.row = atoi(temp);
218     strncpy(temp,
219     buffer + pmatch[2].rm_so,
220     pmatch[2].rm_eo - pmatch[2].rm_so);
221     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
222     p_menu_set->p_menu[i]->title.col = atoi(temp);
223     strncpy(p_menu_set->p_menu[i]->title.text,
224     buffer + pmatch[3].rm_so,
225     pmatch[3].rm_eo - pmatch[3].rm_so);
226     p_menu_set->p_menu[i]->title.text[pmatch[3].rm_eo -
227     pmatch[3].rm_so] =
228     '\0';
229     continue;
230     }
231     if (ireg("^screen[[:space:]]*([0-9]+),"
232     "[[:space:]]*([0-9]+),[[:space:]]*S_([A-Za-z0-9_]+)",
233     buffer, 4, pmatch) == 0)
234     {
235     p_menu_set->p_menu[i]->screen.show = 1;
236     strncpy(temp,
237     buffer + pmatch[1].rm_so,
238     pmatch[1].rm_eo - pmatch[1].rm_so);
239     temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
240     p_menu_set->p_menu[i]->screen.row = atoi(temp);
241     strncpy(temp,
242     buffer + pmatch[2].rm_so,
243     pmatch[2].rm_eo - pmatch[2].rm_so);
244     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
245     p_menu_set->p_menu[i]->screen.col = atoi(temp);
246     strncpy(temp,
247     buffer + pmatch[3].rm_so,
248     pmatch[3].rm_eo - pmatch[3].rm_so);
249     temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
250     sprintf(p_menu_set->p_menu[i]->screen.filename,
251     "%sMENU_SCR_%s", app_temp_dir, temp);
252     continue;
253     }
254     }
255     }
256     break;
257 sysadm 1.10 }
258 sysadm 1.3 }
259 sysadm 1.21 fclose(fin);
260 sysadm 1.3
261 sysadm 1.21 p_menu_set->menu_count = i;
262     p_menu_set->menu_select_depth = 0;
263     p_menu_set->p_menu_select[p_menu_set->menu_select_depth] = (i == 0 ? NULL : p_menu_set->p_menu[0]);
264 sysadm 1.2
265 sysadm 1.21 return 0;
266 sysadm 1.1 }
267    
268 sysadm 1.10 MENU *
269 sysadm 1.21 get_menu(MENU_SET *p_menu_set, const char *menu_name)
270 sysadm 1.3 {
271 sysadm 1.21 int i;
272 sysadm 1.5
273 sysadm 1.21 for (i = 0; i < p_menu_set->menu_count; i++)
274 sysadm 1.10 {
275 sysadm 1.21 if (strcmp(p_menu_set->p_menu[i]->name, menu_name) == 0)
276     {
277     return p_menu_set->p_menu[i];
278     }
279 sysadm 1.10 }
280 sysadm 1.5
281 sysadm 1.21 return NULL;
282 sysadm 1.3 }
283    
284 sysadm 1.22 static void display_menu_cursor(MENU *p_menu, int show)
285 sysadm 1.1 {
286 sysadm 1.21 moveto((p_menu->items[p_menu->item_cur_pos])->r_row,
287     (p_menu->items[p_menu->item_cur_pos])->r_col - 2);
288     prints(show ? ">" : " ");
289     iflush();
290 sysadm 1.1 }
291    
292 sysadm 1.21 int display_menu(MENU *p_menu)
293 sysadm 1.1 {
294 sysadm 1.21 int i, row, col, menu_selectable = 0;
295 sysadm 1.3
296 sysadm 1.21 if (p_menu == NULL)
297     return -1;
298 sysadm 1.5
299 sysadm 1.21 if (p_menu->title.show)
300     show_top(p_menu->title.text);
301 sysadm 1.3
302 sysadm 1.21 if (p_menu->screen.show)
303 sysadm 1.10 {
304 sysadm 1.21 moveto(p_menu->screen.row, p_menu->screen.col);
305     if (display_file(p_menu->screen.filename) != 0)
306     log_error("Display menu screen <%s> failed!\n",
307     p_menu->screen.filename);
308 sysadm 1.10 }
309 sysadm 1.21
310     row = p_menu->items[0]->row;
311     col = p_menu->items[0]->col;
312    
313     for (i = 0; i < p_menu->item_count; i++)
314 sysadm 1.10 {
315 sysadm 1.21 if (checkpriv(&BBS_priv, 0, p_menu->items[i]->priv) == 0 || checklevel(&BBS_priv, p_menu->items[i]->level) == 0)
316     {
317     p_menu->items[i]->display = 0;
318     }
319     else
320     {
321     p_menu->items[i]->display = 1;
322 sysadm 1.10
323 sysadm 1.21 menu_selectable = 1;
324 sysadm 1.3
325 sysadm 1.21 if (p_menu->items[i]->row != 0)
326     row = p_menu->items[i]->row;
327     else
328     row++;
329     p_menu->items[i]->r_row = row;
330     if (p_menu->items[i]->col != 0)
331     col = p_menu->items[i]->col;
332     p_menu->items[i]->r_col = col;
333     moveto(row, col);
334     prints(p_menu->items[i]->text);
335     iflush();
336     }
337 sysadm 1.10 }
338    
339 sysadm 1.21 if (!menu_selectable)
340     return -1;
341 sysadm 1.3
342 sysadm 1.21 display_menu_cursor(p_menu, 1);
343 sysadm 1.1
344 sysadm 1.21 return 0;
345 sysadm 1.1 }
346    
347 sysadm 1.21 int display_current_menu(MENU_SET *p_menu_set)
348 sysadm 1.12 {
349 sysadm 1.21 MENU *p_menu;
350 sysadm 1.12
351 sysadm 1.21 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
352 sysadm 1.12
353 sysadm 1.21 return display_menu(p_menu);
354 sysadm 1.12 }
355    
356 sysadm 1.21 int menu_control(MENU_SET *p_menu_set, int key)
357 sysadm 1.1 {
358 sysadm 1.21 int i;
359     MENU *p_menu;
360 sysadm 1.3
361 sysadm 1.21 if (p_menu_set->menu_count == 0)
362     return 0;
363 sysadm 1.3
364 sysadm 1.21 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
365 sysadm 1.3
366 sysadm 1.21 switch (key)
367 sysadm 1.10 {
368 sysadm 1.21 case CR:
369     case KEY_RIGHT:
370     if (p_menu->items[p_menu->item_cur_pos]->submenu)
371     {
372     if (strcmp(p_menu->items[p_menu->item_cur_pos]->action, "..") == 0)
373     return menu_control(p_menu_set, KEY_LEFT);
374     p_menu_set->menu_select_depth++;
375     p_menu =
376     p_menu_set->p_menu_select[p_menu_set->menu_select_depth] =
377     get_menu(p_menu_set,
378     p_menu->items[p_menu->item_cur_pos]->action);
379     if (display_menu(p_menu) != 0)
380     return menu_control(p_menu_set, KEY_LEFT);
381     break;
382     }
383     else
384     {
385     return (exec_cmd(p_menu->items[p_menu->item_cur_pos]->action,
386     p_menu->items[p_menu->item_cur_pos]->name));
387     }
388     case KEY_LEFT:
389     if (p_menu_set->menu_select_depth > 0)
390     {
391     p_menu_set->menu_select_depth--;
392     if (display_current_menu(p_menu_set) != 0)
393     return menu_control(p_menu_set, KEY_LEFT);
394     break;
395     }
396     else
397     {
398     display_menu_cursor(p_menu, 0);
399     p_menu->item_cur_pos = p_menu->item_count - 1;
400     while (!p_menu->items[p_menu->item_cur_pos]->display || p_menu->items[p_menu->item_cur_pos]->priv != 0 || p_menu->items[p_menu->item_cur_pos]->level != 0)
401     p_menu->item_cur_pos--;
402     display_menu_cursor(p_menu, 1);
403     break;
404     }
405     case KEY_UP:
406     display_menu_cursor(p_menu, 0);
407     do
408     {
409     p_menu->item_cur_pos--;
410     if (p_menu->item_cur_pos < 0)
411     p_menu->item_cur_pos = p_menu->item_count - 1;
412     } while (!p_menu->items[p_menu->item_cur_pos]->display);
413     display_menu_cursor(p_menu, 1);
414     break;
415     case KEY_DOWN:
416     display_menu_cursor(p_menu, 0);
417     do
418     {
419     p_menu->item_cur_pos++;
420     if (p_menu->item_cur_pos >= p_menu->item_count)
421     p_menu->item_cur_pos = 0;
422     } while (!p_menu->items[p_menu->item_cur_pos]->display);
423     display_menu_cursor(p_menu, 1);
424     break;
425     default:
426     for (i = 0; i < p_menu->item_count; i++)
427     {
428     if (key == p_menu->items[i]->name[0] &&
429     p_menu->items[i]->display)
430     {
431     display_menu_cursor(p_menu, 0);
432     p_menu->item_cur_pos = i;
433     display_menu_cursor(p_menu, 1);
434     return 0;
435     }
436     }
437     if (isalpha(key))
438     {
439     for (i = 0; i < p_menu->item_count; i++)
440     {
441     if (toupper(key) == toupper(p_menu->items[i]->name[0]) &&
442     p_menu->items[i]->display)
443     {
444     display_menu_cursor(p_menu, 0);
445     p_menu->item_cur_pos = i;
446     display_menu_cursor(p_menu, 1);
447     return 0;
448     }
449     }
450 sysadm 1.16 }
451 sysadm 1.3 }
452 sysadm 1.1
453 sysadm 1.21 return 0;
454 sysadm 1.1 }
455 sysadm 1.15
456 sysadm 1.21 void unload_menu(MENU_SET *p_menu_set)
457 sysadm 1.15 {
458 sysadm 1.21 MENU *p_menu;
459     MENU_ITEM *p_menuitem;
460     int i, j;
461    
462     for (i = 0; i < p_menu_set->menu_count; i++)
463 sysadm 1.16 {
464 sysadm 1.21 p_menu = p_menu_set->p_menu[i];
465     for (j = 0; j < p_menu->item_count; j++)
466     {
467     free(p_menu->items[j]);
468     }
469     remove(p_menu->screen.filename);
470     free(p_menu);
471 sysadm 1.16 }
472    
473 sysadm 1.21 p_menu_set->menu_count = 0;
474     p_menu_set->menu_select_depth = 0;
475 sysadm 1.15 }
476 sysadm 1.18
477 sysadm 1.21 int reload_menu(MENU_SET *p_menu_set)
478 sysadm 1.18 {
479 sysadm 1.21 int result;
480 sysadm 1.23 char conf_file[FILE_PATH_LEN];
481 sysadm 1.21
482 sysadm 1.23 strncpy(conf_file, p_menu_set->conf_file, sizeof(conf_file));
483 sysadm 1.21 unload_menu(p_menu_set);
484     result = load_menu(p_menu_set, conf_file);
485 sysadm 1.18
486 sysadm 1.21 return result;
487 sysadm 1.18 }

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