/* * Send message to serial port */ static int serial_term_send_msg(struct ipmi_intf * intf, uint8_t * msg, int msg_len) { int i, size, tmp = 0; uint8_t * buf, * data; if (verbose > 3) { fprintf(stderr, "Sending request:\n"); fprintf(stderr, " NetFN/rsLUN = 0x%x\n", msg[0]); fprintf(stderr, " rqSeq = 0x%x\n", msg[1]); fprintf(stderr, " cmd = 0x%x\n", msg[2]); if (msg_len > 7) { fprintf(stderr, " data_len = %d\n", msg_len - 3); fprintf(stderr, " data = %s\n", buf2str(msg + 3, msg_len - 3)); } } if (verbose > 4) { fprintf(stderr, "Message data:\n"); fprintf(stderr, " %s\n", buf2str(msg, msg_len)); } /* calculate required buffer size */ size = msg_len * 2 + 4; /* allocate buffer for output data */ buf = data = (uint8_t *) alloca(size); if (!buf) { lperror(LOG_ERR, "ipmitool: alloca error"); return -1; } /* start character */ *buf++ = '['; /* body */ for (i = 0; i < msg_len; i++) { buf += sprintf( buf, "%02x", msg[i]); } /* stop character */ *buf++ = ']'; /* carriage return */ *buf++ = '\r'; /* line feed */ *buf++ = '\n'; /* write data to serial port */ tmp = write(intf->fd, data, size); if (tmp <= 0) { lperror(LOG_ERR, "ipmitool: write error"); return -1; } return 0; }
static int enter_raw_mode(void) { struct termios tio; if (tcgetattr(fileno(stdout), &_saved_tio) < 0) { lperror(LOG_ERR, "tcgetattr failed"); return -1; } tio = _saved_tio; if (_altterm) { tio.c_iflag &= (ISTRIP | IGNBRK); tio.c_cflag &= ~(CSIZE | PARENB | IXON | IXOFF | IXANY); tio.c_cflag |= (CS8 |CREAD) | (IXON|IXOFF|IXANY); tio.c_lflag &= 0; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; } else { tio.c_iflag |= IGNPAR; tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN); tio.c_oflag &= ~OPOST; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; } if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0) { lperror(LOG_ERR, "tcsetattr(stdin)"); } else if (tcsetattr(fileno(stdout), TCSADRAIN, &tio) < 0) { lperror(LOG_ERR, "tcsetattr(stdout)"); } else { _in_raw_mode = 1; } return 0; }
/** * The string s is the next word of the sentence. * Do not issue the empty string. * Return false if too many words or the word is too long. */ static int issue_sentence_word(Sentence sent, const char * s) { if (*s == '\0') return TRUE; if (strlen(s) > MAX_WORD) { lperror(SEPARATE, ". The word \"%s\" is too long.\n" "A word can have a maximum of %d characters.\n", s, MAX_WORD); return FALSE; } if (sent->length == MAX_SENTENCE) { lperror(SEPARATE, ". The sentence has too many words.\n"); return FALSE; } strcpy(sent->word[sent->length].string, s); /* Now we record whether the first character of the word is upper-case. (The first character may be made lower-case later, but we may want to get at the original version) */ if (is_utf8_upper(s)) sent->word[sent->length].firstupper=1; else sent->word[sent->length].firstupper = 0; sent->length++; return TRUE; }
static int ipmi_openipmi_open(struct ipmi_intf * intf) { int i = 0; char ipmi_dev[16]; char ipmi_devfs[16]; char ipmi_devfs2[16]; int devnum = 0; devnum = intf->devnum; sprintf(ipmi_dev, "/dev/ipmi%d", devnum); sprintf(ipmi_devfs, "/dev/ipmi/%d", devnum); sprintf(ipmi_devfs2, "/dev/ipmidev/%d", devnum); lprintf(LOG_DEBUG, "Using ipmi device %d", devnum); intf->fd = open(ipmi_dev, O_RDWR); if (intf->fd < 0) { intf->fd = open(ipmi_devfs, O_RDWR); if (intf->fd < 0) { intf->fd = open(ipmi_devfs2, O_RDWR); } if (intf->fd < 0) { lperror(LOG_ERR, "Could not open device at %s or %s or %s", ipmi_dev, ipmi_devfs , ipmi_devfs2); return -1; } } if (ioctl(intf->fd, IPMICTL_SET_GETS_EVENTS_CMD, &i) < 0) { lperror(LOG_ERR, "Could not enable event receiver"); return -1; } intf->opened = 1; /* This is never set to 0, the default is IPMI_BMC_SLAVE_ADDR */ if (intf->my_addr != 0) { if (intf->set_my_addr(intf, intf->my_addr) < 0) { lperror(LOG_ERR, "Could not set IPMB address"); return -1; } lprintf(LOG_DEBUG, "Set IPMB address to 0x%x", intf->my_addr ); } intf->manufacturer_id = ipmi_get_oem(intf); return intf->fd; }
static int leave_raw_mode(void) { if (!_in_raw_mode) return -1; else if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) lperror(LOG_ERR, "tcsetattr(stdin)"); else if (tcsetattr(fileno(stdout), TCSADRAIN, &_saved_tio) == -1) lperror(LOG_ERR, "tcsetattr(stdout)"); else _in_raw_mode = 0; return 0; }
/** * This just looks up all the words in the sentence, and builds * up an appropriate error message in case some are not there. * It has no side effect on the sentence. Returns TRUE if all * went well. */ int sentence_in_dictionary(Sentence sent) { int w, ok_so_far; char * s; Dictionary dict = sent->dict; char temp[1024]; ok_so_far = TRUE; for (w=0; w<sent->length; w++) { s = sent->word[w].string; if (!boolean_dictionary_lookup(dict, s) && !(is_utf8_upper(s) && dict->capitalized_word_defined) && !(is_utf8_upper(s) && is_s_word(s) && dict->pl_capitalized_word_defined) && !(ishyphenated(s) && dict->hyphenated_word_defined) && !(is_number(s) && dict->number_word_defined) && !(is_ing_word(s) && dict->ing_word_defined) && !(is_s_word(s) && dict->s_word_defined) && !(is_ed_word(s) && dict->ed_word_defined) && !(is_ly_word(s) && dict->ly_word_defined)) { if (ok_so_far) { safe_strcpy(temp, "The following words are not in the dictionary:", sizeof(temp)); ok_so_far = FALSE; } safe_strcat(temp, " \"", sizeof(temp)); safe_strcat(temp, sent->word[w].string, sizeof(temp)); safe_strcat(temp, "\"", sizeof(temp)); } } if (!ok_so_far) { lperror(NOTINDICT, "\n%s\n", temp); } return ok_so_far; }
/* * Read a line from serial port * Returns > 0 if there is a line, < 0 on error or timeout */ static int serial_read_line(struct ipmi_intf * intf, char *str, int len) { int rv, i; *str = 0; i = 0; while (i < len) { if (serial_wait_for_data(intf)) { return -1; } rv = read(intf->fd, str + i, 1); if (rv < 0) { return -1; } else if (!rv) { lperror(LOG_ERR, "Serial read failed: %s", strerror(errno)); return -1; } if (str[i] == '\n' || str[i] == '\r') { if (verbose > 4) { char c = str[i]; str[i] = '\0'; fprintf(stderr, "Received data: %s\n", str); str[i] = c; } return i + 1; } else { i++; } } lprintf(LOG_ERR, "Serial data is too long"); return -1; }
/* * Read and parse data from serial port */ static int serial_bm_recv_msg(struct ipmi_intf * intf, struct serial_bm_recv_ctx * recv_ctx, uint8_t * msg_data, size_t msg_len) { struct serial_bm_parse_ctx parse_ctx; int rv; parse_ctx.state = MSG_NONE; parse_ctx.msg = msg_data; parse_ctx.max_len = msg_len; do { /* wait for data in the port */ if (serial_bm_wait_for_data(intf)) { return 0; } /* read data into buffer */ rv = read(intf->fd, recv_ctx->buffer + recv_ctx->buffer_size, recv_ctx->max_buffer_size - recv_ctx->buffer_size); if (rv < 0) { lperror(LOG_ERR, "ipmitool: read error"); return -1; } if (verbose > 5) { fprintf(stderr, "Received serial data:\n %s\n", buf2str(recv_ctx->buffer + recv_ctx->buffer_size, rv)); } /* increment buffer size */ recv_ctx->buffer_size += rv; /* parse buffer */ rv = serial_bm_parse_buffer(recv_ctx->buffer, recv_ctx->buffer_size, &parse_ctx); if (rv < recv_ctx->buffer_size) { /* move non-parsed part of the buffer to the beginning */ memmove(recv_ctx->buffer, recv_ctx->buffer + rv, recv_ctx->buffer_size - rv); } /* decrement buffer size */ recv_ctx->buffer_size -= rv; } while (parse_ctx.state != MSG_DONE); if (verbose > 4) { printf("Received message:\n %s\n", buf2str(msg_data, parse_ctx.msg_len)); } /* received a message */ return parse_ctx.msg_len; }
static int ipmi_openipmi_set_my_addr(struct ipmi_intf *intf, uint8_t addr) { unsigned int a = addr; if (ioctl(intf->fd, IPMICTL_SET_MY_ADDRESS_CMD, &a) < 0) { lperror(LOG_ERR, "Could not set IPMB address"); return -1; } intf->my_addr = addr; return 0; }
static void dict_error(Dictionary dict, wchar_t * s) { int i; wchar_t tokens[1024], t[128]; tokens[0] = L'\0'; for (i=0; i<5 && dict->token[0] != L'\0' ; i++) { swprintf_s(t, 128, L"\"%s\" ", dict->token); wcscat_s(tokens, 1024, t); (void) advance(dict); } lperror(DICTPARSE, L". %s\n\t line %d, tokens = %s\n", s, dict->line_number, tokens); }
static int special_string(Sentence sent, int i, const char * s) { X_node * e; if (boolean_dictionary_lookup(sent->dict, s)) { sent->word[i].x = build_word_expressions(sent, s); for (e = sent->word[i].x; e != NULL; e = e->next) { e->string = sent->word[i].string; } return TRUE; } else { lperror(BUILDEXPR, ".\n To process this sentence your dictionary " "needs the word \"%s\".\n", s); return FALSE; } }
static int guessed_string(Sentence sent, int i, const char * s, const char * type) { X_node * e; char *t, *u; char str[MAX_WORD+1]; if (boolean_dictionary_lookup(sent->dict, type)) { sent->word[i].x = build_word_expressions(sent, type); e = sent->word[i].x; if(is_s_word(s)) { for (; e != NULL; e = e->next) { t = strchr(e->string, '.'); if (t != NULL) { sprintf(str, "%.50s[!].%.5s", s, t+1); } else { sprintf(str, "%.50s[!]", s); } t = (char *) xalloc(strlen(str)+1); strcpy(t,str); u = string_set_add(t, sent->string_set); xfree(t, strlen(str)+1); e->string = u; } } else { if(is_ed_word(s)) { sprintf(str, "%.50s[!].v", s); } else if(is_ing_word(s)) { sprintf(str, "%.50s[!].g", s); } else if(is_ly_word(s)) { sprintf(str, "%.50s[!].e", s); } else sprintf(str, "%.50s[!]", s); t = (char *) xalloc(strlen(str)+1); strcpy(t,str); u = string_set_add(t, sent->string_set); xfree(t, strlen(str)+1); e->string = u; } return TRUE; } else { lperror(BUILDEXPR, ".\n To process this sentence your dictionary " "needs the word \"%s\".\n", type); return FALSE; } }
/* * This function waits for incoming data */ static int serial_bm_wait_for_data(struct ipmi_intf * intf) { int n; struct pollfd pfd; pfd.fd = intf->fd; pfd.events = POLLIN; pfd.revents = 0; n = poll(&pfd, 1, intf->ssn_params.timeout * 1000); if (n < 0) { lperror(LOG_ERR, "Poll for serial data failed"); return -1; } else if (!n) { return -1; } return 0; }
void test_ieee754(void) { int i; float x; printf("mantissa-digits: %d\n", FLT_MANT_DIG); printf("enter x:"); int ret = scanf("%f", &x); if (ret == 1) { float_binfprint(stdout, x); endline(); } else { lperror("scanf"); } for (i = 0; i < 32; i++) { uint d = 1 << i; printf("d=%08x x=", d); float_binfprint(stdout, d); endline(); } }
int load_config() { char* cdir = strdup(""); char* xdgdir = getenv("XDG_CONFIG_HOME"); if (xdgdir != NULL) configdir = strrecat(configdir,xdgdir); else { char* homedir = getenv("HOME"); if (homedir == NULL) homedir = getenv("USERPROFILE"); //Windows if (homedir != NULL) { cdir = strrecat(cdir,homedir); cdir = strrecat(cdir,"/.twtclt/"); } } int r = mkdir(cdir,0700); if ((r == -1) && (errno != EEXIST)) lperror("Error while creating config dir"); else configdir = strdup(cdir); free(cdir); return 0; }
static struct ipmi_rs * ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { struct ipmi_recv recv; struct ipmi_addr addr; struct ipmi_system_interface_addr bmc_addr = { .addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE, .channel = IPMI_BMC_CHANNEL, }; struct ipmi_ipmb_addr ipmb_addr = { .addr_type = IPMI_IPMB_ADDR_TYPE, }; struct ipmi_req _req; static struct ipmi_rs rsp; struct timeval read_timeout; static int curr_seq = 0; fd_set rset; uint8_t * data = NULL; int data_len = 0; int retval = 0; if (intf == NULL || req == NULL) return NULL; ipmb_addr.channel = intf->target_channel & 0x0f; if (intf->opened == 0 && intf->open != NULL) if (intf->open(intf) < 0) return NULL; if (verbose > 2) { fprintf(stderr, "OpenIPMI Request Message Header:\n"); fprintf(stderr, " netfn = 0x%x\n", req->msg.netfn ); fprintf(stderr, " cmd = 0x%x\n", req->msg.cmd); printbuf(req->msg.data, req->msg.data_len, "OpenIPMI Request Message Data"); } /* * setup and send message */ memset(&_req, 0, sizeof(struct ipmi_req)); if (intf->target_addr != 0 && intf->target_addr != intf->my_addr) { /* use IPMB address if needed */ ipmb_addr.slave_addr = intf->target_addr; ipmb_addr.lun = req->msg.lun; lprintf(LOG_DEBUG, "Sending request 0x%x to " "IPMB target @ 0x%x:0x%x (from 0x%x)", req->msg.cmd, intf->target_addr,intf->target_channel, intf->my_addr); if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) { uint8_t index = 0; lprintf(LOG_DEBUG, "Encapsulating data sent to " "end target [0x%02x,0x%02x] using transit [0x%02x,0x%02x] from 0x%x ", (0x40 | intf->target_channel), intf->target_addr, intf->transit_channel, intf->transit_addr, intf->my_addr ); /* Convert Message to 'Send Message' */ /* Supplied req : req , internal req : _req */ if (verbose > 4) { fprintf(stderr, "Converting message:\n"); fprintf(stderr, " netfn = 0x%x\n", req->msg.netfn ); fprintf(stderr, " cmd = 0x%x\n", req->msg.cmd); if (req->msg.data && req->msg.data_len) { fprintf(stderr, " data_len = %d\n", req->msg.data_len); fprintf(stderr, " data = %s\n", buf2str(req->msg.data,req->msg.data_len)); } } /* Modify target address to use 'transit' instead */ ipmb_addr.slave_addr = intf->transit_addr; ipmb_addr.channel = intf->transit_channel; /* FIXME backup "My address" */ data_len = req->msg.data_len + 8; data = malloc(data_len); if (data == NULL) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return NULL; } memset(data, 0, data_len); data[index++] = (0x40|intf->target_channel); data[index++] = intf->target_addr; data[index++] = ( req->msg.netfn << 2 ) | req->msg.lun ; data[index++] = ipmi_csum(data+1, 2); data[index++] = 0xFF; /* normally 0x20 , overwritten by IPMC */ data[index++] = ( (0) << 2) | 0 ; /* FIXME */ data[index++] = req->msg.cmd; memcpy( (data+index) , req->msg.data, req->msg.data_len); index += req->msg.data_len; data[index++] = ipmi_csum( (data+4),(req->msg.data_len + 3) ); if (verbose > 4) { fprintf(stderr, "Encapsulated message:\n"); fprintf(stderr, " netfn = 0x%x\n", IPMI_NETFN_APP ); fprintf(stderr, " cmd = 0x%x\n", 0x34 ); if (data && data_len) { fprintf(stderr, " data_len = %d\n", data_len); fprintf(stderr, " data = %s\n", buf2str(data,data_len)); } } } _req.addr = (unsigned char *) &ipmb_addr; _req.addr_len = sizeof(ipmb_addr); } else { /* otherwise use system interface */ lprintf(LOG_DEBUG+2, "Sending request 0x%x to " "System Interface", req->msg.cmd); bmc_addr.lun = req->msg.lun; _req.addr = (unsigned char *) &bmc_addr; _req.addr_len = sizeof(bmc_addr); } _req.msgid = curr_seq++; /* In case of a bridge request */ if( data != NULL && data_len != 0 ) { _req.msg.data = data; _req.msg.data_len = data_len; _req.msg.netfn = IPMI_NETFN_APP; _req.msg.cmd = 0x34; } else { _req.msg.data = req->msg.data; _req.msg.data_len = req->msg.data_len; _req.msg.netfn = req->msg.netfn; _req.msg.cmd = req->msg.cmd; } if (ioctl(intf->fd, IPMICTL_SEND_COMMAND, &_req) < 0) { lperror(LOG_ERR, "Unable to send command"); if (data != NULL) { free(data); data = NULL; } return NULL; } /* * wait for and retrieve response */ if (intf->noanswer) { if (data != NULL) { free(data); data = NULL; } return NULL; } FD_ZERO(&rset); FD_SET(intf->fd, &rset); read_timeout.tv_sec = IPMI_OPENIPMI_READ_TIMEOUT; read_timeout.tv_usec = 0; retval = select(intf->fd+1, &rset, NULL, NULL, &read_timeout); if (retval < 0) { lperror(LOG_ERR, "I/O Error"); if (data != NULL) { free(data); data = NULL; } return NULL; } else if (retval == 0) { lprintf(LOG_ERR, "No data available"); if (data != NULL) { free(data); data = NULL; } return NULL; } if (FD_ISSET(intf->fd, &rset) == 0) { lprintf(LOG_ERR, "No data available"); if (data != NULL) { free(data); data = NULL; } return NULL; } recv.addr = (unsigned char *) &addr; recv.addr_len = sizeof(addr); recv.msg.data = rsp.data; recv.msg.data_len = sizeof(rsp.data); /* get data */ if (ioctl(intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv) < 0) { lperror(LOG_ERR, "Error receiving message"); if (errno != EMSGSIZE) { if (data != NULL) { free(data); data = NULL; } return NULL; } } if (verbose > 4) { fprintf(stderr, "Got message:"); fprintf(stderr, " type = %d\n", recv.recv_type); fprintf(stderr, " channel = 0x%x\n", addr.channel); fprintf(stderr, " msgid = %ld\n", recv.msgid); fprintf(stderr, " netfn = 0x%x\n", recv.msg.netfn); fprintf(stderr, " cmd = 0x%x\n", recv.msg.cmd); if (recv.msg.data && recv.msg.data_len) { fprintf(stderr, " data_len = %d\n", recv.msg.data_len); fprintf(stderr, " data = %s\n", buf2str(recv.msg.data, recv.msg.data_len)); } } if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) { /* ipmb_addr.transit_slave_addr = intf->transit_addr; */ lprintf(LOG_DEBUG, "Decapsulating data received from transit " "IPMB target @ 0x%x", intf->transit_addr); /* comp code */ /* Check data */ if( recv.msg.data[0] == 0 ) { recv.msg.netfn = recv.msg.data[2] >> 2; recv.msg.cmd = recv.msg.data[6]; recv.msg.data = memmove(recv.msg.data ,recv.msg.data+7 , recv.msg.data_len - 7); recv.msg.data_len -=8; if (verbose > 4) { fprintf(stderr, "Decapsulated message:\n"); fprintf(stderr, " netfn = 0x%x\n", recv.msg.netfn ); fprintf(stderr, " cmd = 0x%x\n", recv.msg.cmd); if (recv.msg.data && recv.msg.data_len) { fprintf(stderr, " data_len = %d\n", recv.msg.data_len); fprintf(stderr, " data = %s\n", buf2str(recv.msg.data,recv.msg.data_len)); } } }
int ipmi_tsol_main(struct ipmi_intf * intf, int argc, char ** argv) { struct pollfd fds_wait[3], fds_data_wait[3], *fds; struct sockaddr_in sin, myaddr, *sa_in; socklen_t mylen; char *recvip = NULL; char out_buff[IPMI_BUF_SIZE * 8], in_buff[IPMI_BUF_SIZE]; char buff[IPMI_BUF_SIZE + 4]; int fd_socket, result, i; int out_buff_fill, in_buff_fill; int ip1, ip2, ip3, ip4; int read_only = 0, rows = 0, cols = 0; int port = IPMI_TSOL_DEF_PORT; if (strlen(intf->name) < 3 || strncmp(intf->name, "lan", 3) != 0) { lprintf(LOG_ERR, "Error: Tyan SOL is only available over lan interface"); return -1; } for (i = 0; i<argc; i++) { if (sscanf(argv[i], "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) == 4) { /* not free'd ...*/ /* recvip = strdup(argv[i]); */ recvip = argv[i]; } else if (sscanf(argv[i], "port=%d", &ip1) == 1) port = ip1; else if (sscanf(argv[i], "rows=%d", &ip1) == 1) rows = ip1; else if (sscanf(argv[i], "cols=%d", &ip1) == 1) cols = ip1; else if (strlen(argv[i]) == 2 && strncmp(argv[i], "ro", 2) == 0) read_only = 1; else if (strlen(argv[i]) == 2 && strncmp(argv[i], "rw", 2) == 0) read_only = 0; else if (strlen(argv[i]) == 7 && strncmp(argv[i], "altterm", 7) == 0) _altterm = 1; else if (strlen(argv[i]) == 4 && strncmp(argv[i], "help", 4) == 0) { print_tsol_usage(); return 0; } else { print_tsol_usage(); return 0; } } /* create udp socket to receive the packet */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); sa_in = (struct sockaddr_in *)&intf->session->addr; result = inet_pton(AF_INET, (const char *)intf->session->hostname, &sa_in->sin_addr); if (result <= 0) { struct hostent *host = gethostbyname((const char *)intf->session->hostname); if (host == NULL ) { lprintf(LOG_ERR, "Address lookup for %s failed", intf->session->hostname); return -1; } if (host->h_addrtype != AF_INET) { lprintf(LOG_ERR, "Address lookup for %s failed. Got %s, expected IPv4 address.", intf->session->hostname, (host->h_addrtype == AF_INET6) ? "IPv6" : "Unknown"); return (-1); } sa_in->sin_family = host->h_addrtype; memcpy(&sa_in->sin_addr, host->h_addr, host->h_length); } fd_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd_socket < 0) { lprintf(LOG_ERR, "Can't open port %d", port); return -1; } if (-1 == bind(fd_socket, (struct sockaddr *)&sin, sizeof(sin))) { lprintf(LOG_ERR, "Failed to bind socket."); close(fd_socket); return -1; } /* * retrieve local IP address if not supplied on command line */ if (recvip == NULL) { result = intf->open(intf); /* must connect first */ if (result < 0) { close(fd_socket); return -1; } mylen = sizeof(myaddr); if (getsockname(intf->fd, (struct sockaddr *)&myaddr, &mylen) < 0) { lperror(LOG_ERR, "getsockname failed"); close(fd_socket); return -1; } recvip = inet_ntoa(myaddr.sin_addr); if (recvip == NULL) { lprintf(LOG_ERR, "Unable to find local IP address"); close(fd_socket); return -1; } } printf("[Starting %sSOL with receiving address %s:%d]\n", read_only ? "Read-only " : "", recvip, port); set_terminal_size(rows, cols); enter_raw_mode(); /* * talk to smdc to start Console redirect - IP address and port as parameter * ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x06 0xC0 0xA8 0xA8 0x78 0x1A 0x0A */ result = ipmi_tsol_start(intf, recvip, port); if (result < 0) { lprintf(LOG_ERR, "Error starting SOL"); close(fd_socket); return -1; } printf("[SOL Session operational. Use %c? for help]\n", intf->session->sol_escape_char); gettimeofday(&_start_keepalive, 0); fds_wait[0].fd = fd_socket; fds_wait[0].events = POLLIN; fds_wait[0].revents = 0; fds_wait[1].fd = fileno(stdin); fds_wait[1].events = POLLIN; fds_wait[1].revents = 0; fds_wait[2].fd = -1; fds_wait[2].events = 0; fds_wait[2].revents = 0; fds_data_wait[0].fd = fd_socket; fds_data_wait[0].events = POLLIN | POLLOUT; fds_data_wait[0].revents = 0; fds_data_wait[1].fd = fileno(stdin); fds_data_wait[1].events = POLLIN; fds_data_wait[1].revents = 0; fds_data_wait[2].fd = fileno(stdout); fds_data_wait[2].events = POLLOUT; fds_data_wait[2].revents = 0; out_buff_fill = 0; in_buff_fill = 0; fds = fds_wait; for (;;) { result = poll(fds, 3, 15*1000); if (result < 0) break; /* send keepalive packet */ tsol_keepalive(intf); if ((fds[0].revents & POLLIN) && (sizeof(out_buff) > out_buff_fill)){ socklen_t sin_len = sizeof(sin); result = recvfrom(fd_socket, buff, sizeof(out_buff) - out_buff_fill + 4, 0, (struct sockaddr *)&sin, &sin_len); /* read the data from udp socket, skip some bytes in the head */ if((result - 4) > 0 ){ int length = result - 4; #if 1 length = (unsigned char)buff[2] & 0xff; length *= 256; length += ((unsigned char)buff[3] & 0xff); if ((length <= 0) || (length > (result - 4))) length = result - 4; #endif memcpy(out_buff + out_buff_fill, buff + 4, length); out_buff_fill += length; } } if ((fds[1].revents & POLLIN) && (sizeof(in_buff) > in_buff_fill)) { result = read(fileno(stdin), in_buff + in_buff_fill, sizeof(in_buff) - in_buff_fill); // read from keyboard if (result > 0) { int bytes; bytes = do_inbuf_actions(intf, in_buff + in_buff_fill, result); if(bytes < 0) { result = ipmi_tsol_stop(intf, recvip, port); do_terminal_cleanup(); return result; } if (read_only) bytes = 0; in_buff_fill += bytes; } } if ((fds[2].revents & POLLOUT) && out_buff_fill) { result = write(fileno(stdout), out_buff, out_buff_fill); // to screen if (result > 0) { out_buff_fill -= result; if (out_buff_fill) { memmove(out_buff, out_buff + result, out_buff_fill); } } } if ((fds[0].revents & POLLOUT) && in_buff_fill) { /* * translate key and send that to SMDC using IPMI * ipmitool -I lan -H 192.168.168.227 -U Administrator raw 0x30 0x03 0x04 0x1B 0x5B 0x43 */ result = ipmi_tsol_send_keystroke(intf, in_buff, __min(in_buff_fill,14)); if (result > 0) { gettimeofday(&_start_keepalive, 0); in_buff_fill -= result; if (in_buff_fill) { memmove(in_buff, in_buff + result, in_buff_fill); } } } fds = (in_buff_fill || out_buff_fill )? fds_data_wait : fds_wait; } return 0; }
/* * Send message to serial port */ static int serial_bm_send_msg(struct ipmi_intf * intf, uint8_t * msg, int msg_len) { int i, size, tmp = 0; uint8_t * buf, * data; if (verbose > 3) { fprintf(stderr, "Sending request:\n"); fprintf(stderr, " rsSA = 0x%x\n", msg[0]); fprintf(stderr, " NetFN/rsLUN = 0x%x\n", msg[1]); fprintf(stderr, " rqSA = 0x%x\n", msg[3]); fprintf(stderr, " rqSeq/rqLUN = 0x%x\n", msg[4]); fprintf(stderr, " cmd = 0x%x\n", msg[5]); if (msg_len > 7) { fprintf(stderr, " data_len = %d\n", msg_len - 7); fprintf(stderr, " data = %s\n", buf2str(msg + 6, msg_len - 7)); } } if (verbose > 4) { fprintf(stderr, "Message data:\n"); fprintf(stderr, " %s\n", buf2str(msg, msg_len)); } /* calculate escaped characters number */ for (i = 0; i < msg_len; i++) { if (serial_bm_get_escaped_char(msg[i]) != msg[i]) { tmp++; } } /* calculate required buffer size */ size = msg_len + tmp + 2; /* allocate buffer for output data */ buf = data = (uint8_t *) alloca(size); if (!buf) { lperror(LOG_ERR, "ipmitool: alloca error"); return -1; } /* start character */ *buf++ = 0xA0; for (i = 0; i < msg_len; i++) { tmp = serial_bm_get_escaped_char(msg[i]); if (tmp != msg[i]) { *buf++ = 0xAA; } *buf++ = tmp; } /* stop character */ *buf++ = 0xA5; if (verbose > 5) { fprintf(stderr, "Sent serial data:\n %s\n", buf2str(data, size)); } /* write data to serial port */ tmp = write(intf->fd, data, size); if (tmp <= 0) { lperror(LOG_ERR, "ipmitool: write error"); return -1; } return 0; }
/* * Open serial interface */ static int serial_bm_open(struct ipmi_intf * intf) { struct termios ti; unsigned int rate = 9600; char *p; int i; if (!intf->devfile) { lprintf(LOG_ERR, "Serial device is not specified"); return -1; } is_system = 0; /* check if baud rate is specified */ if ((p = strchr(intf->devfile, ':'))) { char * pp; /* separate device name from baud rate */ *p++ = '\0'; /* check for second colon */ if ((pp = strchr(p, ':'))) { /* this is needed to normally acquire baud rate */ *pp++ = '\0'; /* check if it is a system interface */ if (pp[0] == 'S' || pp[0] == 's') { is_system = 1; } } if (str2uint(p, &rate)) { lprintf(LOG_ERR, "Invalid baud rate specified\n"); return -1; } } intf->fd = open(intf->devfile, O_RDWR | O_NONBLOCK, 0); if (intf->fd < 0) { lperror(LOG_ERR, "Could not open device at %s", intf->devfile); return -1; } for (i = 0; i < sizeof(rates) / sizeof(rates[0]); i++) { if (rates[i].baudrate == rate) { break; } } if (i >= sizeof(rates) / sizeof(rates[0])) { lprintf(LOG_ERR, "Unsupported baud rate %i specified", rate); return -1; } tcgetattr(intf->fd, &ti); cfsetispeed(&ti, rates[i].baudinit); cfsetospeed(&ti, rates[i].baudinit); /* 8N1 */ ti.c_cflag &= ~PARENB; ti.c_cflag &= ~CSTOPB; ti.c_cflag &= ~CSIZE; ti.c_cflag |= CS8; /* enable the receiver and set local mode */ ti.c_cflag |= (CLOCAL | CREAD); /* no flow control */ ti.c_cflag &= ~CRTSCTS; ti.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | INPCK | ISTRIP | IXON | IXOFF | IXANY); #ifdef IUCLC /* Only disable uppercase-to-lowercase mapping on input for platforms supporting the flag. */ ti.c_iflag &= ~(IUCLC); #endif ti.c_oflag &= ~(OPOST); ti.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | NOFLSH); /* set the new options for the port with flushing */ tcsetattr(intf->fd, TCSAFLUSH, &ti); if (intf->ssn_params.timeout == 0) intf->ssn_params.timeout = SERIAL_BM_TIMEOUT; if (intf->ssn_params.retry == 0) intf->ssn_params.retry = SERIAL_BM_RETRY_COUNT; intf->opened = 1; return 0; }
/* ipmi_open_file - safely open a file for reading or writing * * @file: filename * @rw: read-write flag, 1=write * * returns pointer to file handler on success * returns NULL on error */ FILE * ipmi_open_file(const char * file, int rw) { struct stat st1, st2; FILE * fp; /* verify existance */ if (lstat(file, &st1) < 0) { if (rw) { /* does not exist, ok to create */ fp = fopen(file, "w"); if (fp == NULL) { lperror(LOG_ERR, "Unable to open file %s " "for write", file); return NULL; } /* created ok, now return the descriptor */ return fp; } else { lprintf(LOG_ERR, "File %s does not exist", file); return NULL; } } #ifndef ENABLE_FILE_SECURITY if (!rw) { /* on read skip the extra checks */ fp = fopen(file, "r"); if (fp == NULL) { lperror(LOG_ERR, "Unable to open file %s", file); return NULL; } return fp; } #endif /* it exists - only regular files, not links */ if (S_ISREG(st1.st_mode) == 0) { lprintf(LOG_ERR, "File %s has invalid mode: %d", file, st1.st_mode); return NULL; } /* allow only files with 1 link (itself) */ if (st1.st_nlink != 1) { lprintf(LOG_ERR, "File %s has invalid link count: %d != 1", file, (int)st1.st_nlink); return NULL; } fp = fopen(file, rw ? "w+" : "r"); if (fp == NULL) { lperror(LOG_ERR, "Unable to open file %s", file); return NULL; } /* stat again */ if (fstat(fileno(fp), &st2) < 0) { lperror(LOG_ERR, "Unable to stat file %s", file); fclose(fp); return NULL; } /* verify inode */ if (st1.st_ino != st2.st_ino) { lprintf(LOG_ERR, "File %s has invalid inode: %d != %d", file, st1.st_ino, st2.st_ino); fclose(fp); return NULL; } /* verify owner */ if (st1.st_uid != st2.st_uid) { lprintf(LOG_ERR, "File %s has invalid user id: %d != %d", file, st1.st_uid, st2.st_uid); fclose(fp); return NULL; } /* verify inode */ if (st2.st_nlink != 1) { lprintf(LOG_ERR, "File %s has invalid link count: %d != 1", file, st2.st_nlink); fclose(fp); return NULL; } return fp; }
/* The following function is dictionary_create with an extra paramater called "path". If this is non-null, then the path used to find the file is taken from that path. Otherwise the path is taken from the dict_name. This is only needed because an affix_file is opened by a recursive call to this function. */ static Dictionary internal_dictionary_create(char * dict_name, char * pp_name, char * cons_name, char * affix_name, char * path) { Dictionary dict; static int rand_table_inited=FALSE; Dict_node *dict_node; char * dictionary_path_name; dict = (Dictionary) xalloc(sizeof(struct Dictionary_s)); if (!rand_table_inited) { init_randtable(); rand_table_inited=TRUE; } dict->string_set = string_set_create(); dict->name = string_set_add(dict_name, dict->string_set); dict->num_entries = 0; dict->is_special = FALSE; dict->already_got_it = '\0'; dict->line_number = 1; dict->root = NULL; dict->word_file_header = NULL; dict->exp_list = NULL; dict->affix_table = NULL; /* *DS* remove this if (pp_name != NULL) { dict->post_process_filename = string_set_add(pp_name, dict->string_set); } else { dict->post_process_filename = NULL; } */ if (path != NULL) dictionary_path_name = path; else dictionary_path_name = dict_name; if (!open_dictionary(dictionary_path_name, dict)) { lperror(NODICT, dict_name); string_set_delete(dict->string_set); xfree(dict, sizeof(struct Dictionary_s)); return NULL; } if (!read_dictionary(dict)) { string_set_delete(dict->string_set); xfree(dict, sizeof(struct Dictionary_s)); return NULL; } dict->left_wall_defined = boolean_dictionary_lookup(dict, LEFT_WALL_WORD); dict->right_wall_defined = boolean_dictionary_lookup(dict, RIGHT_WALL_WORD); dict->postprocessor = post_process_open(dict->name, pp_name); dict->constituent_pp = post_process_open(dict->name, cons_name); dict->affix_table = NULL; if (affix_name != NULL) { dict->affix_table = internal_dictionary_create(affix_name, NULL, NULL, NULL, dict_name); if (dict->affix_table == NULL) { fprintf(stderr, "%s\n", lperrmsg); exit(-1); } } dict->unknown_word_defined = boolean_dictionary_lookup(dict, UNKNOWN_WORD); dict->use_unknown_word = TRUE; dict->capitalized_word_defined = boolean_dictionary_lookup(dict, PROPER_WORD); dict->pl_capitalized_word_defined = boolean_dictionary_lookup(dict, PL_PROPER_WORD); dict->hyphenated_word_defined = boolean_dictionary_lookup(dict, HYPHENATED_WORD); dict->number_word_defined = boolean_dictionary_lookup(dict, NUMBER_WORD); dict->ing_word_defined = boolean_dictionary_lookup(dict, ING_WORD); dict->s_word_defined = boolean_dictionary_lookup(dict, S_WORD); dict->ed_word_defined = boolean_dictionary_lookup(dict, ED_WORD); dict->ly_word_defined = boolean_dictionary_lookup(dict, LY_WORD); dict->max_cost = 1000; if ((dict_node = dictionary_lookup(dict, ANDABLE_CONNECTORS_WORD)) != NULL) { dict->andable_connector_set = connector_set_create(dict_node->exp); } else { dict->andable_connector_set = NULL; } if ((dict_node = dictionary_lookup(dict, UNLIMITED_CONNECTORS_WORD)) != NULL) { dict->unlimited_connector_set = connector_set_create(dict_node->exp); } else { dict->unlimited_connector_set = NULL; } free_lookup_list(); return dict; }
/** * The string s has just been read in from standard input. * This function breaks it up into words and stores these words in * the sent->word[] array. Returns TRUE if all is well, FALSE otherwise. * Quote marks are treated just like blanks. */ int separate_sentence(char * s, Sentence sent) { char *t; int i, is_first, quote_found; Dictionary dict = sent->dict; for(i=0; i<MAX_SENTENCE; i++) post_quote[i]=0; sent->length = 0; if (dict->left_wall_defined) if (!issue_sentence_word(sent, LEFT_WALL_WORD)) return FALSE; /* Reset the multibyte shift state to the initial state */ mbtowc(NULL, NULL, 4); is_first = TRUE; for(;;) { wchar_t c; int nb = mbtowc(&c, s, 4); quote_found = FALSE; if (0 > nb) goto failure; /* skip all whitespace */ while (iswspace(c) || (c == '\"')) { s += nb; if(*s == '\"') quote_found=TRUE; nb = mbtowc(&c, s, 4); if (0 > nb) goto failure; } if (*s == '\0') break; t = s; nb = mbtowc(&c, t, 6); if (0 > nb) goto failure; while (!iswspace(c) && (c != '\"') && (c != 0) && (nb != 0)) { t += nb; nb = mbtowc(&c, t, 4); if (0 > nb) goto failure; } if (!separate_word(sent, s, t, is_first, quote_found)) return FALSE; is_first = FALSE; s = t; if (*s == '\0') break; } if (dict->right_wall_defined) if (!issue_sentence_word(sent, RIGHT_WALL_WORD)) return FALSE; return (sent->length > dict->left_wall_defined + dict->right_wall_defined); failure: #ifndef _WIN32 lperror(CHARSET, "%s\n", nl_langinfo(CODESET)); #endif return FALSE; }