assuan_error_t 
_assuan_write_line (assuan_context_t ctx, const char *prefix,
                    const char *line, size_t len)
{
  int rc = 0;
  size_t prefixlen = prefix? strlen (prefix):0;

  /* Make sure that the line is short enough. */
  if (len + prefixlen + 2 > ASSUAN_LINELENGTH)
    {
      if (ctx->log_fp)
        fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> "
                 "[supplied line too long -truncated]\n",
                 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx);
      if (prefixlen > 5)
        prefixlen = 5;
      if (len > ASSUAN_LINELENGTH - prefixlen - 2)
        len = ASSUAN_LINELENGTH - prefixlen - 2 - 1;
    }

  /* Fixme: we should do some kind of line buffering.  */
  if (ctx->log_fp)
    {
      fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
	       assuan_get_assuan_log_prefix (),
               (unsigned int)getpid (), (void *)ctx);
      if (ctx->confidential)
	fputs ("[Confidential data not shown]", ctx->log_fp);
      else
	_assuan_log_print_buffer (ctx->log_fp, line, len);
      putc ('\n', ctx->log_fp);
    }

  if (prefixlen)
    {
      rc = writen (ctx, prefix, prefixlen);
      if (rc)
        rc = ASSUAN_Write_Error;
    }
  if (!rc)
    {
      rc = writen (ctx, line, len);
      if (rc)
        rc = ASSUAN_Write_Error;
      if (!rc)
        {
          rc = writen (ctx, "\n", 1);
          if (rc)
            rc = ASSUAN_Write_Error;
        }
    }
  return rc;
}
Beispiel #2
0
/* Write out any buffered data
   This function is used for GNU's custom streams */
int
_assuan_cookie_write_flush(void *cookie)
{
    assuan_context_t ctx = cookie;
    char *line;
    size_t linelen;
    unsigned int monitor_result;

    if(ctx->outbound.data.error)
        return 0;

    line = ctx->outbound.data.line;
    linelen = ctx->outbound.data.linelen;
    line += linelen;

    monitor_result = (ctx->io_monitor
                      ? ctx->io_monitor(ctx, 1,
                                        ctx->outbound.data.line, linelen)
                      : 0);

    if(linelen)
    {
        if(ctx->log_fp && !(monitor_result & 1))
        {
            fprintf(ctx->log_fp, "%s[%u.%d] DBG: -> ",
                    assuan_get_assuan_log_prefix(),
                    (unsigned int)getpid(), ctx->inbound.fd);
            if(ctx->confidential)
                fputs("[Confidential data not shown]", ctx->log_fp);
            else
                _assuan_log_print_buffer(ctx->log_fp,
                                         ctx->outbound.data.line, linelen);
            putc('\n', ctx->log_fp);
        }
        *line++ = '\n';
        linelen++;
        if(!(monitor_result & 2)
                && writen(ctx, ctx->outbound.data.line, linelen))
        {
            ctx->outbound.data.error = _assuan_error(ASSUAN_Write_Error);
            return 0;
        }
        ctx->outbound.data.linelen = 0;
    }
    return 0;
}
/* Write out any buffered data 
   This function is used for GNU's custom streams */
int
_assuan_cookie_write_flush (void *cookie)
{
  assuan_context_t ctx = cookie;
  char *line;
  size_t linelen;

  if (ctx->outbound.data.error)
    return 0;

  line = ctx->outbound.data.line;
  linelen = ctx->outbound.data.linelen;
  line += linelen;
  if (linelen)
    {
      if (ctx->log_fp)
	{
	  fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
		   assuan_get_assuan_log_prefix (),
                   (unsigned int)getpid (), (void *)ctx);
	  if (ctx->confidential)
	    fputs ("[Confidential data not shown]", ctx->log_fp);
	  else
	    _assuan_log_print_buffer (ctx->log_fp,
				      ctx->outbound.data.line, linelen);
	  putc ('\n', ctx->log_fp);
	}
      *line++ = '\n';
      linelen++;
      if (writen (ctx, ctx->outbound.data.line, linelen))
        {
          ctx->outbound.data.error = ASSUAN_Write_Error;
          return 0;
        }
      ctx->outbound.data.linelen = 0;
    }
  return 0;
}
int
_assuan_read_line (assuan_context_t ctx)
{
  char *line = ctx->inbound.line;
  int nread, atticlen;
  int rc;
  char *endp = 0;

  if (ctx->inbound.eof)
    return -1;

  atticlen = ctx->inbound.attic.linelen;
  if (atticlen)
    {
      memcpy (line, ctx->inbound.attic.line, atticlen);
      ctx->inbound.attic.linelen = 0;

      endp = memchr (line, '\n', atticlen);
      if (endp)
	/* Found another line in the attic.  */
	{
	  rc = 0;
	  nread = atticlen;
	  atticlen = 0;
	}
      else
	/* There is pending data but not a full line.  */
        {
          assert (atticlen < LINELENGTH);
          rc = readaline (ctx, line + atticlen,
			 LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
        }
    }
  else
    /* No pending data.  */
    rc = readaline (ctx, line, LINELENGTH,
                   &nread, &ctx->inbound.eof);
  if (rc)
    {
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Error: %s]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx, strerror (errno));
      return ASSUAN_Read_Error;
    }
  if (!nread)
    {
      assert (ctx->inbound.eof);
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [EOF]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx);
      return -1;
    }

  ctx->inbound.attic.pending = 0;
  nread += atticlen;

  if (! endp)
    endp = memchr (line, '\n', nread);

  if (endp)
    {
      int n = endp - line + 1;
      if (n < nread)
	/* LINE contains more than one line.  We copy it to the attic
	   now as handlers are allowed to modify the passed
	   buffer.  */
	{
	  int len = nread - n;
	  memcpy (ctx->inbound.attic.line, endp + 1, len);
	  ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0;
	  ctx->inbound.attic.linelen = len;
	}

      if (endp != line && endp[-1] == '\r')
	endp --;
      *endp = 0;

      ctx->inbound.linelen = endp - line;
      if (ctx->log_fp)
	{
	  fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- ",
		   assuan_get_assuan_log_prefix (),
                   (unsigned int)getpid (), (void *)ctx);
	  if (ctx->confidential)
	    fputs ("[Confidential data not shown]", ctx->log_fp);
	  else
	    _assuan_log_print_buffer (ctx->log_fp,
				      ctx->inbound.line,
				      ctx->inbound.linelen);
	  putc ('\n', ctx->log_fp);
	}
      return 0;
    }
  else
    {
      if (ctx->log_fp)
	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Invalid line]\n",
		 assuan_get_assuan_log_prefix (),
                 (unsigned int)getpid (), (void *)ctx);
      *line = 0;
      ctx->inbound.linelen = 0;
      return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated
	: ASSUAN_Line_Too_Long;
    }
}
/* Write out the data in buffer as datalines with line wrapping and
   percent escaping.  This function is used for GNU's custom streams */
int
_assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
{
  assuan_context_t ctx = cookie;
  size_t size = orig_size;
  char *line;
  size_t linelen;

  if (ctx->outbound.data.error)
    return 0;

  line = ctx->outbound.data.line;
  linelen = ctx->outbound.data.linelen;
  line += linelen;
  while (size)
    {
      /* insert data line header */
      if (!linelen)
        {
          *line++ = 'D';
          *line++ = ' ';
          linelen += 2;
        }
      
      /* copy data, keep some space for the CRLF and to escape one character */
      while (size && linelen < LINELENGTH-2-2)
        {
          if (*buffer == '%' || *buffer == '\r' || *buffer == '\n')
            {
              sprintf (line, "%%%02X", *(unsigned char*)buffer);
              line += 3;
              linelen += 3;
              buffer++;
            }
          else
            {
              *line++ = *buffer++;
              linelen++;
            }
          size--;
        }
      
      if (linelen >= LINELENGTH-2-2)
        {
          if (ctx->log_fp)
            {
	      fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
		       assuan_get_assuan_log_prefix (),
                       (unsigned int)getpid (), (void *)ctx);

              if (ctx->confidential)
                fputs ("[Confidential data not shown]", ctx->log_fp);
              else 
                _assuan_log_print_buffer (ctx->log_fp, 
                                          ctx->outbound.data.line,
                                          linelen);
              putc ('\n', ctx->log_fp);
            }
          *line++ = '\n';
          linelen++;
          if (writen (ctx, ctx->outbound.data.line, linelen))
            {
              ctx->outbound.data.error = ASSUAN_Write_Error;
              return 0;
            }
          line = ctx->outbound.data.line;
          linelen = 0;
        }
    }

  ctx->outbound.data.linelen = linelen;
  return (int)orig_size;
}
Beispiel #6
0
assuan_error_t
_assuan_write_line(assuan_context_t ctx, const char *prefix,
                   const char *line, size_t len)
{
    assuan_error_t rc = 0;
    size_t prefixlen = prefix ? strlen(prefix) : 0;
    unsigned int monitor_result;

    /* Make sure that the line is short enough. */
    if(len + prefixlen + 2 > ASSUAN_LINELENGTH)
    {
        if(ctx->log_fp)
            fprintf(ctx->log_fp, "%s[%u.%d] DBG: -> "
                    "[supplied line too long -truncated]\n",
                    assuan_get_assuan_log_prefix(),
                    (unsigned int)getpid(), ctx->inbound.fd);
        if(prefixlen > 5)
            prefixlen = 5;
        if(len > ASSUAN_LINELENGTH - prefixlen - 2)
            len = ASSUAN_LINELENGTH - prefixlen - 2 - 1;
    }

    monitor_result = (ctx->io_monitor
                      ? ctx->io_monitor(ctx, 1, line, len)
                      : 0);

    /* Fixme: we should do some kind of line buffering.  */
    if(ctx->log_fp && !(monitor_result & 1))
    {
        fprintf(ctx->log_fp, "%s[%u.%d] DBG: -> ",
                assuan_get_assuan_log_prefix(),
                (unsigned int)getpid(), ctx->inbound.fd);
        if(ctx->confidential)
            fputs("[Confidential data not shown]", ctx->log_fp);
        else
        {
            if(prefixlen)
                _assuan_log_print_buffer(ctx->log_fp, prefix, prefixlen);
            _assuan_log_print_buffer(ctx->log_fp, line, len);
        }
        putc('\n', ctx->log_fp);
    }

    if(prefixlen && !(monitor_result & 2))
    {
        rc = writen(ctx, prefix, prefixlen);
        if(rc)
            rc = _assuan_error(ASSUAN_Write_Error);
    }
    if(!rc && !(monitor_result & 2))
    {
        rc = writen(ctx, line, len);
        if(rc)
            rc = _assuan_error(ASSUAN_Write_Error);
        if(!rc)
        {
            rc = writen(ctx, "\n", 1);
            if(rc)
                rc = _assuan_error(ASSUAN_Write_Error);
        }
    }
    return rc;
}