diff --git a/LCDd.conf b/LCDd.conf index ac9f2af..8ba206a 100644 --- a/LCDd.conf +++ b/LCDd.conf @@ -96,14 +96,17 @@ NextScreenKey=Right ## The menu section. The menu is an internal LCDproc client. ## [menu] -# You can configure what keys the menu should use. Note that only the menukey -# will be reserved exclusively, the others in shared mode. +# You can configure what keys the menu should use. Note that the MenuKey +# will be reserved exclusively, the others work in shared mode. -# The following works excelent with 4 keys or more. +# The following works excellent with 4 keys or more. MenuKey=Escape EnterKey=Enter UpKey=Up DownKey=Down +# If you have 6 keys you may define these as well +#LeftKey=Left +#RightKey=Right # If you have only 3 keys, you could use something like this: #MenuKey=Escape diff --git a/server/commands/menu_commands.c b/server/commands/menu_commands.c index 57fd6d6..2acecdc 100644 --- a/server/commands/menu_commands.c +++ b/server/commands/menu_commands.c @@ -7,6 +7,8 @@ * * Copyright (c) 1999, William Ferrell, Scott Scriven * 2002, Joris Robijn + * 2004, F5 Networks, Inc. - IP-address input + * 2005, Peter Marschall - error checks, ... * * * This contains definitions for all the functions which clients can run. @@ -59,6 +61,7 @@ MenuEventFunc(menu_commands_handler); * - slider * - numeric * - alpha + * - ip */ int menu_add_item_func (Client * c, int argc, char **argv) @@ -156,6 +159,10 @@ menu_add_item_func (Client * c, int argc, char **argv) item = menuitem_create_alpha (item_id, menu_commands_handler, text, 0, 0, 10, true, false, true, "-./", ""); break; + case MENUITEM_IP: + item = menuitem_create_ip (item_id, menu_commands_handler, text, + 0, "192.168.1.245"); + break; } menu_add_item (menu, item); menuscreen_inform_item_modified (menu); @@ -305,6 +312,11 @@ menu_del_item_func (Client * c, int argc, char **argv) * -allowed_extra ("") * The chars in this string are also allowed. * + * ip: + * -value + * Sets its current value. ("") + * -v6 false|true + * * Hmm, this is getting very big. We might need a some real parser after all. */ int @@ -356,6 +368,8 @@ menu_set_item_func (Client * c, int argc, char **argv) { MENUITEM_ALPHA, "allow_noncaps",BOOLEAN, offsetof(MenuItem,data.alpha.allow_noncaps) }, { MENUITEM_ALPHA, "allow_numbers",BOOLEAN, offsetof(MenuItem,data.alpha.allow_numbers) }, { MENUITEM_ALPHA, "allowed_extra",STRING, offsetof(MenuItem,data.alpha.allowed_extra) }, + { MENUITEM_IP, "v6", BOOLEAN, offsetof(MenuItem,data.ip.v6) }, + { MENUITEM_IP, "value", STRING, -1 /*offsetof(MenuItem,data.ip.value)*/ }, { -1, NULL, -1, -1 } }; @@ -483,8 +497,7 @@ menu_set_item_func (Client * c, int argc, char **argv) break; case SHORT: short_value = strtol( argv[argnr+1], &p, 0 ); - if( argv[argnr+1][0] == 0 - || *p != 0 ) { + if( argv[argnr+1][0] == '\0' || *p != '\0' ) { error = 1; break; } @@ -494,8 +507,7 @@ menu_set_item_func (Client * c, int argc, char **argv) break; case INT: int_value = strtol( argv[argnr+1], &p, 0 ); - if( argv[argnr+1][0] == 0 - || *p != 0 ) { + if( argv[argnr+1][0] == '\0' || *p != '\0' ) { error = 1; break; } @@ -505,8 +517,7 @@ menu_set_item_func (Client * c, int argc, char **argv) break; case FLOAT: float_value = strtod( argv[argnr+1], &p ); - if( argv[argnr+1][0] == 0 - || *p != 0 ) { + if( argv[argnr+1][0] == '\0' || *p != '\0' ) { error = 1; break; } @@ -575,12 +586,12 @@ menu_set_item_func (Client * c, int argc, char **argv) } new_buf = malloc( short_value + 1 ); strncpy( new_buf, item->data.alpha.value, short_value ); - new_buf[short_value] = 0; /* terminate */ + new_buf[short_value] = '\0'; /* terminate */ free( item->data.alpha.value ); item->data.alpha.value = new_buf; free( item->data.alpha.edit_str ); item->data.alpha.edit_str = malloc( short_value + 1 ); - item->data.alpha.edit_str[0] = 0; + item->data.alpha.edit_str[0] = '\0'; } else if( strcmp( argv[argnr]+1, "value" ) == 0 ) { strncpy( item->data.alpha.value, string_value, item->data.alpha.maxlength ); @@ -588,6 +599,28 @@ menu_set_item_func (Client * c, int argc, char **argv) } menuitem_reset (item); break; + case MENUITEM_IP: + if( strcmp( argv[argnr]+1, "v6" ) == 0 ) { + char * new_buf; + /* set max lenth depending ob boolean option v6 */ + item->data.ip.maxlength = (bool_value == 0) ? 15 : 39; + + new_buf = malloc(item->data.ip.maxlength + 1 ); + strncpy( new_buf, item->data.ip.value, item->data.ip.maxlength); + + new_buf[item->data.ip.maxlength] = '\0'; /* terminate */ + free( item->data.ip.value ); + item->data.ip.value = new_buf; + free( item->data.ip.edit_str ); + item->data.ip.edit_str = malloc( item->data.ip.maxlength +1); + item->data.ip.edit_str[0] = '\0'; + } + else if( strcmp( argv[argnr]+1, "value" ) == 0 ) { + strncpy( item->data.ip.value, string_value, item->data.ip.maxlength ); + item->data.ip.value[item->data.ip.maxlength] = '\0'; /* terminate */ + } + menuitem_reset (item); + break; default: break; } @@ -694,6 +727,11 @@ MenuEventFunc (menu_commands_handler) menuitem_eventtype_to_eventtypename(event), item->id, item->data.alpha.value ); break; + case MENUITEM_IP: + snprintf (buf, sizeof(buf)-1, "menuevent %s %.40s %.40s\n", + menuitem_eventtype_to_eventtypename(event), + item->id, item->data.ip.value ); + break; default: snprintf (buf, sizeof(buf)-1, "menuevent %s %.40s\n", menuitem_eventtype_to_eventtypename(event), diff --git a/server/menu.c b/server/menu.c index c132d46..2b94ee0 100644 --- a/server/menu.c +++ b/server/menu.c @@ -7,7 +7,8 @@ * * Copyright (c) 1999, William Ferrell, Scott Scriven * 2002, Joris Robijn - * + * 2004, F5 Networks, Inc. - IP-address input + * 2005, Peter Marschall - error checks, ... * * Handles a menu and all actions that can be performed on it. Note that a * menu is itself also a menuitem. @@ -244,6 +245,7 @@ void menu_build_screen (MenuItem *menu, Screen *s) case MENUITEM_SLIDER: case MENUITEM_NUMERIC: case MENUITEM_ALPHA: + case MENUITEM_IP: /* Limit string length */ w->text = strdup (subitem->text); if (strlen(subitem->text) >= display_props->width-1) { @@ -401,7 +403,7 @@ void menu_update_screen (MenuItem *menu, Screen *s) report (RPT_ERR, "%s: could not find widget: %s", __FUNCTION__, "downscroller"); } -MenuResult menu_process_input (Menu *menu, MenuToken token, char * key) +MenuResult menu_process_input (Menu *menu, MenuToken token, char * key, bool extended) { MenuItem *subitem; @@ -444,6 +446,7 @@ MenuResult menu_process_input (Menu *menu, MenuToken token, char * key) case MENUITEM_SLIDER: case MENUITEM_NUMERIC: case MENUITEM_ALPHA: + case MENUITEM_IP: //if (subitem->event_func) // subitem->event_func (subitem, MENUEVENT_ENTER); return MENURESULT_ENTER; @@ -472,6 +475,64 @@ MenuResult menu_process_input (Menu *menu, MenuToken token, char * key) menu->data.menu.scroll ++; } return MENURESULT_NONE; + case MENUTOKEN_LEFT: + if (!extended) + return MENURESULT_NONE; + + subitem = LL_GetByIndex (menu->data.menu.contents, + menu->data.menu.selector_pos); + if (subitem == NULL) + break; + switch (subitem->type) { + case MENUITEM_CHECKBOX: + if (subitem->data.checkbox.allow_gray) { + subitem->data.checkbox.value = (subitem->data.checkbox.value - 1) % 3; + } + else { + subitem->data.checkbox.value = (subitem->data.checkbox.value - 1) % 2; + } + if (subitem->event_func) + subitem->event_func (subitem, MENUEVENT_UPDATE); + return MENURESULT_NONE; + case MENUITEM_RING: + subitem->data.ring.value = (subitem->data.ring.value - 1) % LL_Length (subitem->data.ring.strings); + if (subitem->event_func) + subitem->event_func (subitem, MENUEVENT_UPDATE); + return MENURESULT_NONE; + default: + break; + } + return MENURESULT_NONE; + case MENUTOKEN_RIGHT: + if (!extended) + return MENURESULT_NONE; + + subitem = LL_GetByIndex (menu->data.menu.contents, + menu->data.menu.selector_pos); + if (subitem == NULL) + break; + switch (subitem->type) { + case MENUITEM_CHECKBOX: + if (subitem->data.checkbox.allow_gray) { + subitem->data.checkbox.value = (subitem->data.checkbox.value + 1) % 3; + } + else { + subitem->data.checkbox.value = (subitem->data.checkbox.value + 1) % 2; + } + if (subitem->event_func) + subitem->event_func (subitem, MENUEVENT_UPDATE); + return MENURESULT_NONE; + case MENUITEM_RING: + subitem->data.ring.value = (subitem->data.ring.value + 1) % LL_Length (subitem->data.ring.strings); + if (subitem->event_func) + subitem->event_func (subitem, MENUEVENT_UPDATE); + return MENURESULT_NONE; + case MENUITEM_MENU: + return MENURESULT_ENTER; + default: + break; + } + return MENURESULT_NONE; case MENUTOKEN_OTHER: /* TODO: move to the selected number and enter it */ return MENURESULT_NONE; diff --git a/server/menu.h b/server/menu.h index 43b2952..a4ac15b 100644 --- a/server/menu.h +++ b/server/menu.h @@ -6,6 +6,8 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven + * 2004, F5 Networks, Inc. - IP-address input + * 2005, Peter Marschall - error checks, ... * * Defines all the menu data and actions. * @@ -108,7 +110,7 @@ void menu_update_screen (Menu *menu, Screen *s); * DO NOT CALL THIS FUNCTION, CALL menuitem_update_screen INSTEAD ! */ -MenuResult menu_process_input (Menu *menu, MenuToken token, char * key); +MenuResult menu_process_input (Menu *menu, MenuToken token, char * key, bool extended); /* Does something with the given input. * key is only used if token is MENUTOKEN_OTHER. * DO NOT CALL THIS FUNCTION, CALL menuitem_process_input INSTEAD ! diff --git a/server/menuitem.c b/server/menuitem.c index c2bc3ec..a543fbf 100644 --- a/server/menuitem.c +++ b/server/menuitem.c @@ -7,6 +7,8 @@ * * Copyright (c) 1999, William Ferrell, Scott Scriven * 2002, Joris Robijn + * 2004, F5 Networks, Inc. - IP-address input + * 2005, Peter Marschall - error checks, ... * * * Handles a menuitem and all actions that can be performed on it. @@ -21,10 +23,13 @@ #include "menu.h" #include "drivers.h" +/* this is needed for verify_ipv4 and verify_ipv6. */ +#include "sock.h" + #define MAX_NUMERIC_LEN 40 -char *error_strs[] = {"", "Out of range", "Too long", "Too short"}; -char *menuitemtypenames[] = {"menu", "action", "checkbox", "ring", "slider", "numeric", "alpha"}; +char *error_strs[] = {"", "Out of range", "Too long", "Too short", "Invalid Address"}; +char *menuitemtypenames[] = {"menu", "action", "checkbox", "ring", "slider", "numeric", "alpha","ip"}; char *menueventtypenames[] = {"select", "update", "plus", "minus"}; void menuitem_destroy_action (MenuItem *item); @@ -33,21 +38,26 @@ void menuitem_destroy_ring (MenuItem *item); void menuitem_destroy_slider (MenuItem *item); void menuitem_destroy_numeric (MenuItem *item); void menuitem_destroy_alpha (MenuItem *item); +void menuitem_destroy_ip (MenuItem *item); void menuitem_reset_numeric (MenuItem *item); void menuitem_reset_alpha (MenuItem *item); +void menuitem_reset_ip (MenuItem *item); void menuitem_rebuild_screen_slider (MenuItem *item, Screen *s); void menuitem_rebuild_screen_numeric (MenuItem *item, Screen *s); void menuitem_rebuild_screen_alpha (MenuItem *item, Screen *s); +void menuitem_rebuild_screen_ip (MenuItem *item, Screen *s); void menuitem_update_screen_slider (MenuItem *item, Screen *s); void menuitem_update_screen_numeric (MenuItem *item, Screen *s); void menuitem_update_screen_alpha (MenuItem *item, Screen *s); +void menuitem_update_screen_ip (MenuItem *item, Screen *s); -MenuResult menuitem_process_input_slider (MenuItem *item, MenuToken token, char * key); -MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char * key); -MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * key); +MenuResult menuitem_process_input_slider (MenuItem *item, MenuToken token, char * key, bool extended); +MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char * key, bool extended); +MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * key, bool extended); +MenuResult menuitem_process_input_ip (MenuItem *item, MenuToken token, char * key, bool extended); /******** FUNCTION TABLES ********/ @@ -61,7 +71,8 @@ void (*destructor_table[NUM_ITEMTYPES] ) (MenuItem *item) = menuitem_destroy_ring, menuitem_destroy_slider, menuitem_destroy_numeric, - menuitem_destroy_alpha + menuitem_destroy_alpha, + menuitem_destroy_ip }; void (*reset_table[NUM_ITEMTYPES] ) (MenuItem *item) = { @@ -71,7 +82,8 @@ void (*reset_table[NUM_ITEMTYPES] ) (MenuItem *item) = NULL, NULL, menuitem_reset_numeric, - menuitem_reset_alpha + menuitem_reset_alpha, + menuitem_reset_ip }; void (*build_screen_table[NUM_ITEMTYPES] ) (MenuItem *item, Screen *s) = { @@ -81,7 +93,8 @@ void (*build_screen_table[NUM_ITEMTYPES] ) (MenuItem *item, Screen *s) = NULL, menuitem_rebuild_screen_slider, menuitem_rebuild_screen_numeric, - menuitem_rebuild_screen_alpha + menuitem_rebuild_screen_alpha, + menuitem_rebuild_screen_ip }; void (*update_screen_table[NUM_ITEMTYPES] ) (MenuItem *item, Screen *s) = { @@ -91,10 +104,11 @@ void (*update_screen_table[NUM_ITEMTYPES] ) (MenuItem *item, Screen *s) = NULL, menuitem_update_screen_slider, menuitem_update_screen_numeric, - menuitem_update_screen_alpha + menuitem_update_screen_alpha, + menuitem_update_screen_ip }; -MenuResult (*process_input_table[NUM_ITEMTYPES] ) (MenuItem *item, MenuToken token, char *key) = +MenuResult (*process_input_table[NUM_ITEMTYPES] ) (MenuItem *item, MenuToken token, char *key, bool extended) = { menu_process_input, NULL, @@ -102,7 +116,8 @@ MenuResult (*process_input_table[NUM_ITEMTYPES] ) (MenuItem *item, MenuToken tok NULL, menuitem_process_input_slider, menuitem_process_input_numeric, - menuitem_process_input_alpha + menuitem_process_input_alpha, + menuitem_process_input_ip }; /******** METHODS ********/ @@ -130,6 +145,7 @@ MenuItem *menuitem_create (MenuItemType type, char *id, MenuEventFunc(*event_fun new_item->id = strdup (id); if (!new_item->id) { report (RPT_ERR, "%s: Could not allocate memory", __FUNCTION__); + free (new_item); return NULL; } new_item->parent = NULL; @@ -137,11 +153,13 @@ MenuItem *menuitem_create (MenuItemType type, char *id, MenuEventFunc(*event_fun new_item->text = strdup (text); if (!new_item->text) { report (RPT_ERR, "%s: Could not allocate memory", __FUNCTION__); + free (new_item->id); + free (new_item); return NULL; } /* Clear the type specific data part */ - memset ( &(new_item->data), 0, sizeof(new_item->data)); + memset ( &(new_item->data), '\0', sizeof(new_item->data)); return new_item; } @@ -269,11 +287,34 @@ MenuItem *menuitem_create_alpha (char *id, MenuEventFunc(*event_func), return new_item; } +MenuItem *menuitem_create_ip (char *id, MenuEventFunc(*event_func), + char *text, bool v6, char *value) +{ + MenuItem *new_item; + + debug (RPT_DEBUG, "%s( id=\"%s\", event_func=%p, text=\"%s\", v6=%d, value=\"%s\" )", + __FUNCTION__, id, event_func, text, v6, value); + + new_item = menuitem_create (MENUITEM_IP, id, event_func, text); + new_item->data.ip.v6 = v6; + if (v6) + new_item->data.ip.maxlength = 39; + else + new_item->data.ip.maxlength = 15; + + new_item->data.ip.value = malloc (new_item->data.ip.maxlength + 1); + strncpy (new_item->data.ip.value, value, new_item->data.ip.maxlength); + new_item->data.ip.value[new_item->data.ip.maxlength] = 0; + + new_item->data.ip.edit_str = malloc (new_item->data.ip.maxlength + 1); + + return new_item; +} void menuitem_destroy (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { void (*destructor) (MenuItem *); @@ -294,8 +335,8 @@ void menuitem_destroy (MenuItem *item) void menuitem_destroy_ring (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { char * s; @@ -313,8 +354,8 @@ void menuitem_destroy_ring (MenuItem *item) void menuitem_destroy_slider (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { /* These strings should always be allocated */ @@ -325,8 +366,8 @@ void menuitem_destroy_slider (MenuItem *item) void menuitem_destroy_numeric (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { /* This string should always be allocated */ @@ -336,8 +377,8 @@ void menuitem_destroy_numeric (MenuItem *item) void menuitem_destroy_alpha (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { /* These strings should always be allocated */ @@ -347,12 +388,22 @@ void menuitem_destroy_alpha (MenuItem *item) } } +void menuitem_destroy_ip (MenuItem *item) +{ + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); + + /* These strings should always be allocated */ + free (item->data.ip.value); + free (item->data.ip.edit_str); +} + /******** MENU ITEM RESET FUNCTIONS ********/ void menuitem_reset (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { void (*func) (MenuItem *); @@ -366,12 +417,12 @@ void menuitem_reset (MenuItem *item) void menuitem_reset_numeric (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { item->data.numeric.edit_pos = 0; - memset ( item->data.numeric.edit_str, 0, MAX_NUMERIC_LEN); + memset (item->data.numeric.edit_str, '\0', MAX_NUMERIC_LEN); if (item->data.numeric.minvalue < 0) { snprintf (item->data.numeric.edit_str, MAX_NUMERIC_LEN, "%+d", item->data.numeric.value); @@ -384,16 +435,44 @@ void menuitem_reset_numeric (MenuItem *item) void menuitem_reset_alpha (MenuItem *item) { - debug (RPT_DEBUG, "%s( item=[%s] )", - __FUNCTION__, ((item != NULL) ? item->id : "(null)")); + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); if (item != NULL) { item->data.alpha.edit_pos = 0; - memset (item->data.alpha.edit_str, 0, item->data.alpha.maxlength+1); + memset (item->data.alpha.edit_str, '\0', item->data.alpha.maxlength+1); strcpy (item->data.alpha.edit_str, item->data.alpha.value); } } +void menuitem_reset_ip (MenuItem *item) +{ + char *s; + int count,index,i,j; + + debug (RPT_DEBUG, "%s( item=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)")); + + item->data.ip.edit_pos = 0; + memset (item->data.ip.edit_str, '\0', item->data.ip.maxlength+1); +// strcpy (item->data.ip.edit_str, item->data.ip.value); + index = 0; + s = item->data.ip.value; + for (j = 0; j < 4; j++) { + count = strcspn (s, "."); + for (i = 3; i > 0; i--) { + if (i == count) { + item->data.ip.edit_str[index++] = *s++; + count--; + } else { + item->data.ip.edit_str[index++] = ' '; + } + } + /* copy period or null */ + item->data.ip.edit_str[index++] = *s++; + } +} + /******** MENU SCREEN BUILD FUNCTIONS ********/ @@ -446,6 +525,9 @@ void menuitem_rebuild_screen_slider (MenuItem *item, Screen *s) ((item != NULL) ? item->id : "(null)"), ((s != NULL) ? s->id : "(null)")); + if ((item == NULL) || (s == NULL)) + return; + if (display_props->height >= 2 ) { /* Only add a title if enough space... */ w = widget_create ("text", WID_STRING, s); @@ -496,6 +578,9 @@ void menuitem_rebuild_screen_numeric (MenuItem *item, Screen *s) ((item != NULL) ? item->id : "(null)"), ((s != NULL) ? s->id : "(null)")); + if ((item == NULL) || (s == NULL)) + return; + if (display_props->height >= 2 ) { /* Only add a title if enough space... */ w = widget_create ("text", WID_STRING, s); @@ -529,6 +614,9 @@ void menuitem_rebuild_screen_alpha (MenuItem *item, Screen *s) ((item != NULL) ? item->id : "(null)"), ((s != NULL) ? s->id : "(null)")); + if ((item == NULL) || (s == NULL)) + return; + if (display_props->height >= 2 ) { /* Only add a title if enough space... */ w = widget_create ("text", WID_STRING, s); @@ -554,6 +642,42 @@ void menuitem_rebuild_screen_alpha (MenuItem *item, Screen *s) } } +void menuitem_rebuild_screen_ip (MenuItem *item, Screen *s) +{ + Widget * w; + + debug (RPT_DEBUG, "%s( item=[%s], screen=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)"), + ((s != NULL) ? s->id : "(null)")); + + if ((item == NULL) || (s == NULL)) + return; + + if (display_props->height >= 2 ) { + /* Only add a title if enough space... */ + w = widget_create ("text", WID_STRING, s); + screen_add_widget (s, w); + w->text = strdup(item->text); + w->x = 1; + w->y = 1; + } + + w = widget_create ("value", WID_STRING, s); + screen_add_widget (s, w); + w->text = malloc (item->data.ip.maxlength+1); + w->x = 2; + w->y = display_props->height / 2 + 1; + + /* Only display error string if enough space... */ + if (display_props->height > 2 ) { + w = widget_create ("error", WID_STRING, s); + screen_add_widget (s, w); + w->text = strdup(""); + w->x = 1; + w->y = display_props->height; + } +} + /******** MENU SCREEN UPDATE FUNCTIONS ********/ void menuitem_update_screen (MenuItem *item, Screen *s) @@ -661,11 +785,11 @@ void menuitem_update_screen_alpha (MenuItem *item, Screen *s) return; w = screen_find_widget (s, "value"); - if (item->data.alpha.password_char == 0) { + if (item->data.alpha.password_char == '\0') { strcpy (w->text, item->data.alpha.edit_str); } else { memset (w->text, item->data.alpha.password_char, strlen (item->data.alpha.edit_str)); - w->text[ strlen (item->data.alpha.edit_str) ] = 0; + w->text[ strlen (item->data.alpha.edit_str) ] = '\0'; } s->cursor = CURSOR_DEFAULT_ON; @@ -680,11 +804,38 @@ void menuitem_update_screen_alpha (MenuItem *item, Screen *s) } } +void menuitem_update_screen_ip (MenuItem *item, Screen *s) +{ + Widget * w; + + debug (RPT_DEBUG, "%s( item=[%s], screen=[%s] )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)"), + ((s != NULL) ? s->id : "(null)")); + + if ((item == NULL) || (s == NULL)) + return; + + w = screen_find_widget (s, "value"); + if (w != NULL) + strcpy (w->text, item->data.ip.edit_str); + + s->cursor = CURSOR_DEFAULT_ON; + s->cursor_x = w->x + item->data.ip.edit_pos; + s->cursor_y = w->y; + + /* Only display error string if enough space... */ + if (display_props->height > 2 ) { + w = screen_find_widget (s, "error"); + free (w->text); + w->text = strdup (error_strs[item->data.ip.error_code]); + } +} + /******** MENU SCREEN INPUT HANDLING FUNCTIONS ********/ -MenuResult menuitem_process_input (MenuItem *item, MenuToken token, char * key) +MenuResult menuitem_process_input (MenuItem *item, MenuToken token, char * key, bool extended) { - MenuResult (*process_input) (MenuItem *item, MenuToken token, char * key); + MenuResult (*process_input) (MenuItem *item, MenuToken token, char * key, bool extended); debug (RPT_DEBUG, "%s( item=[%s], token=%d, key=\"%s\" )", __FUNCTION__, ((item != NULL) ? item->id : "(null)"), token, key); @@ -695,14 +846,14 @@ MenuResult menuitem_process_input (MenuItem *item, MenuToken token, char * key) /* Call type specific screen building function */ process_input = process_input_table [item->type]; if (process_input ) { - return process_input (item, token, key); + return process_input (item, token, key, extended); } else { report (RPT_ERR, "%s: given menuitem cannot be active", __FUNCTION__); return MENURESULT_ERROR; } } -MenuResult menuitem_process_input_slider (MenuItem *item, MenuToken token, char * key) +MenuResult menuitem_process_input_slider (MenuItem *item, MenuToken token, char * key, bool extended) { debug (RPT_DEBUG, "%s( item=[%s], token=%d, key=\"%s\" )", __FUNCTION__, ((item != NULL) ? item->id : "(null)"), token, key); @@ -715,26 +866,28 @@ MenuResult menuitem_process_input_slider (MenuItem *item, MenuToken token, char case MENUTOKEN_ENTER: return MENURESULT_CLOSE; case MENUTOKEN_UP: + case MENUTOKEN_RIGHT: item->data.slider.value = min (item->data.slider.maxvalue, - item->data.slider.value + item->data.slider.stepsize); + item->data.slider.value + item->data.slider.stepsize); if (item->event_func) item->event_func (item, MENUEVENT_PLUS); return MENURESULT_NONE; case MENUTOKEN_DOWN: + case MENUTOKEN_LEFT: item->data.slider.value = max (item->data.slider.minvalue, - item->data.slider.value - item->data.slider.stepsize); + item->data.slider.value - item->data.slider.stepsize); if (item->event_func) item->event_func (item, MENUEVENT_MINUS); return MENURESULT_NONE; case MENUTOKEN_OTHER: default: - break; + break; } return MENURESULT_ERROR; } -MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char * key) +MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char * key, bool extended) { char buf1[MAX_NUMERIC_LEN]; char buf2[MAX_NUMERIC_LEN]; @@ -767,12 +920,12 @@ MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char else { /* Reset data */ item->data.numeric.edit_pos = 0; - memset (str, 0, MAX_NUMERIC_LEN); + memset (str, '\0', MAX_NUMERIC_LEN); snprintf (str, MAX_NUMERIC_LEN, format_str, item->data.numeric.value); } return MENURESULT_NONE; case MENUTOKEN_ENTER: - if (str[pos] == '\0') { + if ((extended) || (str[pos] == '\0')) { int value; /* The user completed his input */ @@ -822,8 +975,8 @@ MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char if (str[pos] >= '0' && str[pos] < '9') { str[pos] ++; } else if (str[pos] == '9') { - str[pos] = 0; - } else if (str[pos] == 0) { + str[pos] = '\0'; + } else if (str[pos] == '\0') { str[pos] = '0'; } } @@ -843,12 +996,24 @@ MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char if (str[pos] > '0' && str[pos] <= '9') { str[pos] --; } else if (str[pos] == '0') { - str[pos] = 0; - } else if (str[pos] == 0) { + str[pos] = '\0'; + } else if (str[pos] == '\0') { str[pos] = '9'; } } return MENURESULT_NONE; + case MENUTOKEN_RIGHT: + /* The user wants to go to next digit */ + if (str[pos] != '\0' && pos < max_len) { + item->data.numeric.edit_pos ++; + } + return MENURESULT_NONE; + case MENUTOKEN_LEFT: + /* The user wants to go to back a digit */ + if (pos > 0) { + item->data.numeric.edit_pos --; + } + return MENURESULT_NONE; case MENUTOKEN_OTHER: if (pos >= max_len) { /* We're not allowed to add anything anymore */ @@ -867,7 +1032,7 @@ MenuResult menuitem_process_input_numeric (MenuItem *item, MenuToken token, char return MENURESULT_ERROR; } -MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * key) +MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * key, bool extended) { char * p; static char * chars = NULL; @@ -902,12 +1067,12 @@ MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * else { /* Reset data */ item->data.alpha.edit_pos = 0; - memset (str, 0, item->data.alpha.maxlength+1); + memset (str, '\0', item->data.alpha.maxlength+1); strcpy (str, item->data.alpha.value); } return MENURESULT_NONE; case MENUTOKEN_ENTER: - if (str[item->data.alpha.edit_pos] == 0) { + if ((extended) || (str[item->data.alpha.edit_pos] == '\0')) { /* The user completed his input */ /* It's not too short ? */ @@ -939,7 +1104,7 @@ MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * item->data.alpha.edit_pos = 0; return MENURESULT_NONE; } - if (str[pos] == 0) { + if (str[pos] == '\0') { /* User goes past EOL */ str[pos] = chars[0]; } else { @@ -947,9 +1112,9 @@ MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * p = strchr (chars, str[pos]); if (p != NULL) { str[pos] = * (++p); /* next symbol on list */ - /* Might be 0 now */ + /* Might be '\0' now */ } else { - str[pos] = 0; + str[pos] = '\0'; } } return MENURESULT_NONE; @@ -960,23 +1125,31 @@ MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * item->data.alpha.edit_pos = 0; return MENURESULT_NONE; } - if (str[pos] == 0) { + if (str[pos] == '\0') { /* User goes past EOL */ str[pos] = chars[strlen(chars)-1]; } else { /* We should have a symbol from our list */ p = strchr (chars, str[pos]); - if (p != NULL) { - if (p == chars) { - str[pos] = 0; /* Go to EOL */ - } else { - str[pos] = * (--p); /* next symbol on list */ - } + if ((p != NULL) && (p != chars)) { + str[pos] = * (--p); /* previous symbol on list */ } else { - str[pos] = 0; + str[pos] = '\0'; } } return MENURESULT_NONE; + case MENUTOKEN_RIGHT: + /* The user wants to go to next digit */ + if (str[item->data.alpha.edit_pos] != '\0' && + pos < item->data.alpha.maxlength - 1) { + item->data.alpha.edit_pos ++; + } + return MENURESULT_NONE; + case MENUTOKEN_LEFT: + /* The user wants to go to back a digit */ + if (pos > 0) + item->data.alpha.edit_pos --; + return MENURESULT_NONE; case MENUTOKEN_OTHER: if (pos >= item->data.alpha.maxlength) { /* We're not allowed to add anything anymore */ @@ -995,6 +1168,129 @@ MenuResult menuitem_process_input_alpha (MenuItem *item, MenuToken token, char * return MENURESULT_ERROR; } +typedef struct valueProperties { + int start; /* index of first digit of this number */ + int place; /* is this the 1s, 10s or 100s digit */ +} tValueProperties; + +MenuResult menuitem_process_input_ip (MenuItem *item, MenuToken token, char * key, bool extended) +{ + char * p; + tValueProperties valueProperties[] = { + {0, 100 }, + {0, 10 }, + {0, 1 }, + {0, 0 }, + + {4, 100 }, + {4, 10 }, + {4, 1 }, + {0, 0 }, + + {8, 100 }, + {8, 10 }, + {8, 1 }, + {0, 0 }, + + {12, 100 }, + {12, 10 }, + {12, 1 }, + }; + + /* To make life easy... */ + char *str = item->data.ip.edit_str; + char numstr[4]; + int num; + int pos = item->data.ip.edit_pos; + + debug (RPT_DEBUG, "%s( item=[%s], token=%d, key=\"%s\" )", __FUNCTION__, + ((item != NULL) ? item->id : "(null)"), token, key); + + /* Clear the error */ + item->data.ip.error_code = 0; + + switch (token) { + case MENUTOKEN_MENU: + if (pos == 0) { + return MENURESULT_CLOSE; + } + else { + /* Reset data */ + menuitem_reset_ip(item); +// item->data.ip.edit_pos = 0; +// memset (str, '\0', item->data.ip.maxlength+1); +// strcpy (str, item->data.ip.value); + } + return MENURESULT_NONE; + case MENUTOKEN_ENTER: + /* remove the spaces */ + p = str; + while (*p) { + if (*p == ' ') { + memccpy(p, p+1, '\0', item->data.ip.maxlength + 1); + } else { + p++; + } + } + + if (item->data.ip.v6) { + if (verify_ipv6(item->data.ip.edit_str)) { + item->data.ip.error_code = 4; + return MENURESULT_NONE; + } + } else { + if (verify_ipv4(item->data.ip.edit_str)) { + item->data.ip.error_code = 4; + return MENURESULT_NONE; + } + } + + /* Store value */ + strcpy (item->data.ip.value, item->data.ip.edit_str); + + /* Inform client */ + if (item->event_func) + item->event_func (item, MENUEVENT_UPDATE); + + return MENURESULT_CLOSE; + case MENUTOKEN_UP: + num = atoi(&str[(valueProperties[pos].start)]); + num += valueProperties[pos].place; + if (num <= 255) { + sprintf(numstr,"%3d", num); + memcpy(&str[valueProperties[pos].start], numstr, 3); + } + + return MENURESULT_NONE; + case MENUTOKEN_DOWN: + num = atoi(&str[valueProperties[pos].start]); + num -= valueProperties[pos].place; + if (num >= 0) { + sprintf(numstr,"%3d", num); + memcpy(&str[valueProperties[pos].start], numstr, 3); + } + return MENURESULT_NONE; + case MENUTOKEN_RIGHT: + if (pos < item->data.ip.maxlength - 1) { + item->data.ip.edit_pos ++; + if (str[item->data.ip.edit_pos] == '.') + item->data.ip.edit_pos ++; + } + return MENURESULT_NONE; + case MENUTOKEN_LEFT: + /* The user wants to go to back a digit */ + if (pos > 0) { + item->data.ip.edit_pos --; + if (str[item->data.ip.edit_pos] == '.') + item->data.ip.edit_pos --; + } + return MENURESULT_NONE; + case MENUTOKEN_OTHER: + return MENURESULT_NONE; + } + return MENURESULT_ERROR; +} + LinkedList * tablist2linkedlist (char *strings) { LinkedList * list; diff --git a/server/menuitem.h b/server/menuitem.h index 66d37fd..0f227f3 100644 --- a/server/menuitem.h +++ b/server/menuitem.h @@ -6,6 +6,8 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven + * 2004, F5 Networks, Inc. - IP-address input + * 2005, Peter Marschall - error checks, ... * * Defines all the menuitem data and actions. * @@ -39,7 +41,7 @@ * Data definitions of the menustuff */ -#define NUM_ITEMTYPES 7 +#define NUM_ITEMTYPES 8 typedef enum MenuItemType { /* These values are used in the */ MENUITEM_MENU = 0, /* function tables in menuitem.c ! */ MENUITEM_ACTION = 1, @@ -48,6 +50,7 @@ typedef enum MenuItemType { /* These values are used in the */ MENUITEM_SLIDER = 4, MENUITEM_NUMERIC = 5, MENUITEM_ALPHA = 6, + MENUITEM_IP = 7, } MenuItemType; typedef enum CheckboxValue { @@ -60,6 +63,8 @@ typedef enum MenuToken { MENUTOKEN_ENTER, MENUTOKEN_UP, MENUTOKEN_DOWN, + MENUTOKEN_LEFT, + MENUTOKEN_RIGHT, MENUTOKEN_OTHER } MenuToken; @@ -127,7 +132,7 @@ typedef struct MenuItem { } checkbox; struct ring { LinkedList *strings; /* The selectable strings */ - int value; /* Current index */ + short value; /* Current index */ } ring; struct slider { char *mintext; /* Text at minimal value */ @@ -159,6 +164,14 @@ typedef struct MenuItem { short edit_pos; /* Position while editing */ short error_code; } alpha; + struct ip { + char *value; /* Current value */ + char *edit_str; /* Value while being edited */ + short maxlength; + bool v6; /* true if editing ipv6 addr */ + short edit_pos; /* Position while editing */ + short error_code; + } ip; } data; } MenuItem; @@ -241,6 +254,13 @@ MenuItem *menuitem_create_alpha (char *id, MenuEventFunc(*event_func), * MENUEVENT_UPDATE when user finishes the value (no immediate update). */ +MenuItem *menuitem_create_ip (char *id, MenuEventFunc(*event_func), + char *text, bool v6, char *value); +/* Creates an ip value box. can be either v4 or v6 + * Generated events: MENUEVENT_ENTER upon entering this item, + * MENUEVENT_UPDATE when user finishes the value (no immediate update). + */ + void menuitem_destroy (MenuItem *item); /* Deletes item from memory. * All allocated extra data (like strings) will be freed. @@ -248,7 +268,7 @@ void menuitem_destroy (MenuItem *item); static inline MenuItem *menuitem_get_parent (MenuItem *item) { - return item->parent; + return ((item != NULL) ? item->parent : NULL); } void menuitem_reset (MenuItem *item); @@ -271,7 +291,7 @@ void menuitem_update_screen (MenuItem *item, Screen *s); * Fills all widget attributes with the corrrect values. */ -MenuResult menuitem_process_input (MenuItem *item, MenuToken token, char * key); +MenuResult menuitem_process_input (MenuItem *item, MenuToken token, char * key, bool extended); /* Does something with the given input. * key is only used if token is MENUTOKEN_OTHER. */ diff --git a/server/menuscreens.c b/server/menuscreens.c index 77c3d5f..96e7c41 100644 --- a/server/menuscreens.c +++ b/server/menuscreens.c @@ -7,6 +7,8 @@ * * Copyright (c) 1999, William Ferrell, Scott Scriven * 2002, Joris Robijn + * 2004, F5 Networks, Inc. - IP-address input + * 2005, Peter Marschall - error checks, ... * * * Creates the server menu screen(s) and creates the menus that should be @@ -34,10 +36,15 @@ /* Next include files are needed for settings that we can modify */ #include "render.h" +/* uncomment this if you want a binary with test menus in it */ +#define TESTMENUS + char * menu_key; char * enter_key; char * up_key; char * down_key; +char * left_key; +char * right_key; Screen * menuscreen = NULL; MenuItem * active_menuitem = NULL; @@ -54,6 +61,8 @@ MenuEventFunc (brightness_handler); int menuscreens_init() { + char *tmp; + debug (RPT_DEBUG, "%s()", __FUNCTION__); /* Get keys from config file */ @@ -62,11 +71,25 @@ int menuscreens_init() up_key = strdup (config_get_string ("menu", "UpKey", 0, "Up")); down_key = strdup (config_get_string ("menu", "DownKey", 0, "Down")); + /* if the user has specified in the conf file a left and right key */ + left_key = right_key = NULL; + tmp = config_get_string ("menu", "LeftKey", 0, NULL); + if (tmp) + left_key = strdup(tmp); + tmp = config_get_string ("menu", "RightKey", 0, NULL); + if (tmp) + right_key = strdup(tmp); + + /* Now reserve keys */ input_reserve_key (menu_key, true, NULL); input_reserve_key (enter_key, false, NULL); input_reserve_key (up_key, false, NULL); input_reserve_key (down_key, false, NULL); + if (left_key) + input_reserve_key (left_key, false, NULL); + if (right_key) + input_reserve_key (right_key, false, NULL); /* Create screen */ menuscreen = screen_create ("_menu_screen", NULL); @@ -87,10 +110,9 @@ int menuscreens_shutdown() { debug (RPT_DEBUG, "%s()", __FUNCTION__ ); - if (!menuscreen) { - /* Program shutdown before completed startup */ + /* Program shutdown before completed startup */ + if (!menuscreen) return -1; - } /* Quit menu just to make sure */ menuscreen_switch_item (NULL); @@ -112,6 +134,10 @@ int menuscreens_shutdown() free (enter_key); free (up_key); free (down_key); + if (left_key) + free (left_key); + if (right_key) + free (right_key); return 0; } @@ -173,6 +199,7 @@ void menuscreen_switch_item (MenuItem * new_menuitem) if (!old_menuitem && !new_menuitem) { /* Nothing to be done */ } else if (old_menuitem && !new_menuitem) { + /* leave menu system */ menuscreen->priority = PRI_HIDDEN; } else if (!old_menuitem && new_menuitem) { /* Menu is becoming active */ @@ -209,6 +236,12 @@ void menuscreen_key_handler (char *key) else if (strcmp (key, down_key) == 0) { token = MENUTOKEN_DOWN; } + else if (left_key && strcmp (key, left_key) == 0) { + token = MENUTOKEN_LEFT; + } + else if (right_key && strcmp (key, right_key) == 0) { + token = MENUTOKEN_RIGHT; + } else { token = MENUTOKEN_OTHER; } @@ -220,11 +253,12 @@ void menuscreen_key_handler (char *key) return; } - res = menuitem_process_input (active_menuitem, token, key); + res = menuitem_process_input (active_menuitem, token, key, + ((left_key || right_key) ? 1 : 0)); switch (res) { case MENURESULT_ERROR: - report (RPT_ERR, "%s: Error from menu_process_input", __FUNCTION__); + report (RPT_ERR, "%s: Error from menuitem_process_input", __FUNCTION__); break; case MENURESULT_NONE: if (active_menuitem) { @@ -236,7 +270,7 @@ void menuscreen_key_handler (char *key) case MENURESULT_ENTER: /* Enter the selected menuitem * Note: this is not for checkboxes etc that don't have their - * own screen. The menu_process_input function should do + * own screen. The menuitem_process_input function should do * things like toggling checkboxes ! */ debug (RPT_DEBUG, "%s: Entering subitem", __FUNCTION__); @@ -261,8 +295,10 @@ void menuscreen_create_menu () MenuItem * slider; Driver * driver; +#ifdef TESTMENUS MenuItem * test_item; Menu * test_menu; +#endif /*TESTMENUS*/ debug (RPT_DEBUG, "%s()", __FUNCTION__); @@ -271,8 +307,10 @@ void menuscreen_create_menu () options_menu = menu_create ("options", NULL, "Options", NULL); menu_add_item (main_menu, options_menu); +#ifdef TESTMENUS screens_menu = menu_create ("screens", NULL, "Screens", NULL); menu_add_item (main_menu, screens_menu); +#endif /*TESTMENUS*/ checkbox = menuitem_create_checkbox ("heartbeat", heartbeat_handler, "Heartbeat", true, heartbeat); menu_add_item (options_menu, checkbox); @@ -308,6 +346,8 @@ void menuscreen_create_menu () } } } + +#ifdef TESTMENUS test_menu = menu_create ("test", NULL, "Test menu", NULL); menu_add_item (main_menu, test_menu); @@ -340,6 +380,12 @@ void menuscreen_create_menu () menu_add_item (test_menu, test_item); test_item = menuitem_create_alpha ("", NULL, "Alpha, caps only", 0, 3, 12, true, false, false, "-", "LCDPROC"); menu_add_item (test_menu, test_item); + + test_item = menuitem_create_ip ("", NULL, "IPv4", 0, "192.168.1.245"); + menu_add_item (test_menu, test_item); + test_item = menuitem_create_ip ("", NULL, "IPv6", 1, ":::ffff:ffff:ffff:ffff:ffff"); + menu_add_item (test_menu, test_item); +#endif /*TESTMENUS*/ } MenuEventFunc (heartbeat_handler) @@ -381,13 +427,14 @@ MenuEventFunc (contrast_handler) * We need to check the menu association to see which driver. */ if (event == MENUEVENT_MINUS || event == MENUEVENT_PLUS) { - /* Determinte the driver */ + /* Determine the driver */ Driver * driver = item->parent->data.menu.association; - driver->set_contrast (driver, item->data.slider.value); - //item->data.slider.value = driver->get_contrast (driver); - report (RPT_INFO, "Menu: set contrast of [%.40s] to %d", - item->data.checkbox.value); + if (driver != NULL) { + driver->set_contrast (driver, item->data.slider.value); + report (RPT_INFO, "Menu: set contrast of [%.40s] to %d", + driver->name, item->data.slider.value); + } } return 0; } @@ -398,18 +445,20 @@ MenuEventFunc (brightness_handler) ((item != NULL) ? item->id : "(null)"), event); /* This function can be called by one of several drivers that - * support contrast ! + * support brightness ! * We need to check the menu association to see which driver. */ if (event == MENUEVENT_MINUS || event == MENUEVENT_PLUS) { - /* Determinte the driver */ + /* Determine the driver */ Driver * driver = item->parent->data.menu.association; - if ( strcmp (item->id, "onbrightness") == 0) { - driver->set_brightness (driver, BACKLIGHT_ON, item->data.slider.value); - } - else if ( strcmp (item->id, "offbrightness") == 0) { - driver->set_brightness (driver, BACKLIGHT_OFF, item->data.slider.value); + if (driver != NULL) { + if ( strcmp (item->id, "onbrightness") == 0) { + driver->set_brightness (driver, BACKLIGHT_ON, item->data.slider.value); + } + else if ( strcmp (item->id, "offbrightness") == 0) { + driver->set_brightness (driver, BACKLIGHT_OFF, item->data.slider.value); + } } } return 0; @@ -453,8 +502,6 @@ menuscreen_add_screen (Screen * s) void menuscreen_remove_screen (Screen * s) { - Menu * m; - debug (RPT_DEBUG, "%s( s=[%s] )", __FUNCTION__, (s != NULL) ? s->id : "(NULL)"); @@ -462,9 +509,12 @@ menuscreen_remove_screen (Screen * s) if ((s == NULL) || (s == menuscreen)) return; - m = menu_find_item (screens_menu, s->id, false); - menu_remove_item (screens_menu, m); - menuitem_destroy (m); + if (screens_menu) { + Menu * m = menu_find_item (screens_menu, s->id, false); + + menu_remove_item (screens_menu, m); + menuitem_destroy (m); + } } diff --git a/server/sock.c b/server/sock.c index 3c73879..3c85f98 100644 --- a/server/sock.c +++ b/server/sock.c @@ -7,6 +7,8 @@ * * Copyright (c) 1999, William Ferrell, Scott Scriven * 2003, Benjamin Tse (blt@ieee.org) - Winsock port + * 2004, F5 Networks, Inc. - IP-address input + * 2005, Peter Marschall - error checks, ... * * LCDproc sockets code... * @@ -432,3 +434,28 @@ sock_read_from_client(struct ClientSocketMap* clientSocketMap) } return nbytes; } + + +/* return 0 if addr is valid ipv4 */ +int verify_ipv4(const char *addr) +{ + int rsts; + struct in_addr a; + rsts = inet_pton(AF_INET, addr, &a); + /* inet_pton returns positive value if it worked */ + if (rsts <=0) + return -1; + return 0; +} + +/* return 0 if addr is valid ipv4 */ +int verify_ipv6(const char *addr) +{ + int rsts; + struct in6_addr a; + rsts = inet_pton(AF_INET, addr, &a); + /* inet_pton returns positive value if it worked */ + if (rsts <=0) + return -1; + return 0; +} diff --git a/server/sock.h b/server/sock.h index a697675..1d1f703 100644 --- a/server/sock.h +++ b/server/sock.h @@ -6,6 +6,7 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven + * 2004, F5 Networks, Inc. - IP-address verification * */ @@ -21,5 +22,7 @@ int sock_init(char* bind_addr, int bind_port); int sock_shutdown(); int sock_create_inet_socket(char* bind_addr, unsigned int port); int sock_poll_clients(); +int verify_ipv4(const char *addr); +int verify_ipv6(const char *addr); #endif