示例#1
0
文件: cbuf.c 项目: ElijahLuk/samba
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;
}