1 /* 2 * ipmi_cmdlang.h 3 * 4 * A command interpreter for OpenIPMI 5 * 6 * Author: MontaVista Software, Inc. 7 * Corey Minyard <minyard@mvista.com> 8 * source@mvista.com 9 * 10 * Copyright 2004 MontaVista Software Inc. 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU Lesser General Public License 14 * as published by the Free Software Foundation; either version 2 of 15 * the License, or (at your option) any later version. 16 * 17 * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * You should have received a copy of the GNU Lesser General Public 30 * License along with this program; if not, write to the Free 31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 32 */ 33 34 #ifndef OPENIPMI_CMDLANG_H 35 #define OPENIPMI_CMDLANG_H 36 37 #include <OpenIPMI/selector.h> 38 #include <OpenIPMI/ipmi_bits.h> 39 #include <OpenIPMI/ipmi_types.h> 40 #include <OpenIPMI/ipmi_addr.h> 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 /* Forward declaration */ 47 typedef struct ipmi_cmd_info_s ipmi_cmd_info_t; 48 49 /* 50 * A structure that must be passed into the command parser; it has 51 * general information about the how the parser should handle thing 52 * and generate its output. 53 */ 54 typedef struct ipmi_cmdlang_s ipmi_cmdlang_t; 55 56 /* Output is done in name:value pairs. If you don't have a value, 57 pass in NULL. */ 58 typedef void (*cmd_out_cb)(ipmi_cmdlang_t *info, 59 const char *name, 60 const char *value); 61 typedef void (*cmd_out_b_cb)(ipmi_cmdlang_t *info, 62 const char *name, 63 const char *value, 64 unsigned int len); 65 66 /* Command-specific info. */ 67 typedef void (*cmd_info_cb)(ipmi_cmdlang_t *info); 68 69 /* The user provides one of these when they call the command language 70 interpreter. It is used to report errors and generate output. */ 71 struct ipmi_cmdlang_s 72 { 73 cmd_out_cb out; /* Generate output with this. */ 74 cmd_info_cb down; /* Go down a level (new indention or 75 nesting) */ 76 cmd_info_cb up; /* Go up a level (leave the current 77 indention or nesting) */ 78 cmd_info_cb done; /* Called when the command is done. If 79 there was an error, the err value in 80 info will be non-null. */ 81 cmd_out_b_cb out_binary; /* Generate binary output with this. */ 82 cmd_out_b_cb out_unicode; /* Generate unicode output with this. */ 83 84 /* OS handler to use for the commands. Note that this may be set 85 to NULL if not required, don't depend on them except in certain 86 circumstances. */ 87 os_handler_t *os_hnd; 88 89 /* Tells if we are outputting help. */ 90 int help; 91 92 /* 93 * Error reporting 94 */ 95 int err; /* If non-zero, the errno code of the error 96 that occurred. */ 97 98 /* If non-NULL, an error occurred and this is the error info. If 99 the error string is dynamically allocated (and thus should be 100 freed), errstr_dynalloc should be set to true. */ 101 char *errstr; 102 int errstr_dynalloc; 103 104 /* If an error occurs, this will be set to the object name that 105 was dealing with the error. It may be an empty string if 106 no object is handling the error. This must be pre-allocated 107 and the length set properly. */ 108 char *objstr; 109 int objstr_len; 110 111 /* This is the location of an error. */ 112 char *location; 113 114 115 void *user_data; /* User data for anything the user wants */ 116 }; 117 118 /* Parse and handle the given command string. This always calls the 119 done function when complete. */ 120 void ipmi_cmdlang_handle(ipmi_cmdlang_t *cmdlang, char *str); 121 122 /* If the event info is true, then the system will output object 123 information with each add or change event. */ 124 void ipmi_cmdlang_set_evinfo(int evinfo); 125 int ipmi_cmdlang_get_evinfo(void); 126 127 /* 128 * This is used to hold command information. 129 */ 130 typedef struct ipmi_cmdlang_cmd_s ipmi_cmdlang_cmd_t; 131 132 typedef void (*ipmi_cmdlang_handler_cb)(ipmi_cmd_info_t *cmd_info); 133 typedef void (*ipmi_help_finisher_cb)(ipmi_cmdlang_t *cmdlang); 134 135 /* Register a command as a subcommand of the parent, or into the main 136 command list if parent is NULL. The command will have the given 137 name and help text. When the command is executed, the handler will 138 be called with a cmd_info structure passed in. The handler_data parm 139 passed in below will be in the "handler_data" field of the cmd_info 140 structure. Note that if you are attaching subcommands to this 141 command, you should pass in a NULL handler. Returns an error value. */ 142 int ipmi_cmdlang_reg_cmd(ipmi_cmdlang_cmd_t *parent, 143 char *name, 144 char *help, 145 ipmi_cmdlang_handler_cb handler, 146 void *handler_data, 147 ipmi_help_finisher_cb help_finish, 148 ipmi_cmdlang_cmd_t **rv); 149 150 /* Register a table of commands. */ 151 typedef struct ipmi_cmdlang_init_s 152 { 153 char *name; 154 ipmi_cmdlang_cmd_t **parent; 155 char *help; 156 ipmi_cmdlang_handler_cb handler; 157 void *cb_data; 158 ipmi_cmdlang_cmd_t **new_val; 159 ipmi_help_finisher_cb help_finish; 160 } ipmi_cmdlang_init_t; 161 int ipmi_cmdlang_reg_table(ipmi_cmdlang_init_t *table, int len); 162 163 164 /* The following functions handle parsing various OpenIPMI objects 165 according to the naming standard. If you pass it into a command 166 registration as the handler and pass your function as the 167 handler_data, your function will be called with the specified 168 object. The specific function type is given in the individual 169 functions. The cmd_info will be passed in as the cb_data. 170 171 For instance, if you have a command that take an entity argument, 172 then you could write: 173 void ent_cmd_hnd(ipmi_entity_t *entity, void *cb_data) 174 { 175 ipmi_cmd_info_t *cmd_info = cb_data; 176 } 177 178 rv = ipmi_cmdlang_reg_cmd(parent, "ent_cmd", "The ent command", 179 ipmi_cmdlang_entity_handler, ent_cmd_hnd, 180 &cmd); 181 */ 182 183 /* ipmi_domain_ptr_cb */ 184 void ipmi_cmdlang_domain_handler(ipmi_cmd_info_t *cmd_info); 185 186 /* ipmi_entity_ptr_cb */ 187 void ipmi_cmdlang_entity_handler(ipmi_cmd_info_t *cmd_info); 188 189 /* ipmi_sensor_ptr_cb */ 190 void ipmi_cmdlang_sensor_handler(ipmi_cmd_info_t *cmd_info); 191 192 /* ipmi_control_ptr_cb */ 193 void ipmi_cmdlang_control_handler(ipmi_cmd_info_t *cmd_info); 194 195 /* ipmi_mc_ptr_cb */ 196 void ipmi_cmdlang_mc_handler(ipmi_cmd_info_t *cmd_info); 197 198 /* ipmi_connection_ptr_cb */ 199 void ipmi_cmdlang_connection_handler(ipmi_cmd_info_t *cmd_info); 200 201 /* ipmi_pet_ptr_cb */ 202 void ipmi_cmdlang_pet_handler(ipmi_cmd_info_t *cmd_info); 203 204 /* ipmi_lanparm_ptr_cb */ 205 void ipmi_cmdlang_lanparm_handler(ipmi_cmd_info_t *cmd_info); 206 207 /* ipmi_solparm_ptr_cb */ 208 void ipmi_cmdlang_solparm_handler(ipmi_cmd_info_t *cmd_info); 209 210 /* ipmi_fru_ptr_cb */ 211 void ipmi_cmdlang_fru_handler(ipmi_cmd_info_t *cmd_info); 212 213 /* ipmi_pef_ptr_cb */ 214 void ipmi_cmdlang_pef_handler(ipmi_cmd_info_t *cmd_info); 215 216 217 /* All output from the command language is in name/value pairs. The 218 value field may be NULL. */ 219 void ipmi_cmdlang_out(ipmi_cmd_info_t *info, 220 const char *name, 221 const char *value); 222 void ipmi_cmdlang_out_int(ipmi_cmd_info_t *info, 223 const char *name, 224 int value); 225 void ipmi_cmdlang_out_double(ipmi_cmd_info_t *info, 226 const char *name, 227 double value); 228 void ipmi_cmdlang_out_hex(ipmi_cmd_info_t *info, 229 const char *name, 230 int value); 231 void ipmi_cmdlang_out_long(ipmi_cmd_info_t *info, 232 const char *name, 233 long value); 234 void ipmi_cmdlang_out_binary(ipmi_cmd_info_t *info, 235 const char *name, 236 const char *value, 237 unsigned int len); 238 void ipmi_cmdlang_out_unicode(ipmi_cmd_info_t *info, 239 const char *name, 240 const char *value, 241 unsigned int len); 242 void ipmi_cmdlang_out_type(ipmi_cmd_info_t *info, 243 char *name, 244 enum ipmi_str_type_e type, 245 const char *value, 246 unsigned int len); 247 void ipmi_cmdlang_out_ip(ipmi_cmd_info_t *info, 248 const char *name, 249 struct in_addr *ip_addr); 250 void ipmi_cmdlang_out_mac(ipmi_cmd_info_t *info, 251 const char *name, 252 unsigned char mac_addr[6]); 253 void ipmi_cmdlang_out_bool(ipmi_cmd_info_t *info, 254 const char *name, 255 int value); 256 void ipmi_cmdlang_out_time(ipmi_cmd_info_t *info, 257 const char *name, 258 ipmi_time_t value); 259 void ipmi_cmdlang_out_timeout(ipmi_cmd_info_t *info, 260 const char *name, 261 ipmi_timeout_t value); 262 263 /* Generate info for an event. */ 264 void ipmi_cmdlang_event_out(ipmi_event_t *event, 265 ipmi_cmd_info_t *cmd_info); 266 267 /* The output from the command language is done at a nesting level. 268 When you start outputting data for a new thing, you should "down" 269 to create a new nesting level. When you are done, you should 270 "up". */ 271 void ipmi_cmdlang_down(ipmi_cmd_info_t *info); 272 void ipmi_cmdlang_up(ipmi_cmd_info_t *info); 273 274 /* A cmd info structure is refcounted, if you save a pointer to it you 275 must "get" it. When you are done, you must "put" it. It will be 276 destroyed (and the done routine called) after the last user puts it. */ 277 void ipmi_cmdlang_cmd_info_get(ipmi_cmd_info_t *info); 278 void ipmi_cmdlang_cmd_info_put(ipmi_cmd_info_t *info); 279 280 /* Helper functions */ 281 void ipmi_cmdlang_get_int(char *str, int *val, ipmi_cmd_info_t *info); 282 void ipmi_cmdlang_get_double(char *str, double *val, ipmi_cmd_info_t *info); 283 void ipmi_cmdlang_get_uchar(char *str, unsigned char *val, 284 ipmi_cmd_info_t *info); 285 void ipmi_cmdlang_get_user(char *str, int *val, ipmi_cmd_info_t *info); 286 void ipmi_cmdlang_get_time(char *str, ipmi_time_t *val, ipmi_cmd_info_t *info); 287 void ipmi_cmdlang_get_timeout(char *str, ipmi_timeout_t *val, 288 ipmi_cmd_info_t *info); 289 void ipmi_cmdlang_get_bool(char *str, int *val, ipmi_cmd_info_t *info); 290 void ipmi_cmdlang_get_ip(char *str, struct in_addr *val, 291 ipmi_cmd_info_t *info); 292 void ipmi_cmdlang_get_mac(char *str, unsigned char val[6], 293 ipmi_cmd_info_t *info); 294 void ipmi_cmdlang_get_color(char *str, int *val, ipmi_cmd_info_t *info); 295 void ipmi_cmdlang_get_threshold_ev(char *str, 296 enum ipmi_thresh_e *rthresh, 297 enum ipmi_event_value_dir_e *rvalue_dir, 298 enum ipmi_event_dir_e *rdir, 299 ipmi_cmd_info_t *info); 300 void ipmi_cmdlang_get_discrete_ev(char *str, 301 int *roffset, 302 enum ipmi_event_dir_e *rdir, 303 ipmi_cmd_info_t *info); 304 void ipmi_cmdlang_get_threshold(char *str, 305 enum ipmi_thresh_e *rthresh, 306 ipmi_cmd_info_t *info); 307 308 /* Call these to initialize and setup the command interpreter. init 309 should be called after the IPMI library proper is initialized, but 310 before using it. */ 311 int ipmi_cmdlang_init(os_handler_t *os_hnd); 312 void ipmi_cmdlang_cleanup(void); 313 314 315 /* Allocate a cmd info structure that can be used to generate 316 information to an event. Make sure to call the put function when 317 all the data has been output. Note that the refcounts work like 318 normal, you get it at one, when it goes to zero the structure will 319 be returned. */ 320 ipmi_cmd_info_t *ipmi_cmdlang_alloc_event_info(void); 321 322 typedef struct ipmi_cmdlang_event_s ipmi_cmdlang_event_t; 323 324 /* Move to the first field. */ 325 void ipmi_cmdlang_event_restart(ipmi_cmdlang_event_t *event); 326 327 enum ipmi_cmdlang_out_types { 328 IPMI_CMDLANG_STRING, 329 IPMI_CMDLANG_BINARY, 330 IPMI_CMDLANG_UNICODE 331 }; 332 333 /* Returns true if successful, false if no more fields left. */ 334 int ipmi_cmdlang_event_next_field(ipmi_cmdlang_event_t *event, 335 unsigned int *level, 336 enum ipmi_cmdlang_out_types *type, 337 char **name, 338 unsigned int *len, 339 char **value); 340 341 /* Supplied by the user, used to report global errors (ones that don't 342 deal with a specific command invocation). The objstr is the name 343 of the object dealing with the error (like the domain name, entity 344 name, etc) or NULL if none. The location is the file and procedure 345 where the error occurred. The errstr is a descriptive string and 346 errval is an IPMI error value to be printed. */ 347 void ipmi_cmdlang_global_err(char *objstr, 348 char *location, 349 char *errstr, 350 int errval); 351 352 /* Supplied by the user to report events. */ 353 void ipmi_cmdlang_report_event(ipmi_cmdlang_event_t *event); 354 355 /* In callbacks, you must use these to lock the cmd_info structure. */ 356 void ipmi_cmdlang_lock(ipmi_cmd_info_t *info); 357 void ipmi_cmdlang_unlock(ipmi_cmd_info_t *info); 358 359 int ipmi_cmdlang_get_argc(ipmi_cmd_info_t *info); 360 char **ipmi_cmdlang_get_argv(ipmi_cmd_info_t *info); 361 int ipmi_cmdlang_get_curr_arg(ipmi_cmd_info_t *info); 362 ipmi_cmdlang_t *ipmi_cmdinfo_get_cmdlang(ipmi_cmd_info_t *info); 363 364 #ifdef __cplusplus 365 } 366 #endif 367 368 #endif /* OPENIPMI_CMDLANG_H */ 369