/[winpt]/trunk/Src/wptGPG.cpp
ViewVC logotype

Diff of /trunk/Src/wptGPG.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 175 by twoaday, Tue Feb 7 08:58:04 2006 UTC revision 301 by twoaday, Wed Mar 21 10:25:48 2007 UTC
# Line 1  Line 1 
1  /* wptGPG.cpp - GnuPG configuration  /* wptGPG.cpp - GnuPG configuration
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2006 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 43  Line 43 
43  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */  #define GPG_REG_EXE     "gpgProgram"    /* registry name for the binary. */
44  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */  #define GPG_REG_HOME    "HomeDir"       /* registry name of the home dir. */
45    
46  struct gpg_watcher_s {  /* Context to monitor GPG file changes. */
47      FILETIME    last_access;  struct gpg_monitor_s {
48        FILETIME    last_access;    /* last write access. */
49      FILETIME    access;      FILETIME    access;
50      char        *object;      char        *object;        /* name of the object. */
51      int         modified;      char        *fpath_object;  /* full path to the object. */
52        int         modified;       /* 1 = modified. */
53  };  };
54    typedef struct gpg_monitor_s *gpg_monitor_t;
55    
56    static const char *gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};
57  /* XXX need to watch for gpg.conf due to the fact keyring entries could be changed */  static gpg_monitor_s gpg_table[3];
 static const char * gpg_objs[] = {"pubring.gpg", "secring.gpg", "trustdb.gpg"};  
 static gpg_watcher_s gpg_table[3];  
58  static int gpg_table_count = DIM (gpg_table);  static int gpg_table_count = DIM (gpg_table);
59    
60  int idea_available = 0;  int idea_available = 0; /* if the IDEA extension is available. */
61    
62    
63  static int check_keyring (char ** r_path);  static int check_keyring (char ** r_path);
64    
# Line 65  static int check_keyring (char ** r_path Line 67  static int check_keyring (char ** r_path
67  char*  char*
68  multi_gnupg_path (int strict)  multi_gnupg_path (int strict)
69  {  {
70      static char buf[256+64];      static char buf[MAX_PATH+64];
71      BOOL ec;      BOOL ec;
72    
73      /* MSDN: buf must be at least MAX_PATH=256 bytes */      /* MSDN: buf must be at least MAX_PATH=256 bytes */
# Line 92  get_gnupg_path (void) Line 94  get_gnupg_path (void)
94      char *path;      char *path;
95    
96      path = get_reg_entry_gpg (GPG_REG_HOME);      path = get_reg_entry_gpg (GPG_REG_HOME);
97      if (path) {      if (path && dir_exist_check (path) == 0)
98          if (dir_exist_check (path) == 0)          return path;
99              return path;      free_if_alloc (path);
100          free_if_alloc (path);      return multi_gnupg_path (1);
     }  
     path = multi_gnupg_path (1);  
     return path;  
101  }  }
102    
103    
# Line 106  get_gnupg_path (void) Line 105  get_gnupg_path (void)
105     A value of NULL indicates an error. */     A value of NULL indicates an error. */
106  char*  char*
107  get_gnupg_cfgfile (void)  get_gnupg_cfgfile (void)
108  {      {
109      char *p = NULL;      char *optfile;
110      char *optfile = NULL;      char *path;
     char *path = NULL;  
     size_t nlen = 0;  
111    
112      path = get_gnupg_path ();      path = get_gnupg_path ();
113      if (!path)      if (!path)
114          return NULL;          return NULL;
115      p = get_reg_entry_gpg ("OptFile");      optfile = make_filename (path, GPG_CONF, NULL);
     if (p) {  
         nlen = strlen (p) + 4;  
         optfile = new char[nlen + 1];  
         if (!optfile)  
             BUG (NULL);  
         _snprintf (optfile, nlen, "%s", p);  
     }  
     else {  
         nlen = strlen (path) + 64;  
         optfile = new char[nlen + 1];  
         if( !optfile)  
             BUG (NULL);  
         _snprintf (optfile, nlen, "%s\\"GPG_CONF, path);  
     }  
116      free_if_alloc (path);      free_if_alloc (path);
117      free_if_alloc (p);  
118      return optfile;      return optfile;
119  }  }
120    
121    
122    static char*
123    get_keyring_from_conf (const char *fname, int pub)
124    {
125        config_file_t opt;
126        conf_option_t e;
127        char *kring = NULL;
128        int rc;
129    
130        rc = parse_config (fname, &opt);
131        if (rc)
132            return NULL;
133        if (pub)
134            e = conf_find_option (opt, "keyring");
135        else
136            e = conf_find_option (opt, "secret-keyring");
137        if (e != NULL)
138            kring = m_strdup (e->val);
139        release_config (opt);
140    
141        return kring;
142    }
143    
144    
145  /* Return the full path of the keyring. If @pub is 1, the public  /* Return the full path of the keyring. If @pub is 1, the public
146     keyring is return, otherwise the secret keyring. */     keyring is return, otherwise the secret keyring. */
147  char*  char*
148  get_gnupg_keyring (int pub, int strict)  get_gnupg_keyring (int pub, int strict)
149  {      {    
150      char *optfile = NULL;      char *optfile;
151      char *path = NULL;      char *path;
152      char *keyring = NULL;      char *keyring;
153    
154      path = get_gnupg_path ();      path = get_gnupg_path ();
155      if (!path)      if (!path)
# Line 157  get_gnupg_keyring (int pub, int strict) Line 163  get_gnupg_keyring (int pub, int strict)
163          free_if_alloc (path);          free_if_alloc (path);
164          return keyring;          return keyring;
165      }      }
166      if (file_exist_check (keyring) || pub && get_file_size (keyring) == 0) {      if (file_exist_check (keyring) ||
167            pub && get_file_size (keyring) == 0) {
168          free_if_alloc (keyring);          free_if_alloc (keyring);
169          optfile = make_filename (path, GPG_CONF, NULL);          optfile = make_filename (path, GPG_CONF, NULL);
170          keyring = get_gnupg_keyring_from_options (optfile, pub);          keyring = get_keyring_from_conf (optfile, pub);
171            free_if_alloc (optfile);
172      }      }
173      free_if_alloc (path);      free_if_alloc (path);
174      free_if_alloc (optfile);      
175      return keyring;      return keyring;
176  }  }
177    
# Line 171  get_gnupg_keyring (int pub, int strict) Line 179  get_gnupg_keyring (int pub, int strict)
179  /* Return the full path (with the gpg exe name). First the registry is scanned  /* Return the full path (with the gpg exe name). First the registry is scanned
180     for the entry 'gpgProgram'. If it wasn't set, the default path is the     for the entry 'gpgProgram'. If it wasn't set, the default path is the
181     appended string 'gpg.exe' is used. */     appended string 'gpg.exe' is used. */
   
 /* FIXME:  Use gpgme's engine info here. */  
182  char*  char*
183  get_gnupg_prog (void)  get_gnupg_prog (void)
184  {      {    
185      char *p;      char *path;
186      char *pgm = NULL;      char *pgm;
187    
188      p = get_reg_entry_gpg (GPG_REG_EXE);      pgm = get_reg_entry_gpg (GPG_REG_EXE);
189      if (!p) {      if (pgm)
190          char *path = get_gnupg_path ();          return pgm;
191          if (!path)      path = get_gnupg_path ();
192              return NULL;      if (!path)
193          pgm = make_filename (path, "gpg", "exe");          return NULL;    
194          free_if_alloc (path);      pgm = make_filename (path, "gpg", "exe");
195      }      free_if_alloc (path);
     else {  
         pgm = m_strdup (p);  
         free_if_alloc (p);  
     }  
196      return pgm;      return pgm;
197  }  }
198    
# Line 198  get_gnupg_prog (void) Line 200  get_gnupg_prog (void)
200  /* Retrieve the first usable secret key from cache.  /* Retrieve the first usable secret key from cache.
201     If no usable was found, @ret_no_useable is 1.     If no usable was found, @ret_no_useable is 1.
202     Return value: the keyid of the secret key. */     Return value: the keyid of the secret key. */
203  static char *  static char*
204  default_key_from_cache (int *ret_no_useable)  default_key_from_cache (int *ret_no_useable)
205  {  {    
206        gpgme_key_t key, pk;
207        gpg_keycache_t sec, pub;
208      const char *s;      const char *s;
209      char *keyid = NULL;      char *keyid = NULL;
     gpgme_key_t key;  
     gpg_keycache_t sec = keycache_get_ctx (0);  
210    
211      if (!sec)      sec = keycache_get_ctx (0);
212          BUG (0);      pub = keycache_get_ctx (1);
213      gpg_keycache_rewind (sec);      gpg_keycache_rewind (sec);
214      while (!gpg_keycache_next_key (sec, 1, &key)) {      while (!gpg_keycache_next_key (sec, 1, &key)) {
215          if (key_is_useable (key)) {          if (key_is_useable (key) && !get_pubkey (key->subkeys->keyid, &pk)) {
216              s = key->subkeys->keyid;              s = key->subkeys->keyid;
217              if (s)                  if (s)
218                  keyid = m_strdup (s+8);                  keyid = m_strdup (s+8);
219              break;              break;
220          }          }
221      }      }
# Line 228  default_key_from_cache (int *ret_no_usea Line 230  default_key_from_cache (int *ret_no_usea
230     Return value: 0 on success. */     Return value: 0 on success. */
231  int  int
232  gnupg_load_config (void)  gnupg_load_config (void)
233  {  {    
234      int rc;      config_file_t opt;
235      gpg_optfile_t opt;      char *conf;
236      gpg_option_t o;      int rc = 0;
237      char *conf = get_gnupg_cfgfile ();      
238        conf = get_gnupg_cfgfile ();
239      if (!conf)      if (!conf)
240          return -1;          return -1;
241      rc = parse_gpg_options (conf, &opt);      if (parse_config (conf, &opt)) {
     if (rc) {  
242          free_if_alloc (conf);          free_if_alloc (conf);
243          return -1;          return -1;
244      }      }
     o = find_option (opt, "ask-cert-level");  
     if (o)  
         reg_prefs.gpg.ask_cert_level = 1;  
     release_gpg_options (opt);  
245      free_if_alloc (conf);      free_if_alloc (conf);
246      return 0;      if (conf_find_option (opt, "ask-cert-level"))
247            reg_prefs.gpg.ask_cert_level = 1;
248        if (conf_find_option (opt, "ask-cert-expire"))
249            reg_prefs.gpg.ask_cert_expire = 1;
250        /* The 'textmode' option for GPG is useful for text files
251           but it breaks the output of any binary data. Thus we return
252           a warning here to inform the user that binary output is broken. */
253        if (conf_find_option (opt, "textmode"))
254            rc = -2;
255        release_config (opt);
256    
257        return rc;
258    }
259    
260    
261    /* handle the case the user added a '!' to force a subkey. */
262    static char*
263    extract_keyid (const char *val)
264    {    
265        size_t len = strlen (val);
266    
267        if (len > 1 && val[len-1] == '!')
268            return substr (val, 0, len-1);
269        return m_strdup (val);
270  }  }
271    
272    
273    /* Return the default key.
274       This can be either a substring or a key ID. */
275  char*  char*
276  get_gnupg_default_key (void)  get_gnupg_default_key (void)
277  {      {    
278      gpg_optfile_t opt = NULL;      config_file_t opt = NULL;
279      gpg_option_t e;      conf_option_t e;
280      char * keyid = NULL, * optfile = NULL;      char *keyid = NULL, *optfile = NULL;
281      int no_usable=0, rc = 0;      int no_usable=0;
282    
283      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
284      if (!optfile)      if (!optfile)
285          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
286      rc = parse_gpg_options (optfile, &opt);      if (parse_config (optfile, &opt)) {
     if (rc) {  
287          free_if_alloc (optfile);          free_if_alloc (optfile);
288          return default_key_from_cache (&no_usable);          return default_key_from_cache (&no_usable);
289      }      }
290      e = find_option( opt, "default-key" );      /* First we search for config entries which specify a default key. */
291      if ( e )      e = conf_find_option (opt, "default-key");
292          keyid = m_strdup( e->val );      if (!e)
293      if( !e ) {          e = conf_find_option (opt, "local-user");
294          e = find_option( opt, "local-user" );      if (e)
295          if( e )          keyid = extract_keyid (e->val);
296              keyid = m_strdup( e->val );  
     }  
     if( !e ) {  
         e = find_option( opt, "encrypt-to" );  
         if( e )  
             keyid = m_strdup( e->val );  
     }  
297      free_if_alloc (optfile);      free_if_alloc (optfile);
298      release_gpg_options (opt);      release_config (opt);
299    
300        /* If no entry in the config has been found, we get a key
301           from the key cache. */
302      if (!keyid)      if (!keyid)
303          keyid = default_key_from_cache (&no_usable);          keyid = default_key_from_cache (&no_usable);
304      return keyid;      return keyid;
305  } /* get_gnupg_default_key */  }
306    
307    
308  /* Check if GPG4WIN is available and if so, use the  /* Check if GPG4WIN is available and if so, use the
# Line 327  parse_version_nr (const char *buf, int * Line 345  parse_version_nr (const char *buf, int *
345      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
346          tmp[i++] = *buf++;          tmp[i++] = *buf++;
347      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
348      *major = atol( tmp );      *major = atoi (tmp);
349      i=0;      i=0;
350      while (buf && *buf != '.' && i < 8)      while (buf && *buf != '.' && i < 8)
351          tmp[i++] = *buf++;          tmp[i++] = *buf++;
352      tmp[i] = 0; buf++;      tmp[i] = 0; buf++;
353      *minor = atol (tmp);      *minor = atoi (tmp);
354      i=0;      i=0;
355      while (buf && isdigit (*buf) && i < 8)      while (buf && isdigit (*buf) && i < 8)
356          tmp[i++] = *buf++;          tmp[i++] = *buf++;
357      tmp[i] = 0;      tmp[i] = 0;
358      *patch = atol (tmp);      *patch = atoi (tmp);
359      return 0;      return 0;
360  }  }
361    
# Line 369  check_gnupg_engine (const char *need_gpg Line 387  check_gnupg_engine (const char *need_gpg
387      }      }
388    
389      /* We need to exec GPG again to find out if IDEA is available. */      /* We need to exec GPG again to find out if IDEA is available. */
390      if (gpg_get_version (&eng))      if (gpg_get_version (&eng)) {
391            gpgme_release (ctx);
392          return -1;          return -1;
393        }
394      if (strstr (eng, "IDEA"))      if (strstr (eng, "IDEA"))
395          idea_available = 1;          idea_available = 1;
396      free (eng);      safe_free (eng);
397      if (parse_version_nr (inf->version, &major, &minor, &patch)) {      if (parse_version_nr (inf->version, &major, &minor, &patch)) {
398          gpgme_release (ctx);          gpgme_release (ctx);
399          return 1;          return 1;
400      }      }
401        gpgme_release (ctx);
402    
403      if (major > need_major)      if (major > need_major)
404          rc = 0;          rc = 0;
# Line 395  check_gnupg_engine (const char *need_gpg Line 416  check_gnupg_engine (const char *need_gpg
416  }  }
417    
418    
419  int  /* Count the keyring entries in the gpg.conf file.
420  check_gnupg_cfgfile (const char *fname, int *r_secrings, int *r_pubrings)     Return value: 0 on success. */
421    static int
422    cfgfile_count_keyrings (const char *fname, int *r_secrings, int *r_pubrings)
423  {  {
424      gpg_optfile_t opt;          config_file_t opt;    
425      gpg_option_t e;      conf_option_t e;
     int rc = 0;  
426    
427      *r_secrings = 0;      *r_secrings = 0;
428      *r_pubrings = 0;      *r_pubrings = 0;
     rc = parse_gpg_options( fname, &opt );  
     if( rc )  
         return WPTERR_FILE_OPEN;  
429    
430      for( e = opt->list; e; e = e->next ) {      if (parse_config (fname, &opt))
431          if( !strcmp( e->name, "secret-keyring" ) ) {          return WPTERR_FILE_OPEN;
432              if( !file_exist_check( e->val ) )      for (e = opt->list; e; e = e->next) {
433            if (!strcmp (e->name, "secret-keyring")) {
434                if (!file_exist_check (e->val))
435                  r_secrings[0]++;                  r_secrings[0]++;
436          }          }
437          else if( !strcmp( e->name, "keyring" ) ) {          else if (!strcmp (e->name, "keyring")) {
438              if( !file_exist_check( e->val ) )              if (!file_exist_check (e->val))
439                  r_pubrings[0]++;                  r_pubrings[0]++;
440          }          }
441      }      }
442      release_gpg_options( opt );      release_config (opt);
443      return 0;      return 0;
444  } /* check_gnupg_cfgfile */  }
445    
446    
447  /* Usually GPG creates the pubring.gpg, secring.gpg on  /* Usually GPG creates the pubring.gpg, secring.gpg on
# Line 430  static void Line 451  static void
451  create_empty_keyring (int _pub)  create_empty_keyring (int _pub)
452  {  {
453      char *name;      char *name;
454      FILE *f;      FILE *fp;
455    
456      name = get_gnupg_keyring (_pub, 0);      name = get_gnupg_keyring (_pub, 0);
457      if (file_exist_check (name) != 0) {      if (name && file_exist_check (name) != 0) {
458          f = fopen (name, "ab");          fp = fopen (name, "ab");
459          if (f != NULL)          if (fp != NULL)
460              fclose (f);              fclose (fp);
461      }      }
462      free_if_alloc (name);      free_if_alloc (name);
463  }  }
# Line 469  gnupg_access_files (void) Line 490  gnupg_access_files (void)
490              return WPTERR_GPG_KEYRINGS;              return WPTERR_GPG_KEYRINGS;
491          rc = file_exist_check (optfile);          rc = file_exist_check (optfile);
492          if (!rc && get_file_size (optfile) > 0) {          if (!rc && get_file_size (optfile) > 0) {
493              rc = check_gnupg_cfgfile (optfile, &secrings, &pubrings);              rc = cfgfile_count_keyrings (optfile, &secrings, &pubrings);
494              if (!rc && secrings && pubrings) {              if (!rc && secrings > 0 && pubrings > 0) {
495                  free_if_alloc (optfile);                  free_if_alloc (optfile);
496                  return 0; /* found two keyrings in the option file */                  return 0; /* found two keyrings in the option file */
497              }              }
# Line 490  gnupg_access_files (void) Line 511  gnupg_access_files (void)
511    
512    
513  static int  static int
514  create_gpg_options (void)  create_gpg_conf (void)
515  {  {
516      FILE *fp;      FILE *fp;
517      char *s, *optfile;      char *s, *optfile;
518    
519      s = get_gnupg_path ();      s = get_gnupg_path ();
520      if( s == NULL )      if (!s)
521          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
522      optfile = make_filename (s, GPG_CONF, NULL);      optfile = make_filename (s, GPG_CONF, NULL);
523      fp = fopen (optfile, "wb");      fp = fopen (optfile, "wb");
524      if (fp == NULL) {        if (!fp) {
525          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
526          goto fail;          goto fail;
527      }      }
# Line 511  fail: Line 532  fail:
532      free_if_alloc (s);      free_if_alloc (s);
533      free_if_alloc (optfile);      free_if_alloc (optfile);
534      return 0;      return 0;
535  } /* create_gpg_options */  }
536    
537    
538  /*  /* Return the contents of the options file as a char buf. */
539   * Return the contents of the options file as a char buf.  char*
  */  
 char *  
540  get_gnupg_config (void)  get_gnupg_config (void)
541  {  {
542      FILE * fp;      FILE *fp;
543      char * p = NULL, * optfile = NULL;      char *p = NULL, *optfile = NULL;
544      int fsize, rc = 0;      int fsize;
545                    
546      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
547      if( optfile == NULL )      if (!optfile)
548          return NULL;          return NULL;
549      fsize = get_file_size( optfile );      fsize = get_file_size (optfile);
550      if( !fsize ) {      if (!fsize) {
551          rc = create_gpg_options( );          if (create_gpg_conf ())
         if ( rc )  
552              return NULL;              return NULL;
553          fsize = get_file_size( optfile );          fsize = get_file_size (optfile);
554      }      }
555      if( fsize > 100000 )      if (fsize > 100000)
556          goto leave; /* too large */          goto leave; /* too large */
557      p = new char[fsize+1];      p = new char[fsize+1];
558      if( p == NULL )      if (!p)
559          BUG( NULL );          BUG (NULL);
560      fp = fopen( optfile, "rb" );      fp = fopen( optfile, "rb" );
561      if( fp == NULL ) {      if (!fp) {
562          free_if_alloc( p );          free_if_alloc (p);
563          return NULL;          return NULL;
564      }      }
565      fread( p, 1, fsize, fp );      fread (p, 1, fsize, fp);
566      fclose( fp );      fclose (fp);
567      p[fsize] = '\0';      p[fsize] = '\0';
568      free_if_alloc( optfile );      free_if_alloc (optfile);
569    
570  leave:  leave:
571      return p;      return p;
572  } /* get_gnupg_config */  }
573    
574    
575    /* Set the default key in the gpg.conf.
576       If @key is NULL, the entry will be deleted. */
577  int  int
578  set_gnupg_default_key (const char * key)  set_gnupg_default_key (const char *key)
579  {  {
580      gpg_optfile_t opt;      config_file_t opt;
581      gpg_option_t e;      conf_option_t e;
582      char *optfile = NULL;      char *optfile = NULL;
583      int rc = 0;      int rc = 0;
584    
585      optfile = get_gnupg_cfgfile ();      optfile = get_gnupg_cfgfile ();
586      if (!optfile)      if (!optfile)
587          return -1;          return WPTERR_FILE_OPEN;
588      rc = parse_gpg_options (optfile, &opt);      rc = parse_config (optfile, &opt);
589      if( rc ) {      if (rc) {
590          free_if_alloc (optfile);          free_if_alloc (optfile);
591          return -1;          return WPTERR_GENERAL;
592      }      }
593      e = find_option (opt, "default-key");      e = conf_find_option (opt, "default-key");
594      if (e) {      if (e && !key)
595            e->used = 0;
596        else if (e) {
597          free_if_alloc (e->val);          free_if_alloc (e->val);
598          e->val = m_strdup (key);          e->val = m_strdup (key);
599          e->used = 1;          e->used = 1;
600      }      }
601      else      else if (key)
602          add_entry (opt, ENTRY_MULTI, "default-key", key);          conf_add_entry (opt, ENTRY_MULTI, "default-key", key);
603      rc = commit_gpg_options (optfile, opt);      rc = commit_config (optfile, opt);
604    
605      free_if_alloc (optfile);      free_if_alloc (optfile);
606      release_gpg_options (opt);      release_config (opt);
   
607      return rc;      return rc;
608  } /* set_gnupg_default_key */  }
609    
610    
611  /*  /* Set the contents of the options file. */
  * Set the contents of the options file.  
  */  
612  int  int
613  set_gnupg_options( const char *buf, size_t buflen )  set_gnupg_options (const char *buf, size_t buflen)
614  {  {
615      FILE *fp;        FILE *fp;  
616      char *optfile = NULL;      char *optfile;
617    
618      optfile = get_gnupg_cfgfile( );      optfile = get_gnupg_cfgfile ();
619      if( optfile == NULL )      if (!optfile)
620          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
621    
622      fp = fopen( optfile, "wb" );      fp = fopen (optfile, "wb");
623      if( fp == NULL ) {      if (!fp) {
624          free_if_alloc( optfile );          free_if_alloc (optfile);
625          return WPTERR_FILE_CREAT;          return WPTERR_FILE_CREAT;
626      }      }
627      fwrite( buf, 1, buflen, fp );      fwrite (buf, 1, buflen, fp);
628      fclose( fp );      fclose (fp);
629      free_if_alloc( optfile );      free_if_alloc (optfile);
630      return 0;      return 0;
631  } /* set_gnupg_options */  }
632    
633  /*  
634   * Check if the line contains a valid GPG argument.  /* Check if the parameter for the option @buf is an existing file name.
635   */     Return value: 0 on success. */
636    static int
637    check_arg_file_exist (const char *buf)
638    {
639        const char *s = "load-extension ";
640    
641        /* XXX: this is a bit of a kludge because we just
642                detect errors for 'load-extension'. */
643        if (!strncmp (buf, s, strlen (s)))
644            buf += strlen (s);
645        else
646            return 0;
647        return file_exist_check (buf);
648    }
649    
650    
651    /* Check if the line contains a valid GPG argument. */
652  static int  static int
653  check_line( const char *buf )  check_line (const char *buf)
654  {  {
655      int j, len;      int j, len;
656      int rc = 0;      int rc = 0;
657    
658      if( *buf == '#' || *buf == '\r' || *buf == '\n' )      if (*buf == '#' || *buf == '\r' || *buf == '\n')
659          return 1;          return 1;
660      rc = 0;      for (j = 0; valid_gpg_args[j]; j++) {
661      for ( j = 0; valid_gpg_args[j]; j++ ) {          len = strlen (valid_gpg_args[j]);
662          len = strlen( valid_gpg_args[j] );          if (!strncmp (valid_gpg_args[j], buf, len))
663          if( !strncmp( valid_gpg_args[j], buf, len ) )              rc = 1;
             rc = 1;      
664      }      }
   
665      return rc;      return rc;
666  } /* check_line */  }
667    
668    
669  int  int
670  check_gnupg_options( const char *buf )  check_gnupg_options (const char *buf, int showerr)
671  {  {
672      char line[1024];      char line[1024];
673      int nbytes = 0;      int nbytes = 0, lineno=0;
674      unsigned j;      unsigned j;
675                    
676      for ( j = 0; j<strlen( buf ) && j < sizeof(line); j++ ) {      for  (j = 0; j < strlen (buf) && j < DIM (line); j++) {
677          line[nbytes++] = buf[j];          line[nbytes++] = buf[j];
678          if ( buf[j] == '\n' || j == ( strlen( buf ) - 1 ) ) {          if (buf[j] == '\n' || j == (strlen (buf) - 1)) {
679              line[nbytes] = '\0';              line[nbytes] = '\0';
680              if( !check_line( line ) ) {              lineno++;
681                  msg_box( NULL, line, "options", MB_OK );              if (!check_line (line)) {
682                    if (showerr)
683                        log_box ("GPG Config File", MB_ERR,
684                                 "gpg.conf:%d: invalid keyword '%s'",
685                                 lineno, line);
686                  return 1;                        return 1;      
687              }              }
688                if (check_arg_file_exist (line))
689                    return WPTERR_FILE_EXIST;
690              nbytes = 0;              nbytes = 0;
691          }                }
692      }      }
   
693      return 0;      return 0;
694  } /* check_gnupg_options */  }
695    
696    
697  /* Store the last access of the file inside the watcher @ctx. */  /* Store the last access of the file inside the watcher @ctx. */
698  static int  static int
699  get_last_gnupg_access (gpg_watcher_s *ctx)  get_last_gnupg_access (gpg_monitor_t ctx)
700  {  {
701      HANDLE fd;      HANDLE fd;
     char *path;  
     char *file;  
702    
703      path = get_gnupg_path ();      fd = CreateFile (ctx->fpath_object, GENERIC_READ, FILE_SHARE_READ,
704      file =  make_filename (path, ctx->object, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
705      fd = CreateFile (file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);      if (fd == INVALID_HANDLE_VALUE)
     if (fd == INVALID_HANDLE_VALUE) {  
         free_if_alloc (path);  
         free_if_alloc (file);  
706          return WPTERR_FILE_OPEN;          return WPTERR_FILE_OPEN;
     }  
707      GetFileTime (fd, NULL, NULL, &ctx->access);      GetFileTime (fd, NULL, NULL, &ctx->access);
708      CloseHandle (fd);      CloseHandle (fd);
     free_if_alloc (path);  
     free_if_alloc (file);  
709      return 0;      return 0;
710  }  }
711    
712    
713  /* Check if the file inside watcher @ctx was modified. */  /* Check if the file inside watcher @ctx was modified. */
714  static void  static void
715  check_last_gnupg_access (gpg_watcher_s *ctx)  check_last_gnupg_access (gpg_monitor_t ctx)
716  {                {              
717      ctx->modified = 0;      ctx->modified = 0;
718    
719      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&      if (ctx->last_access.dwHighDateTime != ctx->access.dwHighDateTime &&
720          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)          ctx->last_access.dwLowDateTime != ctx->access.dwLowDateTime)
721          ctx->modified = 1;          ctx->modified = 1;
722        
     /* XXX: find a better way. without it, winpt --keymanager loads  
             the key cache twice. */  
723      if (ctx->last_access.dwLowDateTime == 0)      if (ctx->last_access.dwLowDateTime == 0)
724          ctx->modified = 0;          ctx->modified = 0;
725    
# Line 700  check_last_gnupg_access (gpg_watcher_s * Line 728  check_last_gnupg_access (gpg_watcher_s *
728  }  }
729    
730    
731  /* Init GPG watcher table for all monitored files. */  /* Init GPG monitor table for all monitored files. */
732  void  void
733  init_gnupg_table (void)  init_gnupg_table (void)
734  {        {      
735      char *p;      char *path;
736      int j;      int j;
737    
738        path = get_gnupg_path ();
739      for (j = 0; j < gpg_table_count; j++) {      for (j = 0; j < gpg_table_count; j++) {
740          p = gpg_table[j].object = m_strdup (gpg_objs[j]);          gpg_table[j].object = m_strdup (gpg_objs[j]);
741          if (!p)          gpg_table[j].fpath_object = make_filename (path, gpg_objs[j], NULL);
             BUG (NULL);  
742          memset (&gpg_table[j].access, 0, sizeof (FILETIME));          memset (&gpg_table[j].access, 0, sizeof (FILETIME));
743          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));          memset (&gpg_table[j].last_access, 0, sizeof (FILETIME));
744          gpg_table[j].modified = 0;          gpg_table[j].modified = 0;
745      }      }
746        free_if_alloc (path);
747  }  }
748    
749    
750    /* Release the GPG monitor table. */
751  void  void
752  free_gnupg_table (void)  free_gnupg_table (void)
753  {  {
754      int j;      int j;
755    
756      for (j=0; j < gpg_table_count; j++)      for (j=0; j < gpg_table_count; j++) {
757          free_if_alloc (gpg_table[j].object);          free_if_alloc (gpg_table[j].object);
758            free_if_alloc (gpg_table[j].fpath_object);
759        }
760  }  }
761    
762    
763  /* Return the amount of files modified since the last call. */  /* Return the amount of files modified since the last call. */
764  int  int
765  keyring_check_last_access (void)  keyring_check_last_access (void)
766  {        {
767      int rc, j;      int nfiles;
768        int pos;
769    
770      rc = 0;      nfiles = 0;
771      for (j = 0; j < gpg_table_count; j++) {      for (pos = 0; pos < gpg_table_count; pos++) {
772          get_last_gnupg_access (&gpg_table[j]);          get_last_gnupg_access (&gpg_table[pos]);
773          check_last_gnupg_access (&gpg_table[j]);          check_last_gnupg_access (&gpg_table[pos]);
774          if (gpg_table[j].modified)          if (gpg_table[pos].modified)
775              rc++;                    nfiles++;
776      }      }
777    
778      return rc;      return nfiles;
779  }  }
780    
781    
# Line 765  gnupg_check_file_ext (const char *fname, Line 798  gnupg_check_file_ext (const char *fname,
798              *r_type = PGP_SIG;              *r_type = PGP_SIG;
799          return "SIGNED";          return "SIGNED";
800      }      }
801      else if  (!stricmp (file_ext, ".gpg") || !stricmp (file_ext, ".pgp")) {      else if  (!stricmp (file_ext, ".gpg") ||
802                  !stricmp (file_ext, ".pgp")) {
803          if (r_type)          if (r_type)
804              *r_type = PGP_MESSAGE;              *r_type = PGP_MESSAGE;
805          return "ENCRYPTED";          return "ENCRYPTED";
# Line 774  gnupg_check_file_ext (const char *fname, Line 808  gnupg_check_file_ext (const char *fname,
808  }  }
809    
810    
811  char*  /* Check if the device where file @fname is stored on, is write-protected. */
 get_gnupg_keyring_from_options (const char * fname, int pub)  
 {  
     gpg_optfile_t opt;  
     gpg_option_t e;  
     char * kring = NULL;  
     int rc = 0;  
   
     rc = parse_gpg_options (fname, &opt);  
     if (rc)  
         return NULL;  
     if (pub)  
         e = find_option (opt, "keyring");  
     else  
         e = find_option (opt, "secret-keyring");  
     if (e)  
         kring = m_strdup (e->val);  
     release_gpg_options (opt);  
   
     return kring;  
 }  
   
   
   
 /* XXX: does not work with write-protected floppies */  
812  static int  static int
813  my_access (const char *fname)  check_file_access (const char *fname, int mode)
814  {  {
815      HANDLE hd;      HANDLE hd;
816      hd = CreateFile (fname, GENERIC_WRITE, FILE_SHARE_WRITE,  
817        if (!mode)
818            mode = FILE_SHARE_WRITE;
819        hd = CreateFile (fname, GENERIC_WRITE, mode,
820                       NULL, OPEN_EXISTING, 0, NULL);                       NULL, OPEN_EXISTING, 0, NULL);
821      if (hd == INVALID_HANDLE_VALUE)      if (hd == INVALID_HANDLE_VALUE)
822          return -1;          return -1;
# Line 811  my_access (const char *fname) Line 824  my_access (const char *fname)
824      return 0;      return 0;
825  }  }
826    
827        
828    /* Check the device where the file @fname is stored on, is either
829       write-protected or if the file is already opened by another process
830       exclusively. And as a result, we cannot use the file for output. */
831    int
832    gpg_check_file_permissions (const char *fname, int mode)
833    {
834        int api_mode;
835        
836        switch (mode) {
837        case 0: api_mode = FILE_SHARE_READ; break;
838        case 1: api_mode = FILE_SHARE_WRITE; break;
839        case 2: api_mode = FILE_SHARE_WRITE|FILE_SHARE_READ; break;
840        default: api_mode = FILE_SHARE_READ; break;
841        }
842    
843        return check_file_access (fname, api_mode);
844    }
845    
846    
847  /* Check the file permissions of the public keyring.  /* Check the file permissions of the public keyring.
848     If @showmsg is 1 output a message in case of errors.     If @showmsg is 1 output a message in case of errors.
# Line 824  gpg_check_permissions (int showmsg) Line 856  gpg_check_permissions (int showmsg)
856      int failed = 0, ans=0, attrs=0;      int failed = 0, ans=0, attrs=0;
857    
858      p = get_gnupg_path ();      p = get_gnupg_path ();
859      if (check_keyring (&p) && p) {      if (p && check_keyring (&p)) {
860          name = make_filename (p, "pubring", "gpg");          name = make_filename (p, "pubring", "gpg");
861          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {          if ((attrs=GetFileAttributes (name)) & FILE_ATTRIBUTE_READONLY) {
862              ans = msg_box (NULL,              ans = msg_box (NULL,
# Line 845  gpg_check_permissions (int showmsg) Line 877  gpg_check_permissions (int showmsg)
877                  failed = 1;                  failed = 1;
878              }              }
879          }          }
880          if (my_access (name)) {          if (gpg_check_file_permissions (name, 1)) {
881              if (showmsg)              if (showmsg)
882                  msg_box (NULL,                  msg_box (NULL,
883                  _("You do not have file access to modify the contents of\n"                  _("You do not have file access to modify the contents of\n"
# Line 868  gpg_check_permissions (int showmsg) Line 900  gpg_check_permissions (int showmsg)
900  int  int
901  gnupg_check_homedir (void)  gnupg_check_homedir (void)
902  {        {      
903      char *homedir = NULL;      char *homedir;
904      int val = 0;      int val;
905      int rc = 0;      int rc = 0;
906    
907    #ifdef WINPT_MOBILE
908        return 0;
909    #endif
910    
911      homedir = get_reg_entry_gpg (GPG_REG_HOME);      homedir = get_reg_entry_gpg (GPG_REG_HOME);
912      if (!homedir)      if (!homedir)
913          homedir = multi_gnupg_path (0);          homedir = multi_gnupg_path (0);
# Line 896  gnupg_check_homedir (void) Line 932  gnupg_check_homedir (void)
932  int  int
933  gnupg_copy_keyrings (void)  gnupg_copy_keyrings (void)
934  {  {
935      const char * pring, * sring;      const char *pring, *sring;
936      char * file = NULL, * path = NULL;      char *file = NULL, *path = NULL;
937      int id = 0, rc = 0;      int id = 0, rc = 0;
938      HWND hwnd;      HWND hwnd;
939            
# Line 906  gnupg_copy_keyrings (void) Line 942  gnupg_copy_keyrings (void)
942          return WPTERR_GENERAL;          return WPTERR_GENERAL;
943      hwnd = GetDesktopWindow ();      hwnd = GetDesktopWindow ();
944    
945      pring = get_fileopen_dlg (hwnd, _("Please choose your public keyring"),      pring = get_fileopen_dlg (hwnd, _("Please choose your Public Keyring"),
946                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0",NULL);
947      if (!pring) {      if (!pring) {
948          msg_box (hwnd, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR);          msg_box (hwnd, _("No keyring was chosen. Exit."),
949                     _("WinPT Error"), MB_ERR);
950          free_if_alloc (path);          free_if_alloc (path);
951          return WPTERR_GENERAL;          return WPTERR_GENERAL;
952      }      }
953      file = make_filename (path, "pubring", "gpg");      file = make_filename (path, "pubring", "gpg");
954      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
955          id = msg_box (hwnd, _("Overwrite old public keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old public keyring?"),
956                          "WinPT", MB_INFO|MB_YESNO);
957          if (id == IDNO)          if (id == IDNO)
958              goto fail;              goto fail;
959      }      }
# Line 926  gnupg_copy_keyrings (void) Line 964  gnupg_copy_keyrings (void)
964      }      }
965      free_if_alloc (file);      free_if_alloc (file);
966    
967      sring = get_fileopen_dlg (hwnd, _("Please choose your secret keyring"),      sring = get_fileopen_dlg (hwnd, _("Please choose your Secret Keyring"),
968                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);                                "GPG Keyrings (*.gpg)\0*.gpg\0\0", NULL);
969      if (!sring) {      if (!sring) {
970          msg_box( NULL, _("No keyring was chosen. Exit."), _("WinPT Error"), MB_ERR );          msg_box (NULL, _("No keyring was chosen. Exit."),
971                     _("WinPT Error"), MB_ERR);
972          return WPTERR_GENERAL;          return WPTERR_GENERAL;
973      }      }
974      file = make_filename (path, "secring", "gpg");      file = make_filename (path, "secring", "gpg");
975      if (file_exist_check (file) == 0) {      if (file_exist_check (file) == 0) {
976          id = msg_box (hwnd, _("Overwrite old secret keyring?"), "WinPT", MB_INFO|MB_YESNO);          id = msg_box (hwnd, _("Overwrite old secret keyring?"),
977          if( id == IDNO )                        "WinPT", MB_INFO|MB_YESNO);
978            if (id == IDNO)
979              goto fail;              goto fail;
980      }      }
981      if (!CopyFile (sring, file, FALSE)) {      if (!CopyFile (sring, file, FALSE)) {
982          msg_box( NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);          msg_box (NULL, _("Could not copy file."), _("WinPT Error"), MB_ERR);
983          rc = WPTERR_FILE_READ;          rc = WPTERR_FILE_READ;
984      }      }
985    
# Line 947  fail: Line 987  fail:
987      free_if_alloc (file);      free_if_alloc (file);
988      free_if_alloc (path);      free_if_alloc (path);
989      return rc;      return rc;
990  } /* gnupg_import_keyrings */  }
991    
992    
993  /* Backup the gpg.conf file. */  /* Backup the gpg.conf file. */
994  void  void
995  gnupg_backup_options (void)  gnupg_backup_options (void)
996  {  {
997      char *cfgfile = NULL;      char *cfgfile;
998      char bak[512];      char bak[MAX_PATH+32];
999    
1000      cfgfile = get_gnupg_cfgfile ();      cfgfile = get_gnupg_cfgfile ();
1001      if (!cfgfile)      if (!cfgfile)
# Line 970  static int Line 1010  static int
1010  backup_one_file (const char *srcpath, const char *srcn,  backup_one_file (const char *srcpath, const char *srcn,
1011                   const char *dstpath, const char *dstn)                   const char *dstpath, const char *dstn)
1012  {  {
1013      char * src, * dst;      char *src, *dst;
1014      BOOL rc;      BOOL rc;
1015    
1016      src = make_filename (srcpath, srcn, "gpg");      src = make_filename (srcpath, srcn, "gpg");
     if (!src)  
         BUG (NULL);  
1017      dst = make_filename (dstpath, dstn, "gpg");      dst = make_filename (dstpath, dstn, "gpg");
     if (!dst)  
         BUG (NULL);  
1018      rc = CopyFile (src, dst, FALSE);      rc = CopyFile (src, dst, FALSE);
1019      free_if_alloc (src);      free_if_alloc (src);
1020      free_if_alloc (dst);      free_if_alloc (dst);
1021      if (!rc)      if (!rc) {
     {  
1022          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);          log_box (_("Backup"), MB_ERR, _("Backup keyring \"%s\" failed"), srcn);
1023          return WPTERR_GENERAL;          return WPTERR_GENERAL;
1024      }      }
1025      return 0;      return 0;
1026  } /* backup_one_file */  }
1027    
1028    
1029  /* Figure out first public keyring which is not empty.  /* Figure out first public keyring which is not empty.
# Line 1003  check_keyring (char **r_path) Line 1038  check_keyring (char **r_path)
1038      if (!*r_path)      if (!*r_path)
1039          return 0;          return 0;
1040      p = make_filename (*r_path, "pubring", "gpg");      p = make_filename (*r_path, "pubring", "gpg");
1041      if (!p || get_file_size (p) <= 0)      if (get_file_size (p) <= 0)
1042          return 0;          return 0;
1043    
1044      opt = get_gnupg_cfgfile ();      opt = get_gnupg_cfgfile ();
1045      if (!opt)      if (!opt)
1046          BUG (0);          BUG (0);
1047      name = get_gnupg_keyring_from_options (opt, 1);      name = get_keyring_from_conf (opt, 1);
1048      free_if_alloc (opt);      free_if_alloc (opt);
1049      free_if_alloc (p);      free_if_alloc (p);
1050      if (!name)      if (!name)
# Line 1033  static char* Line 1068  static char*
1068  get_backup_name (const char *templ)  get_backup_name (const char *templ)
1069  {  {
1070      struct tm *tm;      struct tm *tm;
1071        const char *fmt;
1072      char *p;      char *p;
1073      time_t t;      time_t t;
1074    
1075      t = time (NULL);      t = time (NULL);
1076      tm = localtime (&t);      tm = localtime (&t);
1077      p = new char [strlen (templ) + 8 + 1];      fmt = "%s-%d";
1078        p = new char [strlen (templ) + strlen (fmt) + 8 + 1];
1079      if (!p)      if (!p)
1080          BUG (0);          BUG (0);
1081      sprintf (p, "%s-%d", templ, tm->tm_wday % 3);      sprintf (p, fmt, templ, tm->tm_wday % 3);
1082      return p;      return p;
1083  }  }
1084    
1085    
1086  /* Make backups of all keyrings. The public key ring is  /* Make backups of all keyrings. The public key ring is rotated like
1087     rotated like this pubring-%d.gpg. */     this pubring-%d.gpg.
1088       If @auto_backup is false, no action is performed.
1089       @include_secr indicated if the backup includes the secret keyring. */
1090  void  void
1091  gnupg_backup_keyrings (void)  gnupg_backup_keyrings (int auto_backup, int backup_mode, int include_secr)
1092  {  {
1093      char *srcpath = NULL, *dstpath = NULL;      char *srcpath, *dstpath;
1094      char *name=NULL;      char *name;
1095      int rc, bakmode=0;      int rc;
1096    
1097      if (!reg_prefs.auto_backup)      if (!auto_backup)
1098          return;          return;
     bakmode = reg_prefs.backup.mode;  
1099      srcpath = get_gnupg_path ();      srcpath = get_gnupg_path ();
1100      check_keyring (&srcpath);      check_keyring (&srcpath);
1101      if (bakmode == 1) {      if (backup_mode == 1) {
1102          dstpath = multi_gnupg_path (1);          /* If the backup mode uses the home directory the source
1103               and destination folder will be the same. */
1104            dstpath = get_gnupg_path ();
1105          check_keyring (&dstpath);          check_keyring (&dstpath);
1106      }      }
1107      else if (bakmode == 2) {      else if (backup_mode == 2) {
1108          char *tmpfile;          char *tmpfile;
1109          FILE *fp;          FILE *fp;
1110    
1111          dstpath = m_strdup (reg_prefs.backup.path);          dstpath = m_strdup (reg_prefs.backup.path);
         if (!dstpath)  
             BUG (0);  
1112          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");          tmpfile = make_filename (reg_prefs.backup.path, "test", "tmp");
1113          fp = fopen (tmpfile, "wb");          fp = fopen (tmpfile, "wb");
1114          if (!fp)          if (!fp)
1115              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,              rc = log_box (_("Backup"), MB_WARN|MB_RETRYCANCEL,
1116                            _("The backup drive '%s' does not seems to accessable.\n"                            _("The backup drive '%s' does not seems to be accessable.\n"
1117                              "Please insert/check the drive to continue."), dstpath);                              "Please insert/check the drive to continue."), dstpath);
1118          else {          else {
1119              rc = 0;              rc = 0;
1120              fclose (fp);              fclose (fp);
1121              remove (tmpfile);              DeleteFile (tmpfile);
1122          }          }
1123          free_if_alloc (tmpfile);          free_if_alloc (tmpfile);
1124          if (!fp || rc == IDCANCEL)          if (!fp || rc == IDCANCEL) {
1125                free_if_alloc (dstpath);
1126                free_if_alloc (srcpath);
1127              return;              return;
1128            }
1129      }      }
1130      else {      else {
1131          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), bakmode);          log_box (_("Backup"), MB_ERR, _("Invalid backup mode %d"), backup_mode);
1132            free_if_alloc (srcpath);
1133          return;          return;
1134      }      }
1135      name = get_backup_name ("pubring-bak");      name = get_backup_name ("pubring-bak");
1136      rc = backup_one_file (srcpath, "pubring", dstpath, name);      rc = backup_one_file (srcpath, "pubring", dstpath, name);
1137      if (!rc)      if (!rc && include_secr)
1138          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");          rc = backup_one_file (srcpath, "secring", dstpath, "secring-bak");
1139      free_if_alloc (name);      free_if_alloc (name);
1140      free_if_alloc (srcpath);      free_if_alloc (srcpath);
# Line 1100  gnupg_backup_keyrings (void) Line 1142  gnupg_backup_keyrings (void)
1142  }  }
1143    
1144    
 /* Display GPG error from file if possible. */  
 void  
 gnupg_display_error (void)  
 {        
     char tmpath[512], *errstr;  
     size_t size = 0;  
     FILE *fp;  
   
     get_temp_name (tmpath, sizeof (tmpath), "gpg_stderr");  
     size = get_file_size (tmpath);  
     if (file_exist_check (tmpath) || size <= 0)  
         return;  
     fp = fopen( tmpath, "rb" );  
     if (!fp) {  
         msg_box (NULL, _("No GPG error description available."),  
                  _("GPG Error"), MB_INFO);  
         return;  
     }  
     errstr = new char[size+1];  
     if (!errstr)  
         BUG (0);  
     fread (errstr, 1, size, fp);  
     errstr[size] = '\0';  
     fclose (fp);  
     msg_box (NULL, errstr, _("GPG Error"), MB_INFO);  
     free_if_alloc (errstr);  
 }  
   
   
   
1145  /* check that the requested GPG keyring exist and.  /* check that the requested GPG keyring exist and.
1146     Return value: 0 for success. */     Return value: 0 for success. */
1147  int  int

Legend:
Removed from v.175  
changed lines
  Added in v.301

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26