gpg: Remove the use of the signature information from a KBX.
[gnupg.git] / g10 / plaintext.c
index 7929f66..c5d1ddb 100644 (file)
@@ -15,7 +15,7 @@
  * 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, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <assert.h>
 #include <sys/types.h>
 #ifdef HAVE_DOSISH_SYSTEM
 # include <fcntl.h> /* for setmode() */
 #endif
 
 #include "gpg.h"
-#include "util.h"
+#include "../common/util.h"
 #include "options.h"
 #include "packet.h"
-#include "ttyio.h"
+#include "../common/ttyio.h"
 #include "filter.h"
 #include "main.h"
-#include "status.h"
-#include "i18n.h"
+#include "../common/status.h"
+#include "../common/i18n.h"
 
 
-/* Handle a plaintext packet.  If MFX is not NULL, update the MDs
- * Note: We should have used the filter stuff here, but we have to add
- * some easy mimic to set a read limit, so we calculate only the bytes
- * from the plaintext.  */
-int
-handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
-                 int nooutput, int clearsig)
-{
-  char *fname = NULL;
-  estream_t fp = NULL;
-  static off_t count = 0;
-  int err = 0;
-  int c;
-  int convert = (pt->mode == 't' || pt->mode == 'u');
-#ifdef __riscos__
-  int filetype = 0xfff;
-#endif
+/* Get the output filename.  On success, the actual filename that is
+   used is set in *FNAMEP and a filepointer is returned in *FP.
 
-  /* Let people know what the plaintext info is. This allows the
-     receiving program to try and do something different based on the
-     format code (say, recode UTF-8 to local). */
-  if (!nooutput && is_status_enabled ())
-    {
-      char status[50];
-
-      /* Better make sure that stdout has been flushed in case the
-         output will be written to it.  This is to make sure that no
-         not-yet-flushed stuff will be written after the plaintext
-         status message.  */
-      es_fflush (es_stdout);
+   EMBEDDED_NAME AND EMBEDDED_NAMELEN are normally stored in a
+   plaintext packet.  EMBEDDED_NAMELEN should not include any NUL
+   terminator (EMBEDDED_NAME does not need to be NUL terminated).
 
-      snprintf (status, sizeof status,
-                "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
-      write_status_text_and_buffer (STATUS_PLAINTEXT,
-                                   status, pt->name, pt->namelen, 0);
+   DATA is the iobuf containing the input data.  We just use it to get
+   the input file's filename.
 
-      if (!pt->is_partial)
-       {
-         snprintf (status, sizeof status, "%lu", (ulong) pt->len);
-         write_status_text (STATUS_PLAINTEXT_LENGTH, status);
-       }
-    }
+   On success, the caller is responsible for calling xfree on *FNAMEP
+   and calling es_close on *FPP.  */
+gpg_error_t
+get_output_file (const byte *embedded_name, int embedded_namelen,
+                 iobuf_t data, char **fnamep, estream_t *fpp)
+{
+  gpg_error_t err = 0;
+  char *fname = NULL;
+  estream_t fp = NULL;
+  int nooutput = 0;
 
   /* Create the filename as C string.  */
-  if (nooutput)
-    ;
-  else if (opt.outfp)
+  if (opt.outfp)
     {
       fname = xtrystrdup ("[FP]");
       if (!fname)
@@ -104,16 +79,17 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
           goto leave;
         }
     }
-  else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8))
+  else if (embedded_namelen == 8 && !memcmp (embedded_name, "_CONSOLE", 8))
     {
       log_info (_("data not saved; use option \"--output\" to save it\n"));
       nooutput = 1;
     }
   else if (!opt.flags.use_embedded_filename)
     {
-      fname = make_outfile_name (iobuf_get_real_fname (pt->buf));
+      if (data)
+        fname = make_outfile_name (iobuf_get_real_fname (data));
       if (!fname)
-       fname = ask_outfile_name (pt->name, pt->namelen);
+       fname = ask_outfile_name (embedded_name, embedded_namelen);
       if (!fname)
        {
          err = gpg_error (GPG_ERR_GENERAL);    /* Can't create file. */
@@ -121,7 +97,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
        }
     }
   else
-    fname = utf8_to_native (pt->name, pt->namelen, 0);
+    fname = utf8_to_native (embedded_name, embedded_namelen, 0);
 
   if (nooutput)
     ;
@@ -132,9 +108,25 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
     }
   else if (iobuf_is_pipe_filename (fname) || !*fname)
     {
-      /* No filename or "-" given; write to stdout. */
-      fp = es_stdout;
-      es_set_binary (fp);
+      /* Special file name, no filename, or "-" given; write to the
+       * file descriptor or to stdout. */
+      int fd;
+      char xname[64];
+
+      fd = check_special_filename (fname, 1, 0);
+      if (fd == -1)
+        {
+          /* Not a special filename, thus we want stdout.  */
+          fp = es_stdout;
+          es_set_binary (fp);
+        }
+      else if (!(fp = es_fdopen_nc (fd, "wb")))
+        {
+          err = gpg_error_from_syserror ();
+          snprintf (xname, sizeof xname, "[fd %d]", fd);
+          log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err));
+          goto leave;
+        }
     }
   else
     {
@@ -188,7 +180,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
     ;
   else
     {
-      /* Note: riscos stuff is not expected to wrok anymore.  If we
+      /* Note: riscos stuff is not expected to work anymore.  If we
          want to port it again to riscos we should do most of the suff
          in estream.  FIXME: Consider to remove all riscos special
          cases.  */
@@ -205,7 +197,8 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
       /* If there's a ,xxx extension in the embedded filename,
          use that, else check whether the user input (in fname)
          has a ,xxx appended, then use that in preference */
-      if ((c = riscos_get_filetype_from_string (pt->name, pt->namelen)) != -1)
+      if ((c = riscos_get_filetype_from_string (embedded_name,
+                                                embedded_namelen)) != -1)
        filetype = c;
       if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
        filetype = c;
@@ -213,6 +206,75 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
     }
 #endif /* __riscos__ */
 
+ leave:
+  if (err)
+    {
+      if (fp && fp != es_stdout && fp != opt.outfp)
+        es_fclose (fp);
+      xfree (fname);
+      return err;
+    }
+
+  *fnamep = fname;
+  *fpp = fp;
+  return 0;
+}
+
+/* Handle a plaintext packet.  If MFX is not NULL, update the MDs
+ * Note: We should have used the filter stuff here, but we have to add
+ * some easy mimic to set a read limit, so we calculate only the bytes
+ * from the plaintext.  */
+int
+handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
+                 int nooutput, int clearsig)
+{
+  char *fname = NULL;
+  estream_t fp = NULL;
+  static off_t count = 0;
+  int err = 0;
+  int c;
+  int convert;
+#ifdef __riscos__
+  int filetype = 0xfff;
+#endif
+
+  if (pt->mode == 't' || pt->mode == 'u' || pt->mode == 'm')
+    convert = pt->mode;
+  else
+    convert = 0;
+
+  /* Let people know what the plaintext info is. This allows the
+     receiving program to try and do something different based on the
+     format code (say, recode UTF-8 to local). */
+  if (!nooutput && is_status_enabled ())
+    {
+      char status[50];
+
+      /* Better make sure that stdout has been flushed in case the
+         output will be written to it.  This is to make sure that no
+         not-yet-flushed stuff will be written after the plaintext
+         status message.  */
+      es_fflush (es_stdout);
+
+      snprintf (status, sizeof status,
+                "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
+      write_status_text_and_buffer (STATUS_PLAINTEXT,
+                                   status, pt->name, pt->namelen, 0);
+
+      if (!pt->is_partial)
+       {
+         snprintf (status, sizeof status, "%lu", (ulong) pt->len);
+         write_status_text (STATUS_PLAINTEXT_LENGTH, status);
+       }
+    }
+
+  if (! nooutput)
+    {
+      err = get_output_file (pt->name, pt->namelen, pt->buf, &fname, &fp);
+      if (err)
+        goto leave;
+    }
+
   if (!pt->is_partial)
     {
       /* We have an actual length (which might be zero). */
@@ -238,8 +300,10 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
              if (mfx->md)
                gcry_md_putc (mfx->md, c);
 #ifndef HAVE_DOSISH_SYSTEM
-             if (c == '\r')    /* convert to native line ending */
-               continue;       /* fixme: this hack might be too simple */
+              /* Convert to native line ending. */
+              /* fixme: this hack might be too simple */
+             if (c == '\r' && convert != 'm')
+               continue;
 #endif
              if (fp)
                {
@@ -313,7 +377,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
              if (mfx->md)
                gcry_md_putc (mfx->md, c);
 #ifndef HAVE_DOSISH_SYSTEM
-             if (convert && c == '\r')
+             if (c == '\r' && convert != 'm')
                continue;       /* fixme: this hack might be too simple */
 #endif
              if (fp)
@@ -594,7 +658,7 @@ ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
       if (opt.verbose)
        log_info (_("reading stdin ...\n"));
       fp = iobuf_open (NULL);
-      assert (fp);
+      log_assert (fp);
     }
   do_hash (md, md2, fp, textmode);
   iobuf_close (fp);