int cbuf_print_quoted(cbuf* ost, const char* s, size_t len) { int n = 1; int ret; cbuf_reserve(ost, len+2); cbuf_putc(ost,'"'); while(len--) { switch (*s) { case '"': case '\\': ret = cbuf_printf(ost, "\\%c", *s); break; default: if (isprint(*s) && ((*s == ' ') || !isspace(*s))) { ret = cbuf_putc(ost, *s); } else { ret = cbuf_printf(ost, "\\%02x", *s); } } s++; if (ret == -1) { return -1; } n += ret; } ret = cbuf_putc(ost,'"'); return (ret == -1) ? -1 : (n + ret); }
struct ipmipower_connection * ipmipower_connection_array_create(const char *hostname, unsigned int *len) { char *str = NULL; int index = 0; hostlist_t hl = NULL; hostlist_iterator_t itr = NULL; struct ipmipower_connection *ics; int size = sizeof(struct ipmipower_connection); int hl_count; int errcount = 0; int emfilecount = 0; assert(hostname && len); *len = 0; if (!(hl = hostlist_create(hostname))) { ipmipower_output(MSG_TYPE_HOSTNAME_INVALID, hostname); return NULL; } if (!(itr = hostlist_iterator_create(hl))) ierr_exit("hostlist_iterator_create() error"); hostlist_uniq(hl); hl_count = hostlist_count(hl); ics = (struct ipmipower_connection *)Malloc(size * hl_count); memset(ics, '\0', (size * hl_count)); while ((str = hostlist_next(itr))) { ics[index].ipmi_fd = -1; ics[index].ping_fd = -1; /* cleanup only at the end, gather all error outputs for * later */ if (_connection_setup(&ics[index], str) < 0) { if (errno == EMFILE && !emfilecount) { cbuf_printf(ttyout, "file descriptor limit reached\n"); emfilecount++; } errcount++; } free(str); index++; } hostlist_iterator_destroy(itr); hostlist_destroy(hl); if (errcount) { int i; for (i = 0; i < hl_count; i++) { close(ics[i].ipmi_fd); close(ics[i].ping_fd); if (ics[i].ipmi_in) cbuf_destroy(ics[i].ipmi_in); if (ics[i].ipmi_out) cbuf_destroy(ics[i].ipmi_out); if (ics[i].ping_in) cbuf_destroy(ics[i].ping_in); if (ics[i].ping_out) cbuf_destroy(ics[i].ping_out); } Free(ics); return NULL; } *len = hl_count; return ics; }
static int _connection_setup(struct ipmipower_connection *ic, char *hostname) { struct sockaddr_in srcaddr; struct hostent *result; assert(ic && hostname); /* Don't use wrapper function, need to exit cleanly on EMFILE errno */ errno = 0; if ((ic->ipmi_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { if (errno == EMFILE) return -1; ierr_exit("socket() error: %s", strerror(errno)); } if ((ic->ping_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { if (errno == EMFILE) return -1; ierr_exit("socket() error: %s", strerror(errno)); } /* Secure ephemeral ports */ bzero(&srcaddr, sizeof(struct sockaddr_in)); srcaddr.sin_family = AF_INET; srcaddr.sin_port = htons(0); srcaddr.sin_addr.s_addr = htonl(INADDR_ANY); Bind(ic->ipmi_fd, &srcaddr, sizeof(struct sockaddr_in)); Bind(ic->ping_fd, &srcaddr, sizeof(struct sockaddr_in)); ic->ipmi_in = Cbuf_create(IPMIPOWER_MIN_CONNECTION_BUF, IPMIPOWER_MAX_CONNECTION_BUF); ic->ipmi_out = Cbuf_create(IPMIPOWER_MIN_CONNECTION_BUF, IPMIPOWER_MAX_CONNECTION_BUF); ic->ping_in = Cbuf_create(IPMIPOWER_MIN_CONNECTION_BUF, IPMIPOWER_MAX_CONNECTION_BUF); ic->ping_out = Cbuf_create(IPMIPOWER_MIN_CONNECTION_BUF, IPMIPOWER_MAX_CONNECTION_BUF); ic->ipmi_requester_sequence_number_counter = get_rand(); ic->ping_sequence_number_counter = get_rand(); memset(&ic->last_ipmi_send, '\0', sizeof(struct timeval)); memset(&ic->last_ping_send, '\0', sizeof(struct timeval)); memset(&ic->last_ipmi_recv, '\0', sizeof(struct timeval)); memset(&ic->last_ping_recv, '\0', sizeof(struct timeval)); ic->link_state = LINK_GOOD; /* assumed good to begin with */ ic->ping_last_packet_recv_flag = 0; ic->ping_packet_count_send = 0; ic->ping_packet_count_recv = 0; ic->ping_consec_count = 0; ic->discover_state = STATE_UNDISCOVERED; strncpy(ic->hostname, hostname, MAXHOSTNAMELEN); ic->hostname[MAXHOSTNAMELEN] = '\0'; /* Determine the destination address */ bzero(&(ic->destaddr), sizeof(struct sockaddr_in)); ic->destaddr.sin_family = AF_INET; ic->destaddr.sin_port = htons(RMCP_PRIMARY_RMCP_PORT); if (!(result = gethostbyname(ic->hostname))) { if (h_errno == HOST_NOT_FOUND) ipmipower_output(MSG_TYPE_HOSTNAME_INVALID, ic->hostname); else { #if HAVE_HSTRERROR cbuf_printf(ttyout, "gethostbyname() error %s: %s", ic->hostname, hstrerror(h_errno)); #else /* !HAVE_HSTRERROR */ cbuf_printf(ttyout, "gethostbyname() error %s: h_errno = %d", ic->hostname, h_errno); #endif /* !HAVE_HSTRERROR */ } return -1; } ic->destaddr.sin_addr = *((struct in_addr *)result->h_addr); ic->skip = 0; return 0; }