Example #1
0
/** Flush empty lines from a buffer.
 * @param[in,out] dyn Data buffer to flush.
 * @return Number of bytes in first available block (or zero if none).
 */
static unsigned int dbuf_flush(struct DBuf *dyn)
{
  struct DBufBuffer *db = dyn->head;

  if (0 == db)
    return 0;

  assert(db->start < db->end);
  /*
   * flush extra line terms
   */
  while (IsEol(*db->start))
  {
    if (++db->start == db->end)
    {
      dyn->head = db->next;
      dbuf_free(db);
      if (0 == (db = dyn->head))
      {
        dyn->tail = 0;
        dyn->length = 0;
        break;
      }
    }
    --dyn->length;
  }
  return dyn->length;
}
Example #2
0
void
va_emitcode (const char *inst, const char *fmt, va_list ap)
{
  const char *line = format_opcode (inst, fmt, ap);
  emit_raw (line);
  dbuf_free (line);
}
Example #3
0
/** Discard data from a DBuf.
 * @param[in,out] dyn DBuf to drop data from.
 * @param[in] length Number of bytes to discard.
 */
void dbuf_delete(struct DBuf *dyn, unsigned int length)
{
  struct DBufBuffer *db;
  unsigned int chunk;

  if (length > dyn->length)
    length = dyn->length;

  while (length > 0)
  {
    if (0 == (db = dyn->head))
      break;
    chunk = db->end - db->start;
    if (chunk > length)
      chunk = length;

    length -= chunk;
    dyn->length -= chunk;
    db->start += chunk;

    if (db->start == db->end)
    {
      dyn->head = db->next;
      dbuf_free(db);
    }
  }
  if (0 == dyn->head)
  {
    dyn->length = 0;
    dyn->tail = 0;
  }
}
Example #4
0
/*
** This is called when malloc fails. Scrap the whole content
** of dynamic buffer and return -1. (malloc errors are FATAL,
** there is no reason to continue this buffer...). After this
** the "dbuf" has consistent EMPTY status... ;)
*/
static int dbuf_malloc_error(struct DBuf* dyn)
{
  struct DBufBuffer* db;

  dyn->length = 0;
  while (0 != (db = dyn->head)) {
    dyn->head = db->next;
    dbuf_free(db);
  }
  dyn->tail = 0;
  return 0;
}
Example #5
0
/*
 * TASK to handle an incoming request
 */
int server_request (void *parm)
{
  SERVERPARM *s;
  DBUF *req, *res;
  char *curl;

  s = (SERVERPARM *) parm;
  curl = xml_get_text (s->xml, "Phineas.Console.Url");
  res = NULL;
  while ((req = server_receive (s->conn)) != NULL)
  {
    debug ("received %d bytes\n", dbuf_size (req));
    if (dbuf_size (req) == 0)
    {
      dbuf_free (req);
      net_close (s->conn);
      return (-1);
    }
    dbuf_putc (req, 0);
    /*
     * log the request, but filter out GET requests for the console... 
     * noise
     */
    if (!(*curl && strstarts (dbuf_getbuf (req) + 4, curl)))
      server_logrequest (s->conn, dbuf_size (req), dbuf_getbuf (req));
    if ((res = server_response (s->xml, dbuf_getbuf (req))) == NULL)
    {
      res = server_respond (500,
	    "<h3>Failure processing ebXML request</h3>");
    }
    server_header (res);
    net_write (s->conn, dbuf_getbuf (res), dbuf_size (res));
    dbuf_free (res);
    dbuf_free (req);
  }
  net_close (s->conn);
  debug ("request completed\n");
  return (0);
}
Example #6
0
/** Handle a memory allocation error on a DBuf.
 * This frees all the buffers owned by the DBuf, since we have to
 * close the associated connection.
 * @param[in] dyn DBuf to clean out.
 * @return Zero.
 */
static int dbuf_malloc_error(struct DBuf *dyn)
{
  struct DBufBuffer *db;
  struct DBufBuffer *next;

  for (db = dyn->head; db; db = next)
  {
    next = db->next;
    dbuf_free(db);
  }
  dyn->tail = dyn->head = 0;
  dyn->length = 0;
  return 0;
}
Example #7
0
/*-----------------------------------------------------------------*/
void
genInline (iCode * ic)
{
  char *buf, *bp, *begin;
  bool inComment = FALSE;

  D (emitcode (";", "genInline"));

  genLine.lineElement.isInline += (!options.asmpeep);

  buf = bp = begin = Safe_strdup (IC_INLINE (ic));

  /* Emit each line as a code */
  while (*bp)
    {
      switch (*bp)
        {
        case ';':
          inComment = TRUE;
          ++bp;
          break;

        case '\x87':
        case '\n':
          inComment = FALSE;
          *bp++ = '\0';

          /* Don't emit leading whitespaces */
          while (isspace (*begin))
            ++begin;

          if (*begin)
            emitcode (begin, NULL);

          begin = bp;
          break;

        default:
          /* Add \n for labels, not dirs such as c:\mydir */
          if (!inComment && (*bp == ':') && (isspace ((unsigned char) bp[1])))
            {
              ++bp;
              *bp = '\0';
              ++bp;
              emitcode (begin, NULL);
              begin = bp;
            }
          else
            ++bp;
          break;
        }
    }
  if (begin != bp)
    {
      /* Don't emit leading whitespaces */
      while (isspace (*begin))
        ++begin;

      if (*begin)
        emitcode (begin, NULL);
    }

  Safe_free (buf);

  /* consumed; we can free it here */
  dbuf_free (IC_INLINE (ic));

  genLine.lineElement.isInline -= (!options.asmpeep);
}
Example #8
0
/*
 * send a message
 * return non-zero if message not sent successful with completed
 * queue info for status and transport
 */
int ebxml_send (XML*xml, QUEUEROW *r, MIME *msg)
{
  DBUF *b;
  NETCON *conn;
  char host[MAX_PATH];	/* need buffers for redirect		*/
  char path[MAX_PATH];
  int port, route, timeout, delay, retry;
  SSL_CTX *ctx;
  char *rname, 		/* route name				*/
       *content, 	/* message content			*/
       buf[MAX_PATH];

  /* format up the message					*/
  if ((content = mime_format (msg)) == NULL)
  {
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "failed formatting message");
    return (-1);
  }
  debug ("Send content:\n%s\n", content);

  /*
   * get connection info from the record route
   */
  if ((route = 
    cfg_route_index (xml, queue_field_get (r, "ROUTEINFO"))) < 0)
  {
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "bad route");
    return (-1);
  }
  rname = cfg_route (xml, route, "Name");
  ctx = ebxml_route_ctx (xml, route);
  strcpy (host, cfg_route (xml, route, "Host"));
  port = atoi (cfg_route (xml, route, "Port"));
  if ((retry = atoi (cfg_route (xml, route, "Retry"))) == 0)
    retry = cfg_retries (xml);
  timeout = atoi (cfg_route (xml, route, "Timeout"));
  delay = cfg_delay (xml);
  strcpy (path, cfg_route (xml, route, "Path"));

sendmsg:

  info ("Sending ebXML %s:%d to %s\n", 
    r->queue->name, r->rowid, rname);
  debug ("opening connection socket on port=%d retrys=%d timeout=%d\n", 
    port, retry, timeout);
  if ((conn = net_open (host, port, 0, ctx)) == NULL)
  {
    error ("failed opening connection to %s:%d\n", host, port);
    goto retrysend;
  }
  				/* set read timeout if given	*/
  if (timeout)
  {
    net_timeout (conn, timeout * 1000);
    timeout <<= 1;		/* bump each try		*/
  }
  delay = 0;			/* connection OK, don't delay	*/
  queue_field_set (r, "MESSAGESENTTIME", ptime (NULL, buf));
  sprintf (buf, "POST %s HTTP/1.1\r\n", path);
  // ch = ebxml_beautify (ch);
  				/* all set... send the message	*/
  debug ("sending message...\n");
  net_write (conn, buf, strlen (buf));
  net_write (conn, content, strlen (content));
  debug ("reading response...\n");
  b = ebxml_receive (conn);
  debug ("closing socket...\n");
  net_close (conn);
  				/* no reply?			*/
  if (b == NULL)
  {
    warn ("Send response timed out or closed for %s\n", rname);

retrysend:			/* retry with a wait, or..	*/	
			
    if (retry-- && phineas_running ())
    {
      if (delay)
      {
	info ("Retrying send to %s in %d seconds\n", rname, delay);
        sleep (delay * 1000);
	delay <<= 1;
      }
      else			/* reset connection delay	*/
        delay = cfg_delay (xml);
      goto sendmsg;
    }
    if (ctx != NULL)		/* give up!			*/
      SSL_CTX_free (ctx);
    free (content);
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "retries exhausted");
    return (-1);
  }
  debug ("reply was %d bytes\n%.*s\n", dbuf_size (b),
    dbuf_size (b), dbuf_getbuf (b));

  /*
   * handle redirects...
   * note this assumes the same SSL context should be used
   */
  if (ebxml_redirect (dbuf_getbuf (b), host, &port, path))
  {
    dbuf_free (b);
    goto sendmsg;
  }

  if (ctx != NULL)
    SSL_CTX_free (ctx);
  if (ebxml_parse_reply (dbuf_getbuf (b), r))
  {
    queue_field_set (r, "PROCESSINGSTATUS", "done");
    queue_field_set (r, "TRANSPORTSTATUS", "failed");
    queue_field_set (r, "TRANSPORTERRORCODE", "garbled reply");
  }
  debug ("send completed\n");
  dbuf_free (b);
  free (content);
  return (0);
}
Example #9
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);
}
Example #10
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);
}