/* * menu_commands.c * This file is part of LCDd, the lcdproc server. * * This file is released under the GNU General Public License. Refer to the * COPYING file distributed with this package. * * 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. * The functions here are to be called only from parse.c's interpreter. * * The client's available function set is defined here, as is the syntax * for each command. * * This particular file defines actions concerning client supplied menus. * */ #include #include #include #include #include #include #include #include #include "shared/report.h" #include "shared/sockets.h" #include "menu.h" #include "menuitem.h" #include "menuscreens.h" #include "menu_commands.h" #include "client.h" /* Local functions */ MenuEventFunc(menu_commands_handler); int set_predecessor(MenuItem *item, char *itemid, Client *client); int set_successor(MenuItem *item, char *itemid, Client *client); /** small utility for debug output of command line. */ static char *argv2string(int argc, char **argv) { char *rtn = NULL; int len; int i; for (i = len = 0; i < argc; ++i) len += strlen(argv[i]) + 1; rtn = malloc(len + 1); rtn[0] = '\0'; for (i = len = 0; i < argc; ++i) { strcat(rtn, argv[i]); strcat(rtn, " "); } return rtn; } /************************************************************************* * menu_add_item_func * * Adds an item to a menu * * Usage: menu_add_item [] * You should use "" as id for the client's main menu. This menu will be * created automatically when you add an item to it the first time. * You (currently?) cannot create a menu in the main level yourself. * The names you use for items should be unique for your client. * The text is the visible text for the item. * * The following types are available: * - menu * - action * - checkbox * - ring (a kind of listbox of one line) * - slider * - numeric * - alpha * - ip */ int menu_add_item_func (Client * c, int argc, char **argv) { char * menu_id; char * item_id; char * text = NULL; Menu * menu = NULL; MenuItem * item; MenuItemType itemtype; char** argv_set = NULL; debug (RPT_DEBUG, "%s( Client [%d], %s, %s )", __FUNCTION__, c->sock, argv[1], argv[2]); if (!c->ack) return 1; if (!c->name) { sock_send_error(c->sock, "You need to give your client a name first\n"); return 0; } if ((argc < 4 )) { sock_send_error(c->sock, "Usage: menu_add_item []\n"); return 0; } menu_id = argv[1]; item_id = argv[2]; /* Does the client have a menu already ? */ if (!c->menu) { /* We need to create it */ report( RPT_INFO, "Client [%d] is using the menu", c->sock ); c->menu = menu_create ("_client_menu_", menu_commands_handler, c->name, c); menu_add_item (main_menu, c->menu); } if ( menu_id[0] == 0 ) { /* No menu specified = client's main menu */ menu = c->menu; } else { /* A specified menu */ menu = menu_find_item (c->menu, menu_id, true); } if (!menu) { sock_send_error(c->sock, "Cannot find menu id\n"); return 0; } item = menu_find_item (c->menu, item_id, true); if (item) { sock_send_error(c->sock, "Item id already in use\n"); return 0; } /* Find menuitem type */ itemtype = menuitem_typename_to_type (argv[3]); if (itemtype == -1) { sock_send_error(c->sock, "Invalid menuitem type\n"); return 0; } /* Is a text given (options don't count)? */ if (argc >= 5 && argv[4][0] != '-') { text = argv[4]; } else { text = ""; } /* Create the menuitem */ switch (itemtype) { case MENUITEM_MENU: item = menu_create (item_id, menu_commands_handler, text, c); break; case MENUITEM_ACTION: item = menuitem_create_action (item_id, menu_commands_handler, text, c, MENURESULT_NONE); break; case MENUITEM_CHECKBOX: item = menuitem_create_checkbox (item_id, menu_commands_handler, text, c, false, false); break; case MENUITEM_RING: item = menuitem_create_ring (item_id, menu_commands_handler, text, c, "", 0); break; case MENUITEM_SLIDER: item = menuitem_create_slider (item_id, menu_commands_handler, text, c, "", "", 0, 100, 1, 25); break; case MENUITEM_NUMERIC: item = menuitem_create_numeric (item_id, menu_commands_handler, text, c, 0, 100, 0); break; case MENUITEM_ALPHA: item = menuitem_create_alpha (item_id, menu_commands_handler, text, c, 0, 0, 10, true, false, true, "-./", ""); break; case MENUITEM_IP: item = menuitem_create_ip (item_id, menu_commands_handler, text, c, 0, "192.168.1.245"); break; default: assert(!"unexpected menuitem type"); } menu_add_item (menu, item); menuscreen_inform_item_modified (menu); sock_send_string(c->sock, "success\n"); /* are there any options (starting with '-')? * - create a temporary argv for menu_set_item() call */ if (argc > 5 || argv[4][0] == '-') { // menu_add_item [] // menu_set_item {