1 /* plaintext.c - process an plaintext packet
2 * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 #ifdef HAVE_DOSISH_SYSTEM
28 #include <fcntl.h> /* for setmode() */
44 * Handle a plaintext packet. If MFX is not NULL, update the MDs
45 * Note: we should use the filter stuff here, but we have to add some
46 * easy mimic to set a read limit, so we calculate only the
47 * bytes from the plaintext.
50 handle_plaintext( PKT_plaintext
*pt
, md_filter_context_t
*mfx
,
51 int nooutput
, int clearsig
)
57 int convert
= pt
->mode
== 't';
59 /* create the filename as C string */
62 else if( opt
.outfile
) {
63 fname
= gcry_xmalloc( strlen( opt
.outfile
) + 1);
64 strcpy(fname
, opt
.outfile
);
66 else if( pt
->namelen
== 8 && !memcmp( pt
->name
, "_CONSOLE", 8 ) ) {
67 log_info(_("data not saved; use option \"--output\" to save it\n"));
70 else if( !opt
.use_embedded_filename
) {
71 fname
= make_outfile_name( iobuf_get_real_fname(pt
->buf
) );
73 fname
= ask_outfile_name( pt
->name
, pt
->namelen
);
75 rc
= GPGERR_CREATE_FILE
;
80 fname
= make_printable_string( pt
->name
, pt
->namelen
, 0 );
85 else if( !*fname
|| (*fname
=='-' && !fname
[1])) {
86 /* no filename or "-" given; write to stdout */
88 #ifdef HAVE_DOSISH_SYSTEM
89 setmode ( fileno(fp
) , O_BINARY
);
92 else if( !overwrite_filep( fname
) ) {
93 rc
= GPGERR_CREATE_FILE
;
99 else if( !(fp
= fopen(fname
,"wb")) ) {
100 log_error("Error creating `%s': %s\n", fname
, strerror(errno
) );
101 rc
= GPGERR_CREATE_FILE
;
107 if( convert
) { /* text mode */
108 for( ; pt
->len
; pt
->len
-- ) {
109 if( (c
= iobuf_get(pt
->buf
)) == -1 ) {
110 log_error("Problem reading source (%u bytes remaining)\n",
112 rc
= GPGERR_READ_FILE
;
116 gcry_md_putc(mfx
->md
, c
);
117 #ifndef HAVE_DOSISH_SYSTEM
118 if( c
== '\r' ) /* convert to native line ending */
119 continue; /* fixme: this hack might be too simple */
122 if( putc( c
, fp
) == EOF
) {
123 log_error("Error writing to `%s': %s\n",
124 fname
, strerror(errno
) );
125 rc
= GPGERR_WRITE_FILE
;
131 else { /* binary mode */
132 byte
*buffer
= gcry_xmalloc( 32768 );
134 int len
= pt
->len
> 32768 ? 32768 : pt
->len
;
135 len
= iobuf_read( pt
->buf
, buffer
, len
);
137 log_error("Problem reading source (%u bytes remaining)\n",
139 rc
= GPGERR_READ_FILE
;
144 gcry_md_write( mfx
->md
, buffer
, len
);
146 if( fwrite( buffer
, 1, len
, fp
) != len
) {
147 log_error("Error writing to `%s': %s\n",
148 fname
, strerror(errno
) );
149 rc
= GPGERR_WRITE_FILE
;
159 else if( !clearsig
) {
160 if( convert
) { /* text mode */
161 while( (c
= iobuf_get(pt
->buf
)) != -1 ) {
163 gcry_md_putc(mfx
->md
, c
);
164 #ifndef HAVE_DOSISH_SYSTEM
165 if( convert
&& c
== '\r' )
166 continue; /* fixme: this hack might be too simple */
169 if( putc( c
, fp
) == EOF
) {
170 log_error("Error writing to `%s': %s\n",
171 fname
, strerror(errno
) );
172 rc
= GPGERR_WRITE_FILE
;
178 else { /* binary mode */
179 byte
*buffer
= gcry_xmalloc( 32768 );
181 for( eof
=0; !eof
; ) {
182 /* Why do we check for len < 32768:
183 * If we won't, we would practically read 2 EOFs but
184 * the first one has already popped the block_filter
185 * off and therefore we don't catch the boundary.
186 * So, always assume EOF if iobuf_read returns less bytes
188 int len
= iobuf_read( pt
->buf
, buffer
, 32768 );
194 gcry_md_write( mfx
->md
, buffer
, len
);
196 if( fwrite( buffer
, 1, len
, fp
) != len
) {
197 log_error("Error writing to `%s': %s\n",
198 fname
, strerror(errno
) );
199 rc
= GPGERR_WRITE_FILE
;
209 else { /* clear text signature - don't hash the last cr,lf */
212 while( (c
= iobuf_get(pt
->buf
)) != -1 ) {
214 if( putc( c
, fp
) == EOF
) {
215 log_error("Error writing to `%s': %s\n",
216 fname
, strerror(errno
) );
217 rc
= GPGERR_WRITE_FILE
;
224 gcry_md_putc(mfx
->md
, '\r' );
225 gcry_md_putc(mfx
->md
, '\n' );
234 gcry_md_putc(mfx
->md
, c
);
236 else if( state
== 1 ) {
240 gcry_md_putc(mfx
->md
, '\r' );
245 gcry_md_putc(mfx
->md
, c
);
253 if( fp
&& fp
!= stdout
&& fclose(fp
) ) {
254 log_error("Error closing `%s': %s\n", fname
, strerror(errno
) );
256 rc
= GPGERR_WRITE_FILE
;
262 if( fp
&& fp
!= stdout
)
269 do_hash( GCRY_MD_HD md
, GCRY_MD_HD md2
, IOBUF fp
, int textmode
)
271 text_filter_context_t tfx
;
275 memset( &tfx
, 0, sizeof tfx
);
276 iobuf_push_filter( fp
, text_filter
, &tfx
);
278 if( md2
) { /* work around a strange behaviour in pgp2 */
279 /* It seems that at least PGP5 converts a single CR to a CR,LF too */
281 while( (c
= iobuf_get(fp
)) != -1 ) {
282 if( c
== '\n' && lc
== '\r' )
283 gcry_md_putc(md2
, c
);
284 else if( c
== '\n' ) {
285 gcry_md_putc(md2
, '\r');
286 gcry_md_putc(md2
, c
);
288 else if( c
!= '\n' && lc
== '\r' ) {
289 gcry_md_putc(md2
, '\n');
290 gcry_md_putc(md2
, c
);
293 gcry_md_putc(md2
, c
);
296 gcry_md_putc(md
, c
);
301 while( (c
= iobuf_get(fp
)) != -1 ) {
303 gcry_md_putc(md
, c
);
310 * Ask for the detached datafile and calculate the digest from it.
311 * INFILE is the name of the input file.
314 ask_for_detached_datafile( GCRY_MD_HD md
, GCRY_MD_HD md2
,
315 const char *inname
, int textmode
)
321 fp
= open_sigfile( inname
); /* open default file */
322 if( !fp
&& !opt
.batch
) {
324 tty_printf(_("Detached signature.\n"));
327 answer
= cpr_get("detached_signature.filename",
328 _("Please enter name of data file: "));
330 if( any
&& !*answer
) {
331 rc
= GPGERR_READ_FILE
;
334 fp
= iobuf_open(answer
);
335 if( !fp
&& errno
== ENOENT
) {
336 tty_printf("No such file, try again or hit enter to quit.\n");
340 log_error("can't open `%s': %s\n", answer
, strerror(errno
) );
341 rc
= GPGERR_READ_FILE
;
349 log_info(_("reading stdin ...\n"));
350 fp
= iobuf_open( NULL
);
353 do_hash( md
, md2
, fp
, textmode
);
365 * Hash the given files and append the hash to hash context md.
366 * If FILES is NULL, hash stdin.
369 hash_datafiles( GCRY_MD_HD md
, GCRY_MD_HD md2
, STRLIST files
,
370 const char *sigfilename
, int textmode
)
376 /* check whether we can open the signed material */
377 fp
= open_sigfile( sigfilename
);
379 do_hash( md
, md2
, fp
, textmode
);
383 /* no we can't (no sigfile) - read signed stuff from stdin */
384 add_to_strlist( &sl
, "-");
389 for( ; sl
; sl
= sl
->next
) {
390 fp
= iobuf_open( sl
->d
);
392 log_error(_("can't open signed data `%s'\n"),
393 print_fname_stdin(sl
->d
));
396 return GPGERR_OPEN_FILE
;
398 do_hash( md
, md2
, fp
, textmode
);