1 /*
2 * cmdlang.c
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
35 #include <errno.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <stdint.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <netdb.h>
44 #include <OpenIPMI/ipmiif.h>
45 #include <OpenIPMI/ipmi_cmdlang.h>
46 #include <OpenIPMI/ipmi_pet.h>
47 #include <OpenIPMI/ipmi_lanparm.h>
48 #include <OpenIPMI/ipmi_solparm.h>
49 #include <OpenIPMI/ipmi_fru.h>
50 #include <OpenIPMI/ipmi_pef.h>
51 #include <OpenIPMI/ipmi_auth.h>
52 #include <OpenIPMI/ipmi_debug.h>
53 #include <OpenIPMI/ipmi_mc.h>
54
55 /* Internal includes, do not use in your programs */
56 #include <OpenIPMI/internal/ipmi_locks.h>
57 #include <OpenIPMI/internal/ipmi_malloc.h>
58
59 /*
60 * This is the value passed to a command handler.
61 */
62 struct ipmi_cmd_info_s
63 {
64 void *handler_data; /* From cb_data in the cmd reg */
65 int curr_arg; /* Argument you should start at */
66 int argc; /* Total number of arguments */
67 char **argv; /* The arguments */
68
69 /* Only allow one writer at a time */
70 ipmi_lock_t *lock;
71
72 /* The cmdlang structure the user passed in. Use this for output
73 and error reporting. */
74 ipmi_cmdlang_t *cmdlang;
75
76 /* The matching cmd structure for the command being executed. May
77 be NULL if no command is being processed. */
78 ipmi_cmdlang_cmd_t *cmd;
79
80 /* Refcount for the structure. */
81 unsigned int usecount;
82
83 /* For use by the user commands */
84 void *data;
85
86 /* Used to know if the command generated output. */
87 int did_output;
88 };
89
90
91 struct ipmi_cmdlang_cmd_s
92 {
93 char *name;
94 char *help;
95 ipmi_help_finisher_cb help_finish;
96
97 /* Only one of handler or subcmds may be non-NULL. */
98 ipmi_cmdlang_handler_cb handler;
99 ipmi_cmdlang_cmd_t *subcmds;
100
101 void *handler_data;
102
103 /* Used for a linked list. */
104 ipmi_cmdlang_cmd_t *next;
105 };
106
107 static os_handler_t *cmdlang_os_hnd;
108
109 /* Parse a string of the form [domain][(class)][.obj] and return each
110 of the strings in the given string pointers. */
111 static int
parse_ipmi_objstr(char * str,char ** domain,char ** class,char ** obj)112 parse_ipmi_objstr(char *str,
113 char **domain,
114 char **class,
115 char **obj)
116 {
117 int i;
118 char *class_start = NULL, *class_end = NULL;
119
120 for (i=0; str[i]; i++) {
121 if (str[i] == '(') {
122 if (class_start)
123 /* Only one '(' allowed. */
124 return EINVAL;
125 class_start = str + i;
126 } else if (str[i] == ')') {
127 if (class_start) {
128 /* a ')' only means something after a '('. */
129 class_end = str + i;
130 i++;
131 break;
132 }
133 }
134 }
135
136 if (str[i]) {
137 if (str[i] != '.')
138 return EINVAL;
139 }
140
141 if (class_start) {
142 if (!class_end)
143 /* If class starts, must see the end paren. */
144 return EINVAL;
145 *class_start = '\0';
146 *class_end = '\0';
147 *class = class_start + 1;
148 } else {
149 *class = NULL;
150 }
151
152 if (strlen(str) == 0)
153 *domain = NULL;
154 else
155 *domain = str;
156
157 if (str[i])
158 *obj = str + i + 1;
159 else
160 *obj = NULL;
161
162 return 0;
163 }
164
165
166 /*
167 * Handling for iterating domains.
168 */
169
170 typedef struct domain_iter_info_s
171 {
172 char *cmpstr;
173 ipmi_domain_ptr_cb handler;
174 void *cb_data;
175 ipmi_cmd_info_t *cmd_info;
176 } domain_iter_info_t;
177
178 static void
for_each_domain_handler(ipmi_domain_t * domain,void * cb_data)179 for_each_domain_handler(ipmi_domain_t *domain, void *cb_data)
180 {
181 domain_iter_info_t *info = cb_data;
182 ipmi_cmd_info_t *cmd_info = info->cmd_info;
183 char domain_name[IPMI_DOMAIN_NAME_LEN];
184
185 if (cmd_info->cmdlang->err)
186 return;
187
188 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
189 if ((!info->cmpstr) || (strcmp(info->cmpstr, domain_name) == 0))
190 info->handler(domain, info->cb_data);
191 }
192
193 static void
for_each_domain(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_domain_ptr_cb handler,void * cb_data)194 for_each_domain(ipmi_cmd_info_t *cmd_info,
195 char *domain,
196 char *class,
197 char *obj,
198 ipmi_domain_ptr_cb handler,
199 void *cb_data)
200 {
201 domain_iter_info_t info;
202
203 if (class || obj) {
204 cmd_info->cmdlang->errstr = "Invalid domain";
205 cmd_info->cmdlang->err = EINVAL;
206 cmd_info->cmdlang->location = "cmdlang.c(for_each_domain)";
207 return;
208 }
209
210 info.cmpstr = domain;
211 info.handler = handler;
212 info.cb_data = cb_data;
213 info.cmd_info = cmd_info;
214 ipmi_domain_iterate_domains(for_each_domain_handler, &info);
215 }
216
217 void
ipmi_cmdlang_domain_handler(ipmi_cmd_info_t * cmd_info)218 ipmi_cmdlang_domain_handler(ipmi_cmd_info_t *cmd_info)
219 {
220 char *domain, *class, *obj;
221 int rv;
222
223 if (cmd_info->curr_arg >= cmd_info->argc) {
224 domain = class = obj = NULL;
225 } else {
226 rv = parse_ipmi_objstr(cmd_info->argv[cmd_info->curr_arg],
227 &domain, &class, &obj);
228 if (rv) {
229 cmd_info->cmdlang->errstr = "Invalid domain";
230 cmd_info->cmdlang->err = rv;
231 cmd_info->cmdlang->location
232 = "cmdlang.c(ipmi_cmdlang_domain_handler)";
233 return;
234 }
235 cmd_info->curr_arg++;
236 }
237
238 for_each_domain(cmd_info, domain, class, obj,
239 cmd_info->handler_data, cmd_info);
240 }
241
242
243 /*
244 * Handling for iterating PETs.
245 */
246 typedef struct pet_iter_info_s
247 {
248 char *cmdstr;
249 ipmi_pet_ptr_cb handler;
250 void *cb_data;
251 ipmi_cmd_info_t *cmd_info;
252 } pet_iter_info_t;
253
254 static void
for_each_pet_handler(ipmi_pet_t * pet,void * cb_data)255 for_each_pet_handler(ipmi_pet_t *pet, void *cb_data)
256 {
257 pet_iter_info_t *info = cb_data;
258 ipmi_cmd_info_t *cmd_info = info->cmd_info;
259 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
260 char name[IPMI_PET_NAME_LEN];
261 char *c;
262
263 if (cmdlang->err)
264 return;
265
266 ipmi_pet_get_name(pet, name, sizeof(name));
267
268 c = strrchr(name, '.');
269 if (!c)
270 goto out_err;
271 c++;
272 if ((! info->cmdstr) || (strcmp(info->cmdstr, c) == 0))
273 info->handler(pet, info->cb_data);
274 return;
275
276 out_err:
277 ipmi_cmdlang_global_err(name,
278 "cmdlang.c(for_each_pet_handler)",
279 "Bad PET name", EINVAL);
280 }
281
282 static void
for_each_pet_domain_handler(ipmi_domain_t * domain,void * cb_data)283 for_each_pet_domain_handler(ipmi_domain_t *domain, void *cb_data)
284 {
285 ipmi_pet_iterate_pets(domain, for_each_pet_handler, cb_data);
286 }
287
288 static void
for_each_pet(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_pet_ptr_cb handler,void * cb_data)289 for_each_pet(ipmi_cmd_info_t *cmd_info,
290 char *domain,
291 char *class,
292 char *obj,
293 ipmi_pet_ptr_cb handler,
294 void *cb_data)
295 {
296 pet_iter_info_t info;
297
298 if (class) {
299 cmd_info->cmdlang->errstr = "Invalid PET";
300 cmd_info->cmdlang->err = EINVAL;
301 cmd_info->cmdlang->location = "cmdlang.c(for_each_pet)";
302 return;
303 }
304
305 info.handler = handler;
306 info.cb_data = cb_data;
307 info.cmd_info = cmd_info;
308 info.cmdstr = obj;
309 for_each_domain(cmd_info, domain, NULL, NULL,
310 for_each_pet_domain_handler, &info);
311 }
312
313 void
ipmi_cmdlang_pet_handler(ipmi_cmd_info_t * cmd_info)314 ipmi_cmdlang_pet_handler(ipmi_cmd_info_t *cmd_info)
315 {
316 char *domain, *class, *obj;
317
318 if (cmd_info->curr_arg >= cmd_info->argc) {
319 domain = class = obj = NULL;
320 } else {
321 domain = cmd_info->argv[cmd_info->curr_arg];
322 class = NULL;
323 obj = strrchr(domain, '.');
324 if (!obj) {
325 cmd_info->cmdlang->errstr = "Invalid PET";
326 cmd_info->cmdlang->err = EINVAL;
327 cmd_info->cmdlang->location
328 = "cmdlang.c(ipmi_cmdlang_pet_handler)";
329 return;
330 }
331 *obj = '\0';
332 obj++;
333 cmd_info->curr_arg++;
334 }
335
336 for_each_pet(cmd_info, domain, class, obj, cmd_info->handler_data,
337 cmd_info);
338 }
339
340 /*
341 * Handling for iterating LANPARMs.
342 */
343 typedef struct lanparm_iter_info_s
344 {
345 char *cmdstr;
346 ipmi_lanparm_ptr_cb handler;
347 void *cb_data;
348 ipmi_cmd_info_t *cmd_info;
349 } lanparm_iter_info_t;
350
351 static void
for_each_lanparm_handler(ipmi_lanparm_t * lanparm,void * cb_data)352 for_each_lanparm_handler(ipmi_lanparm_t *lanparm, void *cb_data)
353 {
354 lanparm_iter_info_t *info = cb_data;
355 ipmi_cmd_info_t *cmd_info = info->cmd_info;
356 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
357 char name[IPMI_LANPARM_NAME_LEN];
358 char *c;
359
360 if (cmdlang->err)
361 return;
362
363 ipmi_lanparm_get_name(lanparm, name, sizeof(name));
364
365 c = strrchr(name, '.');
366 if (!c)
367 goto out_err;
368 c++;
369 if ((! info->cmdstr) || (strcmp(info->cmdstr, c) == 0))
370 info->handler(lanparm, info->cb_data);
371 return;
372
373 out_err:
374 ipmi_cmdlang_global_err(name,
375 "cmdlang.c(for_each_lanparm_handler)",
376 "Bad LANPARM name", EINVAL);
377 }
378
379 static void
for_each_lanparm_domain_handler(ipmi_domain_t * domain,void * cb_data)380 for_each_lanparm_domain_handler(ipmi_domain_t *domain, void *cb_data)
381 {
382 ipmi_lanparm_iterate_lanparms(domain, for_each_lanparm_handler, cb_data);
383 }
384
385 static void
for_each_lanparm(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_lanparm_ptr_cb handler,void * cb_data)386 for_each_lanparm(ipmi_cmd_info_t *cmd_info,
387 char *domain,
388 char *class,
389 char *obj,
390 ipmi_lanparm_ptr_cb handler,
391 void *cb_data)
392 {
393 lanparm_iter_info_t info;
394
395 if (class) {
396 cmd_info->cmdlang->errstr = "Invalid LANPARM";
397 cmd_info->cmdlang->err = EINVAL;
398 cmd_info->cmdlang->location = "cmdlang.c(for_each_lanparm)";
399 return;
400 }
401
402 info.handler = handler;
403 info.cb_data = cb_data;
404 info.cmd_info = cmd_info;
405 info.cmdstr = obj;
406 for_each_domain(cmd_info, domain, NULL, NULL,
407 for_each_lanparm_domain_handler, &info);
408 }
409
410 void
ipmi_cmdlang_lanparm_handler(ipmi_cmd_info_t * cmd_info)411 ipmi_cmdlang_lanparm_handler(ipmi_cmd_info_t *cmd_info)
412 {
413 char *domain, *class, *obj;
414
415 if (cmd_info->curr_arg >= cmd_info->argc) {
416 domain = class = obj = NULL;
417 } else {
418 domain = cmd_info->argv[cmd_info->curr_arg];
419 class = NULL;
420 obj = strrchr(domain, '.');
421 if (!obj) {
422 cmd_info->cmdlang->errstr = "Invalid LANPARM";
423 cmd_info->cmdlang->err = EINVAL;
424 cmd_info->cmdlang->location
425 = "cmdlang.c(ipmi_cmdlang_lanparm_handler)";
426 return;
427 }
428 *obj = '\0';
429 obj++;
430 cmd_info->curr_arg++;
431 }
432
433 for_each_lanparm(cmd_info, domain, class, obj, cmd_info->handler_data,
434 cmd_info);
435 }
436
437 /*
438 * Handling for iterating SOLPARMs.
439 */
440 typedef struct solparm_iter_info_s
441 {
442 char *cmdstr;
443 ipmi_solparm_ptr_cb handler;
444 void *cb_data;
445 ipmi_cmd_info_t *cmd_info;
446 } solparm_iter_info_t;
447
448 static void
for_each_solparm_handler(ipmi_solparm_t * solparm,void * cb_data)449 for_each_solparm_handler(ipmi_solparm_t *solparm, void *cb_data)
450 {
451 solparm_iter_info_t *info = cb_data;
452 ipmi_cmd_info_t *cmd_info = info->cmd_info;
453 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
454 char name[IPMI_SOLPARM_NAME_LEN];
455 char *c;
456
457 if (cmdlang->err)
458 return;
459
460 ipmi_solparm_get_name(solparm, name, sizeof(name));
461
462 c = strrchr(name, '.');
463 if (!c)
464 goto out_err;
465 c++;
466 if ((! info->cmdstr) || (strcmp(info->cmdstr, c) == 0))
467 info->handler(solparm, info->cb_data);
468 return;
469
470 out_err:
471 ipmi_cmdlang_global_err(name,
472 "cmdlang.c(for_each_solparm_handler)",
473 "Bad SOLPARM name", EINVAL);
474 }
475
476 static void
for_each_solparm_domain_handler(ipmi_domain_t * domain,void * cb_data)477 for_each_solparm_domain_handler(ipmi_domain_t *domain, void *cb_data)
478 {
479 ipmi_solparm_iterate_solparms(domain, for_each_solparm_handler, cb_data);
480 }
481
482 static void
for_each_solparm(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_solparm_ptr_cb handler,void * cb_data)483 for_each_solparm(ipmi_cmd_info_t *cmd_info,
484 char *domain,
485 char *class,
486 char *obj,
487 ipmi_solparm_ptr_cb handler,
488 void *cb_data)
489 {
490 solparm_iter_info_t info;
491
492 if (class) {
493 cmd_info->cmdlang->errstr = "Invalid SOLPARM";
494 cmd_info->cmdlang->err = EINVAL;
495 cmd_info->cmdlang->location = "cmdlang.c(for_each_solparm)";
496 return;
497 }
498
499 info.handler = handler;
500 info.cb_data = cb_data;
501 info.cmd_info = cmd_info;
502 info.cmdstr = obj;
503 for_each_domain(cmd_info, domain, NULL, NULL,
504 for_each_solparm_domain_handler, &info);
505 }
506
507 void
ipmi_cmdlang_solparm_handler(ipmi_cmd_info_t * cmd_info)508 ipmi_cmdlang_solparm_handler(ipmi_cmd_info_t *cmd_info)
509 {
510 char *domain, *class, *obj;
511
512 if (cmd_info->curr_arg >= cmd_info->argc) {
513 domain = class = obj = NULL;
514 } else {
515 domain = cmd_info->argv[cmd_info->curr_arg];
516 class = NULL;
517 obj = strrchr(domain, '.');
518 if (!obj) {
519 cmd_info->cmdlang->errstr = "Invalid SOLPARM";
520 cmd_info->cmdlang->err = EINVAL;
521 cmd_info->cmdlang->location
522 = "cmdlang.c(ipmi_cmdlang_solparm_handler)";
523 return;
524 }
525 *obj = '\0';
526 obj++;
527 cmd_info->curr_arg++;
528 }
529
530 for_each_solparm(cmd_info, domain, class, obj, cmd_info->handler_data,
531 cmd_info);
532 }
533
534 /*
535 * Handling for iterating PEFs.
536 */
537 typedef struct pef_iter_info_s
538 {
539 char *cmdstr;
540 ipmi_pef_ptr_cb handler;
541 void *cb_data;
542 ipmi_cmd_info_t *cmd_info;
543 } pef_iter_info_t;
544
545 static void
for_each_pef_handler(ipmi_pef_t * pef,void * cb_data)546 for_each_pef_handler(ipmi_pef_t *pef, void *cb_data)
547 {
548 pef_iter_info_t *info = cb_data;
549 ipmi_cmd_info_t *cmd_info = info->cmd_info;
550 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
551 char name[IPMI_PEF_NAME_LEN];
552 char *c;
553
554 if (cmdlang->err)
555 return;
556
557 ipmi_pef_get_name(pef, name, sizeof(name));
558
559 c = strrchr(name, '.');
560 if (!c)
561 goto out_err;
562 c++;
563 if ((! info->cmdstr) || (strcmp(info->cmdstr, c) == 0))
564 info->handler(pef, info->cb_data);
565 return;
566
567 out_err:
568 ipmi_cmdlang_global_err(name,
569 "cmdlang.c(for_each_pef_handler)",
570 "Bad PEF name", EINVAL);
571 }
572
573 static void
for_each_pef_domain_handler(ipmi_domain_t * domain,void * cb_data)574 for_each_pef_domain_handler(ipmi_domain_t *domain, void *cb_data)
575 {
576 ipmi_pef_iterate_pefs(domain, for_each_pef_handler, cb_data);
577 }
578
579 static void
for_each_pef(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_pef_ptr_cb handler,void * cb_data)580 for_each_pef(ipmi_cmd_info_t *cmd_info,
581 char *domain,
582 char *class,
583 char *obj,
584 ipmi_pef_ptr_cb handler,
585 void *cb_data)
586 {
587 pef_iter_info_t info;
588
589 if (class) {
590 cmd_info->cmdlang->errstr = "Invalid PEF";
591 cmd_info->cmdlang->err = EINVAL;
592 cmd_info->cmdlang->location = "cmdlang.c(for_each_pef)";
593 return;
594 }
595
596 info.handler = handler;
597 info.cb_data = cb_data;
598 info.cmd_info = cmd_info;
599 info.cmdstr = obj;
600 for_each_domain(cmd_info, domain, NULL, NULL,
601 for_each_pef_domain_handler, &info);
602 }
603
604 void
ipmi_cmdlang_pef_handler(ipmi_cmd_info_t * cmd_info)605 ipmi_cmdlang_pef_handler(ipmi_cmd_info_t *cmd_info)
606 {
607 char *domain, *class, *obj;
608
609 if (cmd_info->curr_arg >= cmd_info->argc) {
610 domain = class = obj = NULL;
611 } else {
612 domain = cmd_info->argv[cmd_info->curr_arg];
613 class = NULL;
614 obj = strrchr(domain, '.');
615 if (!obj) {
616 cmd_info->cmdlang->errstr = "Invalid PEF";
617 cmd_info->cmdlang->err = EINVAL;
618 cmd_info->cmdlang->location
619 = "cmdlang.c(ipmi_cmdlang_pef_handler)";
620 return;
621 }
622 *obj = '\0';
623 obj++;
624 cmd_info->curr_arg++;
625 }
626
627 for_each_pef(cmd_info, domain, class, obj, cmd_info->handler_data,
628 cmd_info);
629 }
630
631
632 /*
633 * Handling for iterating FRUs.
634 */
635 typedef struct fru_iter_info_s
636 {
637 char *cmdstr;
638 ipmi_fru_ptr_cb handler;
639 void *cb_data;
640 ipmi_cmd_info_t *cmd_info;
641 } fru_iter_info_t;
642
643 static void
for_each_fru_handler(ipmi_fru_t * fru,void * cb_data)644 for_each_fru_handler(ipmi_fru_t *fru, void *cb_data)
645 {
646 fru_iter_info_t *info = cb_data;
647 ipmi_cmd_info_t *cmd_info = info->cmd_info;
648 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
649 char name[IPMI_FRU_NAME_LEN];
650 char *c;
651
652 if (cmdlang->err)
653 return;
654
655 ipmi_fru_get_name(fru, name, sizeof(name));
656
657 c = strrchr(name, '.');
658 if (!c)
659 goto out_err;
660 c++;
661 if ((! info->cmdstr) || (strcmp(info->cmdstr, c) == 0))
662 info->handler(fru, info->cb_data);
663 return;
664
665 out_err:
666 ipmi_cmdlang_global_err(name,
667 "cmdlang.c(for_each_fru_handler)",
668 "Bad FRU name", EINVAL);
669 }
670
671 static void
for_each_fru_domain_handler(ipmi_domain_t * domain,void * cb_data)672 for_each_fru_domain_handler(ipmi_domain_t *domain, void *cb_data)
673 {
674 ipmi_fru_iterate_frus(domain, for_each_fru_handler, cb_data);
675 }
676
677 static void
for_each_fru(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_fru_ptr_cb handler,void * cb_data)678 for_each_fru(ipmi_cmd_info_t *cmd_info,
679 char *domain,
680 char *class,
681 char *obj,
682 ipmi_fru_ptr_cb handler,
683 void *cb_data)
684 {
685 fru_iter_info_t info;
686
687 if (class) {
688 cmd_info->cmdlang->errstr = "Invalid FRU";
689 cmd_info->cmdlang->err = EINVAL;
690 cmd_info->cmdlang->location = "cmdlang.c(for_each_fru)";
691 return;
692 }
693
694 info.handler = handler;
695 info.cb_data = cb_data;
696 info.cmd_info = cmd_info;
697 info.cmdstr = obj;
698 for_each_domain(cmd_info, domain, NULL, NULL,
699 for_each_fru_domain_handler, &info);
700 }
701
702 void
ipmi_cmdlang_fru_handler(ipmi_cmd_info_t * cmd_info)703 ipmi_cmdlang_fru_handler(ipmi_cmd_info_t *cmd_info)
704 {
705 char *domain, *class, *obj;
706
707 if (cmd_info->curr_arg >= cmd_info->argc) {
708 domain = class = obj = NULL;
709 } else {
710 domain = cmd_info->argv[cmd_info->curr_arg];
711 class = NULL;
712 obj = strrchr(domain, '.');
713 if (!obj) {
714 cmd_info->cmdlang->errstr = "Invalid FRU";
715 cmd_info->cmdlang->err = EINVAL;
716 cmd_info->cmdlang->location
717 = "cmdlang.c(ipmi_cmdlang_fru_handler)";
718 return;
719 }
720 *obj = '\0';
721 obj++;
722 cmd_info->curr_arg++;
723 }
724
725 for_each_fru(cmd_info, domain, class, obj, cmd_info->handler_data,
726 cmd_info);
727 }
728
729
730 /*
731 * Handling for iterating entities.
732 */
733 typedef struct entity_iter_info_s
734 {
735 char *cmpstr;
736 ipmi_entity_ptr_cb handler;
737 void *cb_data;
738 ipmi_cmd_info_t *cmd_info;
739 } entity_iter_info_t;
740
741 static void
for_each_entity_handler(ipmi_entity_t * entity,void * cb_data)742 for_each_entity_handler(ipmi_entity_t *entity, void *cb_data)
743 {
744 entity_iter_info_t *info = cb_data;
745 ipmi_cmd_info_t *cmd_info = info->cmd_info;
746 char entity_name[IPMI_ENTITY_NAME_LEN];
747 char *c, *c2;
748
749 if (cmd_info->cmdlang->err)
750 return;
751
752 ipmi_entity_get_name(entity, entity_name, sizeof(entity_name));
753 c = strchr(entity_name, '(');
754 if (!c)
755 goto out_err;
756 c++;
757 c2 = strchr(c, ')');
758 if (!c2)
759 goto out_err;
760 *c2 = '\0';
761 if ((!info->cmpstr) || (strcmp(info->cmpstr, c) == 0)) {
762 *c2 = ')';
763 info->handler(entity, info->cb_data);
764 } else
765 *c2 = ')';
766 return;
767
768 out_err:
769 ipmi_cmdlang_global_err(entity_name,
770 "cmdlang.c(for_each_entity_handler)",
771 "Bad entity name", EINVAL);
772 }
773
774 static void
for_each_entity_domain_handler(ipmi_domain_t * domain,void * cb_data)775 for_each_entity_domain_handler(ipmi_domain_t *domain, void *cb_data)
776 {
777 ipmi_domain_iterate_entities(domain, for_each_entity_handler, cb_data);
778 }
779
780 static void
for_each_entity(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_entity_ptr_cb handler,void * cb_data)781 for_each_entity(ipmi_cmd_info_t *cmd_info,
782 char *domain,
783 char *class,
784 char *obj,
785 ipmi_entity_ptr_cb handler,
786 void *cb_data)
787 {
788 entity_iter_info_t info;
789
790 if (obj) {
791 cmd_info->cmdlang->errstr = "Invalid entity";
792 cmd_info->cmdlang->err = EINVAL;
793 cmd_info->cmdlang->location = "cmdlang.c(for_each_entity)";
794 return;
795 }
796
797 info.cmpstr = class;
798 info.handler = handler;
799 info.cb_data = cb_data;
800 info.cmd_info = cmd_info;
801 for_each_domain(cmd_info, domain, NULL, NULL,
802 for_each_entity_domain_handler, &info);
803 }
804
805 void
ipmi_cmdlang_entity_handler(ipmi_cmd_info_t * cmd_info)806 ipmi_cmdlang_entity_handler(ipmi_cmd_info_t *cmd_info)
807 {
808 char *domain, *class, *obj;
809 int rv;
810
811 if (cmd_info->curr_arg >= cmd_info->argc) {
812 domain = class = obj = NULL;
813 } else {
814 rv = parse_ipmi_objstr(cmd_info->argv[cmd_info->curr_arg],
815 &domain, &class, &obj);
816 if (rv) {
817 cmd_info->cmdlang->errstr = "Invalid entity";
818 cmd_info->cmdlang->err = rv;
819 cmd_info->cmdlang->location
820 = "cmdlang.c(ipmi_cmdlang_entity_handler)";
821 return;
822 }
823 cmd_info->curr_arg++;
824 }
825
826 for_each_entity(cmd_info, domain, class, obj,
827 cmd_info->handler_data, cmd_info);
828 }
829
830
831 /*
832 * Handling for iterating sensors.
833 */
834 typedef struct sensor_iter_info_s
835 {
836 char *cmpstr;
837 ipmi_sensor_ptr_cb handler;
838 void *cb_data;
839 ipmi_cmd_info_t *cmd_info;
840 } sensor_iter_info_t;
841
842 static void
for_each_sensor_handler(ipmi_entity_t * entity,ipmi_sensor_t * sensor,void * cb_data)843 for_each_sensor_handler(ipmi_entity_t *entity,
844 ipmi_sensor_t *sensor,
845 void *cb_data)
846 {
847 sensor_iter_info_t *info = cb_data;
848 char sensor_name[IPMI_SENSOR_NAME_LEN];
849 char *c;
850
851 ipmi_sensor_get_name(sensor, sensor_name, sizeof(sensor_name));
852 c = strchr(sensor_name, '(');
853 if (!c)
854 goto out_err;
855 c = strchr(c, ')');
856 if (!c)
857 goto out_err;
858 c = strchr(c, '.');
859 if (!c)
860 goto out_err;
861 c++;
862 if ((!info->cmpstr) || (strcmp(info->cmpstr, c) == 0))
863 info->handler(sensor, info->cb_data);
864 return;
865
866 out_err:
867 ipmi_cmdlang_global_err(sensor_name,
868 "cmdlang.c(for_each_sensor_handler)",
869 "Bad sensor name", EINVAL);
870 }
871
872 static void
for_each_sensor_entity_handler(ipmi_entity_t * entity,void * cb_data)873 for_each_sensor_entity_handler(ipmi_entity_t *entity, void *cb_data)
874 {
875 ipmi_entity_iterate_sensors(entity, for_each_sensor_handler, cb_data);
876 }
877
878 static void
for_each_sensor(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_sensor_ptr_cb handler,void * cb_data)879 for_each_sensor(ipmi_cmd_info_t *cmd_info,
880 char *domain,
881 char *class,
882 char *obj,
883 ipmi_sensor_ptr_cb handler,
884 void *cb_data)
885 {
886 sensor_iter_info_t info;
887
888 info.cmpstr = obj;
889 info.handler = handler;
890 info.cb_data = cb_data;
891 info.cmd_info = cmd_info;
892 for_each_entity(cmd_info, domain, class, NULL,
893 for_each_sensor_entity_handler, &info);
894 }
895
896 void
ipmi_cmdlang_sensor_handler(ipmi_cmd_info_t * cmd_info)897 ipmi_cmdlang_sensor_handler(ipmi_cmd_info_t *cmd_info)
898 {
899 char *domain, *class, *obj;
900 int rv;
901
902 if (cmd_info->curr_arg >= cmd_info->argc) {
903 domain = class = obj = NULL;
904 } else {
905 rv = parse_ipmi_objstr(cmd_info->argv[cmd_info->curr_arg],
906 &domain, &class, &obj);
907 if (rv) {
908 cmd_info->cmdlang->errstr = "Invalid sensor";
909 cmd_info->cmdlang->err = rv;
910 cmd_info->cmdlang->location
911 = "cmdlang.c(ipmi_cmdlang_sensor_handler)";
912 return;
913 }
914 cmd_info->curr_arg++;
915 }
916
917 for_each_sensor(cmd_info, domain, class, obj,
918 cmd_info->handler_data, cmd_info);
919 }
920
921
922 /*
923 * Handling for iterating controls.
924 */
925 typedef struct control_iter_info_s
926 {
927 char *cmpstr;
928 ipmi_control_ptr_cb handler;
929 void *cb_data;
930 ipmi_cmd_info_t *cmd_info;
931 } control_iter_info_t;
932
933 static void
for_each_control_handler(ipmi_entity_t * entity,ipmi_control_t * control,void * cb_data)934 for_each_control_handler(ipmi_entity_t *entity,
935 ipmi_control_t *control,
936 void *cb_data)
937 {
938 control_iter_info_t *info = cb_data;
939 char control_name[IPMI_CONTROL_NAME_LEN];
940 char *c;
941
942 ipmi_control_get_name(control, control_name, sizeof(control_name));
943 c = strchr(control_name, '(');
944 if (!c)
945 goto out_err;
946 c = strchr(c, ')');
947 if (!c)
948 goto out_err;
949 c = strchr(c, '.');
950 if (!c)
951 goto out_err;
952 c++;
953 if ((!info->cmpstr) || (strcmp(info->cmpstr, c) == 0))
954 info->handler(control, info->cb_data);
955 return;
956
957 out_err:
958 ipmi_cmdlang_global_err(control_name,
959 "cmdlang.c(for_each_control_handler)",
960 "Bad control name", EINVAL);
961 }
962
963 static void
for_each_control_entity_handler(ipmi_entity_t * entity,void * cb_data)964 for_each_control_entity_handler(ipmi_entity_t *entity, void *cb_data)
965 {
966 ipmi_entity_iterate_controls(entity, for_each_control_handler, cb_data);
967 }
968
969 static void
for_each_control(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_control_ptr_cb handler,void * cb_data)970 for_each_control(ipmi_cmd_info_t *cmd_info,
971 char *domain,
972 char *class,
973 char *obj,
974 ipmi_control_ptr_cb handler,
975 void *cb_data)
976 {
977 control_iter_info_t info;
978
979 info.cmpstr = obj;
980 info.handler = handler;
981 info.cb_data = cb_data;
982 info.cmd_info = cmd_info;
983 for_each_entity(cmd_info, domain, class, NULL,
984 for_each_control_entity_handler, &info);
985 }
986
987 void
ipmi_cmdlang_control_handler(ipmi_cmd_info_t * cmd_info)988 ipmi_cmdlang_control_handler(ipmi_cmd_info_t *cmd_info)
989 {
990 char *domain, *class, *obj;
991 int rv;
992
993 if (cmd_info->curr_arg >= cmd_info->argc) {
994 domain = class = obj = NULL;
995 } else {
996 rv = parse_ipmi_objstr(cmd_info->argv[cmd_info->curr_arg],
997 &domain, &class, &obj);
998 if (rv) {
999 cmd_info->cmdlang->errstr = "Invalid control";
1000 cmd_info->cmdlang->err = rv;
1001 cmd_info->cmdlang->location
1002 = "cmdlang.c(ipmi_cmdlang_control_handler)";
1003 return;
1004 }
1005 cmd_info->curr_arg++;
1006 }
1007
1008 for_each_control(cmd_info, domain, class, obj,
1009 cmd_info->handler_data, cmd_info);
1010 }
1011
1012
1013 /*
1014 * Handling for iterating mcs.
1015 */
1016 typedef struct mc_iter_info_s
1017 {
1018 char *cmpstr;
1019 ipmi_mc_ptr_cb handler;
1020 void *cb_data;
1021 ipmi_cmd_info_t *cmd_info;
1022 } mc_iter_info_t;
1023
1024 static void
for_each_mc_handler(ipmi_domain_t * domain,ipmi_mc_t * mc,void * cb_data)1025 for_each_mc_handler(ipmi_domain_t *domain, ipmi_mc_t *mc, void *cb_data)
1026 {
1027 mc_iter_info_t *info = cb_data;
1028 char mc_name[IPMI_MC_NAME_LEN];
1029 char *c, *c2;
1030
1031 ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
1032 c = strchr(mc_name, '(');
1033 if (!c)
1034 goto out_err;
1035 c++;
1036 c2 = strchr(c, ')');
1037 if (!c2)
1038 goto out_err;
1039 *c2 = '\0';
1040 if ((!info->cmpstr) || (strcmp(info->cmpstr, c) == 0)) {
1041 *c2 = ')';
1042 info->handler(mc, info->cb_data);
1043 } else
1044 *c2 = ')';
1045 return;
1046
1047 out_err:
1048 ipmi_cmdlang_global_err(mc_name,
1049 "cmdlang.c(for_each_entity_handler)",
1050 "Bad mc name", EINVAL);
1051 }
1052
1053 static void
for_each_mc_domain_handler(ipmi_domain_t * domain,void * cb_data)1054 for_each_mc_domain_handler(ipmi_domain_t *domain, void *cb_data)
1055 {
1056 ipmi_domain_iterate_mcs(domain, for_each_mc_handler, cb_data);
1057 }
1058
1059 static void
for_each_mc(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_mc_ptr_cb handler,void * cb_data)1060 for_each_mc(ipmi_cmd_info_t *cmd_info,
1061 char *domain,
1062 char *class,
1063 char *obj,
1064 ipmi_mc_ptr_cb handler,
1065 void *cb_data)
1066 {
1067 mc_iter_info_t info;
1068
1069 if (obj) {
1070 cmd_info->cmdlang->errstr = "Invalid MC";
1071 cmd_info->cmdlang->err = EINVAL;
1072 cmd_info->cmdlang->location = "cmdlang.c(for_each_mc)";
1073 return;
1074 }
1075
1076 info.cmpstr = class;
1077 info.handler = handler;
1078 info.cb_data = cb_data;
1079 info.cmd_info = cmd_info;
1080 for_each_domain(cmd_info, domain, NULL, NULL,
1081 for_each_mc_domain_handler, &info);
1082 }
1083
1084 void
ipmi_cmdlang_mc_handler(ipmi_cmd_info_t * cmd_info)1085 ipmi_cmdlang_mc_handler(ipmi_cmd_info_t *cmd_info)
1086 {
1087 char *domain, *class, *obj;
1088 int rv;
1089
1090 if (cmd_info->curr_arg >= cmd_info->argc) {
1091 domain = class = obj = NULL;
1092 } else {
1093 rv = parse_ipmi_objstr(cmd_info->argv[cmd_info->curr_arg],
1094 &domain, &class, &obj);
1095 if (rv) {
1096 cmd_info->cmdlang->errstr = "Invalid MC";
1097 cmd_info->cmdlang->err = rv;
1098 cmd_info->cmdlang->location
1099 = "cmdlang.c(ipmi_cmdlang_mc_handler)";
1100 return;
1101 }
1102 cmd_info->curr_arg++;
1103 }
1104
1105 for_each_mc(cmd_info, domain, class, obj, cmd_info->handler_data,
1106 cmd_info);
1107 }
1108
1109
1110 /*
1111 * Handling for iterating connections.
1112 */
1113 typedef struct conn_iter_info_s
1114 {
1115 int conn;
1116 ipmi_connection_ptr_cb handler;
1117 void *cb_data;
1118 ipmi_cmd_info_t *cmd_info;
1119 } conn_iter_info_t;
1120
1121 static void
for_each_conn_handler(ipmi_domain_t * domain,int conn,void * cb_data)1122 for_each_conn_handler(ipmi_domain_t *domain, int conn, void *cb_data)
1123 {
1124 conn_iter_info_t *info = cb_data;
1125
1126 if ((info->conn == -1) || (info->conn == conn))
1127 info->handler(domain, conn, info->cb_data);
1128 }
1129
1130 static void
for_each_conn_domain_handler(ipmi_domain_t * domain,void * cb_data)1131 for_each_conn_domain_handler(ipmi_domain_t *domain, void *cb_data)
1132 {
1133 ipmi_domain_iterate_connections(domain, for_each_conn_handler, cb_data);
1134 }
1135
1136 static void
for_each_connection(ipmi_cmd_info_t * cmd_info,char * domain,char * class,char * obj,ipmi_connection_ptr_cb handler,void * cb_data)1137 for_each_connection(ipmi_cmd_info_t *cmd_info,
1138 char *domain,
1139 char *class,
1140 char *obj,
1141 ipmi_connection_ptr_cb handler,
1142 void *cb_data)
1143 {
1144 conn_iter_info_t info;
1145 char *endptr;
1146
1147 if (class) {
1148 cmd_info->cmdlang->errstr = "Invalid connection";
1149 cmd_info->cmdlang->err = EINVAL;
1150 cmd_info->cmdlang->location = "cmdlang.c(for_each_connection)";
1151 return;
1152 }
1153
1154 if (obj) {
1155 if (!isdigit(obj[0])) {
1156 cmd_info->cmdlang->errstr = "Invalid connection number";
1157 cmd_info->cmdlang->err = EINVAL;
1158 cmd_info->cmdlang->location = "cmdlang.c(for_each_connection)";
1159 return;
1160 }
1161 info.conn = strtoul(obj, &endptr, 0);
1162 if (*endptr != '\0') {
1163 cmd_info->cmdlang->errstr = "Invalid connection number";
1164 cmd_info->cmdlang->err = EINVAL;
1165 cmd_info->cmdlang->location = "cmdlang.c(for_each_connection)";
1166 return;
1167 }
1168 } else {
1169 info.conn = -1;
1170 }
1171 info.handler = handler;
1172 info.cb_data = cb_data;
1173 info.cmd_info = cmd_info;
1174 for_each_domain(cmd_info, domain, NULL, NULL,
1175 for_each_conn_domain_handler, &info);
1176 }
1177
1178 void
ipmi_cmdlang_connection_handler(ipmi_cmd_info_t * cmd_info)1179 ipmi_cmdlang_connection_handler(ipmi_cmd_info_t *cmd_info)
1180 {
1181 char *domain, *class, *obj;
1182
1183 if (cmd_info->curr_arg >= cmd_info->argc) {
1184 domain = class = obj = NULL;
1185 } else {
1186 domain = cmd_info->argv[cmd_info->curr_arg];
1187 class = NULL;
1188 obj = strrchr(domain, '.');
1189 if (!obj) {
1190 cmd_info->cmdlang->errstr = "Invalid connection";
1191 cmd_info->cmdlang->err = EINVAL;
1192 cmd_info->cmdlang->location
1193 = "cmdlang.c(ipmi_cmdlang_connection_handler)";
1194 return;
1195 }
1196 *obj = '\0';
1197 obj++;
1198 cmd_info->curr_arg++;
1199 }
1200
1201 for_each_connection(cmd_info,
1202 domain, class, obj, cmd_info->handler_data,
1203 cmd_info);
1204 }
1205
1206
1207 static int
parse_next_str(char ** tok,char ** istr)1208 parse_next_str(char **tok, char **istr)
1209 {
1210 char *str = *istr;
1211 char *tstr;
1212 char *start;
1213 char quote = 0;
1214
1215 while (isspace(*str))
1216 str++;
1217 if (!*str)
1218 return ENOENT;
1219
1220 if ((*str == '"') || (*str == '\'')) {
1221 quote = *str;
1222 str++;
1223 }
1224
1225 start = str;
1226
1227 while (*str) {
1228 if (quote) {
1229 if (*str == quote)
1230 break;
1231 } else {
1232 if (isspace(*str))
1233 break;
1234 }
1235
1236 if (*str == '\\') {
1237 tstr = str;
1238 if (! *(tstr+1))
1239 /* Nothing after a '\' */
1240 return EINVAL;
1241 while (*(tstr+1)) {
1242 *tstr = *(tstr+1);
1243 tstr++;
1244 }
1245 }
1246 str++;
1247 }
1248
1249 if (*str) {
1250 *str = '\0';
1251 *istr = str+1;
1252 } else {
1253 *istr = str;
1254 }
1255 *tok = start;
1256
1257 return 0;
1258 }
1259
1260 static ipmi_cmdlang_cmd_t *cmd_list;
1261
1262 #define MAXARGS 100
1263 void
ipmi_cmdlang_handle(ipmi_cmdlang_t * cmdlang,char * str)1264 ipmi_cmdlang_handle(ipmi_cmdlang_t *cmdlang, char *str)
1265 {
1266 int argc;
1267 char *argv[MAXARGS];
1268 int curr_arg;
1269 ipmi_cmdlang_cmd_t *cmd;
1270 ipmi_cmd_info_t *info;
1271 int rv;
1272
1273 if (*str == '#') {
1274 /* A comment */
1275 cmdlang->done(cmdlang);
1276 return;
1277 }
1278
1279 info = ipmi_mem_alloc(sizeof(*info));
1280 if (!info) {
1281 cmdlang->errstr = "Out of memory";
1282 cmdlang->err = ENOMEM;
1283 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1284 cmdlang->done(cmdlang);
1285 return;
1286 }
1287 memset(info, 0, sizeof(*info));
1288 info->usecount = 1;
1289 info->cmdlang = cmdlang;
1290 rv = ipmi_create_lock_os_hnd(cmdlang->os_hnd, &info->lock);
1291 if (rv) {
1292 cmdlang->errstr = "Could not allocate lock";
1293 cmdlang->err = rv;
1294 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1295 goto done;
1296 }
1297
1298 for (argc=0; argc<MAXARGS; argc++) {
1299 rv = parse_next_str(&argv[argc], &str);
1300 if (rv) {
1301 if (rv == ENOENT)
1302 break;
1303 cmdlang->errstr = "Invalid string";
1304 cmdlang->err = rv;
1305 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1306 goto done;
1307 }
1308 }
1309
1310 if (*str) {
1311 /* Too many arguments */
1312 cmdlang->errstr = "Too many arguments";
1313 cmdlang->err = E2BIG;
1314 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1315 goto done;
1316 }
1317
1318 curr_arg = 0;
1319 rv = 0;
1320 cmd = cmd_list;
1321
1322 if (argc == curr_arg) {
1323 cmdlang->errstr = "No command";
1324 cmdlang->err = ENOMSG;
1325 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1326 goto done;
1327 }
1328 if (strcmp(argv[curr_arg], "help") == 0) {
1329 ipmi_cmdlang_cmd_t *parent = NULL;
1330 int old_help = cmdlang->help;
1331 /* Help has special handling. */
1332
1333 cmdlang->help = 1;
1334 curr_arg++;
1335 for (;;) {
1336 next_help:
1337 if (argc == curr_arg) {
1338 rv = 0;
1339 if (parent) {
1340 cmdlang->out(cmdlang, parent->name, parent->help);
1341 if (parent->help_finish)
1342 parent->help_finish(cmdlang);
1343 }else
1344 cmdlang->out(cmdlang, "help", NULL);
1345 if (cmdlang->err)
1346 goto done_help;
1347 cmdlang->down(cmdlang);
1348 while (cmd) {
1349 cmdlang->out(cmdlang, cmd->name, cmd->help);
1350 if (cmdlang->err) {
1351 cmdlang->up(cmdlang);
1352 goto done_help;
1353 }
1354 if (cmd->help_finish)
1355 cmd->help_finish(cmdlang);
1356 cmd = cmd->next;
1357 }
1358 cmdlang->up(cmdlang);
1359 break;
1360 }
1361 if (!cmd) {
1362 cmdlang->errstr = "Command not found";
1363 cmdlang->err = ENOSYS;
1364 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1365 goto done_help;
1366 }
1367
1368 while (cmd) {
1369 if (strcmp(cmd->name, argv[curr_arg]) == 0) {
1370 curr_arg++;
1371 parent = cmd;
1372 cmd = cmd->subcmds;
1373 goto next_help;
1374 }
1375 cmd = cmd->next;
1376 }
1377
1378 cmdlang->errstr = "Command not found";
1379 cmdlang->err = ENOSYS;
1380 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1381 goto done_help;
1382 }
1383
1384 done_help:
1385 info->did_output = 1;
1386 cmdlang->help = old_help;
1387 goto done;
1388 }
1389
1390 for (;;) {
1391 if (argc == curr_arg) {
1392 cmdlang->errstr = "Missing command";
1393 cmdlang->err = ENOMSG;
1394 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1395 goto done;
1396 }
1397
1398 while (cmd) {
1399 if (strcmp(cmd->name, argv[curr_arg]) == 0) {
1400 if (cmd->subcmds) {
1401 cmd = cmd->subcmds;
1402 curr_arg++;
1403 /* Continue processing this subcommand list */
1404 break;
1405 } else {
1406 curr_arg++;
1407 info->handler_data = cmd->handler_data;
1408 info->curr_arg = curr_arg;
1409 info->argc = argc;
1410 info->argv = argv;
1411 info->cmd = cmd;
1412 cmd->handler(info);
1413 goto done;
1414 }
1415 }
1416 cmd = cmd->next;
1417 }
1418
1419 if (!cmd) {
1420 cmdlang->errstr = "Command not found";
1421 cmdlang->err = ENOSYS;
1422 cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1423 goto done;
1424 }
1425 }
1426
1427 done:
1428 ipmi_cmdlang_cmd_info_put(info);
1429 }
1430
1431 int
ipmi_cmdlang_reg_cmd(ipmi_cmdlang_cmd_t * parent,char * name,char * help,ipmi_cmdlang_handler_cb handler,void * cb_data,ipmi_help_finisher_cb help_finish,ipmi_cmdlang_cmd_t ** new_val)1432 ipmi_cmdlang_reg_cmd(ipmi_cmdlang_cmd_t *parent,
1433 char *name,
1434 char *help,
1435 ipmi_cmdlang_handler_cb handler,
1436 void *cb_data,
1437 ipmi_help_finisher_cb help_finish,
1438 ipmi_cmdlang_cmd_t **new_val)
1439 {
1440 ipmi_cmdlang_cmd_t *rv;
1441 ipmi_cmdlang_cmd_t *cmd;
1442
1443 /* Check for dups. */
1444 if (!parent)
1445 cmd = cmd_list;
1446 else
1447 cmd = parent;
1448 while (cmd) {
1449 if (strcmp(cmd->name, name) == 0)
1450 return EEXIST;
1451 cmd = cmd->next;
1452 }
1453
1454 rv = ipmi_mem_alloc(sizeof(*rv));
1455 if (!rv)
1456 return ENOMEM;
1457
1458 rv->name = name;
1459 rv->help = help;
1460 rv->handler = handler;
1461 rv->subcmds = NULL;
1462 rv->handler_data = cb_data;
1463 rv->help_finish = help_finish;
1464 rv->next = NULL;
1465
1466 if (parent) {
1467 if (!parent->subcmds) {
1468 parent->subcmds = rv;
1469 goto done;
1470 }
1471 cmd = parent->subcmds;
1472 } else {
1473 if (!cmd_list) {
1474 cmd_list = rv;
1475 goto done;
1476 }
1477 cmd = cmd_list;
1478 }
1479 while (cmd->next) {
1480 cmd = cmd->next;
1481 }
1482 cmd->next = rv;
1483
1484 done:
1485 if (new_val)
1486 *new_val = rv;
1487 return 0;
1488 }
1489
1490 int
ipmi_cmdlang_reg_table(ipmi_cmdlang_init_t * table,int len)1491 ipmi_cmdlang_reg_table(ipmi_cmdlang_init_t *table, int len)
1492 {
1493 int i;
1494 int rv;
1495 ipmi_cmdlang_cmd_t *parent = NULL;
1496
1497 for (i=0; i<len; i++) {
1498 if (table[i].parent)
1499 parent = *table[i].parent;
1500 rv = ipmi_cmdlang_reg_cmd(parent,
1501 table[i].name,
1502 table[i].help,
1503 table[i].handler,
1504 table[i].cb_data,
1505 table[i].help_finish,
1506 table[i].new_val);
1507 if (rv)
1508 return rv;
1509 }
1510
1511 return 0;
1512 }
1513
1514 void
ipmi_cmdlang_lock(ipmi_cmd_info_t * info)1515 ipmi_cmdlang_lock(ipmi_cmd_info_t *info)
1516 {
1517 ipmi_lock(info->lock);
1518 }
1519
1520 void
ipmi_cmdlang_unlock(ipmi_cmd_info_t * info)1521 ipmi_cmdlang_unlock(ipmi_cmd_info_t *info)
1522 {
1523 ipmi_unlock(info->lock);
1524 }
1525
1526 void
ipmi_cmdlang_out(ipmi_cmd_info_t * info,const char * name,const char * value)1527 ipmi_cmdlang_out(ipmi_cmd_info_t *info,
1528 const char *name,
1529 const char *value)
1530 {
1531 info->did_output = 1;
1532 info->cmdlang->out(info->cmdlang, name, value);
1533 }
1534
1535 void
ipmi_cmdlang_out_int(ipmi_cmd_info_t * info,const char * name,int value)1536 ipmi_cmdlang_out_int(ipmi_cmd_info_t *info,
1537 const char *name,
1538 int value)
1539 {
1540 char sval[20];
1541
1542 sprintf(sval, "%d", value);
1543 ipmi_cmdlang_out(info, name, sval);
1544 }
1545
1546 void
ipmi_cmdlang_out_double(ipmi_cmd_info_t * info,const char * name,double value)1547 ipmi_cmdlang_out_double(ipmi_cmd_info_t *info,
1548 const char *name,
1549 double value)
1550 {
1551 char sval[80];
1552
1553 sprintf(sval, "%e", value);
1554 ipmi_cmdlang_out(info, name, sval);
1555 }
1556
1557 void
ipmi_cmdlang_out_hex(ipmi_cmd_info_t * info,const char * name,int value)1558 ipmi_cmdlang_out_hex(ipmi_cmd_info_t *info,
1559 const char *name,
1560 int value)
1561 {
1562 char sval[20];
1563
1564 sprintf(sval, "0x%x", value);
1565 ipmi_cmdlang_out(info, name, sval);
1566 }
1567
1568 void
ipmi_cmdlang_out_long(ipmi_cmd_info_t * info,const char * name,long value)1569 ipmi_cmdlang_out_long(ipmi_cmd_info_t *info,
1570 const char *name,
1571 long value)
1572 {
1573 char sval[32];
1574
1575 sprintf(sval, "%ld", value);
1576 ipmi_cmdlang_out(info, name, sval);
1577 }
1578
1579 void
ipmi_cmdlang_out_binary(ipmi_cmd_info_t * info,const char * name,const char * value,unsigned int len)1580 ipmi_cmdlang_out_binary(ipmi_cmd_info_t *info,
1581 const char *name,
1582 const char *value,
1583 unsigned int len)
1584 {
1585 info->did_output = 1;
1586 info->cmdlang->out_binary(info->cmdlang, name, value, len);
1587 }
1588
1589 void
ipmi_cmdlang_out_unicode(ipmi_cmd_info_t * info,const char * name,const char * value,unsigned int len)1590 ipmi_cmdlang_out_unicode(ipmi_cmd_info_t *info,
1591 const char *name,
1592 const char *value,
1593 unsigned int len)
1594 {
1595 info->did_output = 1;
1596 info->cmdlang->out_unicode(info->cmdlang, name, value, len);
1597 }
1598
1599 void
ipmi_cmdlang_out_type(ipmi_cmd_info_t * info,char * name,enum ipmi_str_type_e type,const char * value,unsigned int len)1600 ipmi_cmdlang_out_type(ipmi_cmd_info_t *info,
1601 char *name,
1602 enum ipmi_str_type_e type,
1603 const char *value,
1604 unsigned int len)
1605 {
1606 switch(type) {
1607 case IPMI_ASCII_STR:
1608 ipmi_cmdlang_out(info, name, value);
1609 break;
1610 case IPMI_UNICODE_STR:
1611 ipmi_cmdlang_out_unicode(info, name, value, len);
1612 break;
1613 case IPMI_BINARY_STR:
1614 ipmi_cmdlang_out_binary(info, name, value, len);
1615 break;
1616 }
1617 }
1618
1619 void
ipmi_cmdlang_out_bool(ipmi_cmd_info_t * info,const char * name,int value)1620 ipmi_cmdlang_out_bool(ipmi_cmd_info_t *info,
1621 const char *name,
1622 int value)
1623 {
1624 if (value)
1625 ipmi_cmdlang_out(info, name, "true");
1626 else
1627 ipmi_cmdlang_out(info, name, "false");
1628 }
1629
1630 void
ipmi_cmdlang_out_time(ipmi_cmd_info_t * info,const char * name,ipmi_time_t value)1631 ipmi_cmdlang_out_time(ipmi_cmd_info_t *info,
1632 const char *name,
1633 ipmi_time_t value)
1634 {
1635 char sval[40];
1636
1637 sprintf(sval, "%lld", (long long) value);
1638 ipmi_cmdlang_out(info, name, sval);
1639 }
1640
1641 void
ipmi_cmdlang_out_timeout(ipmi_cmd_info_t * info,const char * name,ipmi_timeout_t value)1642 ipmi_cmdlang_out_timeout(ipmi_cmd_info_t *info,
1643 const char *name,
1644 ipmi_timeout_t value)
1645 {
1646 char sval[40];
1647
1648 sprintf(sval, "%lld", (long long) value);
1649 ipmi_cmdlang_out(info, name, sval);
1650 }
1651
1652 void
ipmi_cmdlang_out_ip(ipmi_cmd_info_t * info,const char * name,struct in_addr * ip_addr)1653 ipmi_cmdlang_out_ip(ipmi_cmd_info_t *info,
1654 const char *name,
1655 struct in_addr *ip_addr)
1656 {
1657 char outstr[16];
1658 uint32_t addr = ntohl(ip_addr->s_addr);
1659
1660 /* Why isn't there an inet_ntoa_r? */
1661 sprintf(outstr, "%d.%d.%d.%d",
1662 (addr >> 24) & 0xff,
1663 (addr >> 16) & 0xff,
1664 (addr >> 8) & 0xff,
1665 (addr >> 0) & 0xff);
1666 ipmi_cmdlang_out(info, name, outstr);
1667 }
1668
1669 void
ipmi_cmdlang_out_mac(ipmi_cmd_info_t * info,const char * name,unsigned char mac_addr[6])1670 ipmi_cmdlang_out_mac(ipmi_cmd_info_t *info,
1671 const char *name,
1672 unsigned char mac_addr[6])
1673 {
1674 char outstr[18];
1675
1676 /* Why isn't there a standard ether_ntoa_r? */
1677 sprintf(outstr, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
1678 mac_addr[0],
1679 mac_addr[1],
1680 mac_addr[2],
1681 mac_addr[3],
1682 mac_addr[4],
1683 mac_addr[5]);
1684 ipmi_cmdlang_out(info, name, outstr);
1685 }
1686
1687 void
ipmi_cmdlang_down(ipmi_cmd_info_t * info)1688 ipmi_cmdlang_down(ipmi_cmd_info_t *info)
1689 {
1690 info->cmdlang->down(info->cmdlang);
1691 }
1692
1693 void
ipmi_cmdlang_up(ipmi_cmd_info_t * info)1694 ipmi_cmdlang_up(ipmi_cmd_info_t *info)
1695 {
1696 info->cmdlang->up(info->cmdlang);
1697 }
1698
1699 void
ipmi_cmdlang_cmd_info_get(ipmi_cmd_info_t * cmd_info)1700 ipmi_cmdlang_cmd_info_get(ipmi_cmd_info_t *cmd_info)
1701 {
1702 ipmi_cmdlang_lock(cmd_info);
1703 cmd_info->usecount++;
1704 ipmi_cmdlang_unlock(cmd_info);
1705 }
1706
1707 void
ipmi_cmdlang_cmd_info_put(ipmi_cmd_info_t * cmd_info)1708 ipmi_cmdlang_cmd_info_put(ipmi_cmd_info_t *cmd_info)
1709 {
1710 ipmi_cmdlang_lock(cmd_info);
1711 cmd_info->usecount--;
1712 if (cmd_info->usecount == 0) {
1713 if ((!cmd_info->cmdlang->err) && (!cmd_info->did_output)) {
1714 cmd_info->cmdlang->errstr = "Specified object not found";
1715 cmd_info->cmdlang->err = EINVAL;
1716 cmd_info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_handle)";
1717 }
1718
1719 cmd_info->cmdlang->done(cmd_info->cmdlang);
1720 ipmi_cmdlang_unlock(cmd_info);
1721 if (cmd_info->lock)
1722 ipmi_destroy_lock(cmd_info->lock);
1723 ipmi_mem_free(cmd_info);
1724 } else
1725 ipmi_cmdlang_unlock(cmd_info);
1726 }
1727
1728 void
ipmi_cmdlang_get_int(char * str,int * val,ipmi_cmd_info_t * info)1729 ipmi_cmdlang_get_int(char *str, int *val, ipmi_cmd_info_t *info)
1730 {
1731 char *end;
1732 int rv;
1733
1734 if (info->cmdlang->err)
1735 return;
1736
1737 rv = strtoul(str, &end, 0);
1738 if (*end != '\0') {
1739 info->cmdlang->errstr = "Invalid integer";
1740 info->cmdlang->err = EINVAL;
1741 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_int)";
1742 return;
1743 }
1744
1745 *val = rv;
1746 }
1747
1748 void
ipmi_cmdlang_get_time(char * str,ipmi_time_t * val,ipmi_cmd_info_t * info)1749 ipmi_cmdlang_get_time(char *str, ipmi_time_t *val, ipmi_cmd_info_t *info)
1750 {
1751 char *end;
1752 ipmi_time_t rv;
1753
1754 if (info->cmdlang->err)
1755 return;
1756
1757 rv = strtoull(str, &end, 0);
1758 if (*end != '\0') {
1759 info->cmdlang->errstr = "Invalid integer";
1760 info->cmdlang->err = EINVAL;
1761 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_int)";
1762 return;
1763 }
1764
1765 *val = rv;
1766 }
1767
1768 void
ipmi_cmdlang_get_timeout(char * str,ipmi_timeout_t * val,ipmi_cmd_info_t * info)1769 ipmi_cmdlang_get_timeout(char *str, ipmi_timeout_t *val,
1770 ipmi_cmd_info_t *info)
1771 {
1772 char *end;
1773 ipmi_timeout_t rv;
1774
1775 if (info->cmdlang->err)
1776 return;
1777
1778 rv = strtoull(str, &end, 0);
1779 if (*end != '\0') {
1780 info->cmdlang->errstr = "Invalid integer";
1781 info->cmdlang->err = EINVAL;
1782 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_int)";
1783 return;
1784 }
1785
1786 *val = rv;
1787 }
1788
1789 void
ipmi_cmdlang_get_double(char * str,double * val,ipmi_cmd_info_t * info)1790 ipmi_cmdlang_get_double(char *str, double *val, ipmi_cmd_info_t *info)
1791 {
1792 char *end;
1793 double rv;
1794
1795 if (info->cmdlang->err)
1796 return;
1797
1798 rv = strtod(str, &end);
1799 if (*end != '\0') {
1800 info->cmdlang->errstr = "Invalid double";
1801 info->cmdlang->err = EINVAL;
1802 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_double)";
1803 return;
1804 }
1805
1806 *val = rv;
1807 }
1808
1809 void
ipmi_cmdlang_get_uchar(char * str,unsigned char * val,ipmi_cmd_info_t * info)1810 ipmi_cmdlang_get_uchar(char *str, unsigned char *val, ipmi_cmd_info_t *info)
1811 {
1812 char *end;
1813 int rv;
1814
1815 if (info->cmdlang->err)
1816 return;
1817
1818 rv = strtoul(str, &end, 0);
1819 if (*end != '\0') {
1820 info->cmdlang->errstr = "Invalid integer";
1821 info->cmdlang->err = EINVAL;
1822 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_uchar)";
1823 return;
1824 }
1825
1826 *val = rv;
1827 }
1828
1829 void
ipmi_cmdlang_get_bool(char * str,int * val,ipmi_cmd_info_t * info)1830 ipmi_cmdlang_get_bool(char *str, int *val, ipmi_cmd_info_t *info)
1831 {
1832 int rv;
1833
1834 if (info->cmdlang->err)
1835 return;
1836
1837 if ((strcasecmp(str, "true") == 0)
1838 || (strcasecmp(str, "on") == 0)
1839 || (strcasecmp(str, "t") == 0)
1840 || (strcmp(str, "1") == 0))
1841 {
1842 rv = 1;
1843 } else if ((strcasecmp(str, "false") == 0)
1844 || (strcasecmp(str, "off") == 0)
1845 || (strcasecmp(str, "f") == 0)
1846 || (strcmp(str, "0") == 0))
1847 {
1848 rv = 0;
1849 } else {
1850 info->cmdlang->errstr = "Invalid boolean";
1851 info->cmdlang->err = EINVAL;
1852 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_bool)";
1853 return;
1854 }
1855
1856 *val = rv;
1857 }
1858
1859 void
ipmi_cmdlang_get_user(char * str,int * val,ipmi_cmd_info_t * info)1860 ipmi_cmdlang_get_user(char *str, int *val, ipmi_cmd_info_t *info)
1861 {
1862 char *end;
1863 int rv;
1864
1865 if (info->cmdlang->err)
1866 return;
1867
1868 rv = strtoul(str, &end, 0);
1869 if (*end != '\0')
1870 goto not_int;
1871
1872 *val = rv;
1873 return;
1874
1875 not_int:
1876 if (strcmp(str, "callback") == 0)
1877 *val = IPMI_PRIVILEGE_CALLBACK;
1878 else if (strcmp(str, "user") == 0)
1879 *val = IPMI_PRIVILEGE_USER;
1880 else if (strcmp(str, "operator") == 0)
1881 *val = IPMI_PRIVILEGE_OPERATOR;
1882 else if (strcmp(str, "admin") == 0)
1883 *val = IPMI_PRIVILEGE_ADMIN;
1884 else if (strcmp(str, "oem") == 0)
1885 *val = IPMI_PRIVILEGE_OEM;
1886 else {
1887 info->cmdlang->errstr = "Invalid privilege level";
1888 info->cmdlang->err = EINVAL;
1889 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_user)";
1890 }
1891 }
1892
1893 void
ipmi_cmdlang_get_ip(char * str,struct in_addr * val,ipmi_cmd_info_t * info)1894 ipmi_cmdlang_get_ip(char *str, struct in_addr *val, ipmi_cmd_info_t *info)
1895 {
1896 #ifdef HAVE_GETADDRINFO
1897 struct addrinfo hints, *res0;
1898 int rv;
1899 struct sockaddr_in *paddr;
1900
1901 if (info->cmdlang->err)
1902 return;
1903
1904 memset(&hints, 0, sizeof(hints));
1905 hints.ai_family = PF_INET;
1906 hints.ai_socktype = SOCK_DGRAM;
1907 rv = getaddrinfo(str, 0, &hints, &res0);
1908 if (rv == 0) {
1909 /* Only get the first choice */
1910 paddr = (struct sockaddr_in *) res0->ai_addr;
1911 *val = paddr->sin_addr;
1912 freeaddrinfo(res0);
1913 } else
1914 info->cmdlang->err = rv;
1915 #else
1916 /* System does not support getaddrinfo, just for IPv4*/
1917 struct hostent *ent;
1918 struct sockaddr_in *paddr;
1919
1920 if (info->cmdlang->err)
1921 return;
1922
1923 ent = gethostbyname(str);
1924 if (!ent) {
1925 info->cmdlang->err = EINVAL;
1926 } else {
1927 paddr = (struct sockaddr_in *) &ent->h_addr_list[0];
1928 *val = paddr->sin_addr;
1929 memcpy(val, ent->h_addr_list[0], ent->h_length);
1930 }
1931 #endif
1932 }
1933
1934 void
ipmi_cmdlang_get_mac(char * str,unsigned char val[6],ipmi_cmd_info_t * info)1935 ipmi_cmdlang_get_mac(char *str, unsigned char val[6], ipmi_cmd_info_t *info)
1936 {
1937 char tmp[3];
1938 char *tv;
1939 int len;
1940 unsigned char tmp_val[6];
1941 int i;
1942 char *end;
1943
1944 if (info->cmdlang->err)
1945 return;
1946
1947 for (i=0; i<6; i++) {
1948 if (i == 5)
1949 tv = str + strlen(str);
1950 else
1951 tv = strchr(str, ':');
1952 if (!tv) {
1953 info->cmdlang->err = EINVAL;
1954 goto out;
1955 }
1956 len = tv-str;
1957 if (len > 2) {
1958 info->cmdlang->err = EINVAL;
1959 goto out;
1960 }
1961 memset(tmp, 0, sizeof(tmp));
1962 memcpy(tmp, str, len);
1963 tmp_val[i] = strtoul(tmp, &end, 16);
1964 if (*end != '\0') {
1965 info->cmdlang->err = EINVAL;
1966 goto out;
1967 }
1968 str = tv+1;
1969 }
1970
1971 memcpy(val, tmp_val, sizeof(tmp_val));
1972 return;
1973
1974 out:
1975 return;
1976 }
1977
1978 void
ipmi_cmdlang_get_color(char * str,int * val,ipmi_cmd_info_t * info)1979 ipmi_cmdlang_get_color(char *str, int *val, ipmi_cmd_info_t *info)
1980 {
1981 int i;
1982
1983 for (i=IPMI_CONTROL_COLOR_BLACK; i<IPMI_CONTROL_COLOR_ORANGE; i++){
1984 if (strcmp(str, ipmi_get_color_string(i)) == 0) {
1985 *val = i;
1986 return;
1987 }
1988 }
1989
1990 info->cmdlang->errstr = "Invalid color";
1991 info->cmdlang->err = EINVAL;
1992 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_color)";
1993 }
1994
1995 static int
issep(char val)1996 issep(char val)
1997 {
1998 return ((val == ' ')
1999 || (val == '\t')
2000 || (val == '\n')
2001 || (val == '\r'));
2002 }
2003
2004 void
ipmi_cmdlang_get_threshold_ev(char * str,enum ipmi_thresh_e * rthresh,enum ipmi_event_value_dir_e * rvalue_dir,enum ipmi_event_dir_e * rdir,ipmi_cmd_info_t * info)2005 ipmi_cmdlang_get_threshold_ev(char *str,
2006 enum ipmi_thresh_e *rthresh,
2007 enum ipmi_event_value_dir_e *rvalue_dir,
2008 enum ipmi_event_dir_e *rdir,
2009 ipmi_cmd_info_t *info)
2010 {
2011 enum ipmi_thresh_e thresh;
2012 enum ipmi_event_value_dir_e value_dir;
2013 enum ipmi_event_dir_e dir;
2014 char val[4][20];
2015 int len;
2016 int vc;
2017
2018
2019 vc = 0;
2020 for (;;) {
2021 char *start, *end;
2022
2023 while (issep(*str))
2024 str++;
2025 if (! *str)
2026 break;
2027
2028 if (vc == 4)
2029 goto out_err;
2030
2031 start = str;
2032 while (*str && (!issep(*str)))
2033 str++;
2034 end = str;
2035 len = end - start;
2036 if (len >= 20)
2037 goto out_err;
2038
2039 memcpy(val[vc], start, len);
2040 val[vc][len] = '\0';
2041 vc++;
2042 }
2043
2044 if (vc == 1) {
2045 /* One value, it is a compressed form. */
2046 if (strlen(val[0]) != 4)
2047 goto out_err;
2048
2049 if ((val[0][0] == 'u') || (val[0][0] == 'U')) {
2050 if ((val[0][1] == 'n') || (val[0][1] == 'N'))
2051 thresh = IPMI_UPPER_NON_CRITICAL;
2052 else if ((val[0][1] == 'c') || (val[0][1] == 'C'))
2053 thresh = IPMI_UPPER_CRITICAL;
2054 else if ((val[0][1] == 'f') || (val[0][1] == 'F'))
2055 thresh = IPMI_UPPER_NON_RECOVERABLE;
2056 else if ((val[0][1] == 'r') || (val[0][1] == 'R'))
2057 thresh = IPMI_UPPER_NON_RECOVERABLE;
2058 else
2059 goto out_err;
2060 } else if ((val[0][0] == 'l') || (val[0][0] == 'L')) {
2061 if ((val[0][1] == 'n') || (val[0][1] == 'N'))
2062 thresh = IPMI_LOWER_NON_CRITICAL;
2063 else if ((val[0][1] == 'c') || (val[0][1] == 'C'))
2064 thresh = IPMI_LOWER_CRITICAL;
2065 else if ((val[0][1] == 'f') || (val[0][1] == 'F'))
2066 thresh = IPMI_LOWER_NON_RECOVERABLE;
2067 else if ((val[0][1] == 'r') || (val[0][1] == 'R'))
2068 thresh = IPMI_LOWER_NON_RECOVERABLE;
2069 else
2070 goto out_err;
2071 } else
2072 goto out_err;
2073
2074 if ((val[0][2] == 'h') || (val[0][2] == 'H'))
2075 value_dir = IPMI_GOING_HIGH;
2076 else if ((val[0][2] == 'l') || (val[0][2] == 'L'))
2077 value_dir = IPMI_GOING_LOW;
2078 else
2079 goto out_err;
2080
2081 if ((val[0][3] == 'a') || (val[0][2] == 'A'))
2082 dir = IPMI_ASSERTION;
2083 else if ((val[0][3] == 'd') || (val[0][3] == 'D'))
2084 dir = IPMI_DEASSERTION;
2085 else
2086 goto out_err;
2087 } else if (vc == 4) {
2088 /* Four values, uncompressed form */
2089 if (strcasecmp(val[0], "upper") == 0) {
2090 if (strcasecmp(val[1], "non-critical") == 0)
2091 thresh = IPMI_UPPER_NON_CRITICAL;
2092 else if (strcasecmp(val[1], "critical") == 0)
2093 thresh = IPMI_UPPER_CRITICAL;
2094 else if (strcasecmp(val[1], "non-recoverable") == 0)
2095 thresh = IPMI_UPPER_NON_RECOVERABLE;
2096 else
2097 goto out_err;
2098 } else if (strcasecmp(val[0], "lower") == 0) {
2099 if (strcasecmp(val[1], "non-critical") == 0)
2100 thresh = IPMI_LOWER_NON_CRITICAL;
2101 else if (strcasecmp(val[1], "critical") == 0)
2102 thresh = IPMI_LOWER_CRITICAL;
2103 else if (strcasecmp(val[1], "non-recoverable") == 0)
2104 thresh = IPMI_LOWER_NON_RECOVERABLE;
2105 else
2106 goto out_err;
2107 } else
2108 goto out_err;
2109
2110 if (strcasecmp(val[2], "going-high") == 0)
2111 value_dir = IPMI_GOING_HIGH;
2112 else if (strcasecmp(val[2], "going-low") == 0)
2113 value_dir = IPMI_GOING_LOW;
2114 else
2115 goto out_err;
2116
2117 if (strcasecmp(val[3], "assertion") == 0)
2118 dir = IPMI_ASSERTION;
2119 else if (strcasecmp(val[3], "deassertion") == 0)
2120 dir = IPMI_DEASSERTION;
2121 else
2122 goto out_err;
2123 } else
2124 goto out_err;
2125 if (rdir)
2126 *rdir = dir;
2127 if (rvalue_dir)
2128 *rvalue_dir = value_dir;
2129 if (rthresh)
2130 *rthresh = thresh;
2131 return;
2132
2133 out_err:
2134 info->cmdlang->errstr = "Invalid threshold event";
2135 info->cmdlang->err = EINVAL;
2136 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_threshold_ev)";
2137 }
2138
2139 void
ipmi_cmdlang_get_threshold(char * str,enum ipmi_thresh_e * rthresh,ipmi_cmd_info_t * info)2140 ipmi_cmdlang_get_threshold(char *str,
2141 enum ipmi_thresh_e *rthresh,
2142 ipmi_cmd_info_t *info)
2143 {
2144 enum ipmi_thresh_e thresh;
2145
2146 for (thresh = IPMI_LOWER_NON_CRITICAL;
2147 thresh <= IPMI_UPPER_NON_RECOVERABLE;
2148 thresh++)
2149 {
2150 if (strcmp(str, ipmi_get_threshold_string(thresh)) == 0) {
2151 if (rthresh)
2152 *rthresh = thresh;
2153 return;
2154 }
2155 }
2156 if (strcasecmp(str, "un") == 0)
2157 thresh = IPMI_UPPER_NON_CRITICAL;
2158 else if (strcasecmp(str, "uc") == 0)
2159 thresh = IPMI_UPPER_CRITICAL;
2160 else if (strcasecmp(str, "ur") == 0)
2161 thresh = IPMI_UPPER_NON_RECOVERABLE;
2162 else if (strcasecmp(str, "ln") == 0)
2163 thresh = IPMI_LOWER_NON_CRITICAL;
2164 else if (strcasecmp(str, "lc") == 0)
2165 thresh = IPMI_LOWER_CRITICAL;
2166 else if (strcasecmp(str, "lr") == 0)
2167 thresh = IPMI_LOWER_NON_RECOVERABLE;
2168 else
2169 goto out_err;
2170
2171 if (rthresh)
2172 *rthresh = thresh;
2173 return;
2174
2175 out_err:
2176 info->cmdlang->errstr = "Invalid threshold";
2177 info->cmdlang->err = EINVAL;
2178 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_threshold)";
2179 }
2180
2181 void
ipmi_cmdlang_get_discrete_ev(char * str,int * roffset,enum ipmi_event_dir_e * rdir,ipmi_cmd_info_t * info)2182 ipmi_cmdlang_get_discrete_ev(char *str,
2183 int *roffset,
2184 enum ipmi_event_dir_e *rdir,
2185 ipmi_cmd_info_t *info)
2186 {
2187 int offset;
2188 enum ipmi_event_dir_e dir;
2189 char val[4][20];
2190 int len;
2191 int vc;
2192 char *end;
2193
2194
2195 vc = 0;
2196 for (;;) {
2197 char *start, *end;
2198
2199 while (issep(*str))
2200 str++;
2201 if (! *str)
2202 break;
2203
2204 if (vc == 4)
2205 goto out_err;
2206
2207 start = str;
2208 while (*str && (!issep(*str)))
2209 str++;
2210 end = str;
2211 len = end - start;
2212 if (len >= 20)
2213 goto out_err;
2214
2215 memcpy(val[vc], start, len);
2216 val[vc][len] = '\0';
2217 vc++;
2218 }
2219
2220 if (vc == 1) {
2221 /* One value, it is a compressed form. */
2222
2223 offset = strtoul(val[0], &end, 0);
2224 if (end == val[0])
2225 goto out_err;
2226 if ((*end == 'd') || (*end == 'D'))
2227 dir = IPMI_DEASSERTION;
2228 else if ((*end == 'a') || (*end == 'A'))
2229 dir = IPMI_ASSERTION;
2230 else
2231 goto out_err;
2232 end++;
2233 if (*end != '\0')
2234 goto out_err;
2235 } else if (vc == 2) {
2236 offset = strtoul(val[0], &end, 0);
2237 if ((end == val[0]) || (*end != '\0'))
2238 goto out_err;
2239 if (strcasecmp(val[1], "deassertion") == 0)
2240 dir = IPMI_DEASSERTION;
2241 else if (strcasecmp(val[1], "assertion") == 0)
2242 dir = IPMI_ASSERTION;
2243 else
2244 goto out_err;
2245 } else
2246 goto out_err;
2247
2248 if (roffset)
2249 *roffset = offset;
2250 if (rdir)
2251 *rdir = dir;
2252 return;
2253
2254 out_err:
2255 info->cmdlang->errstr = "Invalid discrete event";
2256 info->cmdlang->err = EINVAL;
2257 info->cmdlang->location = "cmdlang.c(ipmi_cmdlang_get_discrete_event)";
2258 }
2259
2260 typedef struct ipmi_cmdlang_event_entry_s ipmi_cmdlang_event_entry_t;
2261 struct ipmi_cmdlang_event_entry_s
2262 {
2263 char *name;
2264 enum ipmi_cmdlang_out_types type;
2265 char *value;
2266 unsigned int len;
2267 int level;
2268 ipmi_cmdlang_event_entry_t *next;
2269 };
2270
2271 struct ipmi_cmdlang_event_s
2272 {
2273 int curr_level;
2274 ipmi_cmd_info_t *info;
2275 ipmi_cmdlang_event_entry_t *head, *tail;
2276 ipmi_cmdlang_event_entry_t *curr;
2277 };
2278
2279 void
event_out(ipmi_cmdlang_t * cmdlang,const char * name,const char * value)2280 event_out(ipmi_cmdlang_t *cmdlang, const char *name, const char *value)
2281 {
2282 ipmi_cmdlang_event_entry_t *entry;
2283 ipmi_cmdlang_event_t *event = cmdlang->user_data;
2284
2285 if (cmdlang->err)
2286 return;
2287
2288 entry = ipmi_mem_alloc(sizeof(*entry));
2289 if (!entry)
2290 goto out_nomem;
2291
2292 entry->name = ipmi_strdup(name);
2293 if (!entry->name) {
2294 ipmi_mem_free(entry);
2295 goto out_nomem;
2296 }
2297
2298 entry->type = IPMI_CMDLANG_STRING;
2299
2300 if (value) {
2301 entry->len = strlen(value);
2302 entry->value = ipmi_strdup(value);
2303 if (!entry->value) {
2304 ipmi_mem_free(entry->name);
2305 ipmi_mem_free(entry);
2306 goto out_nomem;
2307 }
2308 } else {
2309 entry->len = 0;
2310 entry->value = NULL;
2311 }
2312
2313 entry->level = event->curr_level;
2314
2315 entry->next = NULL;
2316 if (event->head) {
2317 event->tail->next = entry;
2318 event->tail = entry;
2319 } else {
2320 event->head = entry;
2321 event->tail = entry;
2322 }
2323
2324 return;
2325
2326 out_nomem:
2327 cmdlang->err = ENOMEM;
2328 cmdlang->errstr = "Out of memory";
2329 cmdlang->location = "cmdlang.c(event_out)";
2330 }
2331
2332 static void
event_out_binary(ipmi_cmdlang_t * cmdlang,const char * name,const char * value,unsigned int len)2333 event_out_binary(ipmi_cmdlang_t *cmdlang, const char *name,
2334 const char *value, unsigned int len)
2335 {
2336 ipmi_cmdlang_event_entry_t *entry;
2337 ipmi_cmdlang_event_t *event = cmdlang->user_data;
2338
2339 if (cmdlang->err)
2340 return;
2341
2342 entry = ipmi_mem_alloc(sizeof(*entry));
2343 if (!entry)
2344 goto out_nomem;
2345
2346 entry->name = ipmi_strdup(name);
2347 if (!entry->name) {
2348 ipmi_mem_free(entry);
2349 goto out_nomem;
2350 }
2351
2352 entry->type = IPMI_CMDLANG_BINARY;
2353
2354 entry->len = len;
2355 if (len > 0) {
2356 entry->value = ipmi_mem_alloc(len);
2357 if (!entry->value) {
2358 ipmi_mem_free(entry->name);
2359 ipmi_mem_free(entry);
2360 goto out_nomem;
2361 }
2362 memcpy(entry->value, value, len);
2363 } else
2364 entry->value = NULL;
2365
2366 entry->level = event->curr_level;
2367
2368 entry->next = NULL;
2369 if (event->head) {
2370 event->tail->next = entry;
2371 event->tail = entry;
2372 } else {
2373 event->head = entry;
2374 event->tail = entry;
2375 }
2376
2377 return;
2378
2379 out_nomem:
2380 cmdlang->err = ENOMEM;
2381 cmdlang->errstr = "Out of memory";
2382 cmdlang->location = "cmdlang.c(event_out_binary)";
2383 }
2384
2385 static void
event_out_unicode(ipmi_cmdlang_t * cmdlang,const char * name,const char * value,unsigned int len)2386 event_out_unicode(ipmi_cmdlang_t *cmdlang, const char *name,
2387 const char *value, unsigned int len)
2388 {
2389 ipmi_cmdlang_event_entry_t *entry;
2390 ipmi_cmdlang_event_t *event = cmdlang->user_data;
2391
2392 if (cmdlang->err)
2393 return;
2394
2395 entry = ipmi_mem_alloc(sizeof(*entry));
2396 if (!entry)
2397 goto out_nomem;
2398
2399 entry->name = ipmi_strdup(name);
2400 if (!entry->name) {
2401 ipmi_mem_free(entry);
2402 goto out_nomem;
2403 }
2404
2405 entry->type = IPMI_CMDLANG_UNICODE;
2406
2407 entry->len = len;
2408 if (len > 0) {
2409 entry->value = ipmi_mem_alloc(len);
2410 if (!entry->value) {
2411 ipmi_mem_free(entry->name);
2412 ipmi_mem_free(entry);
2413 goto out_nomem;
2414 }
2415 memcpy(entry->value, value, len);
2416 } else
2417 entry->value = NULL;
2418
2419 entry->level = event->curr_level;
2420
2421 entry->next = NULL;
2422 if (event->head) {
2423 event->tail->next = entry;
2424 event->tail = entry;
2425 } else {
2426 event->head = entry;
2427 event->tail = entry;
2428 }
2429
2430 return;
2431
2432 out_nomem:
2433 cmdlang->err = ENOMEM;
2434 cmdlang->errstr = "Out of memory";
2435 cmdlang->location = "cmdlang.c(event_out_binary)";
2436 }
2437
2438 void
event_up(ipmi_cmdlang_t * cmdlang)2439 event_up(ipmi_cmdlang_t *cmdlang)
2440 {
2441 ipmi_cmdlang_event_t *event = cmdlang->user_data;
2442
2443 if (cmdlang->err)
2444 return;
2445
2446 event->curr_level--;
2447 }
2448
2449 void
event_down(ipmi_cmdlang_t * cmdlang)2450 event_down(ipmi_cmdlang_t *cmdlang)
2451 {
2452 ipmi_cmdlang_event_t *event = cmdlang->user_data;
2453
2454 if (cmdlang->err)
2455 return;
2456
2457 event->curr_level++;
2458 }
2459
2460 void
event_done(ipmi_cmdlang_t * cmdlang)2461 event_done(ipmi_cmdlang_t *cmdlang)
2462 {
2463 ipmi_cmdlang_event_entry_t *entry;
2464 ipmi_cmdlang_event_t *event = cmdlang->user_data;
2465 ipmi_cmd_info_t *info = event->info;
2466
2467 if (strlen(info->cmdlang->objstr) == 0) {
2468 ipmi_mem_free(info->cmdlang->objstr);
2469 cmdlang->objstr = NULL;
2470 }
2471
2472 if (info->cmdlang->err) {
2473 ipmi_cmdlang_global_err(cmdlang->objstr,
2474 cmdlang->location,
2475 cmdlang->errstr,
2476 cmdlang->err);
2477 if (cmdlang->errstr_dynalloc)
2478 ipmi_mem_free(cmdlang->errstr);
2479 } else {
2480 ipmi_cmdlang_report_event(event);
2481 }
2482
2483 if (cmdlang->objstr)
2484 ipmi_mem_free(cmdlang->objstr);
2485 ipmi_mem_free(cmdlang);
2486
2487 entry = event->head;
2488 while (entry) {
2489 event->head = entry->next;
2490 ipmi_mem_free(entry->name);
2491 if (entry->value)
2492 ipmi_mem_free(entry->value);
2493 ipmi_mem_free(entry);
2494 entry = event->head;
2495 }
2496 ipmi_mem_free(event);
2497 }
2498
2499 ipmi_cmd_info_t *
ipmi_cmdlang_alloc_event_info(void)2500 ipmi_cmdlang_alloc_event_info(void)
2501 {
2502 ipmi_cmd_info_t *cmdinfo = NULL;
2503 ipmi_cmdlang_event_t *event;
2504 int rv;
2505
2506 cmdinfo = ipmi_mem_alloc(sizeof(*cmdinfo));
2507 if (!cmdinfo)
2508 return NULL;
2509 memset(cmdinfo, 0, sizeof(*cmdinfo));
2510 cmdinfo->usecount = 1;
2511
2512 rv = ipmi_create_lock_os_hnd(cmdlang_os_hnd, &cmdinfo->lock);
2513 if (rv) {
2514 ipmi_mem_free(cmdinfo);
2515 return NULL;
2516 }
2517
2518 cmdinfo->cmdlang = ipmi_mem_alloc(sizeof(*cmdinfo->cmdlang));
2519 if (!cmdinfo->cmdlang) {
2520 ipmi_destroy_lock(cmdinfo->lock);
2521 ipmi_mem_free(cmdinfo);
2522 return NULL;
2523 }
2524 memset(cmdinfo->cmdlang, 0, sizeof(*cmdinfo->cmdlang));
2525
2526 cmdinfo->cmdlang->objstr = ipmi_mem_alloc(IPMI_MAX_NAME_LEN);
2527 if (!cmdinfo->cmdlang->objstr) {
2528 ipmi_mem_free(cmdinfo->cmdlang);
2529 ipmi_destroy_lock(cmdinfo->lock);
2530 ipmi_mem_free(cmdinfo);
2531 return NULL;
2532 }
2533 cmdinfo->cmdlang->objstr[0] = '\0';
2534 cmdinfo->cmdlang->objstr_len = IPMI_MAX_NAME_LEN;
2535
2536 cmdinfo->cmdlang->user_data = ipmi_mem_alloc(sizeof(ipmi_cmdlang_event_t));
2537 if (!cmdinfo->cmdlang->user_data) {
2538 ipmi_mem_free(cmdinfo->cmdlang->objstr);
2539 ipmi_mem_free(cmdinfo->cmdlang);
2540 ipmi_destroy_lock(cmdinfo->lock);
2541 ipmi_mem_free(cmdinfo);
2542 return NULL;
2543 }
2544
2545 event = cmdinfo->cmdlang->user_data;
2546 memset(event, 0, sizeof(*event));
2547 event->info = cmdinfo;
2548
2549 cmdinfo->cmdlang->out = event_out;
2550 cmdinfo->cmdlang->down = event_down;
2551 cmdinfo->cmdlang->out_binary = event_out_binary;
2552 cmdinfo->cmdlang->out_unicode = event_out_unicode;
2553 cmdinfo->cmdlang->up = event_up;
2554 cmdinfo->cmdlang->done = event_done;
2555
2556 return cmdinfo;
2557 }
2558
2559 /* Move to the first field. */
2560 void
ipmi_cmdlang_event_restart(ipmi_cmdlang_event_t * event)2561 ipmi_cmdlang_event_restart(ipmi_cmdlang_event_t *event)
2562 {
2563 event->curr = event->head;
2564 }
2565
2566 /* Returns true if successful, false if no more fields left. */
2567 int
ipmi_cmdlang_event_next_field(ipmi_cmdlang_event_t * event,unsigned int * level,enum ipmi_cmdlang_out_types * type,char ** name,unsigned int * len,char ** value)2568 ipmi_cmdlang_event_next_field(ipmi_cmdlang_event_t *event,
2569 unsigned int *level,
2570 enum ipmi_cmdlang_out_types *type,
2571 char **name,
2572 unsigned int *len,
2573 char **value)
2574 {
2575 ipmi_cmdlang_event_entry_t *curr = event->curr;
2576
2577 if (!curr)
2578 return 0;
2579
2580 if (level)
2581 *level = curr->level;
2582 if (name)
2583 *name = curr->name;
2584 if (value)
2585 *value = curr->value;
2586 if (type)
2587 *type = curr->type;
2588 if (len)
2589 *len = curr->len;
2590
2591 event->curr = curr->next;
2592 return 1;
2593 }
2594
2595 int
ipmi_cmdlang_get_argc(ipmi_cmd_info_t * info)2596 ipmi_cmdlang_get_argc(ipmi_cmd_info_t *info)
2597 {
2598 return info->argc;
2599 }
2600
2601 char **
ipmi_cmdlang_get_argv(ipmi_cmd_info_t * info)2602 ipmi_cmdlang_get_argv(ipmi_cmd_info_t *info)
2603 {
2604 return info->argv;
2605 }
2606
2607 int
ipmi_cmdlang_get_curr_arg(ipmi_cmd_info_t * info)2608 ipmi_cmdlang_get_curr_arg(ipmi_cmd_info_t *info)
2609 {
2610 return info->curr_arg;
2611 }
2612
2613 ipmi_cmdlang_t *
ipmi_cmdinfo_get_cmdlang(ipmi_cmd_info_t * info)2614 ipmi_cmdinfo_get_cmdlang(ipmi_cmd_info_t *info)
2615 {
2616 return info->cmdlang;
2617 }
2618
2619 static void
evinfo(ipmi_cmd_info_t * cmd_info)2620 evinfo(ipmi_cmd_info_t *cmd_info)
2621 {
2622 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
2623 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
2624 int argc = ipmi_cmdlang_get_argc(cmd_info);
2625 char **argv = ipmi_cmdlang_get_argv(cmd_info);
2626 int do_evinfo;
2627
2628 if ((argc - curr_arg) < 1) {
2629 cmdlang->errstr = "True or False not entered";
2630 cmdlang->err = EINVAL;
2631 goto out_err;
2632 }
2633
2634 ipmi_cmdlang_get_bool(argv[curr_arg], &do_evinfo, cmd_info);
2635 if (cmdlang->err) {
2636 cmdlang->errstr = "True or False not entered";
2637 cmdlang->err = EINVAL;
2638 goto out_err;
2639 }
2640
2641 ipmi_cmdlang_set_evinfo(do_evinfo);
2642 ipmi_cmdlang_out(cmd_info, "event info set", NULL);
2643 return;
2644
2645 out_err:
2646 cmdlang->location = "cmdlang.c(evinfo)";
2647 }
2648
2649 static void
debug(ipmi_cmd_info_t * cmd_info)2650 debug(ipmi_cmd_info_t *cmd_info)
2651 {
2652 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
2653 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
2654 int argc = ipmi_cmdlang_get_argc(cmd_info);
2655 char **argv = ipmi_cmdlang_get_argv(cmd_info);
2656 char *type;
2657 int val;
2658
2659 if ((argc - curr_arg) < 2) {
2660 cmdlang->errstr = "Not enough parameters";
2661 cmdlang->err = EINVAL;
2662 goto out_err;
2663 }
2664
2665 type = argv[curr_arg];
2666 curr_arg++;
2667
2668 ipmi_cmdlang_get_bool(argv[curr_arg], &val, cmd_info);
2669 if (cmdlang->err) {
2670 cmdlang->errstr = "Invalid boolean setting";
2671 cmdlang->err = EINVAL;
2672 goto out_err;
2673 }
2674
2675 if (strcmp(type, "msg") == 0) {
2676 if (val) DEBUG_MSG_ENABLE(); else DEBUG_MSG_DISABLE();
2677 } else if (strcmp(type, "msgerr") == 0) {
2678 if (val) DEBUG_MSG_ERR_ENABLE(); else DEBUG_MSG_ERR_DISABLE();
2679 } else if (strcmp(type, "rawmsg") == 0) {
2680 if (val) DEBUG_RAWMSG_ENABLE(); else DEBUG_RAWMSG_DISABLE();
2681 } else if (strcmp(type, "locks") == 0) {
2682 if (val) DEBUG_LOCKS_ENABLE(); else DEBUG_LOCKS_DISABLE();
2683 } else if (strcmp(type, "events") == 0) {
2684 if (val) DEBUG_EVENTS_ENABLE(); else DEBUG_EVENTS_DISABLE();
2685 } else if (strcmp(type, "con0") == 0) {
2686 if (val) DEBUG_CON_FAIL_ENABLE(0); else DEBUG_CON_FAIL_DISABLE(0);
2687 } else if (strcmp(type, "con1") == 0) {
2688 if (val) DEBUG_CON_FAIL_ENABLE(1); else DEBUG_CON_FAIL_DISABLE(1);
2689 } else if (strcmp(type, "con2") == 0) {
2690 if (val) DEBUG_CON_FAIL_ENABLE(2); else DEBUG_CON_FAIL_DISABLE(2);
2691 } else if (strcmp(type, "con3") == 0) {
2692 if (val) DEBUG_CON_FAIL_ENABLE(3); else DEBUG_CON_FAIL_DISABLE(3);
2693 } else {
2694 cmdlang->errstr = "Invalid debug setting";
2695 cmdlang->err = EINVAL;
2696 goto out_err;
2697 }
2698
2699 ipmi_cmdlang_out(cmd_info, "Debugging set", NULL);
2700 return;
2701
2702 out_err:
2703 if (cmdlang->err)
2704 cmdlang->location = "cmdlang.c(debug)";
2705 }
2706
2707 static ipmi_cmdlang_init_t cmds_global[] =
2708 {
2709 { "evinfo", NULL,
2710 "true | false - Enable/disable printing info about the object"
2711 " when an event is reported on it (such as entity info, domain"
2712 " info, etc.)",
2713 evinfo, NULL, NULL },
2714 { "debug", NULL,
2715 "<type> true | false - "
2716 " Turn on/off the specific debugging. The debugging types are:"
2717 " msg, rawmsg, events, con0, con1, con2, con3. This is primarily"
2718 " for designers of OpenIPMI trying to debug problems.",
2719 debug, NULL, NULL },
2720 };
2721 #define CMDS_GLOBAL_LEN (sizeof(cmds_global)/sizeof(ipmi_cmdlang_init_t))
2722
2723 int ipmi_cmdlang_domain_init(os_handler_t *os_hnd);
2724 int ipmi_cmdlang_con_init(os_handler_t *os_hnd);
2725 int ipmi_cmdlang_entity_init(os_handler_t *os_hnd);
2726 int ipmi_cmdlang_mc_init(os_handler_t *os_hnd);
2727 int ipmi_cmdlang_pet_init(os_handler_t *os_hnd);
2728 int ipmi_cmdlang_lanparm_init(os_handler_t *os_hnd);
2729 int ipmi_cmdlang_solparm_init(os_handler_t *os_hnd);
2730 int ipmi_cmdlang_fru_init(os_handler_t *os_hnd);
2731 void ipmi_cmdlang_lanparm_shutdown();
2732 void ipmi_cmdlang_solparm_shutdown();
2733 int ipmi_cmdlang_pef_init(os_handler_t *os_hnd);
2734 void ipmi_cmdlang_pef_shutdown();
2735 int ipmi_cmdlang_sensor_init(os_handler_t *os_hnd);
2736 int ipmi_cmdlang_control_init(os_handler_t *os_hnd);
2737 int ipmi_cmdlang_sel_init(os_handler_t *os_hnd);
2738
2739 int
ipmi_cmdlang_init(os_handler_t * os_hnd)2740 ipmi_cmdlang_init(os_handler_t *os_hnd)
2741 {
2742 int rv;
2743
2744 rv = ipmi_cmdlang_domain_init(os_hnd);
2745 if (rv) return rv;
2746
2747 rv = ipmi_cmdlang_con_init(os_hnd);
2748 if (rv) return rv;
2749
2750 rv = ipmi_cmdlang_entity_init(os_hnd);
2751 if (rv) return rv;
2752
2753 rv = ipmi_cmdlang_mc_init(os_hnd);
2754 if (rv) return rv;
2755
2756 rv = ipmi_cmdlang_pet_init(os_hnd);
2757 if (rv) return rv;
2758
2759 rv = ipmi_cmdlang_lanparm_init(os_hnd);
2760 if (rv) return rv;
2761
2762 rv = ipmi_cmdlang_solparm_init(os_hnd);
2763 if (rv) return rv;
2764
2765 rv = ipmi_cmdlang_fru_init(os_hnd);
2766 if (rv) return rv;
2767
2768 rv = ipmi_cmdlang_pef_init(os_hnd);
2769 if (rv) return rv;
2770
2771 rv = ipmi_cmdlang_sensor_init(os_hnd);
2772 if (rv) return rv;
2773
2774 rv = ipmi_cmdlang_control_init(os_hnd);
2775 if (rv) return rv;
2776
2777 rv = ipmi_cmdlang_sel_init(os_hnd);
2778 if (rv) return rv;
2779
2780 rv = ipmi_cmdlang_reg_table(cmds_global, CMDS_GLOBAL_LEN);
2781 if (rv) return rv;
2782
2783 return 0;
2784 }
2785
2786 static void
cleanup_level(ipmi_cmdlang_cmd_t * cmds)2787 cleanup_level(ipmi_cmdlang_cmd_t *cmds)
2788 {
2789 ipmi_cmdlang_cmd_t *cmd;
2790
2791 while (cmds) {
2792 cmd = cmds;
2793 cmds = cmd->next;
2794 if (cmd->subcmds)
2795 cleanup_level(cmd->subcmds);
2796 ipmi_mem_free(cmd);
2797 }
2798 }
2799
2800 void
ipmi_cmdlang_cleanup(void)2801 ipmi_cmdlang_cleanup(void)
2802 {
2803 ipmi_cmdlang_pef_shutdown();
2804 ipmi_cmdlang_lanparm_shutdown();
2805 ipmi_cmdlang_solparm_shutdown();
2806 cleanup_level(cmd_list);
2807 }
2808
2809 static int do_evinfo = 0;
2810
2811 void
ipmi_cmdlang_set_evinfo(int evinfo)2812 ipmi_cmdlang_set_evinfo(int evinfo)
2813 {
2814 do_evinfo = evinfo;
2815 }
2816
2817 int
ipmi_cmdlang_get_evinfo(void)2818 ipmi_cmdlang_get_evinfo(void)
2819 {
2820 return do_evinfo;
2821 }
2822