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

Annotation of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22 - (hide annotations)
Wed Apr 30 09:18:19 2025 UTC (10 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.21: +7 -2 lines
Content type: text/x-csrc
Add missing header files
Update compile dependency

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

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