LCOV - code coverage report
Current view: top level - tools - gpgtar.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 138 195 70.8 %
Date: 2016-09-12 13:01:59 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /* gpgtar.c - A simple TAR implementation mainly useful for Windows.
       2             :  * Copyright (C) 2010 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       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 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      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.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : /* GnuPG comes with a shell script gpg-zip which creates archive files
      21             :    in the same format as PGP Zip, which is actually a USTAR format.
      22             :    That is fine and works nicely on all Unices but for Windows we
      23             :    don't have a compatible shell and the supply of tar programs is
      24             :    limited.  Given that we need just a few tar option and it is an
      25             :    open question how many Unix concepts are to be mapped to Windows,
      26             :    we might as well write our own little tar customized for use with
      27             :    gpg.  So here we go.  */
      28             : 
      29             : #include <config.h>
      30             : #include <ctype.h>
      31             : #include <errno.h>
      32             : #include <stdio.h>
      33             : #include <stdlib.h>
      34             : #include <string.h>
      35             : #include <assert.h>
      36             : 
      37             : #include "util.h"
      38             : #include "i18n.h"
      39             : #include "sysutils.h"
      40             : #include "../common/openpgpdefs.h"
      41             : #include "../common/init.h"
      42             : #include "../common/strlist.h"
      43             : 
      44             : #include "gpgtar.h"
      45             : 
      46             : 
      47             : /* Constants to identify the commands and options. */
      48             : enum cmd_and_opt_values
      49             :   {
      50             :     aNull = 0,
      51             :     aCreate = 600,
      52             :     aExtract,
      53             :     aEncrypt    = 'e',
      54             :     aDecrypt    = 'd',
      55             :     aSign       = 's',
      56             :     aList       = 't',
      57             : 
      58             :     oSymmetric  = 'c',
      59             :     oRecipient  = 'r',
      60             :     oUser       = 'u',
      61             :     oOutput     = 'o',
      62             :     oDirectory  = 'C',
      63             :     oQuiet      = 'q',
      64             :     oVerbose    = 'v',
      65             :     oFilesFrom  = 'T',
      66             :     oNoVerbose  = 500,
      67             : 
      68             :     aSignEncrypt,
      69             :     oGpgProgram,
      70             :     oSkipCrypto,
      71             :     oOpenPGP,
      72             :     oCMS,
      73             :     oSetFilename,
      74             :     oNull,
      75             : 
      76             :     /* Compatibility with gpg-zip.  */
      77             :     oGpgArgs,
      78             :     oTarArgs,
      79             : 
      80             :     /* Debugging.  */
      81             :     oDryRun,
      82             :   };
      83             : 
      84             : 
      85             : /* The list of commands and options. */
      86             : static ARGPARSE_OPTS opts[] = {
      87             :   ARGPARSE_group (300, N_("@Commands:\n ")),
      88             : 
      89             :   ARGPARSE_c (aCreate,    "create",  N_("create an archive")),
      90             :   ARGPARSE_c (aExtract,   "extract", N_("extract an archive")),
      91             :   ARGPARSE_c (aEncrypt,   "encrypt", N_("create an encrypted archive")),
      92             :   ARGPARSE_c (aDecrypt,   "decrypt", N_("extract an encrypted archive")),
      93             :   ARGPARSE_c (aSign,      "sign",    N_("create a signed archive")),
      94             :   ARGPARSE_c (aList,      "list-archive", N_("list an archive")),
      95             : 
      96             :   ARGPARSE_group (301, N_("@\nOptions:\n ")),
      97             : 
      98             :   ARGPARSE_s_n (oSymmetric, "symmetric", N_("use symmetric encryption")),
      99             :   ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
     100             :   ARGPARSE_s_s (oUser, "local-user",
     101             :                 N_("|USER-ID|use USER-ID to sign or decrypt")),
     102             :   ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
     103             :   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
     104             :   ARGPARSE_s_n (oQuiet, "quiet",  N_("be somewhat more quiet")),
     105             :   ARGPARSE_s_s (oGpgProgram, "gpg", "@"),
     106             :   ARGPARSE_s_n (oSkipCrypto, "skip-crypto", N_("skip the crypto processing")),
     107             :   ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
     108             :   ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
     109             :   ARGPARSE_s_n (oOpenPGP, "openpgp", "@"),
     110             :   ARGPARSE_s_n (oCMS, "cms", "@"),
     111             : 
     112             :   ARGPARSE_group (302, N_("@\nTar options:\n ")),
     113             : 
     114             :   ARGPARSE_s_s (oDirectory, "directory",
     115             :                 N_("|DIRECTORY|extract files into DIRECTORY")),
     116             :   ARGPARSE_s_s (oFilesFrom, "files-from",
     117             :                 N_("|FILE|get names to create from FILE")),
     118             :   ARGPARSE_s_n (oNull, "null", N_("-T reads null-terminated names")),
     119             : 
     120             :   ARGPARSE_s_s (oGpgArgs, "gpg-args", "@"),
     121             :   ARGPARSE_s_s (oTarArgs, "tar-args", "@"),
     122             : 
     123             :   ARGPARSE_end ()
     124             : };
     125             : 
     126             : 
     127             : /* The list of commands and options for tar that we understand. */
     128             : static ARGPARSE_OPTS tar_opts[] = {
     129             :   ARGPARSE_s_s (oDirectory, "directory",
     130             :                 N_("|DIRECTORY|extract files into DIRECTORY")),
     131             :   ARGPARSE_s_s (oFilesFrom, "files-from",
     132             :                 N_("|FILE|get names to create from FILE")),
     133             :   ARGPARSE_s_n (oNull, "null", N_("-T reads null-terminated names")),
     134             : 
     135             :   ARGPARSE_end ()
     136             : };
     137             : 
     138             : 
     139             : 
     140             : /* Print usage information and and provide strings for help. */
     141             : static const char *
     142         120 : my_strusage( int level )
     143             : {
     144             :   const char *p;
     145             : 
     146         120 :   switch (level)
     147             :     {
     148           4 :     case 11: p = "@GPGTAR@ (@GNUPG@)";
     149           4 :       break;
     150           4 :     case 13: p = VERSION; break;
     151           0 :     case 17: p = PRINTABLE_OS_NAME; break;
     152           4 :     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
     153             : 
     154             :     case 1:
     155             :     case 40:
     156           0 :       p = _("Usage: gpgtar [options] [files] [directories] (-h for help)");
     157           0 :       break;
     158             :     case 41:
     159           4 :       p = _("Syntax: gpgtar [options] [files] [directories]\n"
     160             :             "Encrypt or sign files into an archive\n");
     161           4 :       break;
     162             : 
     163         104 :     default: p = NULL; break;
     164             :     }
     165         120 :   return p;
     166             : }
     167             : 
     168             : 
     169             : static void
     170          74 : set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
     171             : {
     172          74 :   enum cmd_and_opt_values cmd = *ret_cmd;
     173             : 
     174          74 :   if (!cmd || cmd == new_cmd)
     175          72 :     cmd = new_cmd;
     176           2 :   else if (cmd == aSign && new_cmd == aEncrypt)
     177           0 :     cmd = aSignEncrypt;
     178           2 :   else if (cmd == aEncrypt && new_cmd == aSign)
     179           2 :     cmd = aSignEncrypt;
     180             :   else
     181             :     {
     182           0 :       log_error (_("conflicting commands\n"));
     183           0 :       exit (2);
     184             :     }
     185             : 
     186          74 :   *ret_cmd = cmd;
     187          74 : }
     188             : 
     189             : /* Shell-like argument splitting.
     190             : 
     191             :    For compatibility with gpg-zip we accept arguments for GnuPG and
     192             :    tar given as a string argument to '--gpg-args' and '--tar-args'.
     193             :    gpg-zip was implemented as a Bourne Shell script, and therefore, we
     194             :    need to split the string the same way the shell would.  */
     195             : static int
     196          42 : shell_parse_stringlist (const char *str, strlist_t *r_list)
     197             : {
     198          42 :   strlist_t list = NULL;
     199          42 :   const char *s = str;
     200          42 :   char quoted = 0;
     201             :   char arg[1024];
     202          42 :   char *p = arg;
     203             : #define addchar(c) \
     204             :   do { if (p - arg + 2 < sizeof arg) *p++ = (c); else return 1; } while (0)
     205             : #define addargument()                           \
     206             :   do {                                          \
     207             :     if (p > arg)                                \
     208             :       {                                         \
     209             :         *p = 0;                                 \
     210             :         append_to_strlist (&list, arg);         \
     211             :         p = arg;                                \
     212             :       }                                         \
     213             :   } while (0)
     214             : 
     215             : #define unquoted        0
     216             : #define singlequote     '\''
     217             : #define doublequote     '"'
     218             : 
     219        1530 :   for (; *s; s++)
     220             :     {
     221        1488 :       switch (quoted)
     222             :         {
     223             :         case unquoted:
     224        1488 :           if (isspace (*s))
     225          24 :             addargument ();
     226        1464 :           else if (*s == singlequote || *s == doublequote)
     227           0 :             quoted = *s;
     228             :           else
     229        1464 :             addchar (*s);
     230        1488 :           break;
     231             : 
     232             :         case singlequote:
     233           0 :           if (*s == singlequote)
     234           0 :             quoted = unquoted;
     235             :           else
     236           0 :             addchar (*s);
     237           0 :           break;
     238             : 
     239             :         case doublequote:
     240           0 :           assert (s > str || !"cannot be quoted at first char");
     241           0 :           if (*s == doublequote && *(s - 1) != '\\')
     242           0 :             quoted = unquoted;
     243             :           else
     244           0 :             addchar (*s);
     245           0 :           break;
     246             : 
     247             :         default:
     248           0 :           assert (! "reached");
     249             :         }
     250             :     }
     251             : 
     252             :   /* Append the last argument.  */
     253          42 :   addargument ();
     254             : 
     255             : #undef doublequote
     256             : #undef singlequote
     257             : #undef unquoted
     258             : #undef addargument
     259             : #undef addchar
     260          42 :   *r_list = list;
     261          42 :   return 0;
     262             : }
     263             : 
     264             : 
     265             : /* Like shell_parse_stringlist, but returns an argv vector
     266             :    instead of a strlist.  */
     267             : static int
     268           8 : shell_parse_argv (const char *s, int *r_argc, char ***r_argv)
     269             : {
     270             :   int i;
     271             :   strlist_t list;
     272             : 
     273           8 :   if (shell_parse_stringlist (s, &list))
     274           0 :     return 1;
     275             : 
     276           8 :   *r_argc = strlist_length (list);
     277           8 :   *r_argv = xtrycalloc (*r_argc, sizeof **r_argv);
     278           8 :   if (*r_argv == NULL)
     279           0 :     return 1;
     280             : 
     281          16 :   for (i = 0; list; i++)
     282             :     {
     283           8 :       gpgrt_annotate_leaked_object (list);
     284           8 :       (*r_argv)[i] = list->d;
     285           8 :       list = list->next;
     286             :     }
     287           8 :   gpgrt_annotate_leaked_object (*r_argv);
     288           8 :   return 0;
     289             : }
     290             : 
     291             : /* Global flags.  */
     292             : enum cmd_and_opt_values cmd = 0;
     293             : int skip_crypto = 0;
     294             : const char *files_from = NULL;
     295             : int null_names = 0;
     296             : 
     297             : 
     298             : /* Command line parsing.  */
     299             : static void
     300          83 : parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts)
     301             : {
     302          83 :   int no_more_options = 0;
     303             : 
     304         379 :   while (!no_more_options && optfile_parse (NULL, NULL, NULL, pargs, popts))
     305             :     {
     306         213 :       switch (pargs->r_opt)
     307             :         {
     308           9 :         case oOutput:    opt.outfile = pargs->r.ret_str; break;
     309          54 :         case oDirectory: opt.directory = pargs->r.ret_str; break;
     310           0 :         case oSetFilename: opt.filename = pargs->r.ret_str; break;
     311           0 :         case oQuiet:     opt.quiet = 1; break;
     312           0 :         case oVerbose:   opt.verbose++; break;
     313           0 :         case oNoVerbose: opt.verbose = 0; break;
     314           0 :         case oFilesFrom: files_from = pargs->r.ret_str; break;
     315           0 :         case oNull: null_names = 1; break;
     316             : 
     317             :         case aList:
     318             :         case aDecrypt:
     319             :         case aEncrypt:
     320             :         case aSign:
     321          22 :           set_cmd (&cmd, pargs->r_opt);
     322          22 :           break;
     323             : 
     324             :         case aCreate:
     325           2 :           set_cmd (&cmd, aEncrypt);
     326           2 :           skip_crypto = 1;
     327           2 :           break;
     328             : 
     329             :         case aExtract:
     330          47 :           set_cmd (&cmd, aDecrypt);
     331          47 :           skip_crypto = 1;
     332          47 :           break;
     333             : 
     334             :         case oRecipient:
     335           3 :           add_to_strlist (&opt.recipients, pargs->r.ret_str);
     336           3 :           break;
     337             : 
     338             :         case oUser:
     339           3 :           opt.user = pargs->r.ret_str;
     340           3 :           break;
     341             : 
     342             :         case oSymmetric:
     343           3 :           set_cmd (&cmd, aEncrypt);
     344           3 :           opt.symmetric = 1;
     345           3 :           break;
     346             : 
     347             :         case oGpgProgram:
     348          24 :           opt.gpg_program = pargs->r.ret_str;
     349          24 :           break;
     350             : 
     351             :         case oSkipCrypto:
     352           4 :           skip_crypto = 1;
     353           4 :           break;
     354             : 
     355           0 :         case oOpenPGP: /* Dummy option for now.  */ break;
     356           0 :         case oCMS:     /* Dummy option for now.  */ break;
     357             : 
     358             :         case oGpgArgs:;
     359             :           {
     360             :             strlist_t list;
     361          34 :             if (shell_parse_stringlist (pargs->r.ret_str, &list))
     362           0 :               log_error ("failed to parse gpg arguments '%s'\n",
     363             :                          pargs->r.ret_str);
     364             :             else
     365             :               {
     366          34 :                 if (opt.gpg_arguments)
     367          10 :                   strlist_last (opt.gpg_arguments)->next = list;
     368             :                 else
     369          24 :                   opt.gpg_arguments = list;
     370             :               }
     371             :           }
     372          34 :           break;
     373             : 
     374             :         case oTarArgs:;
     375             :           {
     376             :             int tar_argc;
     377             :             char **tar_argv;
     378             : 
     379           8 :             if (shell_parse_argv (pargs->r.ret_str, &tar_argc, &tar_argv))
     380           0 :               log_error ("failed to parse tar arguments '%s'\n",
     381             :                          pargs->r.ret_str);
     382             :             else
     383             :               {
     384             :                 ARGPARSE_ARGS tar_args;
     385           8 :                 tar_args.argc = &tar_argc;
     386           8 :                 tar_args.argv = &tar_argv;
     387           8 :                 tar_args.flags = ARGPARSE_FLAG_ARG0;
     388           8 :                 parse_arguments (&tar_args, tar_opts);
     389           8 :                 if (tar_args.err)
     390           0 :                   log_error ("unsupported tar arguments '%s'\n",
     391             :                              pargs->r.ret_str);
     392           8 :                 pargs->err = tar_args.err;
     393             :               }
     394             :           }
     395           8 :           break;
     396             : 
     397             :         case oDryRun:
     398           0 :           opt.dry_run = 1;
     399           0 :           break;
     400             : 
     401           0 :         default: pargs->err = 2; break;
     402             :         }
     403             :     }
     404          79 : }
     405             : 
     406             : 
     407             : /* gpgtar main. */
     408             : int
     409          75 : main (int argc, char **argv)
     410             : {
     411             :   gpg_error_t err;
     412             :   const char *fname;
     413             :   ARGPARSE_ARGS pargs;
     414             : 
     415             :   assert (sizeof (struct ustar_raw_header) == 512);
     416             : 
     417          75 :   gnupg_reopen_std (GPGTAR_NAME);
     418          75 :   set_strusage (my_strusage);
     419          75 :   log_set_prefix (GPGTAR_NAME, GPGRT_LOG_WITH_PREFIX);
     420             : 
     421             :   /* Make sure that our subsystems are ready.  */
     422          75 :   i18n_init();
     423          75 :   init_common_subsystems (&argc, &argv);
     424             : 
     425             :   /* Parse the command line. */
     426          75 :   pargs.argc  = &argc;
     427          75 :   pargs.argv  = &argv;
     428          75 :   pargs.flags = ARGPARSE_FLAG_KEEP;
     429          75 :   parse_arguments (&pargs, opts);
     430             : 
     431          71 :   if ((files_from && !null_names) || (!files_from && null_names))
     432           0 :     log_error ("--files-from and --null may only be used in conjunction\n");
     433          71 :   if (files_from && strcmp (files_from, "-"))
     434           0 :     log_error ("--files-from only supports argument \"-\"\n");
     435             : 
     436          71 :   if (log_get_errorcount (0))
     437           0 :     exit (2);
     438             : 
     439             :   /* Print a warning if an argument looks like an option.  */
     440          71 :   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
     441             :     {
     442             :       int i;
     443             : 
     444         203 :       for (i=0; i < argc; i++)
     445         132 :         if (argv[i][0] == '-' && argv[i][1] == '-')
     446           0 :           log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
     447             :     }
     448             : 
     449          71 :   if (! opt.gpg_program)
     450          47 :     opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG);
     451             : 
     452          71 :   if (opt.verbose > 1)
     453           0 :     opt.debug_level = 1024;
     454             : 
     455          71 :   switch (cmd)
     456             :     {
     457             :     case aList:
     458           8 :       if (argc > 1)
     459           0 :         usage (1);
     460           8 :       fname = argc ? *argv : NULL;
     461           8 :       if (opt.filename)
     462           0 :         log_info ("note: ignoring option --set-filename\n");
     463           8 :       if (files_from)
     464           0 :         log_info ("note: ignoring option --files-from\n");
     465           8 :       err = gpgtar_list (fname, !skip_crypto);
     466           8 :       if (err && log_get_errorcount (0) == 0)
     467           0 :         log_error ("listing archive failed: %s\n", gpg_strerror (err));
     468           8 :       break;
     469             : 
     470             :     case aEncrypt:
     471             :     case aSign:
     472             :     case aSignEncrypt:
     473           9 :       if ((!argc && !null_names)
     474           9 :           || (argc && null_names))
     475           0 :         usage (1);
     476           9 :       if (opt.filename)
     477           0 :         log_info ("note: ignoring option --set-filename\n");
     478          37 :       err = gpgtar_create (null_names? NULL :argv,
     479           9 :                            !skip_crypto
     480           9 :                            && (cmd == aEncrypt || cmd == aSignEncrypt),
     481          17 :                            cmd == aSign || cmd == aSignEncrypt);
     482           9 :       if (err && log_get_errorcount (0) == 0)
     483           0 :         log_error ("creating archive failed: %s\n", gpg_strerror (err));
     484           9 :       break;
     485             : 
     486             :     case aDecrypt:
     487          54 :       if (argc != 1)
     488           0 :         usage (1);
     489          54 :       if (opt.outfile)
     490           0 :         log_info ("note: ignoring option --output\n");
     491          54 :       if (files_from)
     492           0 :         log_info ("note: ignoring option --files-from\n");
     493          54 :       fname = argc ? *argv : NULL;
     494          54 :       err = gpgtar_extract (fname, !skip_crypto);
     495          54 :       if (err && log_get_errorcount (0) == 0)
     496           0 :         log_error ("extracting archive failed: %s\n", gpg_strerror (err));
     497          54 :       break;
     498             : 
     499             :     default:
     500           0 :       log_error (_("invalid command (there is no implicit command)\n"));
     501           0 :       break;
     502             :     }
     503             : 
     504          71 :   return log_get_errorcount (0)? 1:0;
     505             : }
     506             : 
     507             : 
     508             : /* Read the next record from STREAM.  RECORD is a buffer provided by
     509             :    the caller and must be at leadt of size RECORDSIZE.  The function
     510             :    return 0 on success and and error code on failure; a diagnostic
     511             :    printed as well.  Note that there is no need for an EOF indicator
     512             :    because a tarball has an explicit EOF record. */
     513             : gpg_error_t
     514       39955 : read_record (estream_t stream, void *record)
     515             : {
     516             :   gpg_error_t err;
     517             :   size_t nread;
     518             : 
     519       39955 :   nread = es_fread (record, 1, RECORDSIZE, stream);
     520       39955 :   if (nread != RECORDSIZE)
     521             :     {
     522           0 :       err = gpg_error_from_syserror ();
     523           0 :       if (es_ferror (stream))
     524           0 :         log_error ("error reading '%s': %s\n",
     525             :                    es_fname_get (stream), gpg_strerror (err));
     526             :       else
     527           0 :         log_error ("error reading '%s': premature EOF "
     528             :                    "(size of last record: %zu)\n",
     529             :                    es_fname_get (stream), nread);
     530             :     }
     531             :   else
     532       39955 :     err = 0;
     533             : 
     534       39955 :   return err;
     535             : }
     536             : 
     537             : 
     538             : /* Write the RECORD of size RECORDSIZE to STREAM.  FILENAME is the
     539             :    name of the file used for diagnostics.  */
     540             : gpg_error_t
     541        2920 : write_record (estream_t stream, const void *record)
     542             : {
     543             :   gpg_error_t err;
     544             :   size_t nwritten;
     545             : 
     546        2920 :   nwritten = es_fwrite (record, 1, RECORDSIZE, stream);
     547        2920 :   if (nwritten != RECORDSIZE)
     548             :     {
     549           0 :       err = gpg_error_from_syserror ();
     550           0 :       log_error ("error writing '%s': %s\n",
     551             :                  es_fname_get (stream), gpg_strerror (err));
     552             :     }
     553             :   else
     554        2920 :     err = 0;
     555             : 
     556        2920 :   return err;
     557             : }
     558             : 
     559             : 
     560             : /* Return true if FP is an unarmored OpenPGP message.  Note that this
     561             :    function reads a few bytes from FP but pushes them back.  */
     562             : #if 0
     563             : static int
     564             : openpgp_message_p (estream_t fp)
     565             : {
     566             :   int ctb;
     567             : 
     568             :   ctb = es_getc (fp);
     569             :   if (ctb != EOF)
     570             :     {
     571             :       if (es_ungetc (ctb, fp))
     572             :         log_fatal ("error ungetting first byte: %s\n",
     573             :                    gpg_strerror (gpg_error_from_syserror ()));
     574             : 
     575             :       if ((ctb & 0x80))
     576             :         {
     577             :           switch ((ctb & 0x40) ? (ctb & 0x3f) : ((ctb>>2)&0xf))
     578             :             {
     579             :             case PKT_MARKER:
     580             :             case PKT_SYMKEY_ENC:
     581             :             case PKT_ONEPASS_SIG:
     582             :             case PKT_PUBKEY_ENC:
     583             :             case PKT_SIGNATURE:
     584             :             case PKT_COMMENT:
     585             :             case PKT_OLD_COMMENT:
     586             :             case PKT_PLAINTEXT:
     587             :             case PKT_COMPRESSED:
     588             :             case PKT_ENCRYPTED:
     589             :               return 1; /* Yes, this seems to be an OpenPGP message.  */
     590             :             default:
     591             :               break;
     592             :             }
     593             :         }
     594             :     }
     595             :   return 0;
     596             : }
     597             : #endif

Generated by: LCOV version 1.11