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

Annotation of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.24 - (hide annotations)
Sat May 3 13:41:21 2025 UTC (10 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.23: +1 -0 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 sysadm 1.24 igetch(1); // Cleanup remaining '\n' in the buffer
370 sysadm 1.21 case KEY_RIGHT:
371     if (p_menu->items[p_menu->item_cur_pos]->submenu)
372     {
373     if (strcmp(p_menu->items[p_menu->item_cur_pos]->action, "..") == 0)
374     return menu_control(p_menu_set, KEY_LEFT);
375     p_menu_set->menu_select_depth++;
376     p_menu =
377     p_menu_set->p_menu_select[p_menu_set->menu_select_depth] =
378     get_menu(p_menu_set,
379     p_menu->items[p_menu->item_cur_pos]->action);
380     if (display_menu(p_menu) != 0)
381     return menu_control(p_menu_set, KEY_LEFT);
382     break;
383     }
384     else
385     {
386     return (exec_cmd(p_menu->items[p_menu->item_cur_pos]->action,
387     p_menu->items[p_menu->item_cur_pos]->name));
388     }
389     case KEY_LEFT:
390     if (p_menu_set->menu_select_depth > 0)
391     {
392     p_menu_set->menu_select_depth--;
393     if (display_current_menu(p_menu_set) != 0)
394     return menu_control(p_menu_set, KEY_LEFT);
395     break;
396     }
397     else
398     {
399     display_menu_cursor(p_menu, 0);
400     p_menu->item_cur_pos = p_menu->item_count - 1;
401     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)
402     p_menu->item_cur_pos--;
403     display_menu_cursor(p_menu, 1);
404     break;
405     }
406     case KEY_UP:
407     display_menu_cursor(p_menu, 0);
408     do
409     {
410     p_menu->item_cur_pos--;
411     if (p_menu->item_cur_pos < 0)
412     p_menu->item_cur_pos = p_menu->item_count - 1;
413     } while (!p_menu->items[p_menu->item_cur_pos]->display);
414     display_menu_cursor(p_menu, 1);
415     break;
416     case KEY_DOWN:
417     display_menu_cursor(p_menu, 0);
418     do
419     {
420     p_menu->item_cur_pos++;
421     if (p_menu->item_cur_pos >= p_menu->item_count)
422     p_menu->item_cur_pos = 0;
423     } while (!p_menu->items[p_menu->item_cur_pos]->display);
424     display_menu_cursor(p_menu, 1);
425     break;
426     default:
427     for (i = 0; i < p_menu->item_count; i++)
428     {
429     if (key == p_menu->items[i]->name[0] &&
430     p_menu->items[i]->display)
431     {
432     display_menu_cursor(p_menu, 0);
433     p_menu->item_cur_pos = i;
434     display_menu_cursor(p_menu, 1);
435     return 0;
436     }
437     }
438     if (isalpha(key))
439     {
440     for (i = 0; i < p_menu->item_count; i++)
441     {
442     if (toupper(key) == toupper(p_menu->items[i]->name[0]) &&
443     p_menu->items[i]->display)
444     {
445     display_menu_cursor(p_menu, 0);
446     p_menu->item_cur_pos = i;
447     display_menu_cursor(p_menu, 1);
448     return 0;
449     }
450     }
451 sysadm 1.16 }
452 sysadm 1.3 }
453 sysadm 1.1
454 sysadm 1.21 return 0;
455 sysadm 1.1 }
456 sysadm 1.15
457 sysadm 1.21 void unload_menu(MENU_SET *p_menu_set)
458 sysadm 1.15 {
459 sysadm 1.21 MENU *p_menu;
460     MENU_ITEM *p_menuitem;
461     int i, j;
462    
463     for (i = 0; i < p_menu_set->menu_count; i++)
464 sysadm 1.16 {
465 sysadm 1.21 p_menu = p_menu_set->p_menu[i];
466     for (j = 0; j < p_menu->item_count; j++)
467     {
468     free(p_menu->items[j]);
469     }
470     remove(p_menu->screen.filename);
471     free(p_menu);
472 sysadm 1.16 }
473    
474 sysadm 1.21 p_menu_set->menu_count = 0;
475     p_menu_set->menu_select_depth = 0;
476 sysadm 1.15 }
477 sysadm 1.18
478 sysadm 1.21 int reload_menu(MENU_SET *p_menu_set)
479 sysadm 1.18 {
480 sysadm 1.21 int result;
481 sysadm 1.23 char conf_file[FILE_PATH_LEN];
482 sysadm 1.21
483 sysadm 1.23 strncpy(conf_file, p_menu_set->conf_file, sizeof(conf_file));
484 sysadm 1.21 unload_menu(p_menu_set);
485     result = load_menu(p_menu_set, conf_file);
486 sysadm 1.18
487 sysadm 1.21 return result;
488 sysadm 1.18 }

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