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

Annotation of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.48 - (hide annotations)
Mon May 19 01:44:49 2025 UTC (9 months, 4 weeks ago) by sysadm
Branch: MAIN
Changes since 1.47: +52 -11 lines
Content type: text/x-csrc
Refine menu and display

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.40 #include <errno.h>
31     #include <unistd.h>
32     #include <sys/shm.h>
33     #include <sys/ipc.h>
34 sysadm 1.1
35 sysadm 1.31 #define MENU_SCREEN_PATH_PREFIX "var/MENU_SCR_"
36     #define MENU_CONF_DELIM_WITH_SPACE " ,\t\r\n"
37     #define MENU_CONF_DELIM_WITHOUT_SPACE "\r\n"
38 sysadm 1.25
39 sysadm 1.40 #define MENU_SET_RESERVED_LENGTH (sizeof(int16_t) * 4)
40    
41     MENU_SET *p_bbs_menu;
42 sysadm 1.1
43 sysadm 1.21 int load_menu(MENU_SET *p_menu_set, const char *conf_file)
44 sysadm 1.1 {
45 sysadm 1.40 FILE *fin;
46 sysadm 1.31 int fin_line = 0;
47 sysadm 1.23 char buffer[LINE_BUFFER_LEN];
48 sysadm 1.33 char temp[LINE_BUFFER_LEN];
49 sysadm 1.31 char *p = NULL;
50     char *q = NULL;
51 sysadm 1.48 char *r = NULL;
52 sysadm 1.31 char *saveptr = NULL;
53     MENU *p_menu = NULL;
54 sysadm 1.40 MENU_ITEM *p_menu_item = NULL;
55     MENU_SCREEN *p_screen = NULL;
56     MENU_ID menu_id;
57     MENU_ITEM_ID menu_item_id;
58     MENU_SCREEN_ID screen_id;
59     int proj_id;
60     key_t key;
61     size_t size;
62 sysadm 1.31
63 sysadm 1.40 // Use trie_dict to search menu_id by menu name
64 sysadm 1.39 p_menu_set->p_menu_name_dict = trie_dict_create();
65 sysadm 1.40 if (p_menu_set->p_menu_name_dict == NULL)
66     {
67     log_error("trie_dict_create() error\n");
68     return -3;
69     }
70    
71     // Use trie_dict to search screen_id by menu screen name
72     p_menu_set->p_menu_screen_dict = trie_dict_create();
73     if (p_menu_set->p_menu_screen_dict == NULL)
74     {
75     log_error("trie_dict_create() error\n");
76     return -3;
77     }
78 sysadm 1.21
79     if ((fin = fopen(conf_file, "r")) == NULL)
80     {
81     log_error("Open %s failed", conf_file);
82 sysadm 1.31 return -2;
83 sysadm 1.21 }
84    
85 sysadm 1.40 // Allocate shared memory
86     proj_id = (int)(time(NULL) % getpid());
87     key = ftok(conf_file, proj_id);
88     if (key == -1)
89     {
90     log_error("ftok(%s %d) error (%d)\n", conf_file, proj_id, errno);
91     return -2;
92     }
93    
94     size = MENU_SET_RESERVED_LENGTH +
95     sizeof(MENU) * MAX_MENUS +
96     sizeof(MENU_ITEM) * MAX_MENUITEMS +
97     sizeof(MENU_SCREEN) * MAX_MENUS +
98     MAX_MENU_SCR_BUF_LENGTH * MAX_MENUS;
99     p_menu_set->shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0600);
100     if (p_menu_set->shmid == -1)
101     {
102     log_error("shmget(size = %d) error (%d)\n", size, errno);
103     return -3;
104     }
105     p_menu_set->p_reserved = shmat(p_menu_set->shmid, NULL, 0);
106     if (p_menu_set->p_reserved == (void *)-1)
107     {
108     log_error("shmat() error (%d)\n", errno);
109     return -3;
110     }
111     p_menu_set->p_menu_pool = p_menu_set->p_reserved + MENU_SET_RESERVED_LENGTH;
112     p_menu_set->p_menu_item_pool = p_menu_set->p_menu_pool + sizeof(MENU) * MAX_MENUS;
113     p_menu_set->p_menu_screen_pool = p_menu_set->p_menu_item_pool + sizeof(MENU_ITEM) * MAX_MENUITEMS;
114     p_menu_set->p_menu_screen_buf = p_menu_set->p_menu_screen_pool + sizeof(MENU_SCREEN) * MAX_MENUS;
115     p_menu_set->p_menu_screen_buf_free = p_menu_set->p_menu_screen_buf;
116    
117     p_menu_set->menu_count = 0;
118     p_menu_set->menu_item_count = 0;
119     p_menu_set->menu_screen_count = 0;
120     p_menu_set->choose_step = 0;
121     p_menu_set->menu_id_path[0] = 0;
122 sysadm 1.21
123 sysadm 1.23 while (fgets(buffer, sizeof(buffer), fin))
124 sysadm 1.3 {
125 sysadm 1.31 fin_line++;
126    
127     p = strtok_r(buffer, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
128     if (p == NULL) // Blank line
129 sysadm 1.21 {
130 sysadm 1.31 continue;
131     }
132    
133     if (*p == '#' || *p == '\r' || *p == '\n') // Comment or blank line
134     {
135     continue;
136     }
137    
138     if (*p == '%')
139     {
140     p++;
141    
142     if (strcmp(p, "menu") == 0) // BEGIN of sub-menu
143 sysadm 1.21 {
144 sysadm 1.31 if (p_menu != NULL)
145     {
146 sysadm 1.33 log_error("Incomplete menu definition in menu config line %d\n", fin_line);
147 sysadm 1.31 return -1;
148     }
149 sysadm 1.40
150     if (p_menu_set->menu_count >= MAX_MENUS)
151 sysadm 1.31 {
152 sysadm 1.40 log_error("Menu count (%d) exceed limit (%d)\n", p_menu_set->menu_count, MAX_MENUS);
153 sysadm 1.31 return -3;
154     }
155 sysadm 1.40 menu_id = (MENU_ID)p_menu_set->menu_count;
156     p_menu_set->menu_count++;
157    
158     p_menu = get_menu_by_id(p_menu_set, menu_id);
159 sysadm 1.21
160 sysadm 1.31 p_menu->item_count = 0;
161     p_menu->title.show = 0;
162 sysadm 1.40 p_menu->screen_show = 0;
163 sysadm 1.31
164     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
165     if (q == NULL)
166     {
167     log_error("Error menu name in menu config line %d\n", fin_line);
168     return -1;
169     }
170     p = q;
171 sysadm 1.48 while (isalnum(*q) || *q == '_' || *q == '-')
172 sysadm 1.31 {
173     q++;
174     }
175     if (*q != '\0')
176 sysadm 1.21 {
177 sysadm 1.31 log_error("Error menu name in menu config line %d\n", fin_line);
178     return -1;
179 sysadm 1.21 }
180    
181 sysadm 1.31 if (q - p > sizeof(p_menu->name) - 1)
182 sysadm 1.21 {
183 sysadm 1.31 log_error("Too longer menu name in menu config line %d\n", fin_line);
184     return -1;
185 sysadm 1.21 }
186 sysadm 1.31 strncpy(p_menu->name, p, sizeof(p_menu->name) - 1);
187     p_menu->name[sizeof(p_menu->name) - 1] = '\0';
188 sysadm 1.40
189     if (trie_dict_set(p_menu_set->p_menu_name_dict, p_menu->name, (int64_t)menu_id) != 1)
190 sysadm 1.39 {
191     log_error("Error set menu dict [%s]\n", p_menu->name);
192     }
193 sysadm 1.21
194 sysadm 1.31 // Check syntax
195     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
196     if (q != NULL)
197     {
198     log_error("Unknown extra content in menu config line %d\n", fin_line);
199     return -1;
200     }
201 sysadm 1.21
202 sysadm 1.31 while (fgets(buffer, sizeof(buffer), fin))
203     {
204     fin_line++;
205 sysadm 1.21
206 sysadm 1.31 p = strtok_r(buffer, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
207     if (p == NULL) // Blank line
208     {
209     continue;
210     }
211 sysadm 1.21
212 sysadm 1.31 if (*p == '#' || *p == '\r' || *p == '\n') // Comment or blank line
213 sysadm 1.21 {
214     continue;
215     }
216 sysadm 1.31
217     if (*p == '%') // END of sub-menu
218 sysadm 1.21 {
219 sysadm 1.31 p_menu = NULL;
220 sysadm 1.21 break;
221     }
222 sysadm 1.31 else if (*p == '!' || *p == '@')
223 sysadm 1.21 {
224 sysadm 1.31 // BEGIN of menu item
225 sysadm 1.40 if (p_menu->item_count >= MAX_ITEMS_PER_MENU)
226     {
227     log_error("Menuitem count per menu (%d) exceed limit (%d)\n", p_menu->item_count, MAX_ITEMS_PER_MENU);
228     return -1;
229     }
230     if (p_menu_set->menu_item_count >= MAX_MENUITEMS)
231 sysadm 1.31 {
232 sysadm 1.40 log_error("Menuitem count (%d) exceed limit (%d)\n", p_menu_set->menu_item_count, MAX_MENUITEMS);
233 sysadm 1.31 return -3;
234     }
235 sysadm 1.40 menu_item_id = (MENU_ITEM_ID)p_menu_set->menu_item_count;
236     p_menu_set->menu_item_count++;
237 sysadm 1.31
238 sysadm 1.40 p_menu->items[p_menu->item_count] = menu_item_id;
239     p_menu->item_count++;
240    
241     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
242    
243     p_menu_item->submenu = (*p == '!' ? 1 : 0);
244 sysadm 1.31
245     // Menu item action
246     p++;
247     if (strcmp(p, "..") == 0) // Return to parent menu
248     {
249     q = p + 2; // strlen("..")
250     }
251     else
252     {
253     q = p;
254 sysadm 1.48 while (isalnum(*q) || *q == '_' || *q == '-')
255 sysadm 1.31 {
256     q++;
257     }
258     if (*q != '\0')
259     {
260     log_error("Error menu item action in menu config line %d\n", fin_line);
261     return -1;
262     }
263     }
264    
265 sysadm 1.40 if (q - p > sizeof(p_menu_item->action) - 1)
266 sysadm 1.31 {
267     log_error("Too longer menu action in menu config line %d\n", fin_line);
268     return -1;
269     }
270 sysadm 1.40 strncpy(p_menu_item->action, p, sizeof(p_menu_item->action) - 1);
271     p_menu_item->action[sizeof(p_menu_item->action) - 1] = '\0';
272 sysadm 1.31
273     // Menu item row
274     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
275     if (q == NULL)
276     {
277     log_error("Error menu item row in menu config line %d\n", fin_line);
278     return -1;
279     }
280     p = q;
281     while (isdigit(*q))
282     {
283     q++;
284     }
285     if (*q != '\0')
286     {
287     log_error("Error menu item row in menu config line %d\n", fin_line);
288     return -1;
289     }
290 sysadm 1.40 p_menu_item->row = (int16_t)atoi(p);
291 sysadm 1.31
292     // Menu item col
293     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
294     if (q == NULL)
295     {
296     log_error("Error menu item col in menu config line %d\n", fin_line);
297     return -1;
298     }
299     p = q;
300     while (isdigit(*q))
301     {
302     q++;
303     }
304     if (*q != '\0')
305     {
306     log_error("Error menu item col in menu config line %d\n", fin_line);
307     return -1;
308     }
309 sysadm 1.40 p_menu_item->col = (int16_t)atoi(p);
310 sysadm 1.31
311     // Menu item priv
312     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
313     if (q == NULL)
314     {
315     log_error("Error menu item priv in menu config line %d\n", fin_line);
316     return -1;
317     }
318     p = q;
319     while (isdigit(*q))
320     {
321     q++;
322     }
323     if (*q != '\0')
324     {
325     log_error("Error menu item priv in menu config line %d\n", fin_line);
326     return -1;
327     }
328 sysadm 1.40 p_menu_item->priv = atoi(p);
329 sysadm 1.31
330     // Menu item level
331     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
332     if (q == NULL)
333     {
334     log_error("Error menu item level in menu config line %d\n", fin_line);
335     return -1;
336     }
337     p = q;
338     while (isdigit(*q))
339     {
340     q++;
341     }
342     if (*q != '\0')
343     {
344     log_error("Error menu item level in menu config line %d\n", fin_line);
345     return -1;
346     }
347 sysadm 1.40 p_menu_item->level = atoi(p);
348 sysadm 1.31
349     // Menu item name
350     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
351     if (q == NULL || *q != '\"')
352     {
353     log_error("Error menu item name in menu config line %d\n", fin_line);
354     return -1;
355     }
356     q++;
357     p = q;
358     while (*q != '\0' && *q != '\"')
359     {
360 sysadm 1.48 if (*q == '\\')
361     {
362     r = q;
363     while (*r != '\0')
364     {
365     *r = *(r + 1);
366     r++;
367     }
368     }
369 sysadm 1.31 q++;
370     }
371     if (*q != '\"' || *(q + 1) != '\0')
372     {
373     log_error("Error menu item name in menu config line %d\n", fin_line);
374     return -1;
375     }
376     *q = '\0';
377    
378 sysadm 1.40 if (q - p > sizeof(p_menu_item->name) - 1)
379 sysadm 1.31 {
380     log_error("Too longer menu name in menu config line %d\n", fin_line);
381     return -1;
382     }
383 sysadm 1.40 strncpy(p_menu_item->name, p, sizeof(p_menu_item->name) - 1);
384     p_menu_item->name[sizeof(p_menu_item->name) - 1] = '\0';
385 sysadm 1.31
386     // Menu item text
387     q = strtok_r(NULL, MENU_CONF_DELIM_WITHOUT_SPACE, &saveptr);
388     if (q == NULL || (q = strchr(q, '\"')) == NULL)
389     {
390 sysadm 1.32 log_error("Error menu item text in menu config line %d\n", fin_line);
391 sysadm 1.31 return -1;
392     }
393     q++;
394     p = q;
395     while (*q != '\0' && *q != '\"')
396     {
397 sysadm 1.48 if (*q == '\\')
398     {
399     r = q;
400     while (*r != '\0')
401     {
402     *r = *(r + 1);
403     r++;
404     }
405     }
406 sysadm 1.31 q++;
407     }
408     if (*q != '\"')
409     {
410     log_error("Error menu item text in menu config line %d\n", fin_line);
411     return -1;
412     }
413     *q = '\0';
414    
415 sysadm 1.40 if (q - p > sizeof(p_menu_item->text) - 1)
416 sysadm 1.31 {
417     log_error("Too longer menu item text in menu config line %d\n", fin_line);
418     return -1;
419     }
420 sysadm 1.40 strncpy(p_menu_item->text, p, sizeof(p_menu_item->text) - 1);
421     p_menu_item->text[sizeof(p_menu_item->text) - 1] = '\0';
422 sysadm 1.31
423     // Check syntax
424     q = strtok_r(q + 1, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
425     if (q != NULL)
426     {
427     log_error("Unknown extra content in menu config line %d\n", fin_line);
428     return -1;
429     }
430     }
431     else if (strcmp(p, "title") == 0)
432     {
433     p_menu->title.show = 1;
434    
435     // Menu title row
436     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
437     if (q == NULL)
438     {
439     log_error("Error menu title row in menu config line %d\n", fin_line);
440     return -1;
441     }
442     p = q;
443     while (isdigit(*q))
444     {
445     q++;
446     }
447     if (*q != '\0')
448     {
449     log_error("Error menu title row in menu config line %d\n", fin_line);
450     return -1;
451     }
452 sysadm 1.40 p_menu->title.row = (int16_t)atoi(p);
453 sysadm 1.31
454     // Menu title col
455     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
456     if (q == NULL)
457     {
458     log_error("Error menu title col in menu config line %d\n", fin_line);
459     return -1;
460     }
461     p = q;
462     while (isdigit(*q))
463     {
464     q++;
465     }
466     if (*q != '\0')
467     {
468     log_error("Error menu title col in menu config line %d\n", fin_line);
469     return -1;
470     }
471 sysadm 1.40 p_menu->title.col = (int16_t)atoi(p);
472 sysadm 1.31
473     // Menu title text
474     q = strtok_r(NULL, MENU_CONF_DELIM_WITHOUT_SPACE, &saveptr);
475     if (q == NULL || (q = strchr(q, '\"')) == NULL)
476     {
477     log_error("Error menu title text in menu config line %d\n", fin_line);
478     return -1;
479     }
480     q++;
481     p = q;
482     while (*q != '\0' && *q != '\"')
483     {
484 sysadm 1.48 if (*q == '\\')
485     {
486     r = q;
487     while (*r != '\0')
488     {
489     *r = *(r + 1);
490     r++;
491     }
492     }
493 sysadm 1.31 q++;
494     }
495     if (*q != '\"')
496     {
497     log_error("Error menu title text in menu config line %d\n", fin_line);
498     return -1;
499     }
500     *q = '\0';
501    
502 sysadm 1.48 if (q - p > sizeof(p_menu->title.text) - 1)
503 sysadm 1.31 {
504     log_error("Too longer menu title text in menu config line %d\n", fin_line);
505     return -1;
506     }
507     strncpy(p_menu->title.text, p, sizeof(p_menu->title.text) - 1);
508     p_menu->title.text[sizeof(p_menu->title.text) - 1] = '\0';
509    
510     // Check syntax
511     q = strtok_r(q + 1, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
512     if (q != NULL)
513     {
514     log_error("Unknown extra content in menu config line %d\n", fin_line);
515     return -1;
516     }
517 sysadm 1.21 }
518 sysadm 1.31 else if (strcmp(p, "screen") == 0)
519 sysadm 1.21 {
520 sysadm 1.40 p_menu->screen_show = 1;
521 sysadm 1.31
522     // Menu screen row
523     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
524     if (q == NULL)
525     {
526     log_error("Error menu screen row in menu config line %d\n", fin_line);
527     return -1;
528     }
529     p = q;
530     while (isdigit(*q))
531     {
532     q++;
533     }
534     if (*q != '\0')
535     {
536     log_error("Error menu screen row in menu config line %d\n", fin_line);
537     return -1;
538     }
539 sysadm 1.40 p_menu->screen_row = (int16_t)atoi(p);
540 sysadm 1.31
541     // Menu screen col
542     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
543     if (q == NULL)
544     {
545     log_error("Error menu screen col in menu config line %d\n", fin_line);
546     return -1;
547     }
548     p = q;
549     while (isdigit(*q))
550     {
551     q++;
552     }
553     if (*q != '\0')
554     {
555     log_error("Error menu screen col in menu config line %d\n", fin_line);
556     return -1;
557     }
558 sysadm 1.40 p_menu->screen_col = (int16_t)atoi(p);
559 sysadm 1.31
560     // Menu screen name
561     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
562     if (q == NULL)
563     {
564     log_error("Error menu screen name in menu config line %d\n", fin_line);
565     return -1;
566     }
567     p = q;
568 sysadm 1.48 while (isalnum(*q) || *q == '_' || *q == '-')
569 sysadm 1.31 {
570     q++;
571     }
572     if (*q != '\0')
573     {
574     log_error("Error menu screen name in menu config line %d\n", fin_line);
575     return -1;
576     }
577 sysadm 1.47 strncpy(p_menu->screen_name, p, sizeof(p_menu->screen_name) - 1);
578     p_menu->screen_name[sizeof(p_menu->screen_name) - 1] = '\0';
579 sysadm 1.31
580     // Check syntax
581     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
582     if (q != NULL)
583     {
584     log_error("Unknown extra content in menu config line %d\n", fin_line);
585     return -1;
586     }
587 sysadm 1.21 }
588 sysadm 1.31 }
589     }
590     else // BEGIN of menu screen
591     {
592 sysadm 1.40 if (p_menu_set->menu_item_count >= MAX_MENUS)
593     {
594     log_error("Menu screen count (%d) exceed limit (%d)\n", p_menu_set->menu_screen_count, MAX_MENUS);
595     return -3;
596     }
597     screen_id = (MENU_SCREEN_ID)p_menu_set->menu_screen_count;
598     p_menu_set->menu_screen_count++;
599    
600     p_screen = get_menu_screen_by_id(p_menu_set, screen_id);
601    
602 sysadm 1.31 q = p;
603 sysadm 1.48 while (isalnum(*q) || *q == '_' || *q == '-')
604 sysadm 1.31 {
605     q++;
606     }
607     if (*q != '\0')
608     {
609     log_error("Error menu screen name in menu config line %d\n", fin_line);
610     return -1;
611     }
612 sysadm 1.40 strncpy(p_screen->name, p, sizeof(p_screen->name) - 1);
613     p_screen->name[sizeof(p_screen->name) - 1] = '\0';
614 sysadm 1.31
615 sysadm 1.40 if (trie_dict_set(p_menu_set->p_menu_screen_dict, p_screen->name, (int64_t)screen_id) != 1)
616     {
617     log_error("Error set menu screen dict [%s]\n", p_screen->name);
618     }
619 sysadm 1.31
620     // Check syntax
621     q = strtok_r(NULL, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
622     if (q != NULL)
623     {
624     log_error("Unknown extra content in menu config line %d\n", fin_line);
625     return -1;
626     }
627    
628 sysadm 1.40 p_screen->buf_offset = p_menu_set->p_menu_screen_buf_free - p_menu_set->p_menu_screen_buf;
629     p_screen->buf_length = -1;
630    
631     // safety appending boundary
632     q = p_menu_set->p_menu_screen_buf + MAX_MENU_SCR_BUF_LENGTH * MAX_MENUS - 1;
633 sysadm 1.31
634     while (fgets(buffer, sizeof(buffer), fin))
635     {
636     fin_line++;
637    
638 sysadm 1.40 strncpy(temp, buffer, sizeof(temp) - 1); // Duplicate line for strtok_r
639     temp[sizeof(temp) - 1] = '\0';
640 sysadm 1.33 p = strtok_r(temp, MENU_CONF_DELIM_WITH_SPACE, &saveptr);
641 sysadm 1.31 if (p != NULL && *p == '%') // END of menu screen
642 sysadm 1.21 {
643 sysadm 1.40 if (p_menu_set->p_menu_screen_buf_free + 1 > q)
644     {
645     log_error("Menu screen buffer depleted (%p + 1 > %p)\n", p_menu_set->p_menu_screen_buf_free, q);
646     return -3;
647     }
648    
649     *(p_menu_set->p_menu_screen_buf_free) = '\0';
650     p_menu_set->p_menu_screen_buf_free++;
651     p_screen->buf_length = p_menu_set->p_menu_screen_buf_free - p_menu_set->p_menu_screen_buf - p_screen->buf_offset;
652 sysadm 1.31 break;
653 sysadm 1.21 }
654 sysadm 1.31
655 sysadm 1.47 // Clear line
656     if (p_menu_set->p_menu_screen_buf_free + strlen(CTRL_SEQ_CLR_LINE) > q)
657     {
658     log_error("Menu screen buffer depleted (%p + %d > %p)\n", p_menu_set->p_menu_screen_buf_free, q, strlen(CTRL_SEQ_CLR_LINE));
659     return -3;
660     }
661     p_menu_set->p_menu_screen_buf_free = stpcpy(p_menu_set->p_menu_screen_buf_free, CTRL_SEQ_CLR_LINE);
662    
663 sysadm 1.40 p = buffer;
664     while (*p != '\0')
665 sysadm 1.21 {
666 sysadm 1.40 if (p_menu_set->p_menu_screen_buf_free + 2 > q)
667     {
668     log_error("Menu screen buffer depleted (%p + 2 > %p)\n", p_menu_set->p_menu_screen_buf_free, q);
669     return -3;
670     }
671    
672     if (*p == '\n' && p > buffer && *(p - 1) != '\r')
673     {
674     *(p_menu_set->p_menu_screen_buf_free) = '\r';
675     p_menu_set->p_menu_screen_buf_free++;
676     }
677    
678     *(p_menu_set->p_menu_screen_buf_free) = *p;
679     p++;
680     p_menu_set->p_menu_screen_buf_free++;
681 sysadm 1.21 }
682     }
683 sysadm 1.31
684 sysadm 1.40 if (p_screen->buf_length == -1)
685     {
686     log_error("End of menu screen [%s] not found\n", p_screen->name);
687     }
688 sysadm 1.21 }
689 sysadm 1.31 }
690     else // Invalid prefix
691     {
692     log_error("Error in menu config line %d\n", fin_line);
693     return -1;
694 sysadm 1.10 }
695 sysadm 1.3 }
696 sysadm 1.21 fclose(fin);
697 sysadm 1.3
698 sysadm 1.47 for (menu_id = 0; menu_id < p_menu_set->menu_count; menu_id++)
699     {
700     p_menu = get_menu_by_id(p_menu_set, menu_id);
701    
702     if (trie_dict_get(p_menu_set->p_menu_screen_dict, p_menu->screen_name, (int64_t *)(&(p_menu->screen_id))) != 1)
703     {
704     log_error("Undefined menu screen [%s]\n", p);
705     return -1;
706     }
707     }
708    
709 sysadm 1.40 for (menu_item_id = 0; menu_item_id < p_menu_set->menu_item_count; menu_item_id++)
710     {
711     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
712 sysadm 1.44
713     // Set menu_item->action_cmd_handler of each menu item pointing to bbs_cmd
714     if (p_menu_item->submenu == 0)
715     {
716     if ((p_menu_item->action_cmd_handler = get_cmd_handler(p_menu_item->action)) == NULL)
717     {
718     log_error("Undefined menu action cmd handler [%s]\n", p_menu_item->action);
719     return -1;
720     }
721     }
722     // Set menu_item->action_menu_id of each menu item pointing to a submenu to the menu_id of the corresponding submenu
723     else if (strcmp(p_menu_item->action, "..") != 0)
724 sysadm 1.40 {
725     if (trie_dict_get(p_menu_set->p_menu_name_dict, p_menu_item->action, (int64_t *)&menu_id) != 1)
726     {
727 sysadm 1.48 log_error("Undefined sub menu id [%s]\n", p_menu_item->action);
728 sysadm 1.40 return -1;
729     }
730     p_menu_item->action_menu_id = menu_id;
731     }
732     }
733    
734     // Save status varaibles into reserved memory area
735     *((int16_t *)p_menu_set->p_reserved) = p_menu_set->menu_count;
736     *(((int16_t *)p_menu_set->p_reserved) + 1) = p_menu_set->menu_item_count;
737     *(((int16_t *)p_menu_set->p_reserved) + 2) = p_menu_set->menu_screen_count;
738 sysadm 1.2
739 sysadm 1.21 return 0;
740 sysadm 1.1 }
741    
742 sysadm 1.40 static int display_menu_cursor(MENU_SET *p_menu_set, int show)
743 sysadm 1.3 {
744 sysadm 1.40 MENU_ID menu_id;
745     MENU_ITEM_ID menu_item_id;
746     MENU *p_menu;
747     MENU_ITEM *p_menu_item;
748     int16_t menu_item_pos;
749 sysadm 1.39
750 sysadm 1.40 menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];
751     p_menu = get_menu_by_id(p_menu_set, menu_id);
752     if (p_menu == NULL)
753     {
754     log_error("get_menu_by_id(%d) return NULL pointer\n", menu_id);
755     return -1;
756     }
757 sysadm 1.5
758 sysadm 1.40 menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];
759     menu_item_id = p_menu->items[menu_item_pos];
760     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
761     if (p_menu_item == NULL)
762 sysadm 1.10 {
763 sysadm 1.40 log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
764     return -1;
765 sysadm 1.10 }
766 sysadm 1.5
767 sysadm 1.41 moveto(p_menu_set->menu_item_r_row[menu_item_pos], p_menu_set->menu_item_r_col[menu_item_pos] - 2);
768 sysadm 1.26 outc(show ? '>' : ' ');
769 sysadm 1.40
770     return 0;
771 sysadm 1.1 }
772    
773 sysadm 1.40 int display_menu(MENU_SET *p_menu_set)
774 sysadm 1.1 {
775 sysadm 1.40 int16_t row = 0;
776     int16_t col = 0;
777 sysadm 1.26 int menu_selectable = 0;
778 sysadm 1.40 MENU_ID menu_id;
779     MENU_ITEM_ID menu_item_id;
780     MENU *p_menu;
781     MENU_ITEM *p_menu_item;
782     MENU_SCREEN *p_menu_screen;
783     int16_t menu_item_pos;
784 sysadm 1.3
785 sysadm 1.40 menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];
786     p_menu = get_menu_by_id(p_menu_set, menu_id);
787 sysadm 1.21 if (p_menu == NULL)
788 sysadm 1.26 {
789 sysadm 1.40 log_error("get_menu_by_id(%d) return NULL pointer\n", menu_id);
790 sysadm 1.21 return -1;
791 sysadm 1.26 }
792 sysadm 1.5
793 sysadm 1.40 menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];
794     menu_item_id = p_menu->items[menu_item_pos];
795     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
796     if (p_menu_item == NULL)
797     {
798     log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
799     return -1;
800     }
801    
802     if (menu_item_pos > 0 &&
803     checkpriv(&BBS_priv, 0, p_menu_item->priv) != 0 &&
804     checklevel(&BBS_priv, p_menu_item->level) != 0)
805 sysadm 1.35 {
806     menu_selectable = 1;
807     }
808    
809 sysadm 1.21 if (p_menu->title.show)
810 sysadm 1.26 {
811 sysadm 1.48 if (p_menu->title.row == 0 && p_menu->title.col == 0)
812     {
813     show_top(p_menu->title.text);
814     }
815     else
816     {
817     moveto(p_menu->title.row, p_menu->title.col);
818     prints("%s", p_menu->title.text);
819     }
820 sysadm 1.26 }
821 sysadm 1.3
822 sysadm 1.40 if (p_menu->screen_show)
823 sysadm 1.10 {
824 sysadm 1.40 p_menu_screen = get_menu_screen_by_id(p_menu_set, p_menu->screen_id);
825     if (p_menu_screen == NULL)
826 sysadm 1.26 {
827 sysadm 1.40 log_error("get_menu_screen_by_id(%d) return NULL pointer\n", p_menu->screen_id);
828     return -1;
829 sysadm 1.26 }
830 sysadm 1.40
831 sysadm 1.48 row = p_menu->screen_row;
832     col = p_menu->screen_col;
833    
834     moveto(row, col);
835 sysadm 1.40 prints("%s", p_menu_set->p_menu_screen_buf + p_menu_screen->buf_offset);
836 sysadm 1.10 }
837 sysadm 1.21
838 sysadm 1.41 for (menu_item_pos = 0; menu_item_pos < p_menu->item_count; menu_item_pos++)
839 sysadm 1.26 {
840 sysadm 1.41 menu_item_id = p_menu->items[menu_item_pos];
841 sysadm 1.40 p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
842    
843     if (p_menu_item->row != 0)
844 sysadm 1.26 {
845 sysadm 1.40 row = p_menu_item->row;
846 sysadm 1.26 }
847 sysadm 1.40 if (p_menu_item->col != 0)
848 sysadm 1.26 {
849 sysadm 1.40 col = p_menu_item->col;
850 sysadm 1.26 }
851 sysadm 1.21
852 sysadm 1.40 if (checkpriv(&BBS_priv, 0, p_menu_item->priv) == 0 || checklevel(&BBS_priv, p_menu_item->level) == 0)
853 sysadm 1.21 {
854 sysadm 1.41 p_menu_set->menu_item_display[menu_item_pos] = 0;
855     p_menu_set->menu_item_r_row[menu_item_pos] = 0;
856     p_menu_set->menu_item_r_col[menu_item_pos] = 0;
857 sysadm 1.21 }
858     else
859     {
860 sysadm 1.41 p_menu_set->menu_item_display[menu_item_pos] = 1;
861 sysadm 1.10
862 sysadm 1.26 if (!menu_selectable)
863     {
864 sysadm 1.41 p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
865 sysadm 1.26 menu_selectable = 1;
866     }
867 sysadm 1.3
868 sysadm 1.41 p_menu_set->menu_item_r_row[menu_item_pos] = row;
869     p_menu_set->menu_item_r_col[menu_item_pos] = col;
870 sysadm 1.26
871 sysadm 1.21 moveto(row, col);
872 sysadm 1.40 prints("%s", p_menu_item->text);
873 sysadm 1.26
874     row++;
875 sysadm 1.21 }
876 sysadm 1.10 }
877    
878 sysadm 1.21 if (!menu_selectable)
879 sysadm 1.26 {
880 sysadm 1.21 return -1;
881 sysadm 1.26 }
882 sysadm 1.3
883 sysadm 1.40 display_menu_cursor(p_menu_set, 1);
884 sysadm 1.1
885 sysadm 1.21 return 0;
886 sysadm 1.1 }
887    
888 sysadm 1.40 int menu_control(MENU_SET *p_menu_set, int key)
889 sysadm 1.12 {
890 sysadm 1.40 MENU_ID menu_id;
891     MENU_ITEM_ID menu_item_id;
892 sysadm 1.21 MENU *p_menu;
893 sysadm 1.40 MENU_ITEM *p_menu_item;
894     int16_t menu_item_pos;
895 sysadm 1.12
896 sysadm 1.40 if (p_menu_set->menu_count == 0)
897     {
898     return 0;
899     }
900 sysadm 1.12
901 sysadm 1.40 menu_id = p_menu_set->menu_id_path[p_menu_set->choose_step];
902     p_menu = get_menu_by_id(p_menu_set, menu_id);
903     if (p_menu == NULL)
904     {
905     log_error("get_menu_by_id(%d) return NULL pointer\n", menu_id);
906     return -1;
907     }
908 sysadm 1.12
909 sysadm 1.40 if (p_menu->item_count == 0)
910 sysadm 1.26 {
911 sysadm 1.21 return 0;
912 sysadm 1.26 }
913 sysadm 1.3
914 sysadm 1.40 menu_item_pos = p_menu_set->menu_item_pos[p_menu_set->choose_step];
915     menu_item_id = p_menu->items[menu_item_pos];
916     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
917     if (p_menu_item == NULL)
918     {
919     log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
920     return -1;
921     }
922 sysadm 1.3
923 sysadm 1.21 switch (key)
924 sysadm 1.10 {
925 sysadm 1.21 case CR:
926 sysadm 1.40 igetch_reset();
927 sysadm 1.21 case KEY_RIGHT:
928 sysadm 1.40 if (p_menu_item->submenu)
929 sysadm 1.21 {
930 sysadm 1.40 if (strcmp(p_menu_item->action, "..") == 0)
931 sysadm 1.26 {
932 sysadm 1.21 return menu_control(p_menu_set, KEY_LEFT);
933 sysadm 1.26 }
934 sysadm 1.40 p_menu_set->choose_step++;
935     p_menu_set->menu_id_path[p_menu_set->choose_step] = p_menu_item->action_menu_id;
936     p_menu_set->menu_item_pos[p_menu_set->choose_step] = 0;
937 sysadm 1.26
938 sysadm 1.40 if (display_menu(p_menu_set) != 0)
939 sysadm 1.26 {
940 sysadm 1.21 return menu_control(p_menu_set, KEY_LEFT);
941 sysadm 1.26 }
942 sysadm 1.21 }
943     else
944     {
945 sysadm 1.44 return ((*(p_menu_item->action_cmd_handler))((void *)(p_menu_item->name)));
946 sysadm 1.21 }
947 sysadm 1.38 break;
948 sysadm 1.21 case KEY_LEFT:
949 sysadm 1.40 if (p_menu_set->choose_step > 0)
950 sysadm 1.21 {
951 sysadm 1.40 p_menu_set->choose_step--;
952     if (display_menu(p_menu_set) != 0)
953 sysadm 1.26 {
954 sysadm 1.21 return menu_control(p_menu_set, KEY_LEFT);
955 sysadm 1.26 }
956 sysadm 1.48 if (p_menu_set->choose_step == 0)
957     {
958     return REDRAW;
959     }
960 sysadm 1.21 }
961     else
962     {
963 sysadm 1.40 display_menu_cursor(p_menu_set, 0);
964     menu_item_pos = p_menu->item_count - 1;
965     while (menu_item_pos >= 0)
966 sysadm 1.26 {
967 sysadm 1.40 menu_item_id = p_menu->items[menu_item_pos];
968     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
969     if (p_menu_item == NULL)
970     {
971     log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
972     return -1;
973     }
974    
975 sysadm 1.41 if (!p_menu_set->menu_item_display[menu_item_pos] || p_menu_item->priv != 0 || p_menu_item->level != 0)
976 sysadm 1.40 {
977     menu_item_pos--;
978     }
979     else
980     {
981     break;
982     }
983 sysadm 1.26 }
984 sysadm 1.40 p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
985     display_menu_cursor(p_menu_set, 1);
986 sysadm 1.21 }
987 sysadm 1.38 break;
988 sysadm 1.21 case KEY_UP:
989 sysadm 1.40 display_menu_cursor(p_menu_set, 0);
990 sysadm 1.21 do
991     {
992 sysadm 1.40 menu_item_pos--;
993     if (menu_item_pos < 0)
994     {
995     menu_item_pos = p_menu->item_count - 1;
996     }
997     menu_item_id = p_menu->items[menu_item_pos];
998     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
999     if (p_menu_item == NULL)
1000 sysadm 1.26 {
1001 sysadm 1.40 log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1002     return -1;
1003 sysadm 1.26 }
1004 sysadm 1.41 } while (!p_menu_set->menu_item_display[menu_item_pos]);
1005 sysadm 1.40 p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1006     display_menu_cursor(p_menu_set, 1);
1007 sysadm 1.21 break;
1008     case KEY_DOWN:
1009 sysadm 1.40 display_menu_cursor(p_menu_set, 0);
1010 sysadm 1.21 do
1011     {
1012 sysadm 1.40 menu_item_pos++;
1013     if (menu_item_pos >= p_menu->item_count)
1014     {
1015     menu_item_pos = 0;
1016     }
1017     menu_item_id = p_menu->items[menu_item_pos];
1018     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
1019     if (p_menu_item == NULL)
1020 sysadm 1.26 {
1021 sysadm 1.40 log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1022     return -1;
1023 sysadm 1.26 }
1024 sysadm 1.41 } while (!p_menu_set->menu_item_display[menu_item_pos]);
1025 sysadm 1.40 p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1026     display_menu_cursor(p_menu_set, 1);
1027 sysadm 1.21 break;
1028 sysadm 1.43 case KEY_HOME:
1029 sysadm 1.42 case KEY_PGUP:
1030     display_menu_cursor(p_menu_set, 0);
1031     menu_item_pos = 0;
1032     while (menu_item_pos < p_menu->item_count - 1)
1033     {
1034     menu_item_id = p_menu->items[menu_item_pos];
1035     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
1036     if (p_menu_item == NULL)
1037     {
1038     log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1039     return -1;
1040     }
1041    
1042     if (p_menu_set->menu_item_display[menu_item_pos])
1043     {
1044     break;
1045     }
1046    
1047     menu_item_pos++;
1048     }
1049     p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1050     display_menu_cursor(p_menu_set, 1);
1051     break;
1052 sysadm 1.43 case KEY_END:
1053 sysadm 1.42 case KEY_PGDN:
1054     display_menu_cursor(p_menu_set, 0);
1055     menu_item_pos = p_menu->item_count - 1;
1056     while (menu_item_pos > 0)
1057     {
1058     menu_item_id = p_menu->items[menu_item_pos];
1059     p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
1060     if (p_menu_item == NULL)
1061     {
1062     log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1063     return -1;
1064     }
1065    
1066     if (p_menu_set->menu_item_display[menu_item_pos])
1067     {
1068     break;
1069     }
1070    
1071     menu_item_pos--;
1072     }
1073     p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1074     display_menu_cursor(p_menu_set, 1);
1075     break;
1076 sysadm 1.21 default:
1077 sysadm 1.31 if (isalnum(key))
1078 sysadm 1.21 {
1079 sysadm 1.41 for (menu_item_pos = 0; menu_item_pos < p_menu->item_count; menu_item_pos++)
1080 sysadm 1.21 {
1081 sysadm 1.41 menu_item_id = p_menu->items[menu_item_pos];
1082 sysadm 1.40 p_menu_item = get_menu_item_by_id(p_menu_set, menu_item_id);
1083     if (p_menu_item == NULL)
1084     {
1085     log_error("get_menu_item_by_id(%d) return NULL pointer\n", menu_item_id);
1086     return -1;
1087     }
1088    
1089 sysadm 1.41 if (toupper(key) == toupper(p_menu_item->name[0]) && p_menu_set->menu_item_display[menu_item_pos])
1090 sysadm 1.21 {
1091 sysadm 1.40 display_menu_cursor(p_menu_set, 0);
1092 sysadm 1.41 p_menu_set->menu_item_pos[p_menu_set->choose_step] = menu_item_pos;
1093 sysadm 1.40 display_menu_cursor(p_menu_set, 1);
1094 sysadm 1.21 return 0;
1095     }
1096     }
1097 sysadm 1.16 }
1098 sysadm 1.38 break;
1099 sysadm 1.3 }
1100 sysadm 1.1
1101 sysadm 1.48 return NOREDRAW;
1102 sysadm 1.1 }
1103 sysadm 1.15
1104 sysadm 1.40 int unload_menu(MENU_SET *p_menu_set)
1105 sysadm 1.15 {
1106 sysadm 1.39 if (p_menu_set->p_menu_name_dict != NULL)
1107     {
1108     trie_dict_destroy(p_menu_set->p_menu_name_dict);
1109 sysadm 1.46 p_menu_set->p_menu_name_dict = NULL;
1110 sysadm 1.39 }
1111    
1112 sysadm 1.40 if (p_menu_set->p_menu_screen_dict != NULL)
1113     {
1114     trie_dict_destroy(p_menu_set->p_menu_screen_dict);
1115 sysadm 1.46 p_menu_set->p_menu_screen_dict = NULL;
1116 sysadm 1.40 }
1117    
1118     unload_menu_shm(p_menu_set);
1119    
1120     if (shmctl(p_menu_set->shmid, IPC_RMID, NULL) == -1)
1121     {
1122     log_error("shmctl(shmid=%d, IPC_RMID) error (%d)\n", p_menu_set->shmid, errno);
1123     return -1;
1124     }
1125    
1126     return 0;
1127     }
1128    
1129     int load_menu_shm(MENU_SET *p_menu_set)
1130     {
1131     // Mount shared memory
1132 sysadm 1.45 if (p_menu_set->p_reserved == NULL)
1133 sysadm 1.41 {
1134 sysadm 1.45 p_menu_set->p_reserved = shmat(p_menu_set->shmid, NULL, SHM_RDONLY);
1135     if (p_menu_set->p_reserved == (void *)-1)
1136     {
1137     log_error("shmat() error (%d)\n", errno);
1138     return -1;
1139     }
1140 sysadm 1.41 }
1141    
1142 sysadm 1.40 p_menu_set->p_menu_pool = p_menu_set->p_reserved + MENU_SET_RESERVED_LENGTH;
1143     p_menu_set->p_menu_item_pool = p_menu_set->p_menu_pool + sizeof(MENU) * MAX_MENUS;
1144     p_menu_set->p_menu_screen_pool = p_menu_set->p_menu_item_pool + sizeof(MENU_ITEM) * MAX_MENUITEMS;
1145     p_menu_set->p_menu_screen_buf = p_menu_set->p_menu_screen_pool + sizeof(MENU_SCREEN) * MAX_MENUS;
1146     p_menu_set->p_menu_screen_buf_free = p_menu_set->p_menu_screen_buf;
1147    
1148     // Restore status varaibles into reserved memory area
1149     p_menu_set->menu_count = *((int16_t *)p_menu_set->p_reserved);
1150     p_menu_set->menu_item_count = *(((int16_t *)p_menu_set->p_reserved) + 1);
1151     p_menu_set->menu_screen_count = *(((int16_t *)p_menu_set->p_reserved) + 2);
1152    
1153     p_menu_set->choose_step = 0;
1154     p_menu_set->menu_id_path[0] = 0;
1155 sysadm 1.16
1156 sysadm 1.40 p_menu_set->p_menu_name_dict = NULL;
1157     p_menu_set->p_menu_screen_dict = NULL;
1158    
1159     return 0;
1160 sysadm 1.15 }
1161 sysadm 1.18
1162 sysadm 1.40 int unload_menu_shm(MENU_SET *p_menu_set)
1163 sysadm 1.18 {
1164 sysadm 1.40 p_menu_set->menu_count = 0;
1165     p_menu_set->menu_item_count = 0;
1166     p_menu_set->menu_screen_count = 0;
1167     p_menu_set->choose_step = 0;
1168    
1169     p_menu_set->p_menu_pool = NULL;
1170     p_menu_set->p_menu_item_pool = NULL;
1171     p_menu_set->p_menu_screen_pool = NULL;
1172     p_menu_set->p_menu_screen_buf = NULL;
1173     p_menu_set->p_menu_screen_buf_free = NULL;
1174 sysadm 1.21
1175 sysadm 1.41 if (p_menu_set->p_reserved != NULL && shmdt(p_menu_set->p_reserved) == -1)
1176 sysadm 1.40 {
1177     log_error("shmdt() error (%d)\n", errno);
1178     return -1;
1179     }
1180     p_menu_set->p_reserved = NULL;
1181 sysadm 1.18
1182 sysadm 1.40 return 0;
1183 sysadm 1.18 }

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