Example #1
0
bool
status_read(struct status_output *so, struct buffer *buf)
{
    bool ret = false;

    if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_READ))
    {
        ASSERT(buf_defined(&so->read_buf));
        ASSERT(buf_defined(buf));
        while (true)
        {
            const int c = buf_read_u8(&so->read_buf);

            /* read more of file into buffer */
            if (c == -1)
            {
                int len;

                ASSERT(buf_init(&so->read_buf, 0));
                len = read(so->fd, BPTR(&so->read_buf), BCAP(&so->read_buf));
                if (len <= 0)
                {
                    break;
                }

                ASSERT(buf_inc_len(&so->read_buf, len));
                continue;
            }

            ret = true;

            if (c == '\r')
            {
                continue;
            }

            if (c == '\n')
            {
                break;
            }

            buf_write_u8(buf, c);
        }

        buf_null_terminate(buf);
    }

    return ret;
}
Example #2
0
/* return false if error occurred */
bool
status_close(struct status_output *so)
{
    bool ret = true;
    if (so)
    {
        if (so->errors)
        {
            ret = false;
        }
        if (so->fd >= 0)
        {
            if (close(so->fd) < 0)
            {
                ret = false;
            }
        }
        if (so->filename)
        {
            free(so->filename);
        }
        if (buf_defined(&so->read_buf))
        {
            free_buf(&so->read_buf);
        }
        free(so);
    }
    else
    {
        ret = false;
    }
    return ret;
}
Example #3
0
void
status_flush(struct status_output *so)
{
    if (so && so->fd >= 0 && (so->flags & STATUS_OUTPUT_WRITE))
    {
#if defined(HAVE_FTRUNCATE)
        {
            const off_t off = lseek(so->fd, (off_t)0, SEEK_CUR);
            if (ftruncate(so->fd, off) != 0)
            {
                msg(M_WARN, "Failed to truncate status file: %s", strerror(errno));
            }
        }
#elif defined(HAVE_CHSIZE)
        {
            const long off = (long) lseek(so->fd, (off_t)0, SEEK_CUR);
            chsize(so->fd, off);
        }
#else  /* if defined(HAVE_FTRUNCATE) */
#warning both ftruncate and chsize functions appear to be missing from this OS
#endif

        /* clear read buffer */
        if (buf_defined(&so->read_buf))
        {
            ASSERT(buf_init(&so->read_buf, 0));
        }
    }
}
Example #4
0
/*
 * printf append to a buffer with overflow check
 */
void
buf_printf (struct buffer *buf, const char *format, ...)
{
  if (buf_defined (buf))
    {
      va_list arglist;
      uint8_t *ptr = BEND (buf);
      int cap = buf_forward_capacity (buf);

      if (cap > 0)
	{
	  va_start (arglist, format);
	  vsnprintf ((char *)ptr, cap, format, arglist);
	  va_end (arglist);
	  *(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
	  buf->len += (int) strlen ((char *)ptr);
	}
    }
}
Example #5
0
bool
buf_printf (struct buffer *buf, const char *format, ...)
{
	int ret = false;
	if (buf_defined (buf))
	{
		va_list arglist;
		uint8_t *ptr = buf_bend (buf);
		int cap = buf_forward_capacity (buf);

		if (cap > 0)
		{
			int stat;
			va_start (arglist, format);
			stat = vsnprintf ((char *)ptr, cap, format, arglist);
			va_end (arglist);
			*(buf->data + buf->capacity - 1) = 0; /* windows vsnprintf needs this */
			buf->len += (int) strlen ((char *)ptr);
			if (stat >= 0 && stat < cap)
				ret = true;
		}
	}
	return ret;
}
Example #6
0
static bool
recv_line (socket_descriptor_t sd,
	   char *buf,
	   int len,
	   const int timeout_sec,
	   const bool verbose,
	   struct buffer *lookahead,
	   volatile int *signal_received)
{
  struct buffer la;
  int lastc = 0;

  CLEAR (la);
  if (lookahead)
    la = *lookahead;

  while (true)
    {
      int status;
      ssize_t size;
      fd_set reads;
      struct timeval tv;
      uint8_t c;

      if (buf_defined (&la))
	{
	  ASSERT (buf_init (&la, 0));
	}

      FD_ZERO (&reads);
      FD_SET (sd, &reads);
      tv.tv_sec = timeout_sec;
      tv.tv_usec = 0;

      status = select (sd + 1, &reads, NULL, NULL, &tv);

      get_signal (signal_received);
      if (*signal_received)
	goto error;

      /* timeout? */
      if (status == 0)
	{
	  if (verbose)
	    msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: TCP port read timeout expired");
	  goto error;
	}

      /* error */
      if (status < 0)
	{
	  if (verbose)
	    msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: TCP port read failed on select()");
	  goto error;
	}

      /* read single char */
      size = recv (sd, &c, 1, MSG_NOSIGNAL);

      /* error? */
      if (size != 1)
	{
	  if (verbose)
	    msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: TCP port read failed on recv()");
	  goto error;
	}

#if 0
      if (isprint(c))
	msg (M_INFO, "PROXY: read '%c' (%d)", c, (int)c);
      else
	msg (M_INFO, "PROXY: read (%d)", (int)c);
#endif

      /* store char in buffer */
      if (len > 1)
	{
	  *buf++ = c;
	  --len;
	}

      /* also store char in lookahead buffer */
      if (buf_defined (&la))
	{
	  buf_write_u8 (&la, c);
	  if (!isprint(c) && !isspace(c)) /* not ascii? */
	    {
	      if (verbose)
		msg (D_LINK_ERRORS | M_ERRNO_SOCK, "recv_line: Non-ASCII character (%d) read on recv()", (int)c);
	      *lookahead = la;
	      return false;
	    }
	}

      /* end of line? */
      if (lastc == '\r' && c == '\n')
	break;

      lastc = c;
    }

  /* append trailing null */
  if (len > 0)
    *buf++ = '\0';

  return true;

 error:
  return false;
}