/* 
 * hostsfile_clusterlist_setup
 *
 * hostsfile clusterlist module setup function.  Open hostsfile, read
 * each line of the hostsfile, and save hosts into hosts list.
 */
static int 
hostsfile_clusterlist_setup(void)
{
  int len, fd = -1;
  char buf[HOSTSFILE_PARSE_BUFLEN];
  char *p;

  if (hosts)
    {
      CEREBRO_DBG(("hosts non-null"));
      return 0;
    }

  if (!(hosts = list_create((ListDelF)free)))
    {
      CEREBRO_ERR(("list_create: %s", strerror(errno)));
      goto cleanup;
    }

  if ((fd = open(CEREBRO_CLUSTERLIST_HOSTSFILE_DEFAULT, O_RDONLY)) < 0)
    {
      CEREBRO_ERR(("hostsfile '%s' cannot be opened: %s", 
                   CEREBRO_CLUSTERLIST_HOSTSFILE_DEFAULT, strerror(errno)));
      goto cleanup;
    }
 
  while ((len = _readline(fd, buf, HOSTSFILE_PARSE_BUFLEN)) > 0)
    {
      char *hostPtr;
      char *str;

      if (!(len = _remove_comments(buf, len)))
        continue;

      if (len < 0)
        goto cleanup;

      if (!(len = _remove_trailing_whitespace(buf, len)))
        continue;

      if (len < 0)
        goto cleanup;

      if (!(hostPtr = _move_past_whitespace(buf)))
        goto cleanup;

      if (hostPtr[0] == '\0')
        continue;

      if (strchr(hostPtr, ' ') || strchr(hostPtr, '\t'))
        {
          cerebro_err_output("hostsfile host contains whitespace");
          goto cleanup;
        }

      if (strlen(hostPtr) > CEREBRO_MAX_NODENAME_LEN)
        {
          cerebro_err_output("hostsfile node '%s' exceeds max length", hostPtr);
          goto cleanup;
        }
      
      /* Shorten hostname if necessary */
      if ((p = strchr(hostPtr, '.')))
        *p = '\0';

      if (!(str = strdup(hostPtr)))
        {
          CEREBRO_ERR(("strdup: %s", strerror(errno)));
          goto cleanup;
        }

      if (!list_append(hosts, str))
        {
          CEREBRO_ERR(("list_append: %s", strerror(errno)));
          goto cleanup;
        }
    }
  
  if (len < 0)
    goto cleanup;

  /* ignore potential error, just return result */
  close(fd);
  return 0;

 cleanup:
  /* ignore potential error, just return result */
  close(fd);
  if (hosts)
    list_destroy(hosts);
  hosts = NULL;
  return -1;
}
/*
 * hostsfile_clusterlist_setup
 *
 * hostsfile clusterlist module setup function
 */
static int 
hostsfile_clusterlist_setup(nodeupdown_t handle) 
{
  int fd = -1, len;
  char buf[NODEUPDOWN_BUFFERLEN];
  char *p;

  if (!(hosts = list_create((ListDelF)free)))
    {
#ifndef NDEBUG
      fprintf(stderr, "list_create: %s\n", strerror(errno));
#endif /* NDEBUG */
      nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_OUTMEM);
      goto cleanup;
    }
                                                                                    
  if ((fd = open(NODEUPDOWN_CLUSTERLIST_HOSTSFILE_DEFAULT, O_RDONLY)) < 0)
    {
#ifndef NDEBUG
      fprintf(stderr, "open: %s\n", strerror(errno));
#endif /* NDEBUG */

      /* no nodes, just get out */
      if (errno == ENOENT)
        goto out;

      nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE);
      goto cleanup;
    }
                                                                                     
  while ((len = _readline(handle, fd, buf, NODEUPDOWN_BUFFERLEN)) > 0)
    {
      char *hostPtr;
      char *str;
                                                                                     
      if ((len = _remove_comments(buf, len)) == 0)
        continue;
                                                                                     
      if ((len = _remove_trailing_whitespace(buf, len)) == 0)
        continue;
                                                                                     
      if (!(hostPtr = _move_past_whitespace(buf)))
        continue;
                                                                                     
      if (hostPtr[0] == '\0')
        continue;
                                                                                     
      if (strchr(hostPtr, ' ') || strchr(hostPtr, '\t'))
        {
#ifndef NDEBUG
	  fprintf(stderr, "parse error\n");
#endif /* NDEBUG */
	  nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE);
          goto cleanup;
        }
                                                                                     
      if (strlen(hostPtr) > NODEUPDOWN_MAXHOSTNAMELEN)
        {
#ifndef NDEBUG
	  fprintf(stderr, "parse error\n");
#endif /* NDEBUG */
	  nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE);
          goto cleanup;
        }
          
      /* Shorten hostname if necessary */
      if ((p = strchr(hostPtr, '.')))
        *p = '\0';
      
      if (!(str = strdup(hostPtr)))
        {
	  nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_OUTMEM);
          goto cleanup;
        }

      if (!list_append(hosts, str))
        {
#ifndef NDEBUG
	  fprintf(stderr, "list_append: %s\n", strerror(errno));
#endif /* NDEBUG */
	  nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE);
          goto cleanup;
        }
    }
                                                                                     
 out:
  /* ignore potential error, just return result */
  close(fd);
  return 0;

 cleanup:
  /* ignore potential error, just return result */
  close(fd);
  return -1;
}
Пример #3
0
static int
_readline(conffile_t cf, char *linebuf, int linebuflen)
{
    int ret, len = 0;
    int continuation = 0;
    char buf[CONFFILE_MAX_LINELEN];
    
    if (linebuflen < CONFFILE_MAX_LINELEN) {
        cf->errnum = CONFFILE_ERR_INTERNAL;
        return -1;
    }

    cf->line_num = cf->line_count + 1;
    while (1) {
        ret = fd_read_line(cf->fd, buf, CONFFILE_MAX_LINELEN);
        if (ret < 0) {
            cf->errnum = CONFFILE_ERR_READ;
            return -1;
        }

        if (ret == 0) {
            /* Ok to break here. All continuation characters and
             * comments taken care of earlier
             */
            cf->end_of_file++; 
            break;
        }

        /* MAX_LINELEN - 1 b/c fd_read_line guarantees null termination */
        if (ret >= (CONFFILE_MAX_LINELEN-1)) {
            cf->errnum = CONFFILE_ERR_PARSE_OVERFLOW_LINELEN;
            return -1;
        }

        if ((ret + len) >= linebuflen) {
            cf->errnum = CONFFILE_ERR_PARSE_OVERFLOW_LINELEN;
            return -1;
        }

        cf->line_count++;
        memcpy(linebuf + len, buf, ret);
        len += ret;

        len = _remove_trailing_whitespace(cf, linebuf, len);
        if (len == 0) {
            cf->line_num = cf->line_count + 1;
            continue;
        }

        if ((len = _remove_comments(cf, linebuf, len)) < 0)
            return -1;

        if (len == 0) {
            cf->line_num = cf->line_count + 1;
            continue;
        }

        /* Need to call a second time, for following case
         *
         * optionname arg1 \    # my comment
         *
         *                  ^^^^ need to remove this whitespace 
         */
        len = _remove_trailing_whitespace(cf, linebuf, len);
        if (len == 0) {
            cf->line_num = cf->line_count + 1;
            continue;
        }

        if (linebuf[len-1] == '\\') {
            continuation++;
            linebuf[len-1] = '\0'; 
            len--;
            continue;
        }
        else
            break;
    }

    return len;
}