"Fossies" - the Fresh Open Source Software Archive

Member "gnupg-2.2.17/g10/plaintext.c" (17 May 2019, 20641 Bytes) of package /linux/misc/gnupg-2.2.17.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "plaintext.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.2.15_vs_2.2.16.

    1 /* plaintext.c -  process plaintext packets
    2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    3  *               2006, 2009, 2010 Free Software Foundation, Inc.
    4  *
    5  * This file is part of GnuPG.
    6  *
    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 3 of the License, or
   10  * (at your option) any later version.
   11  *
   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.
   16  *
   17  * You should have received a copy of the GNU General Public License
   18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
   19  */
   20 
   21 #include <config.h>
   22 #include <stdio.h>
   23 #include <stdlib.h>
   24 #include <string.h>
   25 #include <errno.h>
   26 #include <sys/types.h>
   27 #ifdef HAVE_DOSISH_SYSTEM
   28 # include <fcntl.h> /* for setmode() */
   29 #endif
   30 
   31 #include "gpg.h"
   32 #include "../common/util.h"
   33 #include "options.h"
   34 #include "packet.h"
   35 #include "../common/ttyio.h"
   36 #include "filter.h"
   37 #include "main.h"
   38 #include "../common/status.h"
   39 #include "../common/i18n.h"
   40 
   41 
   42 /* Get the output filename.  On success, the actual filename that is
   43    used is set in *FNAMEP and a filepointer is returned in *FP.
   44 
   45    EMBEDDED_NAME AND EMBEDDED_NAMELEN are normally stored in a
   46    plaintext packet.  EMBEDDED_NAMELEN should not include any NUL
   47    terminator (EMBEDDED_NAME does not need to be NUL terminated).
   48 
   49    DATA is the iobuf containing the input data.  We just use it to get
   50    the input file's filename.
   51 
   52    On success, the caller is responsible for calling xfree on *FNAMEP
   53    and calling es_close on *FPP.  */
   54 gpg_error_t
   55 get_output_file (const byte *embedded_name, int embedded_namelen,
   56                  iobuf_t data, char **fnamep, estream_t *fpp)
   57 {
   58   gpg_error_t err = 0;
   59   char *fname = NULL;
   60   estream_t fp = NULL;
   61   int nooutput = 0;
   62 
   63   /* Create the filename as C string.  */
   64   if (opt.outfp)
   65     {
   66       fname = xtrystrdup ("[FP]");
   67       if (!fname)
   68         {
   69           err = gpg_error_from_syserror ();
   70           goto leave;
   71         }
   72     }
   73   else if (opt.outfile
   74            && !(opt.flags.use_embedded_filename && opt.flags.dummy_outfile))
   75     {
   76       fname = xtrystrdup (opt.outfile);
   77       if (!fname)
   78         {
   79           err = gpg_error_from_syserror ();
   80           goto leave;
   81         }
   82     }
   83   else if (embedded_namelen == 8 && !memcmp (embedded_name, "_CONSOLE", 8))
   84     {
   85       log_info (_("data not saved; use option \"--output\" to save it\n"));
   86       nooutput = 1;
   87     }
   88   else if (!opt.flags.use_embedded_filename)
   89     {
   90       if (data)
   91         fname = make_outfile_name (iobuf_get_real_fname (data));
   92       if (!fname)
   93     fname = ask_outfile_name (embedded_name, embedded_namelen);
   94       if (!fname)
   95     {
   96       err = gpg_error (GPG_ERR_GENERAL);    /* Can't create file. */
   97       goto leave;
   98     }
   99     }
  100   else
  101     fname = utf8_to_native (embedded_name, embedded_namelen, 0);
  102 
  103   if (nooutput)
  104     ;
  105   else if (opt.outfp)
  106     {
  107       fp = opt.outfp;
  108       es_set_binary (fp);
  109     }
  110   else if (iobuf_is_pipe_filename (fname) || !*fname)
  111     {
  112       /* Special file name, no filename, or "-" given; write to the
  113        * file descriptor or to stdout. */
  114       int fd;
  115       char xname[64];
  116 
  117       fd = check_special_filename (fname, 1, 0);
  118       if (fd == -1)
  119         {
  120           /* Not a special filename, thus we want stdout.  */
  121           fp = es_stdout;
  122           es_set_binary (fp);
  123         }
  124       else if (!(fp = es_fdopen_nc (fd, "wb")))
  125         {
  126           err = gpg_error_from_syserror ();
  127           snprintf (xname, sizeof xname, "[fd %d]", fd);
  128           log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err));
  129           goto leave;
  130         }
  131     }
  132   else
  133     {
  134       while (!overwrite_filep (fname))
  135     {
  136       char *tmp = ask_outfile_name (NULL, 0);
  137       if (!tmp || !*tmp)
  138         {
  139           xfree (tmp);
  140               /* FIXME: Below used to be GPG_ERR_CREATE_FILE */
  141           err = gpg_error (GPG_ERR_GENERAL);
  142           goto leave;
  143         }
  144       xfree (fname);
  145       fname = tmp;
  146     }
  147     }
  148 
  149 #ifndef __riscos__
  150   if (opt.outfp && is_secured_file (es_fileno (opt.outfp)))
  151     {
  152       err = gpg_error (GPG_ERR_EPERM);
  153       log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
  154       goto leave;
  155     }
  156   else if (fp || nooutput)
  157     ;
  158   else if (is_secured_filename (fname))
  159     {
  160       gpg_err_set_errno (EPERM);
  161       err = gpg_error_from_syserror ();
  162       log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
  163       goto leave;
  164     }
  165   else if (!(fp = es_fopen (fname, "wb")))
  166     {
  167       err = gpg_error_from_syserror ();
  168       log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
  169       goto leave;
  170     }
  171 #else /* __riscos__ */
  172   /* If no output filename was given, i.e. we constructed it, convert
  173      all '.' in fname to '/' but not vice versa as we don't create
  174      directories! */
  175   if (!opt.outfile)
  176     for (c = 0; fname[c]; ++c)
  177       if (fname[c] == '.')
  178     fname[c] = '/';
  179 
  180   if (fp || nooutput)
  181     ;
  182   else
  183     {
  184       /* Note: riscos stuff is not expected to work anymore.  If we
  185          want to port it again to riscos we should do most of the suff
  186          in estream.  FIXME: Consider to remove all riscos special
  187          cases.  */
  188       fp = fopen (fname, "wb");
  189       if (!fp)
  190     {
  191       log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
  192       err = GPG_ERR_CREATE_FILE;
  193       if (errno == 106)
  194         log_info ("Do output file and input file have the same name?\n");
  195       goto leave;
  196     }
  197 
  198       /* If there's a ,xxx extension in the embedded filename,
  199          use that, else check whether the user input (in fname)
  200          has a ,xxx appended, then use that in preference */
  201       if ((c = riscos_get_filetype_from_string (embedded_name,
  202                                                 embedded_namelen)) != -1)
  203     filetype = c;
  204       if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
  205     filetype = c;
  206       riscos_set_filetype_by_number (fname, filetype);
  207     }
  208 #endif /* __riscos__ */
  209 
  210  leave:
  211   if (err)
  212     {
  213       if (fp && fp != es_stdout && fp != opt.outfp)
  214         es_fclose (fp);
  215       xfree (fname);
  216       return err;
  217     }
  218 
  219   *fnamep = fname;
  220   *fpp = fp;
  221   return 0;
  222 }
  223 
  224 /* Handle a plaintext packet.  If MFX is not NULL, update the MDs
  225  * Note: We should have used the filter stuff here, but we have to add
  226  * some easy mimic to set a read limit, so we calculate only the bytes
  227  * from the plaintext.  */
  228 int
  229 handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
  230           int nooutput, int clearsig)
  231 {
  232   char *fname = NULL;
  233   estream_t fp = NULL;
  234   static off_t count = 0;
  235   int err = 0;
  236   int c;
  237   int convert;
  238 #ifdef __riscos__
  239   int filetype = 0xfff;
  240 #endif
  241 
  242   if (pt->mode == 't' || pt->mode == 'u' || pt->mode == 'm')
  243     convert = pt->mode;
  244   else
  245     convert = 0;
  246 
  247   /* Let people know what the plaintext info is. This allows the
  248      receiving program to try and do something different based on the
  249      format code (say, recode UTF-8 to local). */
  250   if (!nooutput && is_status_enabled ())
  251     {
  252       char status[50];
  253 
  254       /* Better make sure that stdout has been flushed in case the
  255          output will be written to it.  This is to make sure that no
  256          not-yet-flushed stuff will be written after the plaintext
  257          status message.  */
  258       es_fflush (es_stdout);
  259 
  260       snprintf (status, sizeof status,
  261                 "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
  262       write_status_text_and_buffer (STATUS_PLAINTEXT,
  263                     status, pt->name, pt->namelen, 0);
  264 
  265       if (!pt->is_partial)
  266     {
  267       snprintf (status, sizeof status, "%lu", (ulong) pt->len);
  268       write_status_text (STATUS_PLAINTEXT_LENGTH, status);
  269     }
  270     }
  271 
  272   if (! nooutput)
  273     {
  274       err = get_output_file (pt->name, pt->namelen, pt->buf, &fname, &fp);
  275       if (err)
  276         goto leave;
  277     }
  278 
  279   if (!pt->is_partial)
  280     {
  281       /* We have an actual length (which might be zero). */
  282 
  283       if (clearsig)
  284     {
  285       log_error ("clearsig encountered while not expected\n");
  286       err = gpg_error (GPG_ERR_UNEXPECTED);
  287       goto leave;
  288     }
  289 
  290       if (convert) /* Text mode.  */
  291     {
  292       for (; pt->len; pt->len--)
  293         {
  294           if ((c = iobuf_get (pt->buf)) == -1)
  295         {
  296           err = gpg_error_from_syserror ();
  297           log_error ("problem reading source (%u bytes remaining)\n",
  298                  (unsigned) pt->len);
  299           goto leave;
  300         }
  301           if (mfx->md)
  302         gcry_md_putc (mfx->md, c);
  303 #ifndef HAVE_DOSISH_SYSTEM
  304               /* Convert to native line ending. */
  305               /* fixme: this hack might be too simple */
  306           if (c == '\r' && convert != 'm')
  307         continue;
  308 #endif
  309           if (fp)
  310         {
  311           if (opt.max_output && (++count) > opt.max_output)
  312             {
  313               log_error ("error writing to '%s': %s\n",
  314                  fname, "exceeded --max-output limit\n");
  315               err = gpg_error (GPG_ERR_TOO_LARGE);
  316               goto leave;
  317             }
  318           else if (es_putc (c, fp) == EOF)
  319             {
  320               if (es_ferror (fp))
  321             err = gpg_error_from_syserror ();
  322               else
  323             err = gpg_error (GPG_ERR_EOF);
  324               log_error ("error writing to '%s': %s\n",
  325                  fname, gpg_strerror (err));
  326               goto leave;
  327             }
  328         }
  329         }
  330     }
  331       else  /* Binary mode.  */
  332     {
  333       byte *buffer = xmalloc (32768);
  334       while (pt->len)
  335         {
  336           int len = pt->len > 32768 ? 32768 : pt->len;
  337           len = iobuf_read (pt->buf, buffer, len);
  338           if (len == -1)
  339         {
  340           err = gpg_error_from_syserror ();
  341           log_error ("problem reading source (%u bytes remaining)\n",
  342                  (unsigned) pt->len);
  343           xfree (buffer);
  344           goto leave;
  345         }
  346           if (mfx->md)
  347         gcry_md_write (mfx->md, buffer, len);
  348           if (fp)
  349         {
  350           if (opt.max_output && (count += len) > opt.max_output)
  351             {
  352               log_error ("error writing to '%s': %s\n",
  353                  fname, "exceeded --max-output limit\n");
  354               err = gpg_error (GPG_ERR_TOO_LARGE);
  355               xfree (buffer);
  356               goto leave;
  357             }
  358           else if (es_fwrite (buffer, 1, len, fp) != len)
  359             {
  360               err = gpg_error_from_syserror ();
  361               log_error ("error writing to '%s': %s\n",
  362                  fname, gpg_strerror (err));
  363               xfree (buffer);
  364               goto leave;
  365             }
  366         }
  367           pt->len -= len;
  368         }
  369       xfree (buffer);
  370     }
  371     }
  372   else if (!clearsig)
  373     {
  374       if (convert)
  375     {           /* text mode */
  376       while ((c = iobuf_get (pt->buf)) != -1)
  377         {
  378           if (mfx->md)
  379         gcry_md_putc (mfx->md, c);
  380 #ifndef HAVE_DOSISH_SYSTEM
  381           if (c == '\r' && convert != 'm')
  382         continue;   /* fixme: this hack might be too simple */
  383 #endif
  384           if (fp)
  385         {
  386           if (opt.max_output && (++count) > opt.max_output)
  387             {
  388               log_error ("Error writing to '%s': %s\n",
  389                  fname, "exceeded --max-output limit\n");
  390               err = gpg_error (GPG_ERR_TOO_LARGE);
  391               goto leave;
  392             }
  393           else if (es_putc (c, fp) == EOF)
  394             {
  395               if (es_ferror (fp))
  396             err = gpg_error_from_syserror ();
  397               else
  398             err = gpg_error (GPG_ERR_EOF);
  399               log_error ("error writing to '%s': %s\n",
  400                  fname, gpg_strerror (err));
  401               goto leave;
  402             }
  403         }
  404         }
  405     }
  406       else
  407     {           /* binary mode */
  408       byte *buffer;
  409       int eof_seen = 0;
  410 
  411           buffer = xtrymalloc (32768);
  412           if (!buffer)
  413             {
  414               err = gpg_error_from_syserror ();
  415               goto leave;
  416             }
  417 
  418       while (!eof_seen)
  419         {
  420           /* Why do we check for len < 32768:
  421            * If we won't, we would practically read 2 EOFs but
  422            * the first one has already popped the block_filter
  423            * off and therefore we don't catch the boundary.
  424            * So, always assume EOF if iobuf_read returns less bytes
  425            * then requested */
  426           int len = iobuf_read (pt->buf, buffer, 32768);
  427           if (len == -1)
  428         break;
  429           if (len < 32768)
  430         eof_seen = 1;
  431           if (mfx->md)
  432         gcry_md_write (mfx->md, buffer, len);
  433           if (fp)
  434         {
  435           if (opt.max_output && (count += len) > opt.max_output)
  436             {
  437               log_error ("error writing to '%s': %s\n",
  438                  fname, "exceeded --max-output limit\n");
  439               err = gpg_error (GPG_ERR_TOO_LARGE);
  440               xfree (buffer);
  441               goto leave;
  442             }
  443           else if (es_fwrite (buffer, 1, len, fp) != len)
  444             {
  445               err = gpg_error_from_syserror ();
  446               log_error ("error writing to '%s': %s\n",
  447                  fname, gpg_strerror (err));
  448               xfree (buffer);
  449               goto leave;
  450             }
  451         }
  452         }
  453       xfree (buffer);
  454     }
  455       pt->buf = NULL;
  456     }
  457   else /* Clear text signature - don't hash the last CR,LF.   */
  458     {
  459       int state = 0;
  460 
  461       while ((c = iobuf_get (pt->buf)) != -1)
  462     {
  463       if (fp)
  464         {
  465           if (opt.max_output && (++count) > opt.max_output)
  466         {
  467           log_error ("error writing to '%s': %s\n",
  468                  fname, "exceeded --max-output limit\n");
  469           err = gpg_error (GPG_ERR_TOO_LARGE);
  470           goto leave;
  471         }
  472           else if (es_putc (c, fp) == EOF)
  473         {
  474           err = gpg_error_from_syserror ();
  475           log_error ("error writing to '%s': %s\n",
  476                  fname, gpg_strerror (err));
  477           goto leave;
  478         }
  479         }
  480       if (!mfx->md)
  481         continue;
  482       if (state == 2)
  483         {
  484           gcry_md_putc (mfx->md, '\r');
  485           gcry_md_putc (mfx->md, '\n');
  486           state = 0;
  487         }
  488       if (!state)
  489         {
  490           if (c == '\r')
  491         state = 1;
  492           else if (c == '\n')
  493         state = 2;
  494           else
  495         gcry_md_putc (mfx->md, c);
  496         }
  497       else if (state == 1)
  498         {
  499           if (c == '\n')
  500         state = 2;
  501           else
  502         {
  503           gcry_md_putc (mfx->md, '\r');
  504           if (c == '\r')
  505             state = 1;
  506           else
  507             {
  508               state = 0;
  509               gcry_md_putc (mfx->md, c);
  510             }
  511         }
  512         }
  513     }
  514       pt->buf = NULL;
  515     }
  516 
  517   if (fp && fp != es_stdout && fp != opt.outfp && es_fclose (fp))
  518     {
  519       err = gpg_error_from_syserror ();
  520       log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
  521       fp = NULL;
  522       goto leave;
  523     }
  524   fp = NULL;
  525 
  526  leave:
  527   /* Make sure that stdout gets flushed after the plaintext has been
  528      handled.  This is for extra security as we do a flush anyway
  529      before checking the signature.  */
  530   if (es_fflush (es_stdout))
  531     {
  532       /* We need to check the return code to detect errors like disk
  533          full for short plaintexts.  See bug#1207.  Checking return
  534          values is a good idea in any case.  */
  535       if (!err)
  536         err = gpg_error_from_syserror ();
  537       log_error ("error flushing '%s': %s\n", "[stdout]",
  538                  gpg_strerror (err));
  539     }
  540 
  541   if (fp && fp != es_stdout && fp != opt.outfp)
  542     es_fclose (fp);
  543   xfree (fname);
  544   return err;
  545 }
  546 
  547 
  548 static void
  549 do_hash (gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode)
  550 {
  551   text_filter_context_t tfx;
  552   int c;
  553 
  554   if (textmode)
  555     {
  556       memset (&tfx, 0, sizeof tfx);
  557       iobuf_push_filter (fp, text_filter, &tfx);
  558     }
  559   if (md2)
  560     {               /* work around a strange behaviour in pgp2 */
  561       /* It seems that at least PGP5 converts a single CR to a CR,LF too */
  562       int lc = -1;
  563       while ((c = iobuf_get (fp)) != -1)
  564     {
  565       if (c == '\n' && lc == '\r')
  566         gcry_md_putc (md2, c);
  567       else if (c == '\n')
  568         {
  569           gcry_md_putc (md2, '\r');
  570           gcry_md_putc (md2, c);
  571         }
  572       else if (c != '\n' && lc == '\r')
  573         {
  574           gcry_md_putc (md2, '\n');
  575           gcry_md_putc (md2, c);
  576         }
  577       else
  578         gcry_md_putc (md2, c);
  579 
  580       if (md)
  581         gcry_md_putc (md, c);
  582       lc = c;
  583     }
  584     }
  585   else
  586     {
  587       while ((c = iobuf_get (fp)) != -1)
  588     {
  589       if (md)
  590         gcry_md_putc (md, c);
  591     }
  592     }
  593 }
  594 
  595 
  596 /****************
  597  * Ask for the detached datafile and calculate the digest from it.
  598  * INFILE is the name of the input file.
  599  */
  600 int
  601 ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
  602                const char *inname, int textmode)
  603 {
  604   progress_filter_context_t *pfx;
  605   char *answer = NULL;
  606   IOBUF fp;
  607   int rc = 0;
  608 
  609   pfx = new_progress_context ();
  610   fp = open_sigfile (inname, pfx);  /* Open default file. */
  611 
  612   if (!fp && !opt.batch)
  613     {
  614       int any = 0;
  615       tty_printf (_("Detached signature.\n"));
  616       do
  617     {
  618       char *name;
  619 
  620       xfree (answer);
  621       tty_enable_completion (NULL);
  622       name = cpr_get ("detached_signature.filename",
  623               _("Please enter name of data file: "));
  624       tty_disable_completion ();
  625       cpr_kill_prompt ();
  626       answer = make_filename (name, (void *) NULL);
  627       xfree (name);
  628 
  629       if (any && !*answer)
  630         {
  631           rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE */
  632           goto leave;
  633         }
  634       fp = iobuf_open (answer);
  635       if (fp && is_secured_file (iobuf_get_fd (fp)))
  636         {
  637           iobuf_close (fp);
  638           fp = NULL;
  639           gpg_err_set_errno (EPERM);
  640         }
  641       if (!fp && errno == ENOENT)
  642         {
  643           tty_printf ("No such file, try again or hit enter to quit.\n");
  644           any++;
  645         }
  646       else if (!fp)
  647         {
  648           rc = gpg_error_from_syserror ();
  649           log_error (_("can't open '%s': %s\n"), answer,
  650              strerror (errno));
  651           goto leave;
  652         }
  653     }
  654       while (!fp);
  655     }
  656 
  657   if (!fp)
  658     {
  659       if (opt.verbose)
  660     log_info (_("reading stdin ...\n"));
  661       fp = iobuf_open (NULL);
  662       log_assert (fp);
  663     }
  664   do_hash (md, md2, fp, textmode);
  665   iobuf_close (fp);
  666 
  667 leave:
  668   xfree (answer);
  669   release_progress_context (pfx);
  670   return rc;
  671 }
  672 
  673 
  674 
  675 /* Hash the given files and append the hash to hash contexts MD and
  676  * MD2.  If FILES is NULL, stdin is hashed.  */
  677 int
  678 hash_datafiles (gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files,
  679         const char *sigfilename, int textmode)
  680 {
  681   progress_filter_context_t *pfx;
  682   IOBUF fp;
  683   strlist_t sl;
  684 
  685   pfx = new_progress_context ();
  686 
  687   if (!files)
  688     {
  689       /* Check whether we can open the signed material.  We avoid
  690          trying to open a file if run in batch mode.  This assumed
  691          data file for a sig file feature is just a convenience thing
  692          for the command line and the user needs to read possible
  693          warning messages. */
  694       if (!opt.batch)
  695         {
  696           fp = open_sigfile (sigfilename, pfx);
  697           if (fp)
  698             {
  699               do_hash (md, md2, fp, textmode);
  700               iobuf_close (fp);
  701               release_progress_context (pfx);
  702               return 0;
  703             }
  704         }
  705       log_error (_("no signed data\n"));
  706       release_progress_context (pfx);
  707       return gpg_error (GPG_ERR_NO_DATA);
  708     }
  709 
  710 
  711   for (sl = files; sl; sl = sl->next)
  712     {
  713       fp = iobuf_open (sl->d);
  714       if (fp && is_secured_file (iobuf_get_fd (fp)))
  715     {
  716       iobuf_close (fp);
  717       fp = NULL;
  718       gpg_err_set_errno (EPERM);
  719     }
  720       if (!fp)
  721     {
  722       int rc = gpg_error_from_syserror ();
  723       log_error (_("can't open signed data '%s'\n"),
  724              print_fname_stdin (sl->d));
  725       release_progress_context (pfx);
  726       return rc;
  727     }
  728       handle_progress (pfx, fp, sl->d);
  729       do_hash (md, md2, fp, textmode);
  730       iobuf_close (fp);
  731     }
  732 
  733   release_progress_context (pfx);
  734   return 0;
  735 }
  736 
  737 
  738 /* Hash the data from file descriptor DATA_FD and append the hash to hash
  739    contexts MD and MD2.  */
  740 int
  741 hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd,
  742              int textmode)
  743 {
  744   progress_filter_context_t *pfx = new_progress_context ();
  745   iobuf_t fp;
  746 
  747   if (is_secured_file (data_fd))
  748     {
  749       fp = NULL;
  750       gpg_err_set_errno (EPERM);
  751     }
  752   else
  753     fp = iobuf_fdopen_nc (data_fd, "rb");
  754 
  755   if (!fp)
  756     {
  757       int rc = gpg_error_from_syserror ();
  758       log_error (_("can't open signed data fd=%d: %s\n"),
  759          data_fd, strerror (errno));
  760       release_progress_context (pfx);
  761       return rc;
  762     }
  763 
  764   handle_progress (pfx, fp, NULL);
  765 
  766   do_hash (md, md2, fp, textmode);
  767 
  768   iobuf_close (fp);
  769 
  770   release_progress_context (pfx);
  771   return 0;
  772 }
  773 
  774 
  775 /* Set up a plaintext packet with the appropriate filename.  If there
  776    is a --set-filename, use it (it's already UTF8).  If there is a
  777    regular filename, UTF8-ize it if necessary.  If there is no
  778    filenames at all, set the field empty. */
  779 
  780 PKT_plaintext *
  781 setup_plaintext_name (const char *filename, IOBUF iobuf)
  782 {
  783   PKT_plaintext *pt;
  784 
  785   if ((filename && !iobuf_is_pipe_filename (filename))
  786        || (opt.set_filename && !iobuf_is_pipe_filename (opt.set_filename)))
  787     {
  788       char *s;
  789 
  790       if (opt.set_filename)
  791     s = make_basename (opt.set_filename, iobuf_get_real_fname (iobuf));
  792       else if (filename && !opt.flags.utf8_filename)
  793     {
  794       char *tmp = native_to_utf8 (filename);
  795       s = make_basename (tmp, iobuf_get_real_fname (iobuf));
  796       xfree (tmp);
  797     }
  798       else
  799     s = make_basename (filename, iobuf_get_real_fname (iobuf));
  800 
  801       pt = xmalloc (sizeof *pt + strlen (s) - 1);
  802       pt->namelen = strlen (s);
  803       memcpy (pt->name, s, pt->namelen);
  804       xfree (s);
  805     }
  806   else
  807     {
  808       /* no filename */
  809       pt = xmalloc (sizeof *pt - 1);
  810       pt->namelen = 0;
  811     }
  812 
  813   return pt;
  814 }