Пример #1
0
void
dbuf_put(struct dbuf_queue *qptr, char *data, size_t count)
{
  struct dbuf_block *last;
  size_t amount;

  assert(count > 0);
  if (qptr->blocks.tail == NULL)
    dbuf_alloc(qptr);

  do {
    last = qptr->blocks.tail->data;

    amount = DBUF_BLOCK_SIZE - last->size;
    if (!amount)
    {
      last = dbuf_alloc(qptr);
      amount = DBUF_BLOCK_SIZE;
    }
    if (amount > count)
      amount = count;

    memcpy((void *) &last->data[last->size], data, amount);
    count -= amount;
    last->size += amount;
    qptr->total_size += amount;

    data += amount;

  } while (count > 0);
}
Пример #2
0
/*
 * format up an HTTP response and return it
 */
DBUF *server_respond (int code, char *fmt, ...)
{
  int l, len, avail;
  va_list ap;
  char *ch;
  DBUF *b;
  char buf[4096];

  /*
   * note our response body is limited to 4096 bytes - only small
   * response is needed or allowed.
   */
  len = sprintf (buf, "<html><body>");
  avail = 4096 - (len * 2 + 4);
  va_start (ap, fmt);
  l = vsnprintf (buf + len, avail, fmt, ap);
  va_end (ap);
  if ((l > 0) && (l < avail))
    len += l;
  len += sprintf (buf + len, "</body></html>");
  /*
   * if we are no longer running, notify the client that we are
   * closing this connection.
   */
  b = dbuf_alloc ();
  dbuf_printf (b, "Status: %d\r\n"
    "Content-Length: %d\r\n"
    "Connection: %s\r\n\r\n%s",
    code, len, phineas_running () ? "Keep-alive" : "Close", buf);
  debug ("response:\n%s\n", dbuf_getbuf (b));
  return (b);
}
Пример #3
0
/*
 * Format a MIME message to an allocated character buffer.  Caller
 * is responsible for freeing this buffer.
 */
char *mime_format (MIME *m)
{
  DBUF *b;

  b = dbuf_alloc ();
  mime_format_part (m, b);
  return (dbuf_extract (b));
}
Пример #4
0
/*
 * Allocate and return an authorization required response
 */
DBUF *basicauth_response (char *realm)
{
  DBUF *b = dbuf_alloc ();
  char *html = 
    "<html><body>Access restricted - "
    "Authorization required!</body></html>";

  dbuf_printf (b,
    "Status: 401\r\n"
    "WWW-Authenticate: Basic realm=\"%s\"\r\n"
    "Content-Length: %d\r\n\r\n%s", 
    realm, strlen (html), html);
  return (b);
}
Пример #5
0
/*
 * dbuf_put - put a sequence of bytes in a dbuf
 */
int dbuf_put(struct DBuf* dyn, const char* buf, size_t length)
{
  struct DBufBuffer** h;
  struct DBufBuffer*  d;
  int                 chunk;

  /*
   * Locate the last non-empty buffer. If the last buffer is
   * full, the loop will terminate with 'd==NULL'. This loop
   * assumes that the 'dyn->length' field is correctly
   * maintained, as it should--no other check really needed.
   */
  if (0 == dyn->length)
    h = &(dyn->head);
  else
    h = &(dyn->tail);
  /*
   * Append users data to buffer, allocating buffers as needed
   */
  dyn->length += length;

  for ( ; length > 0; h = &(d->next)) {
    if (0 == (d = *h)) {
      if (0 == (d = dbuf_alloc()))
        return dbuf_malloc_error(dyn);

      dyn->tail = d;
      *h        = d;        /* prev->next = d */
    }
    chunk = (d->data + DBUF_SIZE) - d->end;
    if (chunk) {
      if (chunk > length)
        chunk = length;
      
      memcpy(d->end, buf, chunk);

      length -= chunk;
      buf    += chunk;
      d->end += chunk;
    }
  }
  return 1;
}
Пример #6
0
/** Append bytes to a data buffer.
 * @param[in] dyn Buffer to append to.
 * @param[in] buf Data to append.
 * @param[in] length Number of bytes to append.
 * @return Non-zero on success, or zero on failure.
 */
int dbuf_put(struct DBuf *dyn, const char *buf, unsigned int length)
{
  struct DBufBuffer** h;
  struct DBufBuffer*  db;
  unsigned int chunk;

  assert(0 != dyn);
  assert(0 != buf);
  /*
   * Locate the last non-empty buffer. If the last buffer is full,
   * the loop will terminate with 'db==NULL'.
   * This loop assumes that the 'dyn->length' field is correctly
   * maintained, as it should--no other check really needed.
   */
  if (!dyn->length)
    h = &(dyn->head);
  else
    h = &(dyn->tail);
  /*
   * Append users data to buffer, allocating buffers as needed
   */
  dyn->length += length;

  for (; length > 0; h = &(db->next)) {
    if (0 == (db = *h)) {
      if (0 == (db = dbuf_alloc())) {
	if (feature_bool(FEAT_HAS_FERGUSON_FLUSHER)) {
	  /*
	   * from "Married With Children" episode were Al bought a REAL toilet
	   * on the black market because he was tired of the wimpy water
	   * conserving toilets they make these days --Bleep
	   */
	  /*
	   * Apparently this doesn't work, the server _has_ to
	   * dump a few clients to handle the load. A fully loaded
	   * server cannot handle a net break without dumping some
	   * clients. If we flush the connections here under a full
	   * load we may end up starving the kernel for mbufs and
	   * crash the machine
	   */
	  /*
	   * attempt to recover from buffer starvation before
	   * bailing this may help servers running out of memory
	   */
	  flush_connections(0);
	  db = dbuf_alloc();
	}

        if (0 == db)
          return dbuf_malloc_error(dyn);
      }
      dyn->tail = db;
      *h = db;
      db->next = 0;
      db->start = db->end = db->data;
    }
    chunk = (db->data + DBUF_SIZE) - db->end;
    if (chunk) {
      if (chunk > length)
        chunk = length;

      memcpy(db->end, buf, chunk);

      length -= chunk;
      buf += chunk;
      db->end += chunk;
    }
  }
  return 1;
}
Пример #7
0
/*
 * Receive a reply message
 */
DBUF *ebxml_receive (NETCON *conn)
{
  long n;
  int e;
  char c, *ch;
  DBUF *b;

  b = dbuf_alloc ();
  n = 0;
  /*
   * read to end of message request header - empty line
   */
  while ((e = net_read (conn, &c, 1)) == 1)
  {
    dbuf_putc (b, c);
    if (c == '\n')
    {
      if (n++ == 1)
        break;
    }
    else if (c != '\r')
      n = 0;
  }
  if (e != 1)
  {
    if (e == 0)
      error ("Acknowledgment header read failed or connection closed\n");
    else
      error ("Timed out reading acknowledgment header\n");
    dbuf_free (b);
    return (NULL);
  }
  ch = strnstr (dbuf_getbuf (b), "Content-Length: ", dbuf_size (b));
  if (ch == NULL)
  {
    error ("Acknowledgment header missing Content-Length\n");
    dbuf_free (b);
    return (NULL);
  }
  n = atol (ch + 16);
  debug ("expecting %d bytes\n", n);

readbytes:

  while (n--)
  {
    if ((e = net_read (conn, &c, 1)) != 1)
    {
      if (e == 0)
        error ("Acknowledgment content read failed or connection closed");
      else
        error ("Timed out reading acknowledgment content\n");
      // note we'll take what we get and hope it's enough...
      break;
    }
    dbuf_putc (b, c);
  }
  if (n = net_available (conn))
  {
    warn ("Found %d unread bytes...\n", n);
    goto readbytes;
  }
  debug ("returning %d bytes\n", dbuf_size (b));
  return (b);
}
Пример #8
0
/*
 * Build and return the mime payload container
 */
MIME *ebxml_getpayload (XML *xml, QUEUEROW *r)
{
  int l, mapi;
  XML *exml;
  MIME *msg;
  char *b,			/* buffer for payload		*/
       *type,
       *unc = NULL,		/* encryption info		*/
       *pw = NULL,
       dn[DNSZ],
       *organization,
       pid[MAX_PATH],
       buf[MAX_PATH],
       fname[MAX_PATH];

  debug ("getpayload container...\n");
  if ((mapi = ebxml_pid (xml, r, pid)) < 0)
    return (NULL);
  ppathf (fname, cfg_map (xml, mapi, "Processed"), "%s",
    queue_field_get (r, "PAYLOADFILE"));

  /* invoke the filter if given					*/
  b = cfg_map (xml, mapi, "Filter");
  if (*b)
  {
    char *emsg;
    DBUF *rbuf = dbuf_alloc ();

    debug ("filter read %s with %s\n", fname, b);
    if (filter_run (b, fname, NULL, NULL, rbuf, &emsg, cfg_timeout (xml)))
    {
      error ("Can't filter %s - %s\n", fname, strerror (errno));
      dbuf_free (rbuf);
      return (NULL);
    }
    if (*emsg)
      warn ("filter %s returned %s\n", b, emsg);
    free (emsg);
    l = dbuf_size (rbuf);
    b = dbuf_extract (rbuf);
  }
  else
  {
    debug ("reading data from %s\n", fname);
    if ((b = readfile (fname, &l)) == NULL)
    {
      error ("Can't read %s - %s\n", fname, strerror (errno));
      return (NULL);
    }
  }

  organization = cfg_org (xml);
  type = cfg_map (xml, mapi, "Encryption.Type");
  if ((type != NULL) && *type)	/* encrypted			*/
  {
    unc = cfg_map (xml, mapi, "Encryption.Unc");
    pw = cfg_map (xml, mapi, "Encryption.Password");
    strcpy (dn, cfg_map (xml, mapi, "Encryption.Id"));
  }

  msg = payload_create (b, l, fname, organization, unc, dn, pw);

  free (b);
  if (msg == NULL)
    error ("Can't create payload container for %s\n", fname);
  return (msg);
}
Пример #9
0
/*
 * Receive an incoming message
 */
DBUF *server_receive (NETCON *conn)
{
  long n, sz;
  char c, *ch;
  DBUF *b;

  b = dbuf_alloc ();
  n = 0;
  /*
   * read to end of message request header - empty line
   */
  while (net_read (conn, &c, 1) == 1)
  {
    dbuf_putc (b, c);
    if (c == '\n')
    {
      if (n++ == 1)
        break;
    }
    else if (c != '\r')
      n = 0;
  }
  if (n != 2)
  {
    debug ("no header - %d read\n", dbuf_size (b));
    if (dbuf_size (b))
    {
      dbuf_printf (b, "%s", n == 1 ? "\r\n" : "\r\n\r\n");
      warn ("can't find end of request header: %.*s", 
	dbuf_size (b), dbuf_getbuf (b));
    }
    n = 0;
  }
  else
  {
    ch = strnstr (dbuf_getbuf (b), "Content-Length: ", dbuf_size (b));
    if (ch == NULL)
      n = 0;
    else
      n = atol (ch + 16);
  }
  debug ("expecting %d bytes\n", n);

readbytes:

  while (n--)
  {
    if ((sz = net_read (conn, &c, 1)) != 1)
    {
      if (sz  == 0)
        error ("Read failed or connection closed\n");
      else
        error ("Read timed out\n");
      // note we'll take what we get and hope it's enough...
      break;
    }
    dbuf_putc (b, c);
  }
  if (n = net_available (conn))
  {
    warn ("Found %d unread bytes...\n", n);
    goto readbytes;
  }
  debug ("returning %d bytes\n", dbuf_size (b));
  return (b);
}