LCOV - code coverage report
Current view: top level - common - init.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 32 33 97.0 %
Date: 2015-11-05 17:10:59 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* init.c - Various initializations
       2             :  *      Copyright (C) 2007 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * This file is free software; you can redistribute it and/or modify
       7             :  * it under the terms of either
       8             :  *
       9             :  *   - the GNU Lesser General Public License as published by the Free
      10             :  *     Software Foundation; either version 3 of the License, or (at
      11             :  *     your option) any later version.
      12             :  *
      13             :  * or
      14             :  *
      15             :  *   - the GNU General Public License as published by the Free
      16             :  *     Software Foundation; either version 2 of the License, or (at
      17             :  *     your option) any later version.
      18             :  *
      19             :  * or both in parallel, as here.
      20             :  *
      21             :  * This file is distributed in the hope that it will be useful,
      22             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24             :  * GNU General Public License for more details.
      25             :  *
      26             :  * You should have received a copy of the GNU General Public License
      27             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      28             :  */
      29             : 
      30             : #include <config.h>
      31             : 
      32             : #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
      33             : #undef HAVE_NPTH
      34             : #undef USE_NPTH
      35             : #endif
      36             : 
      37             : #ifdef HAVE_W32_SYSTEM
      38             : # ifdef HAVE_WINSOCK2_H
      39             : #  include <winsock2.h>
      40             : # endif
      41             : # include <windows.h>
      42             : #endif
      43             : #ifdef HAVE_NPTH
      44             : # include <npth.h>
      45             : #endif
      46             : #ifdef HAVE_W32CE_SYSTEM
      47             : # include <assuan.h> /* For _assuan_w32ce_finish_pipe. */
      48             : #endif
      49             : 
      50             : #include "util.h"
      51             : 
      52             : /* This object is used to register memory cleanup functions.
      53             :    Technically they are not needed but they can avoid frequent
      54             :    questions about un-released memory.  Note that we use the system
      55             :    malloc and not any wrappers.  */
      56             : struct mem_cleanup_item_s;
      57             : typedef struct mem_cleanup_item_s *mem_cleanup_item_t;
      58             : 
      59             : struct mem_cleanup_item_s
      60             : {
      61             :   mem_cleanup_item_t next;
      62             :   void (*func) (void);
      63             : };
      64             : 
      65             : static mem_cleanup_item_t mem_cleanup_list;
      66             : 
      67             : 
      68             : /* The default error source of the application.  This is different
      69             :    from GPG_ERR_SOURCE_DEFAULT in that it does not depend on the
      70             :    source file and thus is usable in code shared by applications.
      71             :    Note that we need to initialize it because otherwise some linkers
      72             :    (OS X at least) won't find the symbol when linking the t-*.c
      73             :    files.  */
      74             : gpg_err_source_t default_errsource = 0;
      75             : 
      76             : 
      77             : #ifdef HAVE_W32CE_SYSTEM
      78             : static void parse_std_file_handles (int *argcp, char ***argvp);
      79             : static void
      80             : sleep_on_exit (void)
      81             : {
      82             :   /* The sshd on CE swallows some of the command output.  Sleeping a
      83             :      while usually helps.  */
      84             :   Sleep (400);
      85             : }
      86             : #endif /*HAVE_W32CE_SYSTEM*/
      87             : 
      88             : 
      89             : static void
      90        1350 : run_mem_cleanup (void)
      91             : {
      92             :   mem_cleanup_item_t next;
      93             : 
      94        3729 :   while (mem_cleanup_list)
      95             :     {
      96        1029 :       next = mem_cleanup_list->next;
      97        1029 :       mem_cleanup_list->func ();
      98        1029 :       free (mem_cleanup_list);
      99        1029 :       mem_cleanup_list = next;
     100             :     }
     101        1350 : }
     102             : 
     103             : 
     104             : void
     105        1030 : register_mem_cleanup_func (void (*func)(void))
     106             : {
     107             :   mem_cleanup_item_t item;
     108             : 
     109        1030 :   item = malloc (sizeof *item);
     110        1030 :   if (item)
     111             :     {
     112        1030 :       item->func = func;
     113        1030 :       item->next = mem_cleanup_list;
     114        1030 :       mem_cleanup_list = item;
     115             :     }
     116        1030 : }
     117             : 
     118             : 
     119             : /* If STRING is not NULL write string to es_stdout or es_stderr.  MODE
     120             :    must be 1 or 2.  If STRING is NULL flush the respective stream.  */
     121             : static int
     122       33205 : writestring_via_estream (int mode, const char *string)
     123             : {
     124       33205 :   if (mode == 1 || mode == 2)
     125             :     {
     126       33205 :       if (string)
     127       33182 :         return es_fputs (string, mode == 1? es_stdout : es_stderr);
     128             :       else
     129          23 :         return es_fflush (mode == 1? es_stdout : es_stderr);
     130             :     }
     131             :   else
     132           0 :     return -1;
     133             : }
     134             : 
     135             : 
     136             : /* This function should be the first called after main.  */
     137             : void
     138        1349 : early_system_init (void)
     139             : {
     140        1349 : }
     141             : 
     142             : 
     143             : /* This function is to be used early at program startup to make sure
     144             :    that some subsystems are initialized.  This is in particular
     145             :    important for W32 to initialize the sockets so that our socket
     146             :    emulation code used directly as well as in libassuan may be used.
     147             :    It should best be called before any I/O is done so that setup
     148             :    required for logging is ready.  ARGCP and ARGVP are the addresses
     149             :    of the parameters given to main.  This function may modify them.
     150             : 
     151             :    This function should be called only via the macro
     152             :    init_common_subsystems.
     153             : 
     154             :    CAUTION: This might be called while running suid(root).  */
     155             : void
     156        1349 : _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
     157             : {
     158             :   /* Store the error source in a global variable. */
     159        1349 :   default_errsource = errsource;
     160             : 
     161        1349 :   atexit (run_mem_cleanup);
     162             : 
     163             :   /* Try to auto set the character set.  */
     164        1349 :   set_native_charset (NULL);
     165             : 
     166             : #ifdef HAVE_W32_SYSTEM
     167             :   /* For W32 we need to initialize the socket layer.  This is because
     168             :      we use recv and send in libassuan as well as at some other
     169             :      places.  */
     170             :   {
     171             :     WSADATA wsadat;
     172             : 
     173             :     WSAStartup (0x202, &wsadat);
     174             :   }
     175             : #endif
     176             : 
     177             : #ifdef HAVE_W32CE_SYSTEM
     178             :   /* Register the sleep exit function before the estream init so that
     179             :      the sleep will be called after the estream registered atexit
     180             :      function which flushes the left open estream streams and in
     181             :      particular es_stdout.  */
     182             :   atexit (sleep_on_exit);
     183             : #endif
     184             : 
     185             :   /* Initialize the Estream library. */
     186        1349 :   gpgrt_init ();
     187        1349 :   gpgrt_set_alloc_func (gcry_realloc);
     188             : #ifdef USE_NPTH
     189           3 :   gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
     190             : #endif
     191             : 
     192             :   /* Special hack for Windows CE: We extract some options from arg
     193             :      to setup the standard handles.  */
     194             : #ifdef HAVE_W32CE_SYSTEM
     195             :   parse_std_file_handles (argcp, argvp);
     196             : #else
     197             :   (void)argcp;
     198             :   (void)argvp;
     199             : #endif
     200             : 
     201             :   /* Access the standard estreams as early as possible.  If we don't
     202             :      do this the original stdio streams may have been closed when
     203             :      _es_get_std_stream is first use and in turn it would connect to
     204             :      the bit bucket.  */
     205             :   {
     206             :     int i;
     207        5396 :     for (i=0; i < 3; i++)
     208        4047 :       (void)_gpgrt_get_std_stream (i);
     209             :   }
     210             : 
     211             :   /* --version et al shall use estream as well.  */
     212        1349 :   argparse_register_outfnc (writestring_via_estream);
     213        1349 : }
     214             : 
     215             : 
     216             : 
     217             : /* WindowsCE uses a very strange way of handling the standard streams.
     218             :    There is a function SetStdioPath to associate a standard stream
     219             :    with a file or a device but what we really want is to use pipes as
     220             :    standard streams.  Despite that we implement pipes using a device,
     221             :    we would have some limitations on the number of open pipes due to
     222             :    the 3 character limit of device file name.  Thus we don't take this
     223             :    path.  Another option would be to install a file system driver with
     224             :    support for pipes; this would allow us to get rid of the device
     225             :    name length limitation.  However, with GnuPG we can get away be
     226             :    redefining the standard streams and passing the handles to be used
     227             :    on the command line.  This has also the advantage that it makes
     228             :    creating a process much easier and does not require the
     229             :    SetStdioPath set and restore game.  The caller needs to pass the
     230             :    rendezvous ids using up to three options:
     231             : 
     232             :      -&S0=<rvid> -&S1=<rvid> -&S2=<rvid>
     233             : 
     234             :    They are all optional but they must be the first arguments on the
     235             :    command line.  Parsing stops as soon as an invalid option is found.
     236             :    These rendezvous ids are then used to finish the pipe creation.*/
     237             : #ifdef HAVE_W32CE_SYSTEM
     238             : static void
     239             : parse_std_file_handles (int *argcp, char ***argvp)
     240             : {
     241             :   int argc = *argcp;
     242             :   char **argv = *argvp;
     243             :   const char *s;
     244             :   assuan_fd_t fd;
     245             :   int i;
     246             :   int fixup = 0;
     247             : 
     248             :   if (!argc)
     249             :     return;
     250             : 
     251             :   for (argc--, argv++; argc; argc--, argv++)
     252             :     {
     253             :       s = *argv;
     254             :       if (*s == '-' && s[1] == '&' && s[2] == 'S'
     255             :           && (s[3] == '0' || s[3] == '1' || s[3] == '2')
     256             :           && s[4] == '='
     257             :           && (strchr ("-01234567890", s[5]) || !strcmp (s+5, "null")))
     258             :         {
     259             :           if (s[5] == 'n')
     260             :             fd = ASSUAN_INVALID_FD;
     261             :           else
     262             :             fd = _assuan_w32ce_finish_pipe (atoi (s+5), s[3] != '0');
     263             :           _es_set_std_fd (s[3] - '0', (int)fd);
     264             :           fixup++;
     265             :         }
     266             :       else
     267             :         break;
     268             :     }
     269             : 
     270             :   if (fixup)
     271             :     {
     272             :       argc = *argcp;
     273             :       argc -= fixup;
     274             :       *argcp = argc;
     275             : 
     276             :       argv = *argvp;
     277             :       for (i=1; i < argc; i++)
     278             :         argv[i] = argv[i + fixup];
     279             :       for (; i < argc + fixup; i++)
     280             :         argv[i] = NULL;
     281             :     }
     282             : 
     283             : 
     284             : }
     285             : #endif /*HAVE_W32CE_SYSTEM*/

Generated by: LCOV version 1.11