1
/* plaintext.c - process plaintext packets
2
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
3
* 2003 Free Software Foundation, Inc.
5
* This file is part of GnuPG.
7
* GnuPG is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* GnuPG is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
28
#ifdef HAVE_DOSISH_SYSTEM
29
#include <fcntl.h> /* for setmode() */
46
* Handle a plaintext packet. If MFX is not NULL, update the MDs
47
* Note: we should use the filter stuff here, but we have to add some
48
* easy mimic to set a read limit, so we calculate only the
49
* bytes from the plaintext.
52
handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
53
int nooutput, int clearsig, int *create_failed )
59
int convert = pt->mode == 't';
63
int dummy_create_failed;
66
create_failed = &dummy_create_failed;
69
/* create the filename as C string */
72
else if( opt.outfile ) {
73
fname = xmalloc ( strlen( opt.outfile ) + 1);
74
strcpy(fname, opt.outfile );
76
else if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) {
77
log_info(_("data not saved; use option \"--output\" to save it\n"));
80
else if( !opt.use_embedded_filename ) {
81
fname = make_outfile_name( iobuf_get_real_fname(pt->buf) );
83
fname = ask_outfile_name( pt->name, pt->namelen );
91
fname = make_printable_string( pt->name, pt->namelen, 0 );
96
else if( !*fname || (*fname=='-' && !fname[1])) {
97
/* no filename or "-" given; write to stdout */
99
#ifdef HAVE_DOSISH_SYSTEM
100
setmode ( fileno(fp) , O_BINARY );
104
while( !overwrite_filep (fname) ) {
105
char *tmp = ask_outfile_name (NULL, 0);
106
if ( !tmp || !*tmp ) {
109
rc = GPG_ERR_GENERAL;
120
else if( !(fp = fopen(fname,"wb")) ) {
121
rc = gpg_error_from_errno (errno);
122
log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
126
#else /* __riscos__ */
127
/* Convert all '.' in fname to '/' -- we don't create directories! */
128
for( c=0; fname[c]; ++c )
129
if( fname[c] == '.' )
135
fp = fopen(fname,"wb");
137
rc == gpg_error_from_errno (errno);
138
log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
141
log_info("Do output file and input file have the same name?\n");
145
/* If there's a ,xxx extension in the embedded filename,
146
use that, else check whether the user input (in fname)
147
has a ,xxx appended, then use that in preference */
148
if( (c = riscos_get_filetype_from_string( pt->name,
149
pt->namelen )) != -1 )
151
if( (c = riscos_get_filetype_from_string( fname,
152
strlen(fname) )) != -1 )
154
riscos_set_filetype_by_number(fname, filetype);
156
#endif /* __riscos__ */
158
if( !pt->is_partial ) {
159
/* we have an actual length (which might be zero). */
161
if( convert ) { /* text mode */
162
for( ; pt->len; pt->len-- ) {
163
if( (c = iobuf_get(pt->buf)) == -1 ) {
164
rc = gpg_error_from_errno (errno);
165
log_error("Problem reading source (%u bytes remaining)\n",
170
gcry_md_putc (mfx->md, c );
171
#ifndef HAVE_DOSISH_SYSTEM
172
if( c == '\r' ) /* convert to native line ending */
173
continue; /* fixme: this hack might be too simple */
176
if( putc( c, fp ) == EOF ) {
177
rc = gpg_error_from_errno (errno);
178
log_error("Error writing to `%s': %s\n",
179
fname, strerror(errno) );
185
else { /* binary mode */
186
byte *buffer = xmalloc ( 32768 );
188
int len = pt->len > 32768 ? 32768 : pt->len;
189
len = iobuf_read( pt->buf, buffer, len );
191
rc = gpg_error_from_errno (errno);
192
log_error("Problem reading source (%u bytes remaining)\n",
198
gcry_md_write( mfx->md, buffer, len );
200
if( fwrite( buffer, 1, len, fp ) != len ) {
201
rc = gpg_error_from_errno (errno);
202
log_error("Error writing to `%s': %s\n",
203
fname, strerror(errno) );
213
else if( !clearsig ) {
214
if( convert ) { /* text mode */
215
while( (c = iobuf_get(pt->buf)) != -1 ) {
217
gcry_md_putc (mfx->md, c );
218
#ifndef HAVE_DOSISH_SYSTEM
219
if( convert && c == '\r' )
220
continue; /* fixme: this hack might be too simple */
223
if( putc( c, fp ) == EOF ) {
224
rc = gpg_error_from_errno (errno);
225
log_error("Error writing to `%s': %s\n",
226
fname, strerror(errno) );
232
else { /* binary mode */
233
byte *buffer = xmalloc ( 32768 );
235
for( eof=0; !eof; ) {
236
/* Why do we check for len < 32768:
237
* If we won't, we would practically read 2 EOFs but
238
* the first one has already popped the block_filter
239
* off and therefore we don't catch the boundary.
240
* So, always assume EOF if iobuf_read returns less bytes
242
int len = iobuf_read( pt->buf, buffer, 32768 );
248
gcry_md_write( mfx->md, buffer, len );
250
if( fwrite( buffer, 1, len, fp ) != len ) {
251
rc = gpg_error_from_errno (errno);
252
log_error("Error writing to `%s': %s\n",
253
fname, strerror(errno) );
263
else { /* clear text signature - don't hash the last cr,lf */
266
while( (c = iobuf_get(pt->buf)) != -1 ) {
268
if( putc( c, fp ) == EOF ) {
269
rc = gpg_error_from_errno (errno);
270
log_error("Error writing to `%s': %s\n",
271
fname, strerror(errno) );
278
gcry_md_putc (mfx->md, '\r' );
279
gcry_md_putc (mfx->md, '\n' );
288
gcry_md_putc (mfx->md, c );
290
else if( state == 1 ) {
294
gcry_md_putc (mfx->md, '\r' );
299
gcry_md_putc (mfx->md, c );
307
if( fp && fp != stdout && fclose(fp) ) {
308
rc = gpg_error_from_errno (errno);
309
log_error("Error closing `%s': %s\n", fname, strerror(errno) );
316
if( fp && fp != stdout )
323
do_hash( MD_HANDLE md, MD_HANDLE md2, iobuf_t fp, int textmode )
325
text_filter_context_t tfx;
329
memset( &tfx, 0, sizeof tfx);
330
iobuf_push_filter( fp, text_filter, &tfx );
332
if( md2 ) { /* work around a strange behaviour in pgp2 */
333
/* It seems that at least PGP5 converts a single CR to a CR,LF too */
335
while( (c = iobuf_get(fp)) != -1 ) {
336
if( c == '\n' && lc == '\r' )
337
gcry_md_putc (md2, c);
338
else if( c == '\n' ) {
339
gcry_md_putc (md2, '\r');
340
gcry_md_putc (md2, c);
342
else if( c != '\n' && lc == '\r' ) {
343
gcry_md_putc (md2, '\n');
344
gcry_md_putc (md2, c);
347
gcry_md_putc (md2, c);
350
gcry_md_putc (md, c );
355
while( (c = iobuf_get(fp)) != -1 ) {
357
gcry_md_putc (md, c );
364
* Ask for the detached datafile and calculate the digest from it.
365
* INFILE is the name of the input file.
368
ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
369
const char *inname, int textmode )
371
progress_filter_context_t pfx;
376
fp = open_sigfile( inname, &pfx ); /* open default file */
378
if( !fp && !opt.batch ) {
380
tty_printf(_("Detached signature.\n"));
383
answer = cpr_get("detached_signature.filename",
384
_("Please enter name of data file: "));
386
if( any && !*answer ) {
387
rc = GPG_ERR_GENERAL;
390
fp = iobuf_open(answer);
391
if( !fp && errno == ENOENT ) {
392
tty_printf("No such file, try again or hit enter to quit.\n");
396
rc = gpg_error_from_errno (errno);
397
log_error("can't open `%s': %s\n", answer, strerror(errno) );
405
log_info(_("reading stdin ...\n"));
406
fp = iobuf_open( NULL );
409
do_hash( md, md2, fp, textmode );
420
* Hash the given files and append the hash to hash context md.
421
* If FILES is NULL, hash stdin.
424
hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files,
425
const char *sigfilename, int textmode )
427
progress_filter_context_t pfx;
432
/* check whether we can open the signed material */
433
fp = open_sigfile( sigfilename, &pfx );
435
do_hash( md, md2, fp, textmode );
439
log_error (_("no signed data\n"));
440
return GPG_ERR_NO_DATA;
444
for (sl=files; sl; sl = sl->next ) {
445
fp = iobuf_open( sl->d );
447
int tmperr = gpg_error_from_errno (errno);
448
log_error(_("can't open signed data `%s'\n"),
449
print_fname_stdin(sl->d));
452
handle_progress (&pfx, fp, sl->d);
453
do_hash( md, md2, fp, textmode );