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

Contents of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.20 - (show annotations)
Thu Jun 23 16:43:21 2005 UTC (20 years, 8 months ago) by sysadm
Branch: MAIN
CVS Tags: lbbs_1-0-0-0_MIL
Changes since 1.19: +1 -0 lines
Content type: text/x-csrc
*** empty log message ***

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

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