00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config.h>
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040 #include <errno.h>
00041 #include <termios.h>
00042 #include <unistd.h>
00043 #include <signal.h>
00044 #include <OpenIPMI/selector.h>
00045 #include <OpenIPMI/ipmi_conn.h>
00046 #include <OpenIPMI/ipmi_err.h>
00047 #include <OpenIPMI/ipmi_posix.h>
00048 #include <OpenIPMI/ipmi_glib.h>
00049 #include <OpenIPMI/ipmi_cmdlang.h>
00050 #include <OpenIPMI/ipmi_debug.h>
00051 #include <editline/readline.h>
00052
00053 #ifdef HAVE_GLIB
00054 #include <glib.h>
00055 #endif
00056
00057
00058 #include <OpenIPMI/internal/ipmi_malloc.h>
00059
00060 #ifdef HAVE_UCDSNMP
00061 # ifdef HAVE_NETSNMP
00062 # include <net-snmp/net-snmp-config.h>
00063 # include <net-snmp/net-snmp-includes.h>
00064 # elif defined(HAVE_ALT_UCDSNMP_DIR)
00065 # include <ucd-snmp/asn1.h>
00066 # include <ucd-snmp/snmp_api.h>
00067 # include <ucd-snmp/snmp.h>
00068 # else
00069 # include <asn1.h>
00070 # include <snmp_api.h>
00071 # include <snmp.h>
00072 # endif
00073 #endif
00074
00075 extern os_handler_t ipmi_debug_os_handlers;
00076 selector_t *debug_sel;
00077
00078 os_hnd_fd_id_t *term_fd_id;
00079
00080 static int done = 0;
00081 static int evcount = 0;
00082 static int handling_input = 0;
00083 static int cmd_redisp = 1;
00084
00085 static void user_input_ready(int fd, void *data, os_hnd_fd_id_t *id);
00086
00087 static void
00088 redraw_cmdline(int force)
00089 {
00090 int redisp = cmd_redisp;
00091
00092 if (force)
00093 redisp = 1;
00094 if (!done && handling_input && redisp) {
00095 rl_redisplay();
00096 fflush(stdout);
00097 }
00098 }
00099
00100 static void
00101 my_vlog(os_handler_t *handler,
00102 const char *format,
00103 enum ipmi_log_type_e log_type,
00104 va_list ap)
00105 {
00106 int do_nl = 1;
00107 static int last_was_cont = 0;
00108
00109 if (handling_input && !last_was_cont && !done && cmd_redisp)
00110 fputc('\n', stdout);
00111
00112 last_was_cont = 0;
00113 switch(log_type) {
00114 case IPMI_LOG_INFO:
00115 printf("INFO: ");
00116 break;
00117
00118 case IPMI_LOG_WARNING:
00119 printf("WARN: ");
00120 break;
00121
00122 case IPMI_LOG_SEVERE:
00123 printf("SEVR: ");
00124 break;
00125
00126 case IPMI_LOG_FATAL:
00127 printf("FATL: ");
00128 break;
00129
00130 case IPMI_LOG_ERR_INFO:
00131 printf("EINF: ");
00132 break;
00133
00134 case IPMI_LOG_DEBUG_START:
00135 do_nl = 0;
00136 last_was_cont = 1;
00137
00138 case IPMI_LOG_DEBUG:
00139 printf("DEBG: ");
00140 break;
00141
00142 case IPMI_LOG_DEBUG_CONT:
00143 last_was_cont = 1;
00144 do_nl = 0;
00145
00146 case IPMI_LOG_DEBUG_END:
00147 break;
00148 }
00149
00150 vprintf(format, ap);
00151 if (do_nl) {
00152 printf("\n");
00153 redraw_cmdline(0);
00154 }
00155 }
00156
00157 #ifdef HAVE_GLIB
00158 void glib_handle_log(const gchar *log_domain,
00159 GLogLevelFlags log_level,
00160 const gchar *message,
00161 gpointer user_data)
00162 {
00163 char *pfx = "";
00164
00165 if (log_level & G_LOG_LEVEL_ERROR)
00166 pfx = "FATL: ";
00167 else if (log_level & G_LOG_LEVEL_CRITICAL)
00168 pfx = "SEVR: ";
00169 else if (log_level & G_LOG_LEVEL_WARNING)
00170 pfx = "WARN: ";
00171 else if (log_level & G_LOG_LEVEL_MESSAGE)
00172 pfx = "EINF: ";
00173 else if (log_level & G_LOG_LEVEL_INFO)
00174 pfx = "INFO: ";
00175 else if (log_level & G_LOG_LEVEL_DEBUG)
00176 pfx = "DEBG: ";
00177 printf("%s%s\n", pfx, message);
00178 redraw_cmdline(0);
00179 }
00180 #endif
00181
00182 static void
00183 enable_term_fd(ipmi_cmdlang_t *cmdlang)
00184 {
00185 int rv;
00186
00187 if (term_fd_id)
00188 return;
00189
00190 rv = cmdlang->os_hnd->add_fd_to_wait_for(cmdlang->os_hnd, 0,
00191 user_input_ready,
00192 cmdlang,
00193 NULL, &term_fd_id);
00194 if (rv) {
00195 fprintf(stderr, "error enabling terminal handler, giving up\n");
00196 exit(1);
00197 }
00198 }
00199
00200 static void
00201 disable_term_fd(ipmi_cmdlang_t *cmdlang)
00202 {
00203 int rv;
00204
00205 if (!term_fd_id)
00206 return;
00207
00208 rv = cmdlang->os_hnd->remove_fd_to_wait_for(cmdlang->os_hnd, term_fd_id);
00209 if (rv) {
00210 fprintf(stderr, "error removing terminal handler, giving up\n");
00211 exit(1);
00212 }
00213 term_fd_id = NULL;
00214 }
00215
00216 #ifdef HAVE_UCDSNMP
00217 #define IPMI_OID_SIZE 9
00218 static oid ipmi_oid[IPMI_OID_SIZE] = {1,3,6,1,4,1,3183,1,1};
00219 int snmp_input(int op,
00220 struct snmp_session *session,
00221 int reqid,
00222 struct snmp_pdu *pdu,
00223 void *magic)
00224 {
00225 struct sockaddr_in *src_ip;
00226 uint32_t specific;
00227 struct variable_list *var;
00228
00229 #ifdef HAVE_NETSNMP
00230 if (op != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE)
00231 goto out;
00232 #else
00233 if (op != RECEIVED_MESSAGE)
00234 goto out;
00235 #endif
00236 if (pdu->command != SNMP_MSG_TRAP)
00237 goto out;
00238 if (snmp_oid_compare(ipmi_oid, IPMI_OID_SIZE,
00239 pdu->enterprise, pdu->enterprise_length)
00240 != 0)
00241 {
00242 goto out;
00243 }
00244 if (pdu->trap_type != SNMP_TRAP_ENTERPRISESPECIFIC)
00245 goto out;
00246
00247 src_ip = (struct sockaddr_in *) &pdu->agent_addr;
00248 specific = pdu->specific_type;
00249
00250 var = pdu->variables;
00251 if (var == NULL)
00252 goto out;
00253 if (var->type != ASN_OCTET_STR)
00254 goto out;
00255 if (snmp_oid_compare(ipmi_oid, IPMI_OID_SIZE, var->name, var->name_length)
00256 != 0)
00257 {
00258 goto out;
00259 }
00260 if (var->val_len < 46)
00261 goto out;
00262
00263 ipmi_handle_snmp_trap_data(src_ip,
00264 sizeof(*src_ip),
00265 IPMI_EXTERN_ADDR_IP,
00266 specific,
00267 var->val.string,
00268 var->val_len);
00269
00270 out:
00271 return 1;
00272 }
00273
00274 #ifdef HAVE_NETSNMP
00275 static int
00276 snmp_pre_parse(netsnmp_session * session, netsnmp_transport *transport,
00277 void *transport_data, int transport_data_length)
00278 {
00279 return 1;
00280 }
00281 #else
00282 static int
00283 snmp_pre_parse(struct snmp_session *session, snmp_ipaddr from)
00284 {
00285 return 1;
00286 }
00287 #endif
00288
00289 static struct snmp_session *snmp_session;
00290
00291 static void
00292 snmp_add_read_fds(selector_t *sel,
00293 int *num_fds,
00294 fd_set *fdset,
00295 struct timeval *timeout,
00296 int *timeout_invalid,
00297 void *cb_data)
00298 {
00299 snmp_select_info(num_fds, fdset, timeout, timeout_invalid);
00300 }
00301
00302 static void
00303 snmp_check_read_fds(selector_t *sel,
00304 fd_set *fds,
00305 void *cb_data)
00306 {
00307 snmp_read(fds);
00308 }
00309
00310 static void
00311 snmp_check_timeout(selector_t *sel,
00312 void *cb_data)
00313 {
00314 snmp_timeout();
00315 }
00316
00317 static int
00318 snmp_init(selector_t *sel)
00319 {
00320 struct snmp_session session;
00321 #ifdef HAVE_NETSNMP
00322 netsnmp_transport *transport = NULL;
00323 static char *snmp_default_port = "udp:162";
00324
00325 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
00326 NETSNMP_DS_LIB_MIB_ERRORS,
00327 0);
00328
00329 init_snmp("ipmish");
00330
00331 transport = netsnmp_tdomain_transport(snmp_default_port, 1, "udp");
00332 if (!transport) {
00333 snmp_sess_perror("ipmish", &session);
00334 return -1;
00335 }
00336 #else
00337 void *transport = NULL;
00338 #endif
00339 snmp_sess_init(&session);
00340 session.peername = SNMP_DEFAULT_PEERNAME;
00341 session.version = SNMP_DEFAULT_VERSION;
00342 session.community_len = SNMP_DEFAULT_COMMUNITY_LEN;
00343 session.retries = SNMP_DEFAULT_RETRIES;
00344 session.timeout = SNMP_DEFAULT_TIMEOUT;
00345 session.local_port = SNMP_TRAP_PORT;
00346 session.callback = snmp_input;
00347 session.callback_magic = transport;
00348 session.authenticator = NULL;
00349 session.isAuthoritative = SNMP_SESS_UNKNOWNAUTH;
00350
00351 #ifdef HAVE_NETSNMP
00352 snmp_session = snmp_add(&session, transport, snmp_pre_parse, NULL);
00353 #else
00354 snmp_session = snmp_open_ex(&session, snmp_pre_parse,
00355 NULL, NULL, NULL, NULL);
00356 #endif
00357 if (snmp_session == NULL) {
00358 snmp_sess_perror("ipmish", &session);
00359 return -1;
00360 }
00361
00362 ipmi_sel_set_read_fds_handler(sel,
00363 snmp_add_read_fds,
00364 snmp_check_read_fds,
00365 snmp_check_timeout,
00366 NULL);
00367
00368 return 0;
00369 }
00370 #endif
00371
00372 typedef struct out_data_s
00373 {
00374 FILE *stream;
00375 int indent;
00376 } out_data_t;
00377
00378 static int columns = 80;
00379
00380 static void
00381 out_help(FILE *s, int indent, const char *name, const char *v)
00382 {
00383 int pos, endpos;
00384 const char *endword;
00385 const char *endspace;
00386
00387 pos = fprintf(s, "%*s%s ", indent, "", name);
00388 while (*v) {
00389 endword = v;
00390 while (isspace(*endword)) {
00391 if (*endword == '\n') {
00392 v = endword + 1;
00393 fprintf(s, "\n%*s", indent+2, "");
00394 pos = indent + 2;
00395 }
00396 endword++;
00397 }
00398 endspace = endword;
00399 while (*endword && !isspace(*endword))
00400 endword++;
00401 endpos = pos + endword - v;
00402 if (endpos > columns) {
00403 v = endspace;
00404 fprintf(s, "\n%*s", indent+2, "");
00405 pos = indent + 2;
00406 }
00407 fwrite(v, 1, endword-v, s);
00408 pos += endword - v;
00409 v = endword;
00410 }
00411 fputc('\n', s);
00412 }
00413
00414 static void
00415 out_value(ipmi_cmdlang_t *info, const char *name, const char *value)
00416 {
00417 out_data_t *out_data = info->user_data;
00418
00419 if (value) {
00420 if (info->help) {
00421 out_help(out_data->stream, out_data->indent*2, name, value);
00422 } else {
00423 fprintf(out_data->stream, "%*s%s: %s\n", out_data->indent*2, "",
00424 name, value);
00425 }
00426 } else
00427 fprintf(out_data->stream, "%*s%s\n", out_data->indent*2, "", name);
00428 fflush(out_data->stream);
00429 }
00430
00431 static void
00432 out_binary(ipmi_cmdlang_t *info, const char *name, const char *value,
00433 unsigned int len)
00434 {
00435 out_data_t *out_data = info->user_data;
00436 unsigned char *data = (unsigned char *) value;
00437 int indent2 = (out_data->indent * 2) + strlen(name) + 1;
00438 int i;
00439 char *sep = ":";
00440
00441 if (info->help)
00442 sep = "";
00443
00444 fprintf(out_data->stream, "%*s%s%s", out_data->indent*2, "", name, sep);
00445 for (i=0; i<len; i++) {
00446 if ((i != 0) && ((i % 8) == 0))
00447 fprintf(out_data->stream, "\n%*s", indent2, "");
00448 fprintf(out_data->stream, " 0x%2.2x", (data[i] & 0xff));
00449 }
00450 fprintf(out_data->stream, "\n");
00451
00452 fflush(out_data->stream);
00453 }
00454
00455 static void
00456 out_unicode(ipmi_cmdlang_t *info, const char *name, const char *value,
00457 unsigned int len)
00458 {
00459 out_binary(info, name, value, len);
00460 }
00461
00462 static void
00463 down_level(ipmi_cmdlang_t *info)
00464 {
00465 out_data_t *out_data = info->user_data;
00466
00467 out_data->indent++;
00468 }
00469
00470 static void
00471 up_level(ipmi_cmdlang_t *info)
00472 {
00473 out_data_t *out_data = info->user_data;
00474
00475 out_data->indent--;
00476 }
00477
00478 static void cmd_done(ipmi_cmdlang_t *info);
00479
00480 static out_data_t lout_data =
00481 {
00482 .stream = NULL,
00483 .indent = 0,
00484 };
00485 static char cmdlang_objstr[IPMI_MAX_NAME_LEN];
00486 static ipmi_cmdlang_t cmdlang =
00487 {
00488 .out = out_value,
00489 .out_binary = out_binary,
00490 .out_unicode = out_unicode,
00491 .down = down_level,
00492 .up = up_level,
00493 .done = cmd_done,
00494
00495 .os_hnd = NULL,
00496
00497 .user_data = &lout_data,
00498
00499 .objstr = cmdlang_objstr,
00500 .objstr_len = sizeof(cmdlang_objstr),
00501 };
00502
00503 int *done_ptr = NULL;
00504
00505 static void
00506 cmd_done(ipmi_cmdlang_t *info)
00507 {
00508 out_data_t *out_data = info->user_data;
00509
00510 if (info->err) {
00511 char errval[128];
00512 if (!info->location)
00513 info->location = "";
00514 if (strlen(info->objstr) == 0) {
00515 fprintf(out_data->stream, "error: %s: %s (0x%x, %s)\n",
00516 info->location, info->errstr,
00517 info->err,
00518 ipmi_get_error_string(info->err, errval, sizeof(errval)));
00519 } else {
00520 fprintf(out_data->stream, "error: %s %s: %s (0x%x, %s)\n",
00521 info->location, info->objstr, info->errstr,
00522 info->err,
00523 ipmi_get_error_string(info->err, errval, sizeof(errval)));
00524 }
00525 if (info->errstr_dynalloc)
00526 ipmi_mem_free(info->errstr);
00527 info->errstr_dynalloc = 0;
00528 info->errstr = NULL;
00529 info->location = NULL;
00530 info->objstr[0] = '\0';
00531 info->err = 0;
00532 }
00533
00534 if (done_ptr) {
00535 *done_ptr = 1;
00536 } else {
00537 handling_input = 1;
00538 redraw_cmdline(1);
00539 enable_term_fd(info);
00540 fflush(out_data->stream);
00541 }
00542 }
00543
00544 void
00545 ipmi_cmdlang_global_err(char *objstr,
00546 char *location,
00547 char *errstr,
00548 int errval)
00549 {
00550 if (handling_input && !done && cmd_redisp)
00551 fputc('\n', stdout);
00552 if (objstr)
00553 fprintf(stderr, "global error: %s %s: %s (0x%x)", location, objstr,
00554 errstr, errval);
00555 else
00556 fprintf(stderr, "global error: %s: %s (0x%x)", location,
00557 errstr, errval);
00558 evcount = 0;
00559 redraw_cmdline(0);
00560 }
00561
00562 void
00563 ipmi_cmdlang_report_event(ipmi_cmdlang_event_t *event)
00564 {
00565 unsigned int level, len;
00566 enum ipmi_cmdlang_out_types type;
00567 char *name, *value;
00568 int indent2;
00569 int i;
00570
00571 if (handling_input && !done && cmd_redisp)
00572 fputc('\n', stdout);
00573 ipmi_cmdlang_event_restart(event);
00574 printf("Event\n");
00575 while (ipmi_cmdlang_event_next_field(event, &level, &type, &name, &len,
00576 &value))
00577 {
00578 switch (type) {
00579 case IPMI_CMDLANG_STRING:
00580 if (value)
00581 printf(" %*s%s: %s\n", level*2, "", name, value);
00582 else
00583 printf(" %*s%s\n", level*2, "", name);
00584 break;
00585
00586 case IPMI_CMDLANG_BINARY:
00587 case IPMI_CMDLANG_UNICODE:
00588 indent2 = (level * 2) + strlen(name) + 1;
00589 printf(" %*s%s:", level*2, "", name);
00590 for (i=0; i<len; i++) {
00591 if ((i != 0) && ((i % 8) == 0))
00592 printf("\n %*s", indent2, "");
00593 printf(" 0x%2.2x", value[i] & 0xff);
00594 }
00595 printf("\n");
00596
00597 fflush(stdout);
00598 break;
00599 }
00600 }
00601 evcount = 0;
00602 redraw_cmdline(0);
00603 }
00604
00605 static void
00606 user_input_ready(int fd, void *data, os_hnd_fd_id_t *id)
00607 {
00608 rl_callback_read_char();
00609 }
00610
00611 static void
00612 rl_ipmish_cb_handler(char *cmdline)
00613 {
00614 char *expansion = NULL;
00615 int result;
00616
00617 if (cmdline == NULL) {
00618 done = 1;
00619 evcount = 1;
00620 return;
00621 }
00622 result = history_expand(cmdline, &expansion);
00623 if (result < 0 || result == 2) {
00624 fprintf(stderr, "%s\n", expansion);
00625 } else if (expansion && strlen(expansion)){
00626 cmdlang.err = 0;
00627 cmdlang.errstr = NULL;
00628 cmdlang.errstr_dynalloc = 0;
00629 cmdlang.location = NULL;
00630 handling_input = 0;
00631 add_history(expansion);
00632 ipmi_cmdlang_handle(&cmdlang, expansion);
00633 }
00634 if (expansion)
00635 free(expansion);
00636 }
00637
00638 static void
00639 cleanup_term(void)
00640 {
00641 rl_callback_handler_remove();
00642 disable_term_fd(&cmdlang);
00643 }
00644
00645 static void cleanup_sig(int sig);
00646
00647 static void
00648 setup_term(os_handler_t *os_hnd)
00649 {
00650 signal(SIGINT, cleanup_sig);
00651 signal(SIGPIPE, cleanup_sig);
00652 signal(SIGUSR1, cleanup_sig);
00653 signal(SIGUSR2, cleanup_sig);
00654 signal(SIGPWR, cleanup_sig);
00655
00656 stifle_history(500);
00657 rl_callback_handler_install("> ", rl_ipmish_cb_handler);
00658 lout_data.stream = stdout;
00659
00660 cmdlang.os_hnd = os_hnd;
00661 }
00662
00663 static void
00664 redisp_cmd(ipmi_cmd_info_t *cmd_info)
00665 {
00666 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00667 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00668 int argc = ipmi_cmdlang_get_argc(cmd_info);
00669 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00670 int redisp;
00671
00672 if ((argc - curr_arg) < 1) {
00673
00674 cmdlang->errstr = "Not enough parameters";
00675 cmdlang->err = EINVAL;
00676 goto out_err;
00677 }
00678
00679 ipmi_cmdlang_get_bool(argv[curr_arg], &redisp, cmd_info);
00680 if (cmdlang->err) {
00681 cmdlang->errstr = "redisp setting invalid";
00682 goto out_err;
00683 }
00684 curr_arg++;
00685
00686 cmd_redisp = redisp;
00687
00688 ipmi_cmdlang_out(cmd_info, "redisp set", NULL);
00689
00690 out_err:
00691 cmdlang->location = "ipmish.c(redisp_cmd)";
00692 }
00693
00694 static void
00695 exit_cmd(ipmi_cmd_info_t *cmd_info)
00696 {
00697 done = 1;
00698 evcount = 0;
00699 ipmi_cmdlang_out(cmd_info, "Exiting ipmish", NULL);
00700 }
00701
00702 static int read_nest = 0;
00703 static void
00704 read_cmd(ipmi_cmd_info_t *cmd_info)
00705 {
00706 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00707 int cdone;
00708 char cmdline[256];
00709 FILE *s;
00710 out_data_t my_out_data;
00711 ipmi_cmdlang_t my_cmdlang = *cmdlang;
00712 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00713 int argc = ipmi_cmdlang_get_argc(cmd_info);
00714 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00715 int *saved_done_ptr;
00716 char *fname;
00717
00718 if ((argc - curr_arg) < 1) {
00719 cmdlang->errstr = "No filename entered";
00720 cmdlang->err = EINVAL;
00721 goto out_err;
00722 }
00723
00724 fname = argv[curr_arg];
00725 curr_arg++;
00726 s = fopen(fname, "r");
00727 if (!s) {
00728 cmdlang->errstr = "Unable to openfile";
00729 cmdlang->err = errno;
00730 goto out_err;
00731 }
00732
00733 if (!read_nest) {
00734 handling_input = 0;
00735 disable_term_fd(cmdlang);
00736 }
00737 read_nest++;
00738 saved_done_ptr = done_ptr;
00739
00740
00741 while (fgets(cmdline, sizeof(cmdline), s)) {
00742 my_out_data.stream = stdout;
00743 my_out_data.indent = 0;
00744 my_cmdlang.user_data = &my_out_data;
00745 cdone = 0;
00746 done_ptr = &cdone;
00747 printf("> %s", cmdline);
00748 fflush(stdout);
00749 ipmi_cmdlang_handle(&my_cmdlang, cmdline);
00750 while (!cdone)
00751 cmdlang->os_hnd->perform_one_op(cmdlang->os_hnd, NULL);
00752 done_ptr = NULL;
00753 }
00754 fclose(s);
00755
00756 done_ptr = saved_done_ptr;
00757 read_nest--;
00758 if (!read_nest) {
00759 handling_input = 1;
00760 enable_term_fd(cmdlang);
00761 }
00762
00763 ipmi_cmdlang_out(cmd_info, "File read", fname);
00764
00765 return;
00766
00767 out_err:
00768 cmdlang->location = "ipmish.c(read_cmd)";
00769 }
00770
00771 static void
00772 setup_cmds(void)
00773 {
00774 int rv;
00775
00776 rv = ipmi_cmdlang_reg_cmd(NULL,
00777 "redisp_cmd",
00778 "on|off - If an asynchronous event comes in,"
00779 " redisplay the current working command. This"
00780 " is on by default.",
00781 redisp_cmd, NULL, NULL, NULL);
00782 if (rv) {
00783 fprintf(stderr, "Error adding exit command: 0x%x\n", rv);
00784 exit(1);
00785 }
00786
00787 rv = ipmi_cmdlang_reg_cmd(NULL,
00788 "exit",
00789 "- leave the program",
00790 exit_cmd, NULL, NULL, NULL);
00791 if (rv) {
00792 fprintf(stderr, "Error adding exit command: 0x%x\n", rv);
00793 exit(1);
00794 }
00795
00796 rv = ipmi_cmdlang_reg_cmd(NULL,
00797 "read",
00798 "<file> - Read commands from the file and"
00799 " execute them",
00800 read_cmd, NULL, NULL, NULL);
00801 if (rv) {
00802 fprintf(stderr, "Error adding read command: 0x%x\n", rv);
00803 exit(1);
00804 }
00805 }
00806
00807 static void
00808 domain_down(void *cb_data)
00809 {
00810 int *count = cb_data;
00811 (*count)--;
00812 }
00813
00814 static void
00815 shutdown_domain_handler(ipmi_domain_t *domain, void *cb_data)
00816 {
00817 int *count = cb_data;
00818 int rv;
00819
00820 rv = ipmi_domain_close(domain, domain_down, cb_data);
00821 if (!rv)
00822 (*count)++;
00823 }
00824
00825 static void
00826 cleanup_sig(int sig)
00827 {
00828 fprintf(stderr, "Exiting due to signal %d\n", sig);
00829 done = 0;
00830 ipmi_domain_iterate_domains(shutdown_domain_handler, &done);
00831 while (done)
00832 cmdlang.os_hnd->perform_one_op(cmdlang.os_hnd, NULL);
00833 cleanup_term();
00834 exit(1);
00835 }
00836
00837 typedef struct exec_list_s
00838 {
00839 char *str;
00840 struct exec_list_s *next;
00841 } exec_list_t;
00842 static exec_list_t *execs, *execs_tail;
00843
00844 static void
00845 add_exec_str(char *str)
00846 {
00847 exec_list_t *e;
00848
00849 e = malloc(sizeof(*e));
00850 if (!e) {
00851 fprintf(stderr, "Out of memory");
00852 exit(1);
00853 }
00854 e->str = str;
00855 e->next = NULL;
00856 if (execs)
00857 execs_tail->next = e;
00858 else
00859 execs = e;
00860 execs_tail = e;
00861 }
00862
00863 static char *usage_str =
00864 "%s is a program that gives access to the OpenIPMI library from a command\n"
00865 "line. It is designed to be script driven. Format is:\n"
00866 " %s [options]\n"
00867 "Options are:\n"
00868 " --execute <string> - execute the given string at startup. This may be\n"
00869 " entered multiple times for multiple commands.\n"
00870 " -x <string> - same as --execute\n"
00871 " --dlock - turn on lock debugging.\n"
00872 " --dmem - turn on memory debugging.\n"
00873 " --drawmsg - turn on raw message tracing.\n"
00874 " --dmsg - turn on message tracing debugging.\n"
00875 " --dmsgerr - turn on printing out low-level message errors.\n"
00876 #ifdef HAVE_GLIB
00877 " --glib - use glib for the OS handler.\n"
00878 #endif
00879 #ifdef HAVE_UCDSNMP
00880 " --snmp - turn on SNMP trap handling.\n"
00881 #endif
00882 " --help - This output.\n"
00883 ;
00884 static void usage(char *name)
00885 {
00886 fprintf(stderr, usage_str, name, name);
00887 }
00888
00889 int
00890 main(int argc, char *argv[])
00891 {
00892 int rv;
00893 int curr_arg = 1;
00894 const char *arg;
00895 #ifdef HAVE_UCDSNMP
00896 int init_snmp = 0;
00897 selector_t *sel;
00898 #endif
00899 os_handler_t *os_hnd;
00900 int use_debug_os = 0;
00901 char *colstr;
00902 #ifdef HAVE_GLIB
00903 int use_glib = 0;
00904 #endif
00905
00906 colstr = getenv("COLUMNS");
00907 if (colstr) {
00908 int tmp = strtoul(colstr, NULL, 0);
00909 if (tmp)
00910 columns = tmp;
00911 }
00912
00913 while ((curr_arg < argc) && (argv[curr_arg][0] == '-')) {
00914 arg = argv[curr_arg];
00915 curr_arg++;
00916 if (strcmp(arg, "--") == 0) {
00917 break;
00918 } else if ((strcmp(arg, "-x") == 0) || (strcmp(arg, "--execute") == 0))
00919 {
00920 if (curr_arg >= argc) {
00921 fprintf(stderr, "No option given for %s", arg);
00922 usage(argv[0]);
00923 return 1;
00924 }
00925 add_exec_str(argv[curr_arg]);
00926 curr_arg++;
00927 } else if (strcmp(arg, "--dlock") == 0) {
00928 DEBUG_LOCKS_ENABLE();
00929 use_debug_os = 1;
00930 } else if (strcmp(arg, "--dmem") == 0) {
00931 DEBUG_MALLOC_ENABLE();
00932 } else if (strcmp(arg, "--drawmsg") == 0) {
00933 DEBUG_RAWMSG_ENABLE();
00934 } else if (strcmp(arg, "--dmsg") == 0) {
00935 DEBUG_MSG_ENABLE();
00936 } else if (strcmp(arg, "--dmsgerr") == 0) {
00937 DEBUG_MSG_ERR_ENABLE();
00938 #ifdef HAVE_UCDSNMP
00939 } else if (strcmp(arg, "--snmp") == 0) {
00940 init_snmp = 1;
00941 #endif
00942 #ifdef HAVE_GLIB
00943 } else if (strcmp(arg, "--glib") == 0) {
00944 use_glib = 1;
00945 #endif
00946 } else if (strcmp(arg, "--help") == 0) {
00947 usage(argv[0]);
00948 return 0;
00949 } else {
00950 fprintf(stderr, "Unknown option: %s\n", arg);
00951 usage(argv[0]);
00952 return 1;
00953 }
00954 }
00955
00956 if (use_debug_os) {
00957 os_hnd = &ipmi_debug_os_handlers;
00958 rv = sel_alloc_selector(os_hnd, &debug_sel);
00959 if (rv) {
00960 fprintf(stderr, "Could not allocate selector\n");
00961 return 1;
00962 }
00963 #ifdef HAVE_UCDSNMP
00964 sel = debug_sel;
00965 #endif
00966 #ifdef HAVE_GLIB
00967 } else if (use_glib) {
00968 #ifdef HAVE_UCDSNMP
00969 init_snmp = 0;
00970 sel = NULL;
00971 #endif
00972 g_thread_init(NULL);
00973 os_hnd = ipmi_glib_get_os_handler();
00974 if (!os_hnd) {
00975 fprintf(stderr,
00976 "ipmi_smi_setup_con: Unable to allocate os handler\n");
00977 return 1;
00978 }
00979 g_log_set_handler("OpenIPMI",
00980 G_LOG_LEVEL_ERROR
00981 | G_LOG_LEVEL_CRITICAL
00982 | G_LOG_LEVEL_WARNING
00983 | G_LOG_LEVEL_MESSAGE
00984 | G_LOG_LEVEL_INFO
00985 | G_LOG_LEVEL_DEBUG
00986 | G_LOG_FLAG_FATAL,
00987 glib_handle_log,
00988 NULL);
00989 #endif
00990 } else {
00991 os_hnd = ipmi_posix_setup_os_handler();
00992 if (!os_hnd) {
00993 fprintf(stderr,
00994 "ipmi_smi_setup_con: Unable to allocate os handler\n");
00995 return 1;
00996 }
00997 #ifdef HAVE_UCDSNMP
00998 sel = ipmi_posix_os_handler_get_sel(os_hnd);
00999 #endif
01000 }
01001
01002 os_hnd->set_log_handler(os_hnd, my_vlog);
01003
01004
01005 ipmi_init(os_hnd);
01006
01007 #ifdef HAVE_UCDSNMP
01008 if (init_snmp) {
01009 if (snmp_init(sel) < 0)
01010 return 1;
01011 }
01012 #endif
01013
01014 rv = ipmi_cmdlang_init(os_hnd);
01015 if (rv) {
01016 fprintf(stderr, "Unable to initialize command processor: 0x%x\n", rv);
01017 return 1;
01018 }
01019
01020 setup_cmds();
01021
01022 setup_term(os_hnd);
01023
01024 while (execs) {
01025 exec_list_t *e = execs;
01026 int cdone = 0;
01027 read_nest = 1;
01028 execs = e->next;
01029 printf("> %s\n", e->str);
01030 fflush(stdout);
01031 done_ptr = &cdone;
01032 rl_ipmish_cb_handler(e->str);
01033 while (!cdone)
01034 os_hnd->perform_one_op(os_hnd, NULL);
01035 done_ptr = NULL;
01036 free(e);
01037 read_nest = 0;
01038 }
01039
01040 fflush(stdout);
01041
01042 handling_input = 1;
01043 enable_term_fd(&cmdlang);
01044
01045 while (!done)
01046 os_hnd->perform_one_op(os_hnd, NULL);
01047
01048 cleanup_term();
01049
01050
01051
01052 done = 0;
01053 ipmi_domain_iterate_domains(shutdown_domain_handler, &done);
01054 while (done)
01055 os_hnd->perform_one_op(os_hnd, NULL);
01056
01057 ipmi_cmdlang_cleanup();
01058 ipmi_shutdown();
01059
01060 ipmi_debug_malloc_cleanup();
01061
01062 os_hnd->free_os_handler(os_hnd);
01063
01064
01065 printf("\b\b \b\b");
01066 if (evcount)
01067 printf("\n");
01068 fflush(stdout);
01069
01070 if (rv)
01071 return 1;
01072 return 0;
01073 }