1 /*
2  * cmd_domain.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 #include <errno.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <OpenIPMI/ipmiif.h>
40 #include <OpenIPMI/ipmi_mc.h>
41 #include <OpenIPMI/ipmi_err.h>
42 #include <OpenIPMI/ipmi_cmdlang.h>
43 #include <OpenIPMI/ipmi_fru.h>
44 #include <OpenIPMI/ipmi_conn.h>
45 
46 /* Internal includes, do not use in your programs */
47 #include <OpenIPMI/internal/ipmi_malloc.h>
48 
49 /* Don't pollute the namespace iwth ipmi_fru_t. */
50 void ipmi_cmdlang_dump_fru_info(ipmi_cmd_info_t *cmd_info, ipmi_fru_t *fru);
51 
52 static void
domain_list_handler(ipmi_domain_t * domain,void * cb_data)53 domain_list_handler(ipmi_domain_t *domain, void *cb_data)
54 {
55     ipmi_cmd_info_t *cmd_info = cb_data;
56     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
57     char            domain_name[IPMI_DOMAIN_NAME_LEN];
58 
59     if (cmdlang->err)
60 	return;
61 
62     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
63 
64     ipmi_cmdlang_out(cmd_info, "Name", domain_name);
65 }
66 
67 static void
domain_list(ipmi_cmd_info_t * cmd_info)68 domain_list(ipmi_cmd_info_t *cmd_info)
69 {
70     ipmi_cmdlang_out(cmd_info, "Domains", NULL);
71     ipmi_cmdlang_down(cmd_info);
72     ipmi_domain_iterate_domains(domain_list_handler, cmd_info);
73     ipmi_cmdlang_up(cmd_info);
74 }
75 
76 static void
domain_info(ipmi_domain_t * domain,void * cb_data)77 domain_info(ipmi_domain_t *domain, void *cb_data)
78 {
79     ipmi_cmd_info_t *cmd_info = cb_data;
80     char            domain_name[IPMI_DOMAIN_NAME_LEN];
81     unsigned char   guid[16];
82 
83     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
84 
85     ipmi_cmdlang_out(cmd_info, "Domain", NULL);
86     ipmi_cmdlang_down(cmd_info);
87     ipmi_cmdlang_out(cmd_info, "Name", domain_name);
88     if (ipmi_domain_get_guid(domain, guid) == 0)
89 	ipmi_cmdlang_out_binary(cmd_info, "GUID", (char *) guid, 16);
90     ipmi_cmdlang_out(cmd_info, "Type",
91 		    ipmi_domain_get_type_string(ipmi_domain_get_type(domain)));
92     ipmi_cmdlang_out_int(cmd_info, "SEL Rescan Time",
93 			 ipmi_domain_get_sel_rescan_time(domain));
94     ipmi_cmdlang_out_int(cmd_info, "IPMB Rescan Time",
95 			 ipmi_domain_get_ipmb_rescan_time(domain));
96     ipmi_cmdlang_up(cmd_info);
97 }
98 
99 static void domain_con_change(ipmi_domain_t *domain,
100 			      int           err,
101 			      unsigned int  conn_num,
102 			      unsigned int  port_num,
103 			      int           still_connected,
104 			      void          *cb_data);
105 void ipmi_cmdlang_entity_change(enum ipmi_update_e op,
106 				ipmi_domain_t      *domain,
107 				ipmi_entity_t      *entity,
108 				void               *cb_data);
109 void ipmi_cmdlang_mc_change(enum ipmi_update_e op,
110 			    ipmi_domain_t      *domain,
111 			    ipmi_mc_t          *mc,
112 			    void               *cb_data);
113 
114 static void
domain_new_done(ipmi_domain_t * domain,int err,unsigned int conn_num,unsigned int port_num,int still_connected,void * cb_data)115 domain_new_done(ipmi_domain_t *domain,
116 		int           err,
117 		unsigned int  conn_num,
118 		unsigned int  port_num,
119 		int           still_connected,
120 		void          *cb_data)
121 {
122     ipmi_cmd_info_t *cmd_info = cb_data;
123     int             rv;
124 
125 
126     /* This call will detect and ignore duplicates, no special
127        handling required. */
128     ipmi_domain_add_connect_change_handler(domain, domain_con_change, NULL);
129 
130     /* Remove ourselves from the connection change list.  This may fail,
131        but that means it's already been done and we don't care. */
132     rv = ipmi_domain_remove_connect_change_handler(domain, domain_new_done,
133 						   cb_data);
134 
135 
136     /* Handle the rest as a normal event. */
137     domain_con_change(domain, err, conn_num, port_num, still_connected,
138 		      NULL);
139 
140     /* If we get an error removing the connect change handler,
141        that means this has already been done. */
142     if ((!rv) && cmd_info) {
143 	char  domain_name[IPMI_DOMAIN_NAME_LEN];
144 
145 	ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
146 	ipmi_cmdlang_lock(cmd_info);
147 	ipmi_cmdlang_out(cmd_info, "Domain Created", domain_name);
148 	ipmi_cmdlang_unlock(cmd_info);
149 	ipmi_cmdlang_cmd_info_put(cmd_info);
150     }
151 }
152 
153 void
domain_fully_up(ipmi_domain_t * domain,void * cb_data)154 domain_fully_up(ipmi_domain_t *domain, void *cb_data)
155 {
156     ipmi_cmd_info_t *cmd_info = cb_data;
157     char            *errstr = NULL;
158     int             rv = 0;
159     ipmi_cmd_info_t *evi;
160     char            domain_name[IPMI_DOMAIN_NAME_LEN];
161 
162     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
163 
164     evi = ipmi_cmdlang_alloc_event_info();
165     if (!evi) {
166 	rv = ENOMEM;
167 	errstr = "Out of memory";
168 	goto out_err;
169     }
170 
171     ipmi_cmdlang_out(evi, "Object Type", "Domain");
172     ipmi_cmdlang_out(evi, "Domain", domain_name);
173     ipmi_cmdlang_out(evi, "Operation", "Domain fully up");
174 
175  out_err:
176     if (rv) {
177 	ipmi_cmdlang_global_err(domain_name,
178 				"cmd_domain.c(domain_fully_up)",
179 				errstr, rv);
180     }
181     if (evi)
182 	ipmi_cmdlang_cmd_info_put(evi);
183 
184     if (cmd_info) {
185 	ipmi_cmdlang_lock(cmd_info);
186 	ipmi_cmdlang_out(cmd_info, "Domain Created", domain_name);
187 	ipmi_cmdlang_unlock(cmd_info);
188 	ipmi_cmdlang_cmd_info_put(cmd_info);
189     }
190 }
191 
192 static void
domain_new(ipmi_cmd_info_t * cmd_info)193 domain_new(ipmi_cmd_info_t *cmd_info)
194 {
195     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
196     ipmi_args_t    *con_parms[2];
197     int            set = 0;
198     int            i, j;
199     ipmi_con_t     *con[2];
200     int            rv;
201     char           *name;
202     int            curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
203     int            argc = ipmi_cmdlang_get_argc(cmd_info);
204     char           **argv = ipmi_cmdlang_get_argv(cmd_info);
205     int            num_options = 0;
206     ipmi_open_option_t options[10];
207     int            wait_til_up = 0;
208     void           *up_info = NULL;
209     void           *con_info = NULL;
210 
211     if (curr_arg >= argc) {
212 	cmdlang->errstr = "No domain name entered";
213 	cmdlang->err = EINVAL;
214 	goto out;
215     }
216     name = argv[curr_arg];
217     curr_arg++;
218 
219     while ((curr_arg < argc) && argv[curr_arg][0] == '-') {
220 	if (num_options >= 10) {
221 	    cmdlang->errstr = "Too many options";
222 	    cmdlang->err = EINVAL;
223 	    goto out;
224 	}
225 
226 	if (! ipmi_parse_options(options+num_options, argv[curr_arg]))
227 	    num_options++;
228 	else if (strcmp(argv[curr_arg], "-wait_til_up") == 0)
229 	    wait_til_up = 1;
230 	else
231 	    break;
232 	curr_arg++;
233     }
234 
235     rv = ipmi_parse_args(&curr_arg, argc, argv, &con_parms[set]);
236     if (rv) {
237 	cmdlang->errstr = "First connection parms are invalid";
238 	cmdlang->err = rv;
239 	goto out;
240     }
241     set++;
242 
243     if (curr_arg < argc) {
244 	rv = ipmi_parse_args(&curr_arg, argc, argv, &con_parms[set]);
245 	if (rv) {
246 	    ipmi_free_args(con_parms[0]);
247 	    cmdlang->errstr = "Second connection parms are invalid";
248 	    cmdlang->err = rv;
249 	    goto out;
250 	}
251 	set++;
252     }
253 
254     for (i=0; i<set; i++) {
255 	rv = ipmi_args_setup_con(con_parms[i],
256 				 cmdlang->os_hnd,
257 				 NULL,
258 				 &con[i]);
259 	if (rv) {
260 	    cmdlang->errstr = "Unable to setup connection";
261 	    cmdlang->err = rv;
262 	    for (j=0; j<set; j++)
263 		ipmi_free_args(con_parms[j]);
264 	    goto out;
265 	}
266     }
267 
268     if (wait_til_up)
269 	up_info = cmd_info;
270     else
271 	con_info = cmd_info;
272 
273     ipmi_cmdlang_cmd_info_get(cmd_info);
274     rv = ipmi_open_domain(name, con, set, domain_new_done, con_info,
275 			  domain_fully_up, up_info,
276 			  options, num_options, NULL);
277     if (rv) {
278 	ipmi_cmdlang_cmd_info_put(cmd_info);
279 	cmdlang->errstr = strerror(rv);
280 	cmdlang->err = rv;
281 	for (i=0; i<set; i++) {
282 	    ipmi_free_args(con_parms[i]);
283 	    con[i]->close_connection(con[i]);
284 	}
285 	goto out;
286     }
287 
288     for (i=0; i<set; i++)
289       ipmi_free_args(con_parms[i]);
290 
291  out:
292     if (cmdlang->err)
293 	cmdlang->location = "cmd_domain.c(domain_new)";
294 
295     return;
296 }
297 
298 
299 static void
domain_open(ipmi_cmd_info_t * cmd_info)300 domain_open(ipmi_cmd_info_t *cmd_info)
301 {
302     ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
303     ipmi_args_t    *con_parms[2];
304     int            set = 0;
305     int            i, j;
306     ipmi_con_t     *con[2];
307     int            rv;
308     char           *name;
309     int            curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
310     int            argc = ipmi_cmdlang_get_argc(cmd_info);
311     char           **argv = ipmi_cmdlang_get_argv(cmd_info);
312     int            num_options = 0;
313     ipmi_open_option_t options[10];
314     int            wait_til_up = 0;
315     void           *up_info = NULL;
316     void           *con_info = NULL;
317 
318     if (curr_arg >= argc) {
319 	cmdlang->errstr = "No domain name entered";
320 	cmdlang->err = EINVAL;
321 	goto out;
322     }
323     name = argv[curr_arg];
324     curr_arg++;
325 
326     while ((curr_arg < argc) && argv[curr_arg][0] == '-') {
327 	if (num_options >= 10) {
328 	    cmdlang->errstr = "Too many options";
329 	    cmdlang->err = EINVAL;
330 	    goto out;
331 	}
332 
333 	if (! ipmi_parse_options(options+num_options, argv[curr_arg]))
334 	    num_options++;
335 	else if (strcmp(argv[curr_arg], "-wait_til_up") == 0)
336 	    wait_til_up = 1;
337 	else
338 	    break;
339 	curr_arg++;
340     }
341 
342     rv = ipmi_parse_args2(&curr_arg, argc, argv, &con_parms[set]);
343     if (rv) {
344 	cmdlang->errstr = "First connection parms are invalid";
345 	cmdlang->err = rv;
346 	goto out;
347     }
348     set++;
349 
350     if (curr_arg < argc) {
351 	rv = ipmi_parse_args2(&curr_arg, argc, argv, &con_parms[set]);
352 	if (rv) {
353 	    ipmi_free_args(con_parms[0]);
354 	    cmdlang->errstr = "Second connection parms are invalid";
355 	    cmdlang->err = rv;
356 	    goto out;
357 	}
358 	set++;
359     }
360 
361     for (i=0; i<set; i++) {
362 	rv = ipmi_args_setup_con(con_parms[i],
363 				 cmdlang->os_hnd,
364 				 NULL,
365 				 &con[i]);
366 	if (rv) {
367 	    cmdlang->errstr = "Unable to setup connection";
368 	    cmdlang->err = rv;
369 	    for (j=0; j<i; j++)
370 		con[j]->close_connection(con[j]);
371 	    for (j=0; j<set; j++)
372 		ipmi_free_args(con_parms[j]);
373 	    goto out;
374 	}
375     }
376 
377     if (wait_til_up)
378 	up_info = cmd_info;
379     else
380 	con_info = cmd_info;
381 
382     ipmi_cmdlang_cmd_info_get(cmd_info);
383     rv = ipmi_open_domain(name, con, set, domain_new_done, con_info,
384 			  domain_fully_up, up_info,
385 			  options, num_options, NULL);
386     if (rv) {
387 	ipmi_cmdlang_cmd_info_put(cmd_info);
388 	cmdlang->errstr = strerror(rv);
389 	cmdlang->err = rv;
390 	for (i=0; i<set; i++) {
391 	    ipmi_free_args(con_parms[i]);
392 	    con[i]->close_connection(con[i]);
393 	}
394 	goto out;
395     }
396 
397     for (i=0; i<set; i++)
398       ipmi_free_args(con_parms[i]);
399 
400  out:
401     if (cmdlang->err)
402 	cmdlang->location = "cmd_domain.c(domain_open)";
403 
404     return;
405 }
406 
con_usage(const char * name,const char * help,void * cb_data)407 void con_usage(const char *name, const char *help, void *cb_data)
408 {
409     ipmi_cmdlang_t *cmdlang = cb_data;
410 
411     cmdlang->out(cmdlang, name, help);
412 }
413 
414 static void
domain_open_help(ipmi_cmdlang_t * cmdlang)415 domain_open_help(ipmi_cmdlang_t *cmdlang)
416 {
417     ipmi_parse_args_iter_help(con_usage, cmdlang);
418     cmdlang->out(cmdlang, "Options are:\n", ipmi_parse_options_help());
419 }
420 
421 static void
domain_fru_fetched(ipmi_domain_t * domain,ipmi_fru_t * fru,int err,void * cb_data)422 domain_fru_fetched(ipmi_domain_t *domain, ipmi_fru_t *fru,
423 		   int err, void *cb_data)
424 {
425     ipmi_cmd_info_t *cmd_info = cb_data;
426     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
427     char            domain_name[IPMI_DOMAIN_NAME_LEN];
428 
429     ipmi_cmdlang_lock(cmd_info);
430 
431     if (err && (ipmi_fru_get_data_length(fru) == 0)) {
432 	cmdlang->errstr = "Error fetching FRU info";
433 	cmdlang->err = err;
434 	ipmi_domain_get_name(domain, cmdlang->objstr,
435 			     cmdlang->objstr_len);
436 	cmdlang->location = "cmd_domain.c(domain_fru_fetched)";
437 	goto out;
438     }
439 
440     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
441     ipmi_cmdlang_out(cmd_info, "Domain", NULL);
442     ipmi_cmdlang_down(cmd_info);
443     ipmi_cmdlang_out(cmd_info, "Name", domain_name);
444     if (err)
445 	ipmi_cmdlang_out_int(cmd_info, "Warning fetching FRU", err);
446     ipmi_cmdlang_dump_fru_info(cmd_info, fru);
447     ipmi_cmdlang_up(cmd_info);
448 
449  out:
450     ipmi_cmdlang_unlock(cmd_info);
451     ipmi_cmdlang_cmd_info_put(cmd_info);
452 }
453 
454 static void
domain_fru(ipmi_domain_t * domain,void * cb_data)455 domain_fru(ipmi_domain_t *domain, void *cb_data)
456 {
457     ipmi_cmd_info_t *cmd_info = cb_data;
458     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
459     int             is_logical;
460     int             device_addr;
461     int             device_id;
462     int             lun;
463     int             private_bus;
464     int             channel;
465     int             rv;
466     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
467     int             argc = ipmi_cmdlang_get_argc(cmd_info);
468     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
469 
470     if ((argc - curr_arg) < 6) {
471 	/* Not enough parameters */
472 	cmdlang->errstr = "Not enough parameters";
473 	cmdlang->err = EINVAL;
474 	goto out_err;
475     }
476 
477     ipmi_cmdlang_get_bool(argv[curr_arg], &is_logical, cmd_info);
478     if (cmdlang->err) {
479 	cmdlang->errstr = "is_logical invalid";
480 	goto out_err;
481     }
482     curr_arg++;
483 
484     ipmi_cmdlang_get_int(argv[curr_arg], &device_addr, cmd_info);
485     if (cmdlang->err) {
486 	cmdlang->errstr = "device_address invalid";
487 	goto out_err;
488     }
489     curr_arg++;
490 
491     ipmi_cmdlang_get_int(argv[curr_arg], &device_id, cmd_info);
492     if (cmdlang->err) {
493 	cmdlang->errstr = "device_id invalid";
494 	goto out_err;
495     }
496     curr_arg++;
497 
498     ipmi_cmdlang_get_int(argv[curr_arg], &lun, cmd_info);
499     if (cmdlang->err) {
500 	cmdlang->errstr = "lun invalid";
501 	goto out_err;
502     }
503     curr_arg++;
504 
505     ipmi_cmdlang_get_int(argv[curr_arg], &private_bus, cmd_info);
506     if (cmdlang->err) {
507 	cmdlang->errstr = "private_bus invalid";
508 	goto out_err;
509     }
510     curr_arg++;
511 
512     ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
513     if (cmdlang->err) {
514 	cmdlang->errstr = "channel invalid";
515 	goto out_err;
516     }
517     curr_arg++;
518 
519     ipmi_cmdlang_cmd_info_get(cmd_info);
520     rv = ipmi_domain_fru_alloc(domain,
521 			       is_logical,
522 			       device_addr,
523 			       device_id,
524 			       lun,
525 			       private_bus,
526 			       channel,
527 			       domain_fru_fetched,
528 			       cmd_info,
529 			       NULL);
530     if (rv) {
531 	ipmi_cmdlang_cmd_info_put(cmd_info);
532 	cmdlang->errstr = "Error allocating FRU info";
533 	cmdlang->err = rv;
534 	goto out_err;
535     }
536 
537     return;
538 
539  out_err:
540     ipmi_domain_get_name(domain, cmdlang->objstr,
541 			 cmdlang->objstr_len);
542     cmdlang->location = "cmd_domain.c(domain_fru)";
543 }
544 
545 static int
domain_msg_handler(ipmi_domain_t * domain,ipmi_msgi_t * rspi)546 domain_msg_handler(ipmi_domain_t *domain, ipmi_msgi_t *rspi)
547 {
548     ipmi_msg_t       *msg = &rspi->msg;
549     ipmi_ipmb_addr_t *addr = (ipmi_ipmb_addr_t *) &rspi->addr;
550     ipmi_cmd_info_t  *cmd_info = rspi->data1;
551     char             domain_name[IPMI_DOMAIN_NAME_LEN];
552 
553     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
554 
555     ipmi_cmdlang_lock(cmd_info);
556     ipmi_cmdlang_out(cmd_info, "Response", NULL);
557     ipmi_cmdlang_down(cmd_info);
558     ipmi_cmdlang_out(cmd_info, "Domain", domain_name);
559     ipmi_cmdlang_out_int(cmd_info, "channel", addr->channel);
560     ipmi_cmdlang_out_hex(cmd_info, "ipmb", addr->slave_addr);
561     ipmi_cmdlang_out_int(cmd_info, "LUN", addr->lun);
562     ipmi_cmdlang_out_int(cmd_info, "NetFN", msg->netfn);
563     ipmi_cmdlang_out_int(cmd_info, "command", msg->cmd);
564     if (msg->data_len)
565 	ipmi_cmdlang_out_binary(cmd_info, "Data",
566 				(char *) msg->data, msg->data_len);
567     ipmi_cmdlang_unlock(cmd_info);
568     ipmi_cmdlang_up(cmd_info);
569 
570     ipmi_cmdlang_cmd_info_put(cmd_info);
571 
572     return IPMI_MSG_ITEM_NOT_USED;
573 }
574 
575 static void
domain_msg(ipmi_domain_t * domain,void * cb_data)576 domain_msg(ipmi_domain_t *domain, void *cb_data)
577 {
578     ipmi_cmd_info_t  *cmd_info = cb_data;
579     ipmi_cmdlang_t   *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
580     int              channel;
581     int              ipmb;
582     int              is_broadcast = 0;
583     int              LUN;
584     int              NetFN;
585     int              command;
586     unsigned char    data[100];
587     int              rv;
588     int              i;
589     ipmi_ipmb_addr_t addr;
590     ipmi_msg_t       msg;
591     int              curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
592     int              argc = ipmi_cmdlang_get_argc(cmd_info);
593     char             **argv = ipmi_cmdlang_get_argv(cmd_info);
594 
595 
596     if ((argc - curr_arg) < 5) {
597 	/* Not enough parameters */
598 	cmdlang->errstr = "Not enough parameters";
599 	cmdlang->err = EINVAL;
600 	goto out_err;
601     }
602 
603     ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
604     if (cmdlang->err) {
605 	cmdlang->errstr = "channel invalid";
606 	goto out_err;
607     }
608     curr_arg++;
609 
610     ipmi_cmdlang_get_int(argv[curr_arg], &ipmb, cmd_info);
611     if (cmdlang->err) {
612 	cmdlang->errstr = "ipmb invalid";
613 	goto out_err;
614     }
615     curr_arg++;
616 
617     if (ipmb == 0) {
618 	is_broadcast = 1;
619 	if ((argc - curr_arg) < 5) {
620 	    /* Not enough parameters */
621 	    cmdlang->errstr = "Not enough parameters";
622 	    cmdlang->err = EINVAL;
623 	    goto out_err;
624 	}
625 	ipmi_cmdlang_get_int(argv[curr_arg], &ipmb, cmd_info);
626 	if (cmdlang->err) {
627 	    cmdlang->errstr = "ipmb invalid";
628 	    goto out_err;
629 	}
630 	curr_arg++;
631     }
632 
633     ipmi_cmdlang_get_int(argv[curr_arg], &LUN, cmd_info);
634     if (cmdlang->err) {
635 	cmdlang->errstr = "LUN invalid";
636 	goto out_err;
637     }
638     curr_arg++;
639 
640     ipmi_cmdlang_get_int(argv[curr_arg], &NetFN, cmd_info);
641     if (cmdlang->err) {
642 	cmdlang->errstr = "NetFN invalid";
643 	goto out_err;
644     }
645     curr_arg++;
646 
647     ipmi_cmdlang_get_int(argv[curr_arg], &command, cmd_info);
648     if (cmdlang->err) {
649 	cmdlang->errstr = "command invalid";
650 	goto out_err;
651     }
652     curr_arg++;
653 
654     i = 0;
655     while (curr_arg < argc) {
656 	ipmi_cmdlang_get_uchar(argv[curr_arg], &data[i], cmd_info);
657 	if (cmdlang->err) {
658 	    cmdlang->errstr = "data invalid";
659 	    goto out_err;
660 	}
661 	curr_arg++;
662 	i++;
663     }
664 
665     if (is_broadcast)
666 	addr.addr_type = IPMI_IPMB_BROADCAST_ADDR_TYPE;
667     else
668 	addr.addr_type = IPMI_IPMB_ADDR_TYPE;
669     addr.channel = channel;
670     addr.slave_addr = ipmb;
671     addr.lun = LUN;
672     msg.netfn = NetFN;
673     msg.cmd = command;
674     msg.data_len = i;
675     msg.data = data;
676 
677     ipmi_cmdlang_cmd_info_get(cmd_info);
678     rv = ipmi_send_command_addr(domain,
679 				(ipmi_addr_t *) &(addr),
680 				sizeof(addr),
681 				&msg,
682 				domain_msg_handler,
683 				cmd_info, NULL);
684     if (rv) {
685 	ipmi_cmdlang_cmd_info_put(cmd_info);
686 	cmdlang->errstr = "Error sending message";
687 	cmdlang->err = rv;
688 	goto out_err;
689     }
690 
691     return;
692 
693  out_err:
694     if (cmdlang->err) {
695 	ipmi_domain_get_name(domain, cmdlang->objstr,
696 			     cmdlang->objstr_len);
697 	cmdlang->location = "cmd_domain.c(domain_msg)";
698     }
699 }
700 
701 static void
scan_done(ipmi_domain_t * domain,int err,void * cb_data)702 scan_done(ipmi_domain_t *domain, int err, void *cb_data)
703 {
704     ipmi_cmd_info_t *cmd_info = cb_data;
705     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
706     char             domain_name[IPMI_DOMAIN_NAME_LEN];
707 
708     ipmi_cmdlang_lock(cmd_info);
709     if (err) {
710 	if (! cmdlang->err) {
711 	    cmdlang->err = err;
712 	    cmdlang->errstr = "Error scanning domain";
713 	    ipmi_domain_get_name(domain, cmdlang->objstr,
714 				 cmdlang->objstr_len);
715 	    cmdlang->location = "cmd_domain.c(scan_done)";
716 	}
717 	goto out;
718     }
719 
720     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
721     ipmi_cmdlang_out(cmd_info, "Scan done", domain_name);
722 
723  out:
724     ipmi_cmdlang_unlock(cmd_info);
725     ipmi_cmdlang_cmd_info_put(cmd_info);
726 }
727 
728 static void
domain_scan(ipmi_domain_t * domain,void * cb_data)729 domain_scan(ipmi_domain_t *domain, void *cb_data)
730 {
731     ipmi_cmd_info_t *cmd_info = cb_data;
732     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
733     int             rv;
734     int             channel;
735     int             ipmb1, ipmb2;
736     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
737     int             argc = ipmi_cmdlang_get_argc(cmd_info);
738     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
739 
740     if ((argc - curr_arg) < 2) {
741 	/* Not enough parameters */
742 	cmdlang->errstr = "Not enough parameters";
743 	cmdlang->err = EINVAL;
744 	goto out_err;
745     }
746 
747     ipmi_cmdlang_get_int(argv[curr_arg], &channel, cmd_info);
748     if (cmdlang->err) {
749 	cmdlang->errstr = "channel invalid";
750 	goto out_err;
751     }
752     curr_arg++;
753 
754     ipmi_cmdlang_get_int(argv[curr_arg], &ipmb1, cmd_info);
755     if (cmdlang->err) {
756 	cmdlang->errstr = "ipmb1 invalid";
757 	goto out_err;
758     }
759     curr_arg++;
760 
761     if (curr_arg < argc) {
762 	ipmi_cmdlang_get_int(argv[curr_arg], &ipmb2, cmd_info);
763 	if (cmdlang->err) {
764 	    cmdlang->errstr = "ipmb2 invalid";
765 	    goto out_err;
766 	}
767 	curr_arg++;
768     } else
769 	ipmb2 = ipmb1;
770 
771     ipmi_cmdlang_cmd_info_get(cmd_info);
772     rv = ipmi_start_ipmb_mc_scan(domain, channel, ipmb1, ipmb2,
773 				 scan_done, cmd_info);
774     if (rv) {
775 	ipmi_cmdlang_cmd_info_put(cmd_info);
776 	cmdlang->errstr = "Error requesting scan";
777 	cmdlang->err = rv;
778 	goto out_err;
779     }
780 
781  out_err:
782     if (cmdlang->err) {
783 	ipmi_domain_get_name(domain, cmdlang->objstr,
784 			     cmdlang->objstr_len);
785 	cmdlang->location = "cmd_domain.c(domain_scan)";
786     }
787 }
788 
789 static void
domain_rescan_sels_done(ipmi_domain_t * domain,int err,void * cb_data)790 domain_rescan_sels_done(ipmi_domain_t *domain, int err, void *cb_data)
791 {
792     ipmi_cmd_info_t *cmd_info = cb_data;
793     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
794     char             domain_name[IPMI_DOMAIN_NAME_LEN];
795 
796     ipmi_cmdlang_lock(cmd_info);
797     if (err) {
798 	if (! cmdlang->err) {
799 	    cmdlang->err = err;
800 	    cmdlang->errstr = "Error scanning SELs";
801 	    ipmi_domain_get_name(domain, cmdlang->objstr,
802 				 cmdlang->objstr_len);
803 	    cmdlang->location = "cmd_domain.c(sel_rescan_done)";
804 	}
805 	goto out;
806     }
807 
808     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
809     ipmi_cmdlang_out(cmd_info, "SEL Rescan done", domain_name);
810 
811  out:
812     ipmi_cmdlang_unlock(cmd_info);
813     ipmi_cmdlang_cmd_info_put(cmd_info);
814 }
815 
816 static void
domain_rescan_sels(ipmi_domain_t * domain,void * cb_data)817 domain_rescan_sels(ipmi_domain_t *domain, void *cb_data)
818 {
819     ipmi_cmd_info_t *cmd_info = cb_data;
820     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
821     int             rv;
822 
823     ipmi_cmdlang_cmd_info_get(cmd_info);
824     rv = ipmi_domain_reread_sels(domain, domain_rescan_sels_done, cmd_info);
825     if (rv) {
826 	ipmi_cmdlang_cmd_info_put(cmd_info);
827 	cmdlang->errstr = "Error requesting SEL rescan";
828 	cmdlang->err = rv;
829 	goto out_err;
830     }
831 
832  out_err:
833     if (cmdlang->err) {
834 	ipmi_domain_get_name(domain, cmdlang->objstr,
835 			     cmdlang->objstr_len);
836 	cmdlang->location = "cmd_domain.c(domain_rescan_sels)";
837     }
838 }
839 
840 static void
domain_presence(ipmi_domain_t * domain,void * cb_data)841 domain_presence(ipmi_domain_t *domain, void *cb_data)
842 {
843     ipmi_cmd_info_t *cmd_info = cb_data;
844     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
845     int             rv;
846     char             domain_name[IPMI_DOMAIN_NAME_LEN];
847 
848     rv = ipmi_detect_domain_presence_changes(domain, 1);
849     if (rv) {
850 	cmdlang->err = rv;
851 	ipmi_domain_get_name(domain, cmdlang->objstr,
852 			     cmdlang->objstr_len);
853 	cmdlang->location = "cmd_domain.c(domain_presence)";
854 	goto out;
855     }
856     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
857     ipmi_cmdlang_out(cmd_info, "Presence check started", domain_name);
858  out:
859     return;
860 }
861 
862 static void
domain_sel_rescan_time(ipmi_domain_t * domain,void * cb_data)863 domain_sel_rescan_time(ipmi_domain_t *domain, void *cb_data)
864 {
865     ipmi_cmd_info_t *cmd_info = cb_data;
866     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
867     int             time;
868     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
869     int             argc = ipmi_cmdlang_get_argc(cmd_info);
870     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
871     char             domain_name[IPMI_DOMAIN_NAME_LEN];
872 
873     if ((argc - curr_arg) < 1) {
874 	/* Not enough parameters */
875 	cmdlang->errstr = "Not enough parameters";
876 	cmdlang->err = EINVAL;
877 	goto out_err;
878     }
879 
880     ipmi_cmdlang_get_int(argv[curr_arg], &time, cmd_info);
881     if (cmdlang->err) {
882 	cmdlang->errstr = "time invalid";
883 	goto out_err;
884     }
885     curr_arg++;
886 
887     ipmi_domain_set_sel_rescan_time(domain, time);
888 
889     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
890     ipmi_cmdlang_out(cmd_info, "Domain SEL rescan time set", domain_name);
891 
892  out_err:
893     if (cmdlang->err) {
894 	ipmi_domain_get_name(domain, cmdlang->objstr,
895 			     cmdlang->objstr_len);
896 	cmdlang->location = "cmd_domain.c(domain_sel_rescan_time)";
897     }
898 }
899 
900 
901 static void
domain_ipmb_rescan_time(ipmi_domain_t * domain,void * cb_data)902 domain_ipmb_rescan_time(ipmi_domain_t *domain, void *cb_data)
903 {
904     ipmi_cmd_info_t *cmd_info = cb_data;
905     ipmi_cmdlang_t  *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
906     int             time;
907     int             curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
908     int             argc = ipmi_cmdlang_get_argc(cmd_info);
909     char            **argv = ipmi_cmdlang_get_argv(cmd_info);
910     char            domain_name[IPMI_DOMAIN_NAME_LEN];
911 
912     if ((argc - curr_arg) < 1) {
913 	cmdlang->errstr = "Not enough parameters";
914 	cmdlang->err = EINVAL;
915 	goto out_err;
916     }
917 
918     ipmi_cmdlang_get_int(argv[curr_arg], &time, cmd_info);
919     if (cmdlang->err) {
920 	cmdlang->errstr = "time invalid";
921 	goto out_err;
922     }
923     curr_arg++;
924 
925     ipmi_domain_set_ipmb_rescan_time(domain, time);
926 
927     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
928     ipmi_cmdlang_out(cmd_info, "Domain IPMB rescan time set", domain_name);
929 
930  out_err:
931     if (cmdlang->err) {
932 	ipmi_domain_get_name(domain, cmdlang->objstr,
933 			     cmdlang->objstr_len);
934 	cmdlang->location = "cmd_domain.c(domain_ipmb_rescan_time)";
935     }
936 }
937 
938 static void
handle_stat(ipmi_domain_t * domain,ipmi_domain_stat_t * stat,void * cb_data)939 handle_stat(ipmi_domain_t *domain, ipmi_domain_stat_t *stat, void *cb_data)
940 {
941     ipmi_cmd_info_t *cmd_info = cb_data;
942     const char      *name = ipmi_domain_stat_get_name(stat);
943     const char      *inst = ipmi_domain_stat_get_instance(stat);
944     char            *s = ipmi_mem_alloc(strlen(name) + strlen(inst) + 2);
945 
946     if (!s)
947 	return;
948     sprintf(s, "%s %s", name, inst);
949     ipmi_cmdlang_out_int(cmd_info, s, ipmi_domain_stat_get(stat));
950     ipmi_mem_free(s);
951 }
952 
953 static void
domain_stats(ipmi_domain_t * domain,void * cb_data)954 domain_stats(ipmi_domain_t *domain, void *cb_data)
955 {
956     ipmi_cmd_info_t *cmd_info = cb_data;
957     char            domain_name[IPMI_DOMAIN_NAME_LEN];
958 
959     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
960     ipmi_cmdlang_out(cmd_info, "Domain statistics", NULL);
961     ipmi_cmdlang_down(cmd_info);
962     ipmi_cmdlang_out(cmd_info, "Domain", domain_name);
963     ipmi_domain_stat_iterate(domain, NULL, NULL, handle_stat, cmd_info);
964     ipmi_cmdlang_up(cmd_info);
965 }
966 
967 typedef struct domain_close_info_s
968 {
969     char            domain_name[IPMI_DOMAIN_NAME_LEN];
970     ipmi_cmd_info_t *cmd_info;
971 } domain_close_info_t;
972 
973 static void
final_close(void * cb_data)974 final_close(void *cb_data)
975 {
976     domain_close_info_t *info = cb_data;
977     ipmi_cmd_info_t *cmd_info = info->cmd_info;
978 
979     ipmi_cmdlang_lock(cmd_info);
980     ipmi_cmdlang_out(cmd_info, "Domain closed", info->domain_name);
981     ipmi_cmdlang_unlock(cmd_info);
982 
983     ipmi_mem_free(info);
984 
985     ipmi_cmdlang_cmd_info_put(cmd_info);
986 }
987 
988 static void
domain_close(ipmi_domain_t * domain,void * cb_data)989 domain_close(ipmi_domain_t *domain, void *cb_data)
990 {
991     ipmi_cmd_info_t     *cmd_info = cb_data;
992     ipmi_cmdlang_t      *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
993     int                 rv;
994     domain_close_info_t *info = cb_data;
995 
996     info = ipmi_mem_alloc(sizeof(*info));
997     if (!info) {
998 	cmdlang->errstr = "Out of memory";
999 	cmdlang->err = ENOMEM;
1000 	goto out_err;
1001     }
1002     ipmi_domain_get_name(domain, info->domain_name, sizeof(info->domain_name));
1003     info->cmd_info = cmd_info;
1004 
1005     ipmi_cmdlang_cmd_info_get(cmd_info);
1006     rv = ipmi_domain_close(domain, final_close, info);
1007     if (rv) {
1008 	ipmi_cmdlang_cmd_info_put(cmd_info);
1009 	cmdlang->errstr = "Unable to close domain";
1010 	cmdlang->err = rv;
1011 	goto out_err;
1012     }
1013     return;
1014 
1015  out_err:
1016     ipmi_domain_get_name(domain, cmdlang->objstr,
1017 			 cmdlang->objstr_len);
1018     cmdlang->location = "cmd_domain.c(domain_close)";
1019 }
1020 
1021 
1022 /**********************************************************************
1023  *
1024  * Domain event handling.
1025  *
1026  **********************************************************************/
1027 
1028 static void
domain_event_handler(ipmi_domain_t * domain,ipmi_event_t * event,void * cb_data)1029 domain_event_handler(ipmi_domain_t *domain,
1030 		     ipmi_event_t  *event,
1031 		     void          *cb_data)
1032 {
1033     char            *errstr = NULL;
1034     int             rv = 0;
1035     ipmi_cmd_info_t *evi;
1036 
1037     evi = ipmi_cmdlang_alloc_event_info();
1038     if (!evi) {
1039 	rv = ENOMEM;
1040 	errstr = "Out of memory";
1041 	goto out_err;
1042     }
1043 
1044     ipmi_cmdlang_out(evi, "Object Type", "Event");
1045     ipmi_cmdlang_event_out(event, evi);
1046 
1047  out_err:
1048     if (rv) {
1049 	char domain_name[IPMI_DOMAIN_NAME_LEN];
1050 
1051 	ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1052 	ipmi_cmdlang_global_err(domain_name,
1053 				"cmd_domain.c(domain_event_handler)",
1054 				errstr, rv);
1055     }
1056     if (evi)
1057 	ipmi_cmdlang_cmd_info_put(evi);
1058 }
1059 
1060 static void
domain_con_change(ipmi_domain_t * domain,int err,unsigned int conn_num,unsigned int port_num,int still_connected,void * cb_data)1061 domain_con_change(ipmi_domain_t *domain,
1062 		  int           err,
1063 		  unsigned int  conn_num,
1064 		  unsigned int  port_num,
1065 		  int           still_connected,
1066 		  void          *cb_data)
1067 {
1068     char            *errstr;
1069     int             rv = 0;
1070     ipmi_cmd_info_t *evi;
1071     char            domain_name[IPMI_DOMAIN_NAME_LEN];
1072 
1073     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1074 
1075     evi = ipmi_cmdlang_alloc_event_info();
1076     if (!evi) {
1077 	rv = ENOMEM;
1078 	errstr = "Out of memory";
1079 	goto out_err;
1080     }
1081 
1082     ipmi_cmdlang_out(evi, "Object Type", "Domain");
1083     ipmi_cmdlang_out(evi, "Name", domain_name);
1084     ipmi_cmdlang_out(evi, "Operation", "Connection Change");
1085     ipmi_cmdlang_out_int(evi, "Connection Number", conn_num);
1086     ipmi_cmdlang_out_int(evi, "Port Number", port_num);
1087     ipmi_cmdlang_out_bool(evi, "Any Connection Up", still_connected);
1088     ipmi_cmdlang_out_int(evi, "Error", err);
1089 
1090     if (err) {
1091 	char errval[128];
1092 	ipmi_cmdlang_out(evi, "Error String",
1093 			 ipmi_get_error_string(err, errval, sizeof(errval)));
1094 
1095     }
1096     errstr = NULL; /* Get rid of warning */
1097 
1098  out_err:
1099     if (rv) {
1100 	ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1101 	ipmi_cmdlang_global_err(domain_name, "cmd_domain.c(domain_con_change)",
1102 				errstr, rv);
1103     }
1104     if (evi)
1105 	ipmi_cmdlang_cmd_info_put(evi);
1106 }
1107 
1108 void
domain_change(ipmi_domain_t * domain,enum ipmi_update_e op,void * cb_data)1109 domain_change(ipmi_domain_t      *domain,
1110 	      enum ipmi_update_e op,
1111 	      void               *cb_data)
1112 {
1113     ipmi_cmd_info_t *evi;
1114     int             rv = 0;
1115     char            *errstr = NULL;
1116     char            domain_name[IPMI_DOMAIN_NAME_LEN];
1117 
1118     evi = ipmi_cmdlang_alloc_event_info();
1119     if (!evi) {
1120 	rv = ENOMEM;
1121 	errstr = "Out of memory";
1122 	goto out_err;
1123     }
1124 
1125     ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
1126 
1127 
1128     ipmi_cmdlang_out(evi, "Object Type", "Domain");
1129     ipmi_cmdlang_out(evi, "Name", domain_name);
1130 
1131     switch (op) {
1132     case IPMI_ADDED:
1133 	ipmi_cmdlang_out(evi, "Operation", "Add");
1134 	if (ipmi_cmdlang_get_evinfo()) {
1135 	    ipmi_cmdlang_down(evi);
1136 	    domain_info(domain, evi);
1137 	    ipmi_cmdlang_up(evi);
1138 	}
1139 	/* Register handlers. */
1140 	rv = ipmi_domain_add_event_handler(domain, domain_event_handler, NULL);
1141 	if (rv) {
1142 	    errstr = "ipmi_register_for_events";
1143 	    goto out_err;
1144 	}
1145 
1146 	rv = ipmi_domain_enable_events(domain);
1147 	if (rv) {
1148 	    errstr = "ipmi_domain_enable_events";
1149 	    goto out_err;
1150 	}
1151 
1152 	rv = ipmi_domain_add_entity_update_handler(domain,
1153 						   ipmi_cmdlang_entity_change,
1154 						   domain);
1155 	if (rv) {
1156 	    errstr = "ipmi_bmc_set_entity_update_handler";
1157 	    goto out_err;
1158 	}
1159 
1160 	rv = ipmi_domain_add_mc_updated_handler(domain,
1161 						ipmi_cmdlang_mc_change,
1162 						domain);
1163 	if (rv) {
1164 	    errstr = "ipmi_bmc_set_entity_update_handler";
1165 	    goto out_err;
1166 	}
1167 	break;
1168 
1169     case IPMI_DELETED:
1170 	ipmi_cmdlang_out(evi, "Operation", "Delete");
1171 	break;
1172 
1173     default:
1174 	break;
1175     }
1176 
1177  out_err:
1178     /* FIXME - should we shut the connection down on errors? */
1179     if (rv) {
1180 	ipmi_cmdlang_global_err(domain_name, "cmd_domain.c(domain_change)",
1181 				errstr, rv);
1182     }
1183     if (evi)
1184 	ipmi_cmdlang_cmd_info_put(evi);
1185 }
1186 
1187 static void
get_mc_name(ipmi_mc_t * mc,void * cb_data)1188 get_mc_name(ipmi_mc_t *mc, void *cb_data)
1189 {
1190     char *mc_name = cb_data;
1191 
1192     ipmi_mc_get_name(mc, mc_name, IPMI_MC_NAME_LEN);
1193 }
1194 
1195 void
ipmi_cmdlang_event_out(ipmi_event_t * event,ipmi_cmd_info_t * cmd_info)1196 ipmi_cmdlang_event_out(ipmi_event_t    *event,
1197 		       ipmi_cmd_info_t *cmd_info)
1198 {
1199     ipmi_mcid_t     mcid;
1200     char            mc_name[IPMI_MC_NAME_LEN];
1201     unsigned int    len;
1202     int             rv;
1203 
1204     mcid = ipmi_event_get_mcid(event);
1205     rv = ipmi_mc_pointer_cb(mcid, get_mc_name, mc_name);
1206     if (rv) {
1207 	/* The MC went away, that's actually ok, just ignore it. */
1208 	ipmi_cmdlang_cmd_info_put(cmd_info);
1209 	return;
1210     }
1211 
1212     ipmi_cmdlang_out(cmd_info, "MC", mc_name);
1213     ipmi_cmdlang_out_int(cmd_info, "Record ID",
1214 			 ipmi_event_get_record_id(event));
1215     ipmi_cmdlang_out_int(cmd_info, "Event type", ipmi_event_get_type(event));
1216     ipmi_cmdlang_out_time(cmd_info, "Timestamp",
1217 			  ipmi_event_get_timestamp(event));
1218     len = ipmi_event_get_data_len(event);
1219     if (len) {
1220 	unsigned char *data;
1221 	data = ipmi_mem_alloc(len);
1222 	if (!data)
1223 	    return;
1224 	len = ipmi_event_get_data(event, data, 0, len);
1225 	ipmi_cmdlang_out_binary(cmd_info, "Data", (char *) data, len);
1226 	ipmi_mem_free(data);
1227     }
1228 }
1229 
1230 static ipmi_cmdlang_cmd_t *domain_cmds;
1231 
1232 static ipmi_cmdlang_init_t cmds_domain[] =
1233 {
1234     { "domain", NULL,
1235       "- Commands dealing with domains",
1236       NULL, NULL, &domain_cmds},
1237     { "list", &domain_cmds,
1238       "- List all the domains in the system",
1239       domain_list, NULL,  NULL },
1240     { "info", &domain_cmds,
1241       "<domain> - Dump information about a domain",
1242       ipmi_cmdlang_domain_handler, domain_info, NULL },
1243     { "new", &domain_cmds,
1244       "Obsolete, use domain open",
1245       domain_new, NULL, NULL },
1246     { "open", &domain_cmds,
1247       "<domain name> [<options>] <domain parms> [<domain parms>]- Set up a"
1248       " new domain using an argument parser.  Format for the connection's"
1249       " <domain parms> depends on the connections type.  Two connections"
1250       " (to two different MCs) can be done by specifying two sets of parms."
1251       " Connections types are:",
1252       domain_open, NULL, NULL, domain_open_help },
1253     { "close", &domain_cmds,
1254       "<domain> - Close the domain",
1255       ipmi_cmdlang_domain_handler, domain_close, NULL },
1256     { "fru", &domain_cmds,
1257       "<domain> <is_logical> <device_address> <device_id>"
1258       " <lun> <private_bus> <channel>"
1259       " - Fetch FRU data with the given parms",
1260       ipmi_cmdlang_domain_handler, domain_fru, NULL },
1261     { "msg", &domain_cmds,
1262       "<domain> <channel> <ipmb> <LUN> <NetFN> <command> [data...]"
1263       " - Send a message to the given address",
1264       ipmi_cmdlang_domain_handler, domain_msg, NULL },
1265     { "scan", &domain_cmds,
1266       "<domain> <channel> <ipmb addr> [ipmb addr]"
1267       " - scan an IPMB to add or remove it. If a range is given,"
1268       " then scan all IPMBs in the range",
1269       ipmi_cmdlang_domain_handler, domain_scan, NULL },
1270     { "presence", &domain_cmds,
1271       "<domain> - Check the presence of all entities in the domain",
1272       ipmi_cmdlang_domain_handler, domain_presence, NULL },
1273     { "sel_rescan_time", &domain_cmds,
1274       "<domain> <time in seconds> - Set the time between SEL rescans"
1275       " for all SELs in the domain.  Zero disables scans.",
1276       ipmi_cmdlang_domain_handler, domain_sel_rescan_time, NULL },
1277     { "rescan_sels", &domain_cmds,
1278       "<domain> - Rescan all the SELs in the domain",
1279       ipmi_cmdlang_domain_handler, domain_rescan_sels, NULL },
1280     { "ipmb_rescan_time", &domain_cmds,
1281       "<domain> <time in seconds> - Set the time between IPMB rescans"
1282       " for this domain.  zero disables scans.",
1283       ipmi_cmdlang_domain_handler, domain_ipmb_rescan_time, NULL },
1284     { "stats", &domain_cmds,
1285       "<domain> - Dump all the domain's statistics",
1286       ipmi_cmdlang_domain_handler, domain_stats, NULL },
1287 };
1288 #define CMDS_DOMAIN_LEN (sizeof(cmds_domain)/sizeof(ipmi_cmdlang_init_t))
1289 
1290 int
ipmi_cmdlang_domain_init(os_handler_t * os_hnd)1291 ipmi_cmdlang_domain_init(os_handler_t *os_hnd)
1292 {
1293     int rv;
1294 
1295     rv = ipmi_domain_add_domain_change_handler(domain_change, NULL);
1296     if (rv)
1297 	return rv;
1298 
1299     return ipmi_cmdlang_reg_table(cmds_domain, CMDS_DOMAIN_LEN);
1300 }
1301