mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +01:00
c0c2c58054
to libgcrypt functions, using shared error codes from libgpg-error, replacing the old functions we used to have in ../util by those in ../jnlib and ../common, renaming the malloc functions and a couple of types. Note, that not all changes are listed below becuause they are too similar and done at far too many places. As of today the code builds using the current libgcrypt from CVS but it is very unlikely that it actually works.
236 lines
5.7 KiB
C
236 lines
5.7 KiB
C
/* textfilter.c
|
|
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
|
*
|
|
* This file is part of GnuPG.
|
|
*
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GnuPG is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <assert.h>
|
|
|
|
#include "gpg.h"
|
|
#include "errors.h"
|
|
#include "iobuf.h"
|
|
#include "memory.h"
|
|
#include "util.h"
|
|
#include "filter.h"
|
|
#include "i18n.h"
|
|
#include "options.h"
|
|
|
|
#ifdef HAVE_DOSISH_SYSTEM
|
|
#define LF "\r\n"
|
|
#else
|
|
#define LF "\n"
|
|
#endif
|
|
|
|
#define MAX_LINELEN 19995 /* a little bit smaller than in armor.c */
|
|
/* to make sure that a warning is displayed while */
|
|
/* creating a message */
|
|
|
|
static unsigned
|
|
len_without_trailing_chars( byte *line, unsigned len, const char *trimchars )
|
|
{
|
|
byte *p, *mark;
|
|
unsigned n;
|
|
|
|
for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
|
|
if( strchr( trimchars, *p ) ) {
|
|
if( !mark )
|
|
mark = p;
|
|
}
|
|
else
|
|
mark = NULL;
|
|
}
|
|
|
|
return mark? (mark - line) : len;
|
|
}
|
|
|
|
unsigned
|
|
len_without_trailing_ws( byte *line, unsigned len )
|
|
{
|
|
return len_without_trailing_chars( line, len, " \t\r\n" );
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
standard( text_filter_context_t *tfx, iobuf_t a,
|
|
byte *buf, size_t size, size_t *ret_len)
|
|
{
|
|
int rc=0;
|
|
size_t len = 0;
|
|
unsigned maxlen;
|
|
|
|
assert( size > 10 );
|
|
size -= 2; /* reserve 2 bytes to append CR,LF */
|
|
while( !rc && len < size ) {
|
|
int lf_seen;
|
|
|
|
while( len < size && tfx->buffer_pos < tfx->buffer_len )
|
|
buf[len++] = tfx->buffer[tfx->buffer_pos++];
|
|
if( len >= size )
|
|
continue;
|
|
|
|
/* read the next line */
|
|
maxlen = MAX_LINELEN;
|
|
tfx->buffer_pos = 0;
|
|
tfx->buffer_len = iobuf_read_line( a, &tfx->buffer,
|
|
&tfx->buffer_size, &maxlen );
|
|
if( !maxlen )
|
|
tfx->truncated++;
|
|
if( !tfx->buffer_len ) {
|
|
if( !len )
|
|
rc = -1; /* eof */
|
|
break;
|
|
}
|
|
lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n';
|
|
tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len );
|
|
if( lf_seen ) {
|
|
tfx->buffer[tfx->buffer_len++] = '\r';
|
|
tfx->buffer[tfx->buffer_len++] = '\n';
|
|
}
|
|
}
|
|
*ret_len = len;
|
|
return rc;
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************
|
|
* The filter is used to make canonical text: Lines are terminated by
|
|
* CR, LF, trailing white spaces are removed.
|
|
*/
|
|
int
|
|
text_filter( void *opaque, int control,
|
|
iobuf_t a, byte *buf, size_t *ret_len)
|
|
{
|
|
size_t size = *ret_len;
|
|
text_filter_context_t *tfx = opaque;
|
|
int rc=0;
|
|
|
|
if( control == IOBUFCTRL_UNDERFLOW ) {
|
|
rc = standard( tfx, a, buf, size, ret_len );
|
|
}
|
|
else if( control == IOBUFCTRL_FREE ) {
|
|
if( tfx->truncated )
|
|
log_error(_("can't handle text lines longer than %d characters\n"),
|
|
MAX_LINELEN );
|
|
xfree ( tfx->buffer );
|
|
tfx->buffer = NULL;
|
|
}
|
|
else if( control == IOBUFCTRL_DESC )
|
|
*(char**)buf = "text_filter";
|
|
return rc;
|
|
}
|
|
|
|
|
|
/****************
|
|
* Copy data from INP to OUT and do some escaping if requested.
|
|
* md is updated as required by rfc2440
|
|
*/
|
|
int
|
|
copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md,
|
|
int escape_dash, int escape_from, int pgp2mode )
|
|
{
|
|
unsigned maxlen;
|
|
byte *buffer = NULL; /* malloced buffer */
|
|
unsigned bufsize; /* and size of this buffer */
|
|
unsigned n;
|
|
int truncated = 0;
|
|
int pending_lf = 0;
|
|
|
|
if( !opt.pgp2_workarounds )
|
|
pgp2mode = 0;
|
|
|
|
if( !escape_dash )
|
|
escape_from = 0;
|
|
|
|
for(;;) {
|
|
maxlen = MAX_LINELEN;
|
|
n = iobuf_read_line( inp, &buffer, &bufsize, &maxlen );
|
|
if( !maxlen )
|
|
truncated++;
|
|
|
|
if( !n )
|
|
break; /* read_line has returned eof */
|
|
|
|
/* update the message digest */
|
|
if( escape_dash ) {
|
|
if( pending_lf ) {
|
|
gcry_md_putc( md, '\r' );
|
|
gcry_md_putc( md, '\n' );
|
|
}
|
|
gcry_md_write( md, buffer,
|
|
len_without_trailing_chars( buffer, n,
|
|
pgp2mode? " \r\n":" \t\r\n"));
|
|
}
|
|
else
|
|
gcry_md_write( md, buffer, n );
|
|
pending_lf = buffer[n-1] == '\n';
|
|
|
|
/* write the output */
|
|
if( ( escape_dash && *buffer == '-')
|
|
|| ( escape_from && n > 4 && !memcmp(buffer, "From ", 5 ) ) ) {
|
|
iobuf_put( out, '-' );
|
|
iobuf_put( out, ' ' );
|
|
}
|
|
|
|
#if 0 /*defined(HAVE_DOSISH_SYSTEM)*/
|
|
/* We don't use this anymore because my interpretation of rfc2440 7.1
|
|
* is that there is no conversion needed. If one decides to
|
|
* clearsign a unix file on a DOS box he will get a mixed line endings.
|
|
* If at some point it turns out, that a conversion is a nice feature
|
|
* we can make an option out of it.
|
|
*/
|
|
/* make sure the lines do end in CR,LF */
|
|
if( n > 1 && ( (buffer[n-2] == '\r' && buffer[n-1] == '\n' )
|
|
|| (buffer[n-2] == '\n' && buffer[n-1] == '\r'))) {
|
|
iobuf_write( out, buffer, n-2 );
|
|
iobuf_put( out, '\r');
|
|
iobuf_put( out, '\n');
|
|
}
|
|
else if( n && buffer[n-1] == '\n' ) {
|
|
iobuf_write( out, buffer, n-1 );
|
|
iobuf_put( out, '\r');
|
|
iobuf_put( out, '\n');
|
|
}
|
|
else
|
|
iobuf_write( out, buffer, n );
|
|
|
|
#else
|
|
iobuf_write( out, buffer, n );
|
|
#endif
|
|
}
|
|
|
|
/* at eof */
|
|
if( !pending_lf ) { /* make sure that the file ends with a LF */
|
|
iobuf_writestr( out, LF );
|
|
if( !escape_dash )
|
|
gcry_md_putc( md, '\n' );
|
|
}
|
|
|
|
if( truncated )
|
|
log_info(_("input line longer than %d characters\n"), MAX_LINELEN );
|
|
|
|
return 0; /* okay */
|
|
}
|