LCOV - code coverage report
Current view: top level - src - gpg-error.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 212 0.0 %
Date: 2016-12-21 11:11:56 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /* gpg-error.c - Determining gpg-error error codes.
       2             :    Copyright (C) 2004, 2016 g10 Code GmbH
       3             : 
       4             :    This file is part of libgpg-error.
       5             : 
       6             :    libgpg-error is free software; you can redistribute it and/or
       7             :    modify it under the terms of the GNU Lesser General Public License
       8             :    as published by the Free Software Foundation; either version 2.1 of
       9             :    the License, or (at your option) any later version.
      10             : 
      11             :    libgpg-error is distributed in the hope that it will be useful, but
      12             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :    Lesser General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU Lesser General Public
      17             :    License along with libgpg-error; if not, write to the Free
      18             :    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      19             :    02111-1307, USA.  */
      20             : 
      21             : #if HAVE_CONFIG_H
      22             : #include <config.h>
      23             : #endif
      24             : 
      25             : #include <stddef.h>
      26             : #include <stdlib.h>
      27             : #include <string.h>
      28             : #include <errno.h>
      29             : #include <limits.h>
      30             : #include <stdio.h>
      31             : 
      32             : #ifdef HAVE_LOCALE_H
      33             : # include <locale.h>
      34             : #endif
      35             : #ifdef ENABLE_NLS
      36             : #ifdef HAVE_W32_SYSTEM
      37             : # include "gettext.h"
      38             : #else
      39             : # include <libintl.h>
      40             : #endif
      41             : # define _(a) gettext (a)
      42             : # ifdef gettext_noop
      43             : #  define N_(a) gettext_noop (a)
      44             : # else
      45             : #  define N_(a) (a)
      46             : # endif
      47             : #else
      48             : # define _(a) (a)
      49             : # define N_(a) (a)
      50             : #endif
      51             : 
      52             : #include <gpg-error.h>
      53             : 
      54             : 
      55             : #if HAVE_W32_SYSTEM
      56             : /* The implementation follows below.  */
      57             : static char *get_locale_dir (void);
      58             : static void drop_locale_dir (char *locale_dir);
      59             : #else
      60             : #define get_locale_dir() LOCALEDIR
      61             : #define drop_locale_dir(dir)
      62             : #endif
      63             : 
      64             : static void
      65           0 : i18n_init (void)
      66             : {
      67             : #ifdef ENABLE_NLS
      68             :   char *locale_dir;
      69             : 
      70             : #ifdef HAVE_LC_MESSAGES
      71             :   setlocale (LC_TIME, "");
      72             :   setlocale (LC_MESSAGES, "");
      73             : #else
      74             : # ifndef HAVE_W32_SYSTEM
      75           0 :   setlocale (LC_ALL, "" );
      76             : # endif
      77             : #endif
      78             : 
      79             :   /* Note that for this program we would only need the textdomain call
      80             :      because libgpg-error already initializes itself to its locale dir
      81             :      (via gpg_err_init or a constructor).  However this is only done
      82             :      for the static standard locale and thus if the above setlocale
      83             :      calls select a different locale the bindtext below will do
      84             :      something else.  */
      85             : 
      86             :   locale_dir = get_locale_dir ();
      87             :   if (locale_dir)
      88             :     {
      89           0 :       bindtextdomain (PACKAGE, locale_dir);
      90             :       drop_locale_dir (locale_dir);
      91             :     }
      92           0 :   textdomain (PACKAGE);
      93             : #endif
      94           0 : }
      95             : 
      96             : 
      97             : #ifdef HAVE_W32_SYSTEM
      98             : 
      99             : #include <windows.h>
     100             : 
     101             : 
     102             : static char *
     103             : get_locale_dir (void)
     104             : {
     105             :   static wchar_t moddir[MAX_PATH+5];
     106             :   char *result, *p;
     107             :   int nbytes;
     108             : 
     109             :   if (!GetModuleFileNameW (NULL, moddir, MAX_PATH))
     110             :     *moddir = 0;
     111             : 
     112             : #define SLDIR "\\share\\locale"
     113             :   if (*moddir)
     114             :     {
     115             :       nbytes = WideCharToMultiByte (CP_UTF8, 0, moddir, -1, NULL, 0, NULL, NULL);
     116             :       if (nbytes < 0)
     117             :         return NULL;
     118             : 
     119             :       result = malloc (nbytes + strlen (SLDIR) + 1);
     120             :       if (result)
     121             :         {
     122             :           nbytes = WideCharToMultiByte (CP_UTF8, 0, moddir, -1,
     123             :                                         result, nbytes, NULL, NULL);
     124             :           if (nbytes < 0)
     125             :             {
     126             :               free (result);
     127             :               result = NULL;
     128             :             }
     129             :           else
     130             :             {
     131             :               p = strrchr (result, '\\');
     132             :               if (p)
     133             :                 *p = 0;
     134             :               /* If we are installed below "bin" strip that part and
     135             :                  use the top directory instead.  */
     136             :               p = strrchr (result, '\\');
     137             :               if (p && !strcmp (p+1, "bin"))
     138             :                 *p = 0;
     139             :               /* Append the static part.  */
     140             :               strcat (result, SLDIR);
     141             :             }
     142             :         }
     143             :     }
     144             :   else /* Use the old default value.  */
     145             :     {
     146             :       result = malloc (10 + strlen (SLDIR) + 1);
     147             :       if (result)
     148             :         {
     149             :           strcpy (result, "c:\\gnupg");
     150             :           strcat (result, SLDIR);
     151             :         }
     152             :     }
     153             : #undef SLDIR
     154             :   return result;
     155             : }
     156             : 
     157             : 
     158             : static void
     159             : drop_locale_dir (char *locale_dir)
     160             : {
     161             :   free (locale_dir);
     162             : }
     163             : 
     164             : #endif  /* HAVE_W32_SYSTEM */
     165             : 
     166             : 
     167             : const char *gpg_strerror_sym (gpg_error_t err);
     168             : const char *gpg_strsource_sym (gpg_error_t err);
     169             : 
     170             : 
     171             : static int
     172           0 : get_err_from_number (char *str, gpg_error_t *err)
     173             : {
     174             :   unsigned long nr;
     175             :   char *tail;
     176             : 
     177           0 :   gpg_err_set_errno (0);
     178           0 :   nr = strtoul (str, &tail, 0);
     179           0 :   if (errno)
     180             :     return 0;
     181             : 
     182           0 :   if (nr > UINT_MAX)
     183             :     return 0;
     184             : 
     185           0 :   if (*tail)
     186             :     {
     187           0 :       unsigned long cnr = strtoul (tail + 1, &tail, 0);
     188           0 :       if (errno || *tail)
     189             :         return 0;
     190             : 
     191           0 :       if (nr >= GPG_ERR_SOURCE_DIM || cnr >= GPG_ERR_CODE_DIM)
     192             :         return 0;
     193             : 
     194           0 :       nr = gpg_err_make (nr, cnr);
     195             :     }
     196             : 
     197           0 :   *err = (unsigned int) nr;
     198           0 :   return 1;
     199             : }
     200             : 
     201             : 
     202             : static int
     203           0 : get_err_from_symbol_one (char *str, gpg_error_t *err,
     204             :                          int *have_source, int *have_code)
     205             : {
     206             :   static const char src_prefix[] = "GPG_ERR_SOURCE_";
     207             :   static const char code_prefix[] = "GPG_ERR_";
     208             : 
     209           0 :   if (!strncasecmp (src_prefix, str, sizeof (src_prefix) - 1))
     210             :     {
     211             :       gpg_err_source_t src;
     212             : 
     213           0 :       if (*have_source)
     214             :         return 0;
     215           0 :       *have_source = 1;
     216           0 :       str += sizeof (src_prefix) - 1;
     217             : 
     218           0 :       for (src = 0; src < GPG_ERR_SOURCE_DIM; src++)
     219             :         {
     220             :           const char *src_sym;
     221             : 
     222           0 :           src_sym = gpg_strsource_sym (src << GPG_ERR_SOURCE_SHIFT);
     223           0 :           if (src_sym && !strcasecmp (str, src_sym + sizeof (src_prefix) - 1))
     224             :             {
     225           0 :               *err |= src << GPG_ERR_SOURCE_SHIFT;
     226           0 :               return 1;
     227             :             }
     228             :         }
     229             :     }
     230           0 :   else if (!strncasecmp (code_prefix, str, sizeof (code_prefix) - 1))
     231             :     {
     232             :       gpg_err_code_t code;
     233             : 
     234           0 :       if (*have_code)
     235             :         return 0;
     236           0 :       *have_code = 1;
     237           0 :       str += sizeof (code_prefix) - 1;
     238             : 
     239           0 :       for (code = 0; code < GPG_ERR_CODE_DIM; code++)
     240             :         {
     241           0 :           const char *code_sym = gpg_strerror_sym (code);
     242           0 :           if (code_sym
     243           0 :               && !strcasecmp (str, code_sym + sizeof (code_prefix) - 1))
     244             :             {
     245           0 :               *err |= code;
     246           0 :               return 1;
     247             :             }
     248             :         }
     249             :     }
     250             :   return 0;
     251             : }
     252             : 
     253             : 
     254             : static int
     255           0 : get_err_from_symbol (char *str, gpg_error_t *err)
     256             : {
     257             :   char *str2 = str;
     258           0 :   int have_source = 0;
     259           0 :   int have_code = 0;
     260             :   int ret;
     261             :   char *saved_pos = NULL;
     262             :   char saved_char;
     263             : 
     264           0 :   *err = 0;
     265           0 :   while (*str2 && ((*str2 >= 'A' && *str2 <= 'Z')
     266           0 :                    || (*str2 >= '0' && *str2 <= '9')
     267           0 :                    || *str2 == '_'))
     268           0 :     str2++;
     269           0 :   if (*str2)
     270             :     {
     271             :       saved_pos = str2;
     272             :       saved_char = *str2;
     273           0 :       *str2 = '\0';
     274           0 :       str2++;
     275             :     }
     276             :   else
     277             :     str2 = NULL;
     278             : 
     279           0 :   ret = get_err_from_symbol_one (str, err, &have_source, &have_code);
     280           0 :   if (ret && str2)
     281           0 :     ret = get_err_from_symbol_one (str2, err, &have_source, &have_code);
     282             : 
     283           0 :   if (saved_pos)
     284           0 :     *saved_pos = saved_char;
     285           0 :   return ret;
     286             : }
     287             : 
     288             : 
     289             : static int
     290           0 : get_err_from_str_one (char *str, gpg_error_t *err,
     291             :                       int *have_source, int *have_code)
     292             : {
     293             :   gpg_err_source_t src;
     294             :   gpg_err_code_t code;
     295             : 
     296           0 :   for (src = 0; src < GPG_ERR_SOURCE_DIM; src++)
     297             :     {
     298           0 :       const char *src_str = gpg_strsource (src << GPG_ERR_SOURCE_SHIFT);
     299           0 :       if (src_str && !strcasecmp (str, src_str))
     300             :         {
     301           0 :           if (*have_source)
     302             :             return 0;
     303             : 
     304           0 :           *have_source = 1;
     305           0 :           *err |= src << GPG_ERR_SOURCE_SHIFT;
     306           0 :           return 1;
     307             :         }
     308             :     }
     309             : 
     310           0 :   for (code = 0; code < GPG_ERR_CODE_DIM; code++)
     311             :     {
     312           0 :       const char *code_str = gpg_strerror (code);
     313           0 :       if (code_str && !strcasecmp (str, code_str))
     314             :         {
     315           0 :           if (*have_code)
     316             :             return 0;
     317             : 
     318           0 :           *have_code = 1;
     319           0 :           *err |= code;
     320           0 :           return 1;
     321             :         }
     322             :     }
     323             : 
     324             :   return 0;
     325             : }
     326             : 
     327             : 
     328             : static int
     329           0 : get_err_from_str (char *str, gpg_error_t *err)
     330             : {
     331             :   char *str2 = str;
     332           0 :   int have_source = 0;
     333           0 :   int have_code = 0;
     334             :   int ret;
     335             :   char *saved_pos = NULL;
     336             :   char saved_char = 0; /* (avoid warning) */
     337             : 
     338           0 :   *err = 0;
     339           0 :   ret = get_err_from_str_one (str, err, &have_source, &have_code);
     340           0 :   if (ret)
     341             :     return ret;
     342             : 
     343           0 :   while (*str2 && ((*str2 >= 'A' && *str2 <= 'Z')
     344           0 :                    || (*str2 >= 'a' && *str2 <= 'z')
     345           0 :                    || (*str2 >= '0' && *str2 <= '9')
     346           0 :                    || *str2 == '_'))
     347           0 :     str2++;
     348           0 :   if (*str2)
     349             :     {
     350             :       saved_pos = str2;
     351             :       saved_char = *str2;
     352           0 :       *((char *) str2) = '\0';
     353           0 :       str2++;
     354           0 :       while (*str2 && !((*str2 >= 'A' && *str2 <= 'Z')
     355           0 :                         || (*str2 >= 'a' && *str2 <= 'z')
     356           0 :                         || (*str2 >= '0' && *str2 <= '9')
     357             :                         || *str2 == '_'))
     358           0 :         str2++;
     359             :     }
     360             :   else
     361             :     str2 = NULL;
     362             : 
     363           0 :   ret = get_err_from_str_one (str, err, &have_source, &have_code);
     364           0 :   if (ret && str2)
     365           0 :     ret = get_err_from_str_one (str2, err, &have_source, &have_code);
     366             : 
     367           0 :   if (saved_pos)
     368           0 :     *saved_pos = saved_char;
     369             :   return ret;
     370             : }
     371             : 
     372             : 
     373             : static void
     374           0 : print_desc (const char *symbol)
     375             : {
     376             :   static int initialized;
     377             :   static FILE *fp;
     378             :   char line[512];
     379             :   char *p;
     380             :   int indesc = 0;
     381             :   int blanklines = 0;
     382             :   int last_was_keyword = 0;
     383             : 
     384           0 :   if (!symbol)
     385           0 :     return;
     386             : 
     387           0 :   if (!initialized)
     388             :     {
     389           0 :       initialized = 1;
     390           0 :       fp = fopen (PKGDATADIR "/errorref.txt", "r");
     391             :     }
     392           0 :   if (!fp)
     393             :     return;
     394           0 :   rewind (fp);
     395           0 :   while (fgets (line, sizeof line, fp))
     396             :     {
     397           0 :       if (*line == '#')
     398           0 :         continue;
     399           0 :       if (*line && line[strlen(line)-1] == '\n')
     400           0 :         line[strlen(line)-1] = 0;
     401             : 
     402           0 :       if (!strncmp (line, "GPG_ERR_", 8))
     403             :         {
     404           0 :           if (indesc == 1 && last_was_keyword)
     405           0 :             continue; /* Skip keywords immediately following a matched
     406             :                        * keyword.  */
     407             :           last_was_keyword = 1;
     408             : 
     409             :           indesc = 0;
     410           0 :           p = strchr (line, ' ');
     411           0 :           if (!p)
     412           0 :             continue;
     413           0 :           *p = 0;
     414           0 :           if (!strcmp (line, symbol))
     415             :             {
     416             :               indesc = 1;
     417           0 :               continue; /* Skip this line.  */
     418             :             }
     419             :         }
     420             :       else
     421             :         last_was_keyword = 0;
     422           0 :       if (!indesc)
     423           0 :         continue;
     424           0 :       if (indesc == 1 && !*line)
     425           0 :         continue; /* Skip leading empty lines in a description.  */
     426           0 :       if (indesc == 1)
     427             :         putchar ('\n'); /* One leading empty line.  */
     428             :       indesc = 2;
     429           0 :       if (!*line)
     430             :         {
     431           0 :           blanklines++;
     432           0 :           continue;
     433             :         }
     434           0 :       for (; blanklines; blanklines--)
     435             :         putchar ('\n');
     436           0 :       printf ("%s\n", line);
     437             :     }
     438             :   putchar ('\n'); /* One trailing blank line.  */
     439             : }
     440             : 
     441             : 
     442             : 
     443             : 
     444             : 
     445             : static int
     446           0 : show_usage (const char *name)
     447             : {
     448           0 :   if (name)
     449             :     {
     450           0 :       fprintf (stderr, _("Usage: %s GPG-ERROR [...]\n"),
     451           0 :                strrchr (name,'/')? (strrchr (name, '/')+1): name);
     452           0 :       exit (1);
     453             :     }
     454             : 
     455           0 :   fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout);
     456           0 :   fputs ("Options:\n"
     457             :          "  --version      Print version\n"
     458             :          "  --lib-version  Print library version\n"
     459             :          "  --help         Print this help\n"
     460             :          "  --list         Print all error codes\n"
     461             :          "  --defines      Print all error codes as #define lines\n"
     462             :          "  --desc         Print with error description\n"
     463             :          , stdout);
     464           0 :   exit (0);
     465             : }
     466             : 
     467             : 
     468             : 
     469             : int
     470           0 : main (int argc, char *argv[])
     471             : {
     472           0 :   const char *pgmname = argv[0];
     473             :   int last_argc = -1;
     474             :   int i;
     475             :   int listmode = 0;
     476             :   int desc = 0;
     477             :   const char *source_sym;
     478             :   const char *error_sym;
     479             :   gpg_error_t err;
     480             : 
     481           0 :   gpgrt_init ();
     482           0 :   i18n_init ();
     483             : 
     484             : 
     485           0 :   if (argc)
     486             :     {
     487           0 :       argc--; argv++;
     488             :     }
     489           0 :   while (argc && last_argc != argc )
     490             :     {
     491             :       last_argc = argc;
     492           0 :       if (!strcmp (*argv, "--"))
     493             :         {
     494           0 :           argc--; argv++;
     495           0 :           break;
     496             :         }
     497           0 :       else if (!strcmp (*argv, "--version"))
     498             :         {
     499           0 :           fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout);
     500           0 :           exit (0);
     501             :         }
     502           0 :       else if (!strcmp (*argv, "--help"))
     503             :         {
     504           0 :           show_usage (NULL);
     505             :         }
     506           0 :       else if (!strcmp (*argv, "--lib-version"))
     507             :         {
     508             :           argc--; argv++;
     509           0 :           printf ("Version from header: %s (0x%06x)\n",
     510             :                   GPG_ERROR_VERSION, GPG_ERROR_VERSION_NUMBER);
     511           0 :           printf ("Version from binary: %s\n", gpg_error_check_version (NULL));
     512           0 :           printf ("Copyright blurb ...:%s\n",
     513             :                   gpg_error_check_version ("\x01\x01"));
     514           0 :           exit (0);
     515             :         }
     516           0 :       else if (!strcmp (*argv, "--list"))
     517             :         {
     518             :           listmode = 1;
     519           0 :           argc--; argv++;
     520             :         }
     521           0 :       else if (!strcmp (*argv, "--defines"))
     522             :         {
     523             :           listmode = 2;
     524           0 :           argc--; argv++;
     525             :         }
     526           0 :       else if (!strcmp (*argv, "--desc"))
     527             :         {
     528             :           desc = 1;
     529           0 :           argc--; argv++;
     530             :         }
     531           0 :       else if (!strncmp (*argv, "--", 2))
     532           0 :         show_usage (pgmname);
     533             :     }
     534             : 
     535           0 :   if ((argc && listmode) || (!argc && !listmode))
     536           0 :     show_usage (pgmname);
     537             : 
     538             : 
     539           0 :   if (listmode == 1)
     540             :     {
     541           0 :       for (i=0; i <  GPG_ERR_SOURCE_DIM; i++)
     542             :         {
     543             :           /* We use error code 1 because gpg_err_make requires a
     544             :              non-zero error code. */
     545           0 :           err = gpg_err_make (i, 1);
     546           0 :           err -= 1;
     547           0 :           source_sym = gpg_strsource_sym (err);
     548           0 :           if (source_sym)
     549             :             {
     550           0 :               printf ("%u = (%u, -) = (%s, -) = (%s, -)\n",
     551             :                       err, gpg_err_source (err),
     552             :                       source_sym, gpg_strsource (err));
     553           0 :               if (desc)
     554           0 :                 print_desc (source_sym);
     555             :             }
     556             :         }
     557           0 :       for (i=0; i <  GPG_ERR_CODE_DIM; i++)
     558             :         {
     559           0 :           err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
     560           0 :           error_sym = gpg_strerror_sym (err);
     561           0 :           if (error_sym)
     562             :             {
     563           0 :               printf ("%u = (-, %u) = (-, %s) = (-, %s)\n",
     564             :                       err, gpg_err_code (err),
     565             :                       error_sym, gpg_strerror (err));
     566           0 :               if (desc)
     567           0 :                 print_desc (error_sym);
     568             :             }
     569             :         }
     570             :     }
     571           0 :   else if (listmode == 2)
     572             :     {
     573             :       int n, nmax;
     574             : 
     575           0 :       for (i=0, nmax=0; i <  GPG_ERR_SOURCE_DIM; i++)
     576             :         {
     577           0 :           err = gpg_err_make (i, 1);
     578           0 :           source_sym = gpg_strsource_sym (err);
     579           0 :           if (source_sym)
     580             :             {
     581           0 :               n = strlen (source_sym);
     582           0 :               if (n > nmax)
     583             :                 nmax = n;
     584             :             }
     585             :         }
     586           0 :       for (i=0; i <  GPG_ERR_SOURCE_DIM; i++)
     587             :         {
     588           0 :           err = gpg_err_make (i, 1);
     589           0 :           source_sym = gpg_strsource_sym (err);
     590           0 :           if (source_sym)
     591           0 :             printf ("#define %-*s %3u\n", nmax,source_sym,gpg_err_source (err));
     592             :         }
     593             : 
     594             : 
     595           0 :       for (i=0, nmax = 0; i <  GPG_ERR_CODE_DIM; i++)
     596             :         {
     597           0 :           err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
     598           0 :           error_sym = gpg_strerror_sym (err);
     599           0 :           if (error_sym)
     600             :             {
     601           0 :               n = strlen (error_sym);
     602           0 :               if (n > nmax)
     603             :                 nmax = n;
     604             :             }
     605             :         }
     606           0 :       for (i=0; i <  GPG_ERR_CODE_DIM; i++)
     607             :         {
     608           0 :           err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
     609           0 :           error_sym = gpg_strerror_sym (err);
     610           0 :           if (error_sym)
     611           0 :             printf ("#define %-*s %5u\n", nmax, error_sym, gpg_err_code (err));
     612             :         }
     613             :     }
     614             :   else /* Standard mode.  */
     615             :     {
     616           0 :       for (i=0; i < argc; i++)
     617             :         {
     618           0 :           if (get_err_from_number (argv[i], &err)
     619           0 :               || get_err_from_symbol (argv[i], &err)
     620           0 :               || get_err_from_str (argv[i], &err))
     621             :             {
     622           0 :               source_sym = gpg_strsource_sym (err);
     623           0 :               error_sym = gpg_strerror_sym (err);
     624             : 
     625           0 :               printf ("%u = (%u, %u) = (%s, %s) = (%s, %s)\n",
     626             :                       err, gpg_err_source (err), gpg_err_code (err),
     627             :                       source_sym ? source_sym : "-", error_sym ? error_sym:"-",
     628             :                       gpg_strsource (err), gpg_strerror (err));
     629           0 :               if (desc)
     630           0 :                 print_desc (error_sym);
     631             :             }
     632             :           else
     633           0 :             fprintf (stderr, _("%s: warning: could not recognize %s\n"),
     634             :                      argv[0], argv[i]);
     635             :         }
     636             :     }
     637             : 
     638           0 :   exit (0);
     639             : }

Generated by: LCOV version 1.12