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

Diff of /trunk/Src/wptFileManager.cpp

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

revision 36 by werner, Thu Oct 27 15:25:13 2005 UTC revision 244 by twoaday, Mon Jul 3 14:10:21 2006 UTC
# Line 1  Line 1 
1  /* wptFileManager.cpp - File Manager routines  /* wptFileManager.cpp - File Manager routines
2   *      Copyright (C) 2001-2005 Timo Schulz   *      Copyright (C) 2001-2006 Timo Schulz
3   *      Copyright (C) 2005 g10 Code GmbH   *      Copyright (C) 2005 g10 Code GmbH
4   *   *
5   * This file is part of WinPT.   * This file is part of WinPT.
# Line 18  Line 18 
18   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
19   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20   */   */
 /* TODO:  
  *    check_armor_type: we should check the whole file and not only the first line!  
  */  
21    
22  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
23  #include <config.h>  #include <config.h>
24  #endif  #endif
25    
26  #include <sys/types.h>  #include <sys/types.h>
 #include <sys/types.h>  
27  #include <windows.h>  #include <windows.h>
28  #include <commdlg.h>  #include <commdlg.h>
29  #include <io.h>  #include <io.h>
30    #include <stdio.h>
31    
32  #include "../resource.h"  #include "resource.h"
33  #include "wptTypes.h"  #include "wptTypes.h"
34  #include "wptGPG.h"  #include "wptGPG.h"
35  #include "wptAgent.h"  #include "wptAgent.h"
# Line 49  Line 46 
46  #include "wptUTF8.h"  #include "wptUTF8.h"
47  #include "wptRegistry.h"  #include "wptRegistry.h"
48  #include "wptImport.h"  #include "wptImport.h"
49    #include "wptCrypto.h"
50    #include "wptKeyManager.h"
51  #include "openpgp.h"  #include "openpgp.h"
52    
 #define op_begin()  SetCursor (LoadCursor (NULL, IDC_WAIT))  
 #define op_end()    SetCursor (LoadCursor (NULL, IDC_ARROW))  
53    
54  void progress_cleanup (progress_filter_s *pfx);  void progress_cleanup (progress_filter_s *pfx);
55  BOOL CALLBACK file_secdel_confirm_dlg_proc (HWND dlg, UINT msg,  BOOL CALLBACK file_secdel_confirm_dlg_proc (HWND dlg, UINT msg,
# Line 61  BOOL CALLBACK file_secdel_confirm_dlg_pr Line 57  BOOL CALLBACK file_secdel_confirm_dlg_pr
57  char* gpg_keylist_to_pattern (gpgme_key_t *rset, int n);  char* gpg_keylist_to_pattern (gpgme_key_t *rset, int n);
58  gpgme_error_t sym_passphrase_cb (void *hook, const char *hint, const char *pass_inf,  gpgme_error_t sym_passphrase_cb (void *hook, const char *hint, const char *pass_inf,
59                                   int prev_was_bad, int fd);                                   int prev_was_bad, int fd);
60    void verify_show_signature_state (gpgme_signature_t sig);
61    
 /*-- wptFileVerifyDlg.cpp --*/  
 void file_verify_add_state (file_sig_ctx_t c);  
 void file_verify_use_event (void);  
 void file_verify_wait (void);  
62    
63  static const char * mm_files[] = {".mov", ".avi", ".mpg", ".mpeg",  static const char *mm_files[] = {".mov", ".avi", ".mpg", ".mpeg",
64                                    ".mp3", ".wav", ".mid", ".wma",                                    ".mp3", ".wav", ".mid", ".wma",
65                                    ".gif", ".jpg", ".png", ".jpeg", ".dib", 0};                                    ".gif", ".jpg", ".png", ".jpeg", ".dib", 0};
66    
67    
68    /* Add a new file to the model @fm. */
69    static void
70    fm_model_add_file (fm_model_t *fm, fm_model_t file)
71    {
72        fm_model_t m;
73    
74        if (!*fm) {
75            *fm = file;
76            return;
77        }
78        for (m = *fm; m->next; m = m->next)
79            ;
80        m->next = file;
81    }
82    
83    
84    /* Search for a file model based on the name @name. */
85    static fm_model_t
86    fm_model_find_file (fm_model_t fm, const char *name)
87    {
88        fm_model_t m;
89    
90        for (m=fm; m; m=m->next) {
91            if (!stricmp (m->name, name))
92                return m;
93        }
94        return NULL;
95    }
96    
97    
98  /* Check if the drive given by @fname is a floppy disc.  /* Check if the drive given by @fname is a floppy disc.
99     Return value: 1 for success. */     Return value: -1 for success. */
100  static int  static int
101  is_floppy_disc (const char * fname)  is_floppy_disc (const char *fname)
102  {  {
103      char drv[32] = {0};      char drv[32] = {0};    
104        int max = sizeof (drv)-1;
105      int i=0;      int i=0;
106    
107      if (!strstr (fname, ":\\"))      if (!strstr (fname, ":\\"))
108          return 0;          return 0;
109    
110      while (fname && *fname && *fname != '\\')      while (fname && *fname && *fname != '\\' && i < max)
111          drv[i++] = *fname++;          drv[i++] = *fname++;
112      drv[i++] = '\\';      drv[i++] = '\\';
113      drv[i++] = '\0';      drv[i++] = '\0';
# Line 96  is_floppy_disc (const char * fname) Line 120  is_floppy_disc (const char * fname)
120    
121  /* Ask the user to overwrite file @fname.  /* Ask the user to overwrite file @fname.
122     Return value: 0 for cancel. */     Return value: 0 for cancel. */
123  int  static int
124  overwrite_file (const char *fname)  overwrite_file (const char *fname)
125  {  {
126      int id;      int id;
# Line 112  overwrite_file (const char *fname) Line 136  overwrite_file (const char *fname)
136    
137  /* Removes 'critical' attributes from the file @fname.  /* Removes 'critical' attributes from the file @fname.
138     If @force is 1, the user is not asked for permission. */     If @force is 1, the user is not asked for permission. */
139  static void  void
140  remove_crit_file_attrs (const char *fname, int force)  remove_crit_file_attrs (const char *fname, int force)
141  {  {
142      u32 f_attr;      DWORD fattr;
143      int id;      int id = 0;
144    
145      if (file_exist_check (fname))      if (file_exist_check (fname))
146          return; /* Does not exist */          return; /* Does not exist */
147                    
148      f_attr = GetFileAttributes (fname);      fattr = GetFileAttributes (fname);
149      if ((f_attr & FILE_ATTRIBUTE_READONLY) && force)      if ((fattr & FILE_ATTRIBUTE_READONLY) && force)
150          SetFileAttributes (fname, FILE_ATTRIBUTE_NORMAL);          id = IDYES;
151      else if (f_attr & FILE_ATTRIBUTE_READONLY) {      else if (fattr & FILE_ATTRIBUTE_READONLY)
152          id = log_box (_("File Manager"), MB_YESNO,                    id = log_box (_("File Manager"), MB_YESNO,          
153                        _("\"%s\" has read-only attribute.\n"                        _("\"%s\" has read-only attribute.\n"
154                          "Set attribute to normal?"), fname);                          "Set attribute to normal?"), fname);
155          if (id == IDYES)      if (id == IDYES) {
156              SetFileAttributes (fname, FILE_ATTRIBUTE_NORMAL);          if (!SetFileAttributes (fname, FILE_ATTRIBUTE_NORMAL))
157                msg_box (NULL, _("Could not reset file attribute to normal."),
158                         _("File Manager"), MB_ERR);
159      }      }
160  }  }
161    
162    
163  static int inline  /* Return 1 if the given path @fname is a directory, 0 otherwise. */
164    static int
165  is_directory (const char *fname)  is_directory (const char *fname)
166  {      {
167      return GetFileAttributes (fname) & FILE_ATTRIBUTE_DIRECTORY? 1 : 0;      return GetFileAttributes (fname) & FILE_ATTRIBUTE_DIRECTORY? 1 : 0;
168  }  }
169    
170    
171  static int inline  /* Return -1 if the given name @name is a valid GPG extension. */
172    int
173  is_openpgp_ext (const char *name)  is_openpgp_ext (const char *name)
174  {  {
175      if (strstr (name, ".gpg") || strstr (name, ".asc")      if (stristr (name, ".gpg") ||
176          || strstr (name, ".sig") || strstr (name, ".pgp"))          stristr (name, ".asc") ||
177            stristr (name, ".sig") ||
178            stristr (name, ".pgp"))
179          return -1;          return -1;
180      return 0;      return 0;
181  }  }
# Line 177  is_multi_media (const char * name) Line 207  is_multi_media (const char * name)
207      p = strrchr (name, '.');      p = strrchr (name, '.');
208      if (!p)      if (!p)
209          return 0;          return 0;
210      for (i=0; (val = mm_files[i]); i++)      for (i=0; (val = mm_files[i]); i++) {
     {  
211          if (!stricmp (p, val))          if (!stricmp (p, val))
212              return -1;              return -1;
213      }      }
# Line 186  is_multi_media (const char * name) Line 215  is_multi_media (const char * name)
215  }  }
216    
217    
218    /* Return a GPG file extension which depends on the operation
219       mode in @ctx and the sig mode @sigmode. */
220  const char*  const char*
221  file_get_extension (gpgme_ctx_t ctx, gpgme_sig_mode_t sigmode)  file_get_extension (gpgme_ctx_t ctx, gpgme_sig_mode_t sigmode)
222  {  {
# Line 195  file_get_extension (gpgme_ctx_t ctx, gpg Line 226  file_get_extension (gpgme_ctx_t ctx, gpg
226          return ".asc";          return ".asc";
227      if (!use_armor && sigmode == GPGME_SIG_MODE_DETACH)      if (!use_armor && sigmode == GPGME_SIG_MODE_DETACH)
228          return ".sig";          return ".sig";
229      return ".gpg";      return reg_prefs.default_ext == 1? ".pgp" : ".gpg";
230  }  }
231    
232    
233    /* Quote a file to avoid shell problems with spaces in the files. */
234  char*  char*
235  fm_quote_file (const char * name)  fm_quote_file (const char * name)
236  {  {
# Line 213  fm_quote_file (const char * name) Line 245  fm_quote_file (const char * name)
245      _snprintf (p, len, "\"%s\"", name);      _snprintf (p, len, "\"%s\"", name);
246    
247      return p;      return p;
248  } /* fm_quote_file */  }
249    
250    
251    
252  /* Check the armor type of the file @fname and return  /* Check the armor type of the file @fname and return
253     a string representation of it. */     a string representation of it. */
254  static const char *  static const char*
255  fm_check_armor_type (const char *fname, int *r_type)  fm_check_armor_type (const char *fname, int *r_type)
256  {  {
257      FILE * fp;      FILE *fp;
258      char header[768], * p;      char header[768], *p;
259            
260      if (r_type)      if (r_type)
261          *r_type = PGP_NONE;          *r_type = PGP_NONE;
# Line 266  leave: Line 298  leave:
298    
299  /* Extract file type from @fname. If @r_type is valid,  /* Extract file type from @fname. If @r_type is valid,
300     it contains the PGP type on success. */     it contains the PGP type on success. */
301  static const char *  static const char*
302  fm_get_file_type (const char *fname, int *r_type)  fm_get_file_type (const char *fname, int *r_type)
303  {          {        
304      gpg_iobuf_t inp;      gpg_iobuf_t inp;
305      armor_filter_context_t afx;      armor_filter_context_t afx;
306      PACKET * pkt = (PACKET *)calloc (1, sizeof *pkt);      PACKET *pkt;
     int i = 0, rc = 0;  
307      const char *s = NULL;      const char *s = NULL;
308        size_t count = 0, compr = 0;
309        int rc = 0;
310    
311      if (r_type)      if (r_type)
312          *r_type = PGP_NONE;          *r_type = PGP_NONE;
313      if (!fname) {      if (!fname) {
314          safe_free (pkt);          log_debug ("fm_get_file_type: !fname\r\n");
315          return NULL;          return NULL;
316      }      }
317    
# Line 287  fm_get_file_type (const char *fname, int Line 320  fm_get_file_type (const char *fname, int
320    
321      inp = gpg_iobuf_open (fname);      inp = gpg_iobuf_open (fname);
322      if (!inp) {      if (!inp) {
323          const char *s = winpt_strerror (WPTERR_FILE_OPEN);          const char *err = winpt_strerror (WPTERR_FILE_OPEN);
324          log_box( _("File Manager"), MB_ERR, "\"%s\": %s", fname, s );          log_box (_("File Manager"), MB_ERR, "\"%s\": %s", fname, err);
         safe_free( pkt );  
325          return NULL;          return NULL;
326      }      }
327      gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */      gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */
# Line 303  fm_get_file_type (const char *fname, int Line 335  fm_get_file_type (const char *fname, int
335          memset (&afx, 0, sizeof (afx));          memset (&afx, 0, sizeof (afx));
336          gpg_iobuf_push_filter (inp, gpg_armor_filter, &afx);          gpg_iobuf_push_filter (inp, gpg_armor_filter, &afx);
337      }      }
338            pkt = (PACKET *)calloc (1, sizeof *pkt);
339        if (!pkt)
340            BUG (NULL);
341      gpg_init_packet (pkt);      gpg_init_packet (pkt);
342      while (!(rc = gpg_parse_packet (inp, pkt))) {      while (!(rc = gpg_parse_packet (inp, pkt))) {
343          switch (pkt->pkttype) {          switch (pkt->pkttype) {
# Line 329  fm_get_file_type (const char *fname, int Line 363  fm_get_file_type (const char *fname, int
363              s = "SECKEY";   rc = -2;              s = "SECKEY";   rc = -2;
364              if (r_type) *r_type = PGP_SECKEY;              if (r_type) *r_type = PGP_SECKEY;
365              break;              break;
366    
367            case PKT_COMPRESSED:
368                /* If we only find 1 packet and it is compressed,
369                   we assume a compress one-pass signature. */
370                if (count != 0)
371                    break;
372                s = "SIGNED";   rc = -2;
373                compr = 1;
374                break;
375    
376            default:
377                break;
378          }          }
379            count++;
380          gpg_free_packet (pkt);          gpg_free_packet (pkt);
381          gpg_init_packet (pkt);          gpg_init_packet (pkt);
382          if (rc == -2)          if (rc == -2)
# Line 341  fm_get_file_type (const char *fname, int Line 388  fm_get_file_type (const char *fname, int
388          s = fm_check_armor_type (fname, r_type);          s = fm_check_armor_type (fname, r_type);
389      if (!s)      if (!s)
390          s = "UNKNOWN";          s = "UNKNOWN";
391      if (!strcmp (s, "SIGNED")      if (!strcmp (s, "SIGNED") && !compr
392          && strcmp (fm_check_armor_type (fname, r_type), "SIGNED-CLEAR ")) {          && strcmp (fm_check_armor_type (fname, r_type), "SIGNED-CLEAR ")) {
393          if (r_type) *r_type = PGP_SIG;          if (r_type) *r_type = PGP_SIG;
394          s = "SIGNED-DETACH";          s = "SIGNED-DETACH";
# Line 350  fm_get_file_type (const char *fname, int Line 397  fm_get_file_type (const char *fname, int
397  }  }
398    
399    
400  int  /* Build the File Manager dialog context. */
401  fm_build (listview_ctrl_t *lv, HWND ctrl)  void
402    fm_build (fm_info_t *r_fm, HWND ctrl)
403  {  {
404      int i, rc = 0;      int i;
405      listview_ctrl_t c;      fm_info_t fm;
406      struct listview_column_s col[] =      struct listview_column_s col[] = {
     {  
407          {0,  80, (char *)_("Status") },          {0,  80, (char *)_("Status") },
408          {1, 256, (char *)_("Name") },          {1, 256, (char *)_("Name") },
409          {2, 128, (char *)_("Operation") },          {2, 128, (char *)_("Operation") },
410          {0,   0, NULL }          {0,   0, NULL}  
411      };      };
412            
413      rc = listview_new( &c );      fm = new fm_info_s;
414      if( rc )      memset (fm, 0, sizeof *fm);
415          BUG( NULL );      listview_new (&fm->lv, ctrl);
416      c->ctrl = ctrl;      for (i = 0; col[i].width; i++)
417      for ( i = 0; col[i].width; i++ )          listview_add_column (fm->lv, &col[i]);
418          listview_add_column( c, &col[i] );      listview_set_ext_style (fm->lv);
419      listview_set_ext_style( c );      fm->model = NULL; /*init*/
420      if( lv )      *r_fm = fm;
421          *lv = c;  }
     return 0;  
 } /* fm_build */  
422    
423    
424  void  /* Release the file model. */
425  fm_delete( listview_ctrl_t lv )  static void
426    fm_model_release (fm_model_t mod)
427  {  {
428      if( lv ) {      fm_model_t m;
429          listview_release( lv );  
430        while (mod) {
431            m = mod->next;
432            free_if_alloc (mod->name);
433            free_if_alloc (mod->op);
434            free_if_alloc (mod->status);
435            free_if_alloc (mod);
436            mod = m;
437      }      }
438  } /* fm_delete */  }
439    
440    
441    /* Reset the File Manager info context. */
442    void
443    fm_reset (fm_info_t fm)
444    {
445        listview_del_all_items (fm->lv);
446        fm_model_release (fm->model);
447        fm->model = NULL;
448    }
449    
450    
451    /* Release the File Manager dialog context. */
452    void
453    fm_delete (fm_info_t fm)
454    {
455        if (!fm)
456            return;
457        if (fm->menu)
458            DestroyMenu (fm->menu);
459        listview_release (fm->lv);
460        fm_model_release (fm->model);
461        free_if_alloc (fm);  
462    }
463    
464    
465  int  int
466  fm_state_new (fm_state_t * ctx)  fm_state_new (fm_state_t * ctx)
467  {  {
468      gpgme_error_t rc;      fm_state_s *c;
     fm_state_s * c;  
469    
470      c = new fm_state_s;      c = new fm_state_s;
471      if (!c)      if (!c)
472          BUG (0);          BUG (0);
473      memset (c, 0, sizeof * c);      memset (c, 0, sizeof *c);
474      rc = gpgme_new (&c->ctx);      if (gpgme_new (&c->ctx))
     if (rc)  
475          BUG (0);          BUG (0);
     /* XXX rc = gpgme_recipients_new (&c->recp);*/  
     /* XXX gpgme_set_comment (c->ctx, "Generated by WinPT "PGM_VERSION); */  
476      *ctx = c;      *ctx = c;
477      return 0;      return 0;
478  } /* fm_state_new */  }
479    
480    
481  /* Release the FM state handle @c. */  /* Release the FM state handle @c. */
# Line 411  fm_state_release (fm_state_t c) Line 484  fm_state_release (fm_state_t c)
484  {  {
485      if (!c)      if (!c)
486          return;          return;
     if (c->recp)  
         free (c->recp);  
487      if (c->ctx) {      if (c->ctx) {
488          gpgme_release (c->ctx);          gpgme_release (c->ctx);
489          c->ctx = NULL;            c->ctx = NULL;  
490      }      }
491        safe_free (c->recp);
492      free_if_alloc (c->opaque);      free_if_alloc (c->opaque);
493      free_if_alloc (c->output);      free_if_alloc (c->output);
494      delete c; c = NULL;          delete c;
495  }  }
496    
497    
498    /* Check if file @file is already in the list (view). */
499  static int  static int
500  fm_check_for_entry( listview_ctrl_t lv, const char *file )  fm_check_for_entry (listview_ctrl_t lv, const char *file)
501  {  {
502      char name[512];      char name[MAX_PATH+128];
503      int i;      int i;
504    
505      memset (name, 0, sizeof (name));      memset (name, 0, sizeof (name));
506      for( i = 0; i < listview_count_items( lv, 0 ); i++ )      for (i = 0; i < listview_count_items (lv, 0); i++) {
507      {          listview_get_item_text (lv, i, FM_COL_NAME, name, sizeof (name) - 1);
508          listview_get_item_text( lv, i, 1, name, sizeof (name) - 1 );          if (!strcmp (name, file))
         if( !strcmp( name, file ) )  
509              return 1; /* found */                    return 1; /* found */      
510      }      }
511    
512      return 0;      return 0;
513  } /* fm_check_for_entry */  }
514    
515    
516  static int  static int
517  fm_set_ftype (listview_ctrl_t lv, const char *name)  fm_set_ftype (listview_ctrl_t lv, fm_model_t *fm, const char *name)
518  {  {
519        fm_model_t m;
520      const char *type;      const char *type;
521      int rc;      int rc;
522    
523      rc = fm_check_for_entry (lv, name);      rc = fm_check_for_entry (lv, name);
524      if (rc)      if (rc)
525          return 0;          return 0;
526        m = new fm_model_s;
527        memset (m, 0, sizeof *m);
528      type = fm_get_file_type (name, NULL);      type = fm_get_file_type (name, NULL);
529      if (!type || !strcmp (type, "UNKNOWN"))      if (!type || !strcmp (type, "UNKNOWN"))
530          type = gnupg_check_file_ext (name, NULL);          type = gnupg_check_file_ext (name, NULL);
531      rc = listview_add_item (lv, " ");      listview_add_item2 (lv, " ", (void*)m);
532      if (rc)      listview_add_sub_item (lv, 0, FM_COL_STAT, type);
533          return -1;      listview_add_sub_item (lv, 0, FM_COL_NAME, name);
534      listview_add_sub_item (lv, 0, 0, type);      m->name = m_strdup (name);
535      listview_add_sub_item (lv, 0, 1, name);      m->status = m_strdup (type);
536        m->op = NULL;
537        fm_model_add_file (fm, m);
538      return 0;      return 0;
539  }  }
540    
541    
542    /* Add all files from the directory @path to the list view @lv. */
543  static int  static int
544  fm_add_dir_files (listview_ctrl_t lv, char *path)  fm_add_dir_files (listview_ctrl_t lv, fm_model_t *fm, char *path)
545  {  {
546      struct _finddata_t fd;      struct _finddata_t fd;
547      char * p;      char *p;
548      long hd;      long hd;
549    
550      strcat (path, "\\*");      strcat (path, "\\*");
551      hd = _findfirst (path, &fd);      hd = _findfirst (path, &fd);
552      do {      do {
553          p = new char [(strlen (path) + strlen (fd.name))+1];          p = new char [strlen (path) + strlen (fd.name)+1];
554          if (!p)          if (!p)
555              BUG (0);              BUG (0);
556          memcpy (p, path, strlen (path)-1);          memcpy (p, path, strlen (path)-1);
557          p[strlen (path)-1] = 0;          p[strlen (path)-1] = 0;
558          strcat (p, fd.name);          strcat (p, fd.name);
559          if (!is_directory (p))          if (!is_directory (p))
560              fm_set_ftype (lv, p);              fm_set_ftype (lv, fm, p);
561          free_if_alloc (p);          free_if_alloc (p);
           
562      } while (_findnext (hd, &fd) == 0);      } while (_findnext (hd, &fd) == 0);
563      _findclose (hd);      _findclose (hd);
564      return 0;      return 0;
# Line 490  fm_add_dir_files (listview_ctrl_t lv, ch Line 568  fm_add_dir_files (listview_ctrl_t lv, ch
568  /* Add the drag & drop files from @dd_files to the  /* Add the drag & drop files from @dd_files to the
569     list view control @lv. */     list view control @lv. */
570  int  int
571  fm_add_dropped_files (listview_ctrl_t lv, HDROP dd_files)  fm_add_dropped_files (fm_info_t fm, HDROP dd_files)
572  {  {
573      char name[384+4];      char name[384+4];
574      int nfiles, rc, i;      int nfiles;
575        int rc = 0;
576        int i;
577            
578      memset (name, 0, sizeof (name));      memset (name, 0, sizeof (name));
579      nfiles = DragQueryFile (dd_files, 0xFFFFFFFF, NULL, 0);      nfiles = DragQueryFile (dd_files, 0xFFFFFFFF, NULL, 0);
580      for (i = 0;  i < nfiles; i++) {      for (i = 0;  i < nfiles; i++) {
581          DragQueryFile (dd_files, i, name, sizeof (name) -1);          DragQueryFile (dd_files, i, name, sizeof (name) -1);
582          if (is_directory (name))          if (is_directory (name))
583              rc = fm_add_dir_files (lv, name);              rc = fm_add_dir_files (fm->lv, &fm->model, name);
584          else          else
585              rc = fm_set_ftype (lv, name);              rc = fm_set_ftype (fm->lv, &fm->model, name);
586          if (rc == -1)          if (rc == -1)
587              break;              break; /* XXX: fixme? */
588      }      }
589        DragFinish (dd_files);
590        return rc;
591    }
592    
593    
594    /* Add a single file @name to the list view and before
595       figure out the type of it.
596       Return value: 0 on success. */
597    static int
598    add_single_file (listview_ctrl_t lv, fm_model_t *fm, const char *name)
599    {
600        fm_model_t m;
601        const char *type;
602        int rc = 0;
603        
604        type = fm_get_file_type (name, NULL);
605        if (!type)
606            return WPTERR_FILE_OPEN;
607        m = new fm_model_s;
608        memset (m, 0, sizeof *m);
609        if (!strcmp (type, "UNKNOWN"))      
610            type = gnupg_check_file_ext (name, NULL);
611        rc = listview_add_item2 (lv, "", (void*)m);
612        if (!rc) {
613            listview_add_sub_item (lv, 0, FM_COL_STAT, type);
614            listview_add_sub_item (lv, 0, FM_COL_NAME, name);
615        }
616        m->status = m_strdup (type);
617        m->name = m_strdup (name);
618        m->op = NULL;
619        fm_model_add_file (fm, m);
620      return rc;      return rc;
621  }  }
622    
623    
624    /* Use the common Open-File-Dialog to allow the user to
625       add one ore more selected files to the listview @lv. */
626  int  int
627  fm_add_opened_files (listview_ctrl_t lv, HWND dlg)  fm_add_opened_files (fm_info_t fm, HWND dlg)
628  {  {
629      OPENFILENAME open;      OPENFILENAME open;
630      const char *type;        char file[512], name[MAX_PATH+1];
631      char file[512] = "";      char *path = NULL;
632      int rc;      const char *s;
633            int i, len=0, n=0;
634      /* XXX: support to add multiple files. */      int rc=0;
635    
636      memset (&open, 0, sizeof (open));      memset (&open, 0, sizeof (open));
637      open.lStructSize = sizeof (OPENFILENAME);      open.lStructSize = sizeof (OPENFILENAME);
638      open.hInstance = glob_hinst;      open.hInstance = glob_hinst;
639      open.lpstrTitle = _("File Open");      open.lpstrTitle = _("File Open");
640      open.lpstrFilter = _("All Files (*.*)\0*.*\0\0");      open.lpstrFilter = "All Files (*.*)\0*.*\0\0";
641      open.hwndOwner = dlg;      open.hwndOwner = dlg;
642      open.lpstrFile = file;      open.lpstrFile = file;
643      open.nMaxFile = sizeof (file) - 1;      open.nMaxFile = sizeof (file) - 1;
644      open.Flags = 0;      open.Flags = OFN_ALLOWMULTISELECT|OFN_EXPLORER ;
645            
646      if (GetOpenFileName (&open)) {      memset (file, 0, sizeof file);
647          type = fm_get_file_type (open.lpstrFile, NULL);      if (!GetOpenFileName (&open))
648          if (!type)          return 0;
649              return WPTERR_FILE_OPEN;  
650          if (!strcmp (type, "UNKNOWN"))      /* It is possible that multiple files are returned
651              type = gnupg_check_file_ext (open.lpstrFile, NULL);         and then they are separated by \0 chars. */
652          rc = listview_add_item (lv, "");      s = file;
653          if (!rc) {      len = sizeof (file)-1;
654              listview_add_sub_item (lv, 0, 0, type);      for (;;) {
655              listview_add_sub_item (lv, 0, 1, open.lpstrFile);          if (len < 2 || (*s == '\0' && *(s+1) == '\0'))
656          }              break;
657            memset (name, 0, sizeof (name));
658            for (i=0; len > 0; len--, i++) {
659                if (*s == '\0') {
660                    name[i] = *s++;
661                    break;
662                }
663                name[i] = *s++;
664            }
665            if (n == 0)
666                path = m_strdup (name);
667            else {
668                char *p = make_filename (path, name, NULL);
669                rc = add_single_file (fm->lv, &fm->model, p);
670                free_if_alloc (p);
671            }
672            n++;
673      }      }
674            if (n == 1) /* single file selected. */
675            rc = add_single_file (fm->lv, &fm->model, path);
676        free_if_alloc (path);
677      return rc;      return rc;
678  }  }
679    
680    
681  int  int
682  fm_assume_onepass_sig (const char * fname)  fm_assume_onepass_sig (const char *fname)
683  {  {    
     gpgme_data_t dat;  
684      armor_filter_context_t afx;      armor_filter_context_t afx;
685      gpg_iobuf_t fp;      gpg_iobuf_t fp;
686      PACKET * pkt = (PACKET *)calloc (1, sizeof *pkt);      gpgme_data_t dat;
687        PACKET *pkt;
688        char tmpfile[MAX_PATH+1];
689      int check = 0;      int check = 0;
690    
691        pkt = (PACKET *)calloc (1, sizeof *pkt);
692      if (!fname) {      if (!fname) {
693            get_temp_name (tmpfile, sizeof (tmpfile)-1, "gpgme.tmp");
694          gpg_data_new_from_clipboard (&dat, 0);          gpg_data_new_from_clipboard (&dat, 0);
695          gpg_data_release_and_set_file (dat, "gpgme.tmp");          gpg_data_release_and_set_file (dat, tmpfile);
696    
697          fp = gpg_iobuf_open ("gpgme.tmp");          fp = gpg_iobuf_open (tmpfile);
698          if (!fp)          if (!fp)
699              return 0;              return 0;
700          gpg_iobuf_ioctl (fp, 3, 1, NULL);          gpg_iobuf_ioctl (fp, 3, 1, NULL);
# Line 572  fm_assume_onepass_sig (const char * fnam Line 707  fm_assume_onepass_sig (const char * fnam
707              && pkt->pkttype == PKT_COMPRESSED)              && pkt->pkttype == PKT_COMPRESSED)
708              check = 1;                check = 1;  
709          gpg_free_packet (pkt);          gpg_free_packet (pkt);
         safe_free (pkt);  
710          gpg_iobuf_close (fp);          gpg_iobuf_close (fp);
711          unlink ("gpgme.tmp");          DeleteFile (tmpfile);
712      }      }
713      /* XXX: implement it for real files */      /* XXX: implement it for real files */
714        safe_free (pkt);
715      return check;      return check;
716  }  }
717    
# Line 589  fm_get_current_pos (listview_ctrl_t lv) Line 724  fm_get_current_pos (listview_ctrl_t lv)
724      items = listview_count_items (lv, 0);      items = listview_count_items (lv, 0);
725      if (!items)      if (!items)
726          return -1;          return -1;
727      else if (items == 1)      else if (items == 1) {
     {  
728          listview_select_one (lv, 0);          listview_select_one (lv, 0);
729          return 0;          return 0;
730      }      }
731      else if (items > 1)      else if (items > 1) {
     {  
732          i = listview_get_curr_pos (lv);          i = listview_get_curr_pos (lv);
733          if (i == -1)          if (i == -1) {
734          {              msg_box (lv->ctrl, _("Please select a file."),
735              msg_box (lv->ctrl, _("Please select a file."), _("File Manager"), MB_ERR);                       _("File Manager"), MB_ERR);
736              return -1;              return -1;
737          }          }
738          return i;          return i;
739      }      }
740    
741      return -1;      return -1;
742  } /* fm_get_current_pos */  }
743    
744    
745  static int  static int
746  fm_check_detached_sig( listview_ctrl_t lv, int pos )  fm_check_detached_sig (listview_ctrl_t lv, int pos)
747  {  {
748      char type[128];      char type[128];
749    
750      listview_get_item_text( lv, pos, 0, type, 127 );      listview_get_item_text (lv, pos, 0, type, sizeof (type)-1);
751      return !strcmp( type, "SIGNED-DETACH" )? 1 : 0;      return !strcmp (type, "SIGNED-DETACH")? 1 : 0;
752  } /* fm_check_detached_sig */  }
753    
754    
755  int  int
# Line 637  fm_check_file_type (listview_ctrl_t lv, Line 770  fm_check_file_type (listview_ctrl_t lv,
770          break;          break;
771                    
772      case FM_DECRYPT:      case FM_DECRYPT:
773          if (!strcmp (status, "DATA")          if (!strcmp (status, "DATA") ||
774              || !strcmp (status, "ENCRYPTED")              !strcmp (status, "ENCRYPTED") ||
775              || !strcmp (status, "SYMKEYENC")              !strcmp (status, "SYMKEYENC") ||
776              || !strcmp (status, "ARMORED"))              !strcmp (status, "ARMORED"))
777              rc = 1;              rc = 1;
778          break;          break;
779                    
# Line 673  fm_check_file_type (listview_ctrl_t lv, Line 806  fm_check_file_type (listview_ctrl_t lv,
806      }      }
807            
808      return rc;      return rc;
809  } /* fm_check_file_type */  }
810    
811    
812    /* Set the file status of the given command @fm_cmd.
813       @success is 0 on success. */
814  static void  static void
815  fm_set_status (listview_ctrl_t lv, int pos, int fm_cmd, int success,  fm_set_status (listview_ctrl_t lv, int pos, int fm_cmd,
816                 const char * output)                 gpgme_sig_mode_t sigmode, int success, const char *output)
817  {  {
818      char status[128], operat[128];      char status[128], operat[128];
819      int update = 1;      int update = 1;
820      const char *s;      const char *s;
821    
822      if ( fm_cmd == FM_LIST )      if (fm_cmd == FM_LIST)
823          return;          return;
824      success ? s = "SUCCESS" : s = "FAILED";      success ? s = "SUCCESS" : s = "FAILED";
825      strcpy( operat, s );      strcpy (operat, s);
826    
827      switch (fm_cmd) {      switch (fm_cmd) {
828      case FM_ENCRYPT:      case FM_ENCRYPT:
829      case FM_ENCRYPT_DIR:      case FM_ENCRYPT_DIR:
830      case FM_SIGNENCRYPT: strcpy( status, "ENCRYPTED" ); break;      case FM_SIGNENCRYPT: strcpy (status, "ENCRYPTED"); break;
831      case FM_DECRYPT:     strcpy( status, "UNKNOWN" );   break;      case FM_DECRYPT:     strcpy (status, "UNKNOWN");   break;
832      case FM_SIGN:        strcpy( status, "SIGNED" );    break;      case FM_SIGN:
833            if (sigmode == GPGME_SIG_MODE_DETACH)
834                strcpy (status, "SIGNED-DETACH");
835            else if (sigmode == GPGME_SIG_MODE_CLEAR)
836                strcpy (status, "SIGNED-CLEAR");
837            else
838                strcpy (status, "SIGNED");
839            break;
840      case FM_VERIFY:      update = 0;                    break;      case FM_VERIFY:      update = 0;                    break;
841      case FM_SYMENC:      strcpy( status, "SYMKEYENC" ); break;      case FM_SYMENC:      strcpy (status, "SYMKEYENC"); break;
842      case FM_IMPORT:      update = 0;                    break;      case FM_IMPORT:      update = 0;                    break;
843      case FM_WIPE:        strcpy( status, "WIPED" );     break;      case FM_WIPE:        strcpy (status, "WIPED");     break;
844      default:             strcpy( status, "UNKNOWN");    break;      default:             strcpy (status, "UNKNOWN");    break;
845      }      }
846    
847      if (success) {      if (success && update) {
848          if (update) {          listview_add_sub_item (lv, pos, 0, status);
849              listview_add_sub_item (lv, pos, 0, status);          listview_add_sub_item (lv, pos, 1, output);
             listview_add_sub_item (lv, pos, 1, output);  
         }  
850      }      }
851      listview_add_sub_item( lv, pos, 2, operat );      listview_add_sub_item( lv, pos, 2, operat );
852  } /* fm_set_status */  }
853    
854    
855  int  int
856  fm_clearsign_8bit (listview_ctrl_t lv, fm_state_s *ctx)  fm_clearsign_8bit (listview_ctrl_t lv, fm_state_s *ctx)
857  {  {
858      FILE *f;      FILE *f;
859      byte buf[32];      BYTE buf[32];
860      char name[256];      char name[256];
861      int i, n, cnt=0;      int i, n, cnt=0;
862    
863      if (ctx->sigmode != GPGME_SIG_MODE_CLEAR)      if (ctx->sigmode != GPGME_SIG_MODE_CLEAR)
864          return 0;          return 0;
865      listview_get_item_text (lv, -1, 1, name, sizeof (name)-1);      listview_get_item_text (lv, -1, FM_COL_NAME, name, sizeof (name)-1);
866      if (stristr (name, ".TXT"))      if (stristr (name, ".TXT"))
867          return 0;          return 0;
868      f = fopen (name, "rb");      f = fopen (name, "rb");
869      if (!f)      if (!f)
870          return -1; /* should never happen */          return -1; /* should never happen */
871      n = fread (buf, 1, 32, f);      n = fread (buf, 1, 32, f);
872        fclose (f);
873      for (i = 0; i < n; i++) {      for (i = 0; i < n; i++) {
874          if (buf[i] == 0x00 || buf[i] > 170)          if (buf[i] == 0x00 || buf[i] > 170)
875              cnt++;              cnt++;
876      }      }
     fclose (f);  
877      if (!cnt)      if (!cnt)
878          return 0;          return 0;
879      n = -1;      n = -1;
880      i = log_box (_("File Manager"), MB_WARN|MB_YESNO,      i = log_box (_("File Manager"), MB_WARN|MB_YESNO,
881                   _("\"%s\" does not seems to be a text file.\n"                   _("\"%s\" does not seems to be a text file.\n"
882                     "Do you really want to clearsign it?"), name);                     "Do you really want to clearsign it?"), name);
883      if (i == IDYES)      if (i == IDYES)
# Line 745  fm_clearsign_8bit (listview_ctrl_t lv, f Line 885  fm_clearsign_8bit (listview_ctrl_t lv, f
885      return n;      return n;
886  }  }
887    
888    
889  int  int
890  fm_parse_files (listview_ctrl_t lv, HWND dlg, int cmd)  fm_parse_files (listview_ctrl_t lv, HWND dlg, int cmd)
891  {  {
# Line 757  fm_parse_files (listview_ctrl_t lv, HWND Line 898  fm_parse_files (listview_ctrl_t lv, HWND
898            
899      switch (cmd) {      switch (cmd) {
900      case ID_FILEMISC_ENCRYPT: fm_cmd = FM_ENCRYPT; break;      case ID_FILEMISC_ENCRYPT: fm_cmd = FM_ENCRYPT; break;
901        case ID_FILEMISC_ENCRYPT_ZIP:fm_cmd = FM_ENCRYPT_ZIP; break;
902      case ID_FILEMISC_DECRYPT: fm_cmd = FM_DECRYPT; break;      case ID_FILEMISC_DECRYPT: fm_cmd = FM_DECRYPT; break;
903      case ID_FILEMISC_SYMENC:  fm_cmd = FM_SYMENC;  break;      case ID_FILEMISC_SYMENC:  fm_cmd = FM_SYMENC;  break;
904      case ID_FILEMISC_SIGN:    fm_cmd = FM_SIGN;    break;          case ID_FILEMISC_SIGN:    fm_cmd = FM_SIGN;    break;    
# Line 769  fm_parse_files (listview_ctrl_t lv, HWND Line 911  fm_parse_files (listview_ctrl_t lv, HWND
911      }      }
912            
913      if (fm_get_current_pos (lv) == -1)      if (fm_get_current_pos (lv) == -1)
914          return WPTERR_GENERAL;              return WPTERR_GENERAL;
915      rc = fm_state_new (&ctx);      rc = fm_state_new (&ctx);
916      if (rc)      if (rc)
917          BUG (0);          BUG (0);
# Line 790  fm_parse_files (listview_ctrl_t lv, HWND Line 932  fm_parse_files (listview_ctrl_t lv, HWND
932            
933      /* Commands we need before we can perform the main command */      /* Commands we need before we can perform the main command */
934      switch (fm_cmd) {      switch (fm_cmd) {
935        case FM_ENCRYPT_ZIP:
936      case FM_ENCRYPT:      case FM_ENCRYPT:
937      case FM_SIGNENCRYPT:      case FM_SIGNENCRYPT:
938          if (fm_cmd == FM_SIGNENCRYPT)          if (fm_cmd == FM_SIGNENCRYPT)
939              ctx->req_signer = 1;              ctx->req_signer = 1;
940          DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_ENCRYPT, ctx->dlg,          DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_ENCRYPT,
941                          file_encrypt_dlg_proc, (LPARAM)ctx);                          ctx->dlg, file_encrypt_dlg_proc, (LPARAM)ctx);
942          if (ctx->cancel == 1) {          if (ctx->cancel == 1) {
943              rc = WPTERR_GENERAL;              rc = WPTERR_GENERAL;
944              goto leave;              goto leave;
945          }          }
946          break;          break;
# Line 836  fm_parse_files (listview_ctrl_t lv, HWND Line 979  fm_parse_files (listview_ctrl_t lv, HWND
979          memset (&confirm, 0, sizeof confirm);          memset (&confirm, 0, sizeof confirm);
980          confirm.lv_files = lv;          confirm.lv_files = lv;
981          DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILES_SECDEL, ctx->dlg,          DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILES_SECDEL, ctx->dlg,
982                              file_secdel_confirm_dlg_proc, (LPARAM)&confirm);                          file_secdel_confirm_dlg_proc, (LPARAM)&confirm);
983          if (!confirm.yes)          if (!confirm.yes)
984              goto leave;              goto leave;
985      }      }
986        
987      for( i = 0; i < listview_count_items( lv, 0 ); i++ ) {      if (fm_cmd == FM_ENCRYPT_ZIP)
988          if( !listview_get_item_state( lv, i ) )          fm_encrypt_into_zip (ctx, lv);
989    
990        for (i = 0; i < listview_count_items (lv, 0); i++) {
991            if (!listview_get_item_state (lv, i))
992              continue;              continue;
993          listview_get_item_text( lv, i, 1, fname, sizeof (fname) - 1 );          listview_get_item_text (lv, i, 1, fname, sizeof (fname) - 1);
994          if( file_exist_check( fname ) && !is_directory( fname ) ) {          if( file_exist_check (fname) && !is_directory (fname)) {
995              log_box( _("File Manager"), MB_ERR, _("\"%s\" does not exist"), fname );              log_box (_("File Manager"), MB_ERR,
996                         _("\"%s\" does not exist"), fname);
997              continue;              continue;
998          }          }
999          if( is_directory( fname ) )          if (is_directory (fname))
1000              fm_cmd = FM_ENCRYPT_DIR;                      fm_cmd = FM_ENCRYPT_DIR;        
1001          if( !fm_check_file_type( lv, i, fm_cmd ) )          if (!fm_check_file_type (lv, i, fm_cmd))
1002              continue;              continue;
1003          sig_detached = fm_check_detached_sig( lv, i );          sig_detached = fm_check_detached_sig (lv, i);
1004          switch( fm_cmd ) {          switch (fm_cmd) {
1005          case FM_LIST:        rc = fm_list( fname, dlg );       break;          case FM_LIST:        rc = fm_list( fname, dlg );       break;
1006          case FM_WIPE:        rc = fm_wipe( fname );            break;          case FM_WIPE:        rc = fm_wipe( fname );            break;
1007          case FM_ENCRYPT:     rc = fm_encrypt( ctx, fname, 0 ); break;          case FM_ENCRYPT:     rc = fm_encrypt( ctx, fname, 0 ); break;
# Line 862  fm_parse_files (listview_ctrl_t lv, HWND Line 1009  fm_parse_files (listview_ctrl_t lv, HWND
1009          case FM_SIGNENCRYPT: rc = fm_encrypt( ctx, fname, 1 ); break;          case FM_SIGNENCRYPT: rc = fm_encrypt( ctx, fname, 1 ); break;
1010          case FM_DECRYPT:     rc = fm_decrypt( ctx, fname );    break;          case FM_DECRYPT:     rc = fm_decrypt( ctx, fname );    break;
1011          case FM_SIGN:        rc = fm_sign( ctx, fname );       break;          case FM_SIGN:        rc = fm_sign( ctx, fname );       break;
1012          case FM_SYMENC:      rc = fm_sym_encrypt( ctx, fname );break;          case FM_SYMENC:      rc = fm_sym_encrypt (ctx, fname); break;
1013          case FM_VERIFY:      rc = fm_verify (ctx, sig_detached, fname);break;          case FM_VERIFY:      rc = fm_verify (ctx, sig_detached, fname);break;
1014          case FM_IMPORT:          case FM_IMPORT:
1015              free_if_alloc (ctx->opaque);              free_if_alloc (ctx->opaque);
1016              ctx->opaque = m_strdup (fname);              ctx->opaque = m_strdup (fname);
1017              if (!ctx->opaque)              DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
1018                  BUG (0);                              file_import_dlg_proc, (LPARAM)ctx);
             DialogBoxParam( glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,  
                            file_import_dlg_proc, (LPARAM)ctx );  
1019              if (ctx->cancel == 1)              if (ctx->cancel == 1)
1020                  continue;                  continue;
1021              rc = fm_import (ctx, fname);              rc = fm_import (ctx, fname);
1022              break;              break;
1023          }          }
1024          fm_set_status (lv, i, fm_cmd, !rc, ctx->output);          if (ctx->cancel == 1) {
1025                ctx->cancel = 0;
1026                continue;
1027            }
1028            fm_set_status (lv, i, fm_cmd, ctx->sigmode, !rc, ctx->output);
1029          free_if_alloc (ctx->output);          free_if_alloc (ctx->output);
1030          progress_cleanup (&pfx);          progress_cleanup (&pfx);
1031      }      }
1032    
1033      if (fm_cmd == FM_WIPE) {      if (fm_cmd == FM_WIPE) {
1034          secure_unlink_set_cb (NULL, NULL);          secure_unlink_set_cb (NULL, NULL);
1035          progress_cleanup (&pfx2);          progress_cleanup (&pfx2);
# Line 892  fm_parse_files (listview_ctrl_t lv, HWND Line 1042  fm_parse_files (listview_ctrl_t lv, HWND
1042      /* remove wipe files from the list */      /* remove wipe files from the list */
1043      n = listview_count_items (lv, 0);      n = listview_count_items (lv, 0);
1044      while (n--) {      while (n--) {
         char status[128];  
1045          listview_get_item_text (lv, n, 0, status, sizeof (status) - 1);          listview_get_item_text (lv, n, 0, status, sizeof (status) - 1);
1046          if( !strcmp (status, "WIPED"))          if (!strcmp (status, "WIPED"))
1047              listview_del_item (lv, n);              listview_del_item (lv, n);
1048      }      }
1049            
# Line 936  fm_list (const char *name, HWND dlg) Line 1085  fm_list (const char *name, HWND dlg)
1085  static int  static int
1086  ask_filename (fm_state_t c, const char *msg, char **dst)  ask_filename (fm_state_t c, const char *msg, char **dst)
1087  {  {
1088      const char * s;      const char *s;
1089    
1090      s = get_filename_dlg (c->dlg, FILE_SAVE, msg, NULL, NULL);      s = get_filesave_dlg (c->dlg, msg, NULL, NULL);
1091      if (!s)      if (!s)
1092          return WPTERR_GENERAL;          return WPTERR_GENERAL;
1093    
# Line 946  ask_filename (fm_state_t c, const char * Line 1095  ask_filename (fm_state_t c, const char *
1095          free_if_alloc (*dst);          free_if_alloc (*dst);
1096      free_if_alloc (c->output);      free_if_alloc (c->output);
1097      c->output = m_strdup (s);      c->output = m_strdup (s);
     if (!c->output)  
         BUG (0);  
1098      if (dst)      if (dst)
1099          *dst = fm_quote_file (s);          *dst = fm_quote_file (s);
1100      return 0;      return 0;
# Line 962  fm_encrypt (fm_state_t c, const char *na Line 1109  fm_encrypt (fm_state_t c, const char *na
1109      gpgme_ctx_t ctx = c->ctx;      gpgme_ctx_t ctx = c->ctx;
1110      file_data_t in=NULL, out=NULL;      file_data_t in=NULL, out=NULL;
1111      char *keyid = NULL, ext[5];      char *keyid = NULL, ext[5];
1112      int no_compr = 0;      /*int no_compr = 0;*/
1113      int rc = 0;      int rc = 0;
1114    
1115      c->output = new char[strlen (name) + 5 + 1];      c->output = new char[strlen (name) + 5 + 1];
# Line 970  fm_encrypt (fm_state_t c, const char *na Line 1117  fm_encrypt (fm_state_t c, const char *na
1117          BUG (0);          BUG (0);
1118      strcpy (ext, file_get_extension (ctx, c->sigmode));      strcpy (ext, file_get_extension (ctx, c->sigmode));
1119      strcpy (c->output, name);      strcpy (c->output, name);
1120      strcat (c->output, ext);              strcat (c->output, ext);
1121            
1122      if (!overwrite_file (c->output)) {      if (!overwrite_file (c->output)) {
1123          rc = ask_filename (c, _("Enter filename for encrypted file"), NULL);          rc = ask_filename (c, _("Enter Filename for Encrypted File"), NULL);
1124          if (rc)          if (rc)
1125              goto leave;              goto leave;
1126      }      }
1127    
1128      err = gpg_file_data_new (name, 1, &in);      err = gpg_file_data_new (name, F_DATA_READ, &in);
1129      if (err)      if (err)
1130          goto leave;          goto leave;
1131      err = gpg_file_data_new (c->output, 0, &out);      remove_crit_file_attrs (c->output, 0);
1132        err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);
1133      if (err)      if (err)
1134          goto leave;          goto leave;
1135    
# Line 992  fm_encrypt (fm_state_t c, const char *na Line 1140  fm_encrypt (fm_state_t c, const char *na
1140      }      }
1141      */      */
1142            
1143      /* XXX      /* XXX: disable compression for multi-media files.
1144      no_compr = is_multi_media (name);      no_compr = is_multi_media (name);
1145      gpgme_control (ctx, GPGME_CTRL_NO_COMPR, no_compr);      gpgme_control (ctx, GPGME_CTRL_NO_COMPR, no_compr);
1146      */      */
# Line 1011  fm_encrypt (fm_state_t c, const char *na Line 1159  fm_encrypt (fm_state_t c, const char *na
1159              gpgme_signers_add (ctx, key);              gpgme_signers_add (ctx, key);
1160          }          }
1161          else {          else {
1162              gpgme_key_t key = gpgme_signers_enum (ctx, 0);              gpgme_key_t sigkey = gpgme_signers_enum (ctx, 0);
1163              if (key && key->subkeys) {              if (sigkey && sigkey->subkeys) {
1164                  keyid = m_strdup (key->subkeys->keyid);                  keyid = m_strdup (sigkey->subkeys->keyid);
                 if (!keyid)  
                     BUG (NULL);  
1165              }              }
1166          }          }
1167          if (!c->init_cb || !c->cache_cb) {          if (!c->init_cb || !c->cache_cb) {
# Line 1052  fm_encrypt (fm_state_t c, const char *na Line 1198  fm_encrypt (fm_state_t c, const char *na
1198              goto leave;              goto leave;
1199          }          }
1200      }      }
     if (c->wipe)  
         secure_unlink (name, WIPE_MODE_SIMPLE);  
1201            
1202  leave:  leave:
1203      if (in)      if (in)
# Line 1061  leave: Line 1205  leave:
1205      if (out)      if (out)
1206          gpg_file_data_release (out);          gpg_file_data_release (out);
1207      free_if_alloc (keyid);      free_if_alloc (keyid);
1208        if (!rc && c->wipe)
1209            secure_unlink (name, WIPE_MODE_SIMPLE);
1210      return rc;      return rc;
1211  }  }
1212    
# Line 1072  fm_sym_encrypt (fm_state_t c, const char Line 1218  fm_sym_encrypt (fm_state_t c, const char
1218      gpgme_error_t err;          gpgme_error_t err;    
1219      file_data_t in=NULL, out=NULL;      file_data_t in=NULL, out=NULL;
1220      int rc = 0, cancel = 0;      int rc = 0, cancel = 0;
1221      char * src = NULL, * dst = NULL;      char ext[5], *pass;    
     char ext[5], * pass;      
1222            
1223      pass = request_passphrase2 (_("Symmetric"), 0, &cancel);      pass = request_passphrase2 (_("Symmetric Encryption"), 0, &cancel);
1224      if (cancel)      if (cancel) {
1225            c->cancel = 1;
1226          return 0;          return 0;
1227        }
1228            
1229      /* XXX gpgme_control (ctx, GPGME_CTRL_CIPHER, -1);*/      /* XXX: a convenient feature could be to select the preferred
1230                symmetric algorithm. */
1231      c->output = new char[strlen (name) + 5 + 1];      c->output = new char[strlen (name) + 5 + 1];
1232      if (!c->output)      if (!c->output)
1233          BUG (0);          BUG (0);
# Line 1092  fm_sym_encrypt (fm_state_t c, const char Line 1240  fm_sym_encrypt (fm_state_t c, const char
1240          goto leave;              goto leave;    
1241      }      }
1242    
1243      gpgme_set_passphrase_cb (ctx, sym_passphrase_cb, pass);          gpgme_set_passphrase_cb (ctx, sym_passphrase_cb, pass);
   
1244      err = gpg_file_data_new (name, 1, &in);      err = gpg_file_data_new (name, 1, &in);
1245      if (err)      if (err)
1246          goto leave;          goto leave;
# Line 1122  leave: Line 1269  leave:
1269          gpg_file_data_release (out);          gpg_file_data_release (out);
1270      sfree_if_alloc (pass);      sfree_if_alloc (pass);
1271      return rc;      return rc;
 } /* fm_sym_encrypt */  
   
   
 /* Show the human readable verify result from @sigres. */  
 static void  
 show_verify_result (gpgme_verify_result_t sigres)  
 {  
     gpgme_key_t key=NULL;  
     gpgme_signature_t sig=sigres->signatures;  
     const char *s, *keyid;  
     int sigok = 0;  
     int type;  
     char buf[384];  
   
     sig = sigres->signatures;  
     sigok = sig->summary & GPGME_SIGSUM_GREEN;  
     s = sigok? _("Good signature") : _("BAD signature");  
     type = sigok? MB_OK: MB_ICONWARNING|MB_OK;  
     keyid = sig->fpr;    
     if (!keyid)  
         return;  
   
     keyid = strlen (sig->fpr) == 40? sig->fpr+32 : sig->fpr + 24;  
     get_pubkey (sig->fpr, &key);  
     _snprintf (buf, sizeof (buf)-1, "Signature made %s using %s key ID %s\n"  
                                     "%s from \"%s\"",  
                 strtimestamp (sig->timestamp), get_key_pubalgo (sig->pubkey_algo),  
                 keyid, s, key? key->uids->uid : _("user ID not found"));  
     msg_box (NULL, buf, _("Decrypt Verify"), type);  
1272  }  }
1273    
1274    
1275  /* Check the recipients if we have at least one secret key. */  /* Check the recipients if we have at least one secret key. */
1276  bool  bool
1277  secret_key_available (gpgme_recipient_t rset)  is_seckey_available (gpgme_recipient_t rset)
1278  {  {
1279      gpgme_recipient_t r;      gpgme_recipient_t r;
1280      gpgme_key_t key;      winpt_key_s key;
1281    
1282      for (r=rset; r; r = r->next) {            for (r=rset; r; r = r->next) {
1283          if (gpgme_err_code (r->status) == GPG_ERR_NO_SECKEY)          if (gpgme_err_code (r->status) == GPG_ERR_NO_SECKEY)
1284              continue;              continue;
1285          else {          else {
1286                memset (&key, 0, sizeof (key));
1287              /* extra check to make sure the key is available right now. */              /* extra check to make sure the key is available right now. */
1288              if (!get_seckey (r->keyid, &key))              if (!winpt_get_seckey (r->keyid, &key)) {
1289                    winpt_release_pubkey (&key);
1290                  return true;                  return true;
1291                }
1292                winpt_release_pubkey (&key);
1293          }          }
1294      }      }
1295      return false;      return false;
1296  }  }
1297    
1298    
1299    /* If the decrypt result contains the original file name,
1300       we use it instead of the artificial "output - .gpg" string. */
1301    static int
1302    restore_original_name (const char *output, const char *file_name)
1303    {
1304        char *dir;
1305        char *orig;
1306        int rc = 0;
1307    
1308        dir = strrchr (output, '\\');
1309        if (!dir)
1310            orig = strdup (file_name);
1311        else {
1312            orig = (char*)calloc (1, strlen (file_name)+ 1 +
1313                                     strlen (output)+1);
1314            if (!orig)
1315                BUG (0);
1316            memcpy (orig, output, (dir-output)+1);
1317            strcat (orig, file_name);
1318        }
1319        /* XXX: we need to find out if the string needs to be utf8 decoded. */
1320        if (overwrite_file (orig)) {
1321            DeleteFile (orig);
1322            if (!MoveFile (output, orig))
1323                rc = -1;
1324        }
1325        safe_free (orig);
1326        return rc;
1327    }
1328    
1329    
1330  /* Decrypt the file @name. */  /* Decrypt the file @name. */
1331  int  int
1332  fm_decrypt (fm_state_t c, const char *name)  fm_decrypt (fm_state_t c, const char *name)
# Line 1182  fm_decrypt (fm_state_t c, const char *na Line 1335  fm_decrypt (fm_state_t c, const char *na
1335      gpgme_ctx_t ctx = c->ctx;          gpgme_ctx_t ctx = c->ctx;    
1336      gpgme_decrypt_result_t res;      gpgme_decrypt_result_t res;
1337      gpgme_verify_result_t sigres;      gpgme_verify_result_t sigres;
1338      file_data_t in =NULL, out=NULL;      file_data_t in = NULL, out = NULL;
     int is_signed = 0;  
1339      int rc = 0;      int rc = 0;
1340            
1341      if (!c->init_cb || !c->cache_cb) {      if (!c->init_cb || !c->cache_cb) {
1342          set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_DECRYPT,          set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_DECRYPT,
1343                                 c->dlg, _("Decryption"));                                 c->dlg, _("Decryption"));
1344          c->init_cb = 1;          c->init_cb = 1;
1345      }          }
1346            
1347      c->output = m_strdup (name);      c->output = m_strdup (name);
     if (!c->output)  
         BUG (0);  
1348      if (is_openpgp_ext (c->output))      if (is_openpgp_ext (c->output))
1349          c->output[strlen (c->output)-4] = '\0';          c->output[strlen (c->output)-4] = '\0';
1350      else {      else {
1351          const char *s = get_filesave_dlg (c->dlg, _("Choose Filename for Output"),          const char *s;
1352                                            NULL, NULL);          s = get_filesave_dlg (c->dlg, _("Choose Filename for Output"),
1353                                  NULL, NULL);
1354          if (s) {          if (s) {
1355              free_if_alloc (c->output);              free_if_alloc (c->output);
1356              c->output = m_strdup (s);              c->output = m_strdup (s);
             if (!c->output)  
                 BUG (NULL);  
1357          }          }
1358      }      }
1359    
1360      if (overwrite_file (c->output) == 0) {      if (overwrite_file (c->output) == 0) {
1361          rc = ask_filename (c, _("Please enter filename for plaintext file"), NULL);          rc = ask_filename (c, _("Enter Filename for Plaintext File"), NULL);
1362          if (rc)          if (rc)
1363              goto leave;              goto leave;
1364      }          }
1365    
1366      remove_crit_file_attrs (c->output, 0);      /* we fetch all recipients here to make sure they list is complete. */
1367        release_gpg_recipients (&c->pass_cb.recipients);
1368        gpg_get_recipients (name, &c->pass_cb.recipients);
1369    
1370      err = gpg_file_data_new (name, 1, &in);      err = gpg_file_data_new (name, F_DATA_READ, &in);
1371      if (err)      if (err)
1372          goto leave;          goto leave;
1373      err = gpg_file_data_new (c->output, 0, &out);      remove_crit_file_attrs (c->output, 0);
1374        err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);
1375      if (err)      if (err)
1376          goto leave;          goto leave;
1377        
1378      op_begin ();      op_begin ();
1379      err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);      err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);
1380      op_end ();      op_end ();
# Line 1234  fm_decrypt (fm_state_t c, const char *na Line 1386  fm_decrypt (fm_state_t c, const char *na
1386      }      }
1387    
1388      res = gpgme_op_decrypt_result (ctx);      res = gpgme_op_decrypt_result (ctx);
1389      if (res && res->recipients && !secret_key_available (res->recipients)) {      if (res && res->recipients && !is_seckey_available (res->recipients)) {
1390          const char *keyid = res->recipients->keyid;          const char *keyid = res->recipients->keyid;
1391          char *p = get_key_userid (keyid+8);          char *p = get_key_userid (keyid+8);
1392          gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;          gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;
1393                    
1394          log_box( _("Decryption"), MB_ERR,          log_box (_("Decryption"), MB_ERR,
1395                   _("Encrypted with %s key, ID %s.%s\n"                   _("Encrypted with %s key, ID %s.%s\n"
1396                     "Decryption failed: secret key not available."),                     "Decryption failed: secret key not available."),
1397                     get_key_pubalgo (pkalgo), keyid+8, p);                     get_key_pubalgo (pkalgo), keyid+8, p);
# Line 1253  fm_decrypt (fm_state_t c, const char *na Line 1405  fm_decrypt (fm_state_t c, const char *na
1405          goto leave;          goto leave;
1406      }      }
1407      if (file_exist_check (c->output)) {      if (file_exist_check (c->output)) {
1408          log_box ("Decrypt", MB_ERR, _("Decryption failed.\n%s: does not exist."), c->output);          log_box ("Decrypt", MB_ERR,
1409                     _("Decryption failed.\n%s: does not exist."), c->output);
1410          rc = WPTERR_GENERAL;          rc = WPTERR_GENERAL;
1411            goto leave;
1412        }
1413        else if (res && res->file_name) {
1414            char *file;
1415            int id = IDNO;
1416    
1417            file = strrchr (c->output, '\\');
1418            if (!file)
1419                file = c->output;
1420            else
1421                file++;
1422            if (strcmp (res->file_name, file))
1423                id = log_box (_("Decrypt"), MB_QUEST_ASK,
1424                              _("The original file name is '%s'.\n\n"
1425                                "Do you want to use this instead of '%s'?"),
1426                          res->file_name, file);
1427            if (id == IDYES) {
1428                /* before we can move the file, it needs to be closed first. */
1429                gpg_file_data_release (out);
1430                out = NULL;
1431                restore_original_name (c->output, res->file_name);
1432            }
1433      }      }
       
1434      sigres = gpgme_op_verify_result (ctx);      sigres = gpgme_op_verify_result (ctx);
1435      if (sigres && sigres->signatures)      if (sigres && sigres->signatures)
1436          show_verify_result (sigres);          verify_show_signature_state (sigres->signatures);
   
1437            
1438  leave:  leave:
1439      if (in)      if (in)
1440          gpg_file_data_release (in);          gpg_file_data_release (in);
1441      if (out)      if (out)
1442          gpg_file_data_release (out);          gpg_file_data_release (out);
1443    
1444      return rc;      return rc;
1445  }  }
1446    
1447    
1448  int  int
1449  fm_sign (fm_state_t c, const char * name)  fm_sign (fm_state_t c, const char * name)
1450  {        {
     int rc = 0;  
1451      gpgme_ctx_t ctx = c->ctx;      gpgme_ctx_t ctx = c->ctx;
1452      gpgme_error_t err;      gpgme_error_t err;
1453      file_data_t in=NULL, out=NULL;      file_data_t in=NULL, out=NULL;
1454      char ext[5];      char ext[5];
1455        int rc = 0;
1456    
1457      if (!c->init_cb || !c->cache_cb) {      if (!c->init_cb || !c->cache_cb) {
1458          set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_SIGN, c->dlg, _("Signing") );          set_gpg_passphrase_cb (&c->pass_cb, c->ctx,
1459                                   GPG_CMD_SIGN, c->dlg, _("Signing"));
1460          c->init_cb = 1;          c->init_cb = 1;
1461      }      }
1462            
1463      free_if_alloc (c->output);      free_if_alloc (c->output);
1464      c->output = new char[strlen (name) + 5 + 1];      c->output = new char[strlen (name) + 5 + 1];
1465      if( !c->output)      if (!c->output)
1466          BUG( NULL );          BUG (NULL);
1467      strcpy (ext, file_get_extension (ctx, c->sigmode));      strcpy (ext, file_get_extension (ctx, c->sigmode));
1468      strcpy (c->output, name);      strcpy (c->output, name);
1469      strcat (c->output, ext);      strcat (c->output, ext);
1470            
1471      if (!overwrite_file (c->output)) {      if (!overwrite_file (c->output)) {
1472          rc = ask_filename (c, _("Enter filename for signed file"), NULL);          rc = ask_filename (c, _("Enter Filename for Signed File"), NULL);
1473          if (rc)          if (rc)
1474              goto leave;              goto leave;
1475      }      }
1476      remove_crit_file_attrs (c->output, 0);      
1477        err = gpg_file_data_new (name, F_DATA_READ, &in);
     err = gpg_file_data_new (name, 1, &in);  
1478      if (err)      if (err)
1479          goto leave;          goto leave;
1480      err = gpg_file_data_new (c->output, 0, &out);      remove_crit_file_attrs (c->output, 0);
1481        err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);
1482      if (err)      if (err)
1483          goto leave;          goto leave;
1484    
1485      op_begin ();      op_begin ();
1486      err = gpgme_op_sign (ctx, in->dat, out->dat, c->sigmode);      err = gpgme_op_sign (ctx, in->dat, out->dat, c->sigmode);
1487      op_end ();      op_end ();
1488      if( !c->cache_cb )      if (!c->cache_cb)
1489          release_gpg_passphrase_cb (&c->pass_cb);          release_gpg_passphrase_cb (&c->pass_cb);
1490      if( c->pass_cb.cancel ) {      if (c->pass_cb.cancel) {
1491          rc = WPTERR_GENERAL;          rc = WPTERR_GENERAL;
1492          goto leave;          goto leave;
1493      }      }
1494      if( err ) {      if (err) {
1495          msg_box( c->dlg, gpgme_strerror( err ), _("Sign"), MB_ERR );          msg_box (c->dlg, gpgme_strerror (err), _("Sign"), MB_ERR);
1496          rc = WPTERR_GENERAL;          rc = WPTERR_GENERAL;
1497          goto leave;              goto leave;    
1498      }      }
# Line 1331  leave: Line 1506  leave:
1506  }  }
1507    
1508    
1509  static int  static void
1510  fm_add_sig_stat (file_sig_ctx_t log)  fm_add_sig_stat (file_sig_ctx_t log)
1511  {  {
1512      gpgme_key_t key;          struct winpt_key_s key;
1513      const char *kid;      const char *kid;
     int not_found = 0;  
1514    
1515      kid = log->sig->fpr;      memset (&key, 0, sizeof (key));
1516      if (!kid)      kid = get_keyid_from_fpr (log->sig->fpr);
1517          BUG (NULL);      log->use_uid = 0;
1518      if (strlen (kid) == 40)      if (!winpt_get_pubkey (kid, &key)) {
1519          kid += 32;                log->user_id = key.ext->uids->uid;
     else if (strlen (kid) == 32)  
         kid += 24;  
     if (get_pubkey (kid, &key))  
         log->use_uid = 0;  
     else {  
         log->user_id = key->uids->uid;  
1520          log->use_uid = 1;          log->use_uid = 1;
1521      }      }
1522        winpt_release_pubkey (&key);
1523      file_verify_add_state (log);      file_verify_add_state (log);
     return 0;  
1524  }  }
1525    
1526    
1527    /* Verify a detached signature from the clipboard. */  
1528  static int  static int
1529  verify_pasted (listview_ctrl_t lv, fm_state_t ctx, const char * dat,  verify_pasted (listview_ctrl_t lv, fm_state_t ctx,
1530                 int i, HWND dlg)                 const char *dat, int pos, HWND dlg)
1531  {  {
1532      FILE * fp;      FILE *fp;
1533      char stat[32];      char stat[32];
1534      char file[256], * fname = NULL;      char file[256], *fname = NULL;
1535      int del_end=0;      int del_end = 0;
1536    
1537      listview_get_item_text (lv, i, 0, stat, sizeof (stat)-1);      listview_get_item_text (lv, pos, FM_COL_STAT, stat, sizeof (stat)-1);
1538      listview_get_item_text (lv, i, 1, file, sizeof (file)-1);      listview_get_item_text (lv, pos, FM_COL_NAME, file, sizeof (file)-1);
1539      if (strcmp (stat, "UNKNOWN"))      if (strcmp (stat, "UNKNOWN"))
1540          return 0;          return 0;
1541      fname = make_filename (NULL, file, "asc");      fname = make_filename (NULL, file, "asc");
1542      if (file_exist_check (fname) != 0) {      if (file_exist_check (fname) != 0) {
1543          fp = fopen (fname, "wb");          fp = fopen (fname, "wb");
1544          if (fp == NULL) {          if (fp == NULL) {
1545              log_box (_("File Manager"), MB_ERR, "could not create '%s'", fname);              log_box (_("File Manager"), MB_ERR, "Could not create '%s'", fname);
1546              free_if_alloc (fname);              free_if_alloc (fname);
1547              return WPTERR_GENERAL;                    return WPTERR_GENERAL;
1548          }                }
1549          fwrite (dat, 1, strlen (dat), fp);          fwrite (dat, 1, strlen (dat), fp);
1550          fclose (fp);          fclose (fp);
1551          del_end = 1;          del_end = 1;
1552      }      }
1553      fm_verify (ctx, 1, fname);      fm_verify (ctx, 1, fname);
1554      if (del_end)      if (del_end)
1555          unlink (fname);          DeleteFile (fname);
1556      free_if_alloc (fname);      free_if_alloc (fname);
1557      return 0;      return 0;
1558  }  }
1559    
1560    
1561    /* Figure out if the clipboard contains a detached signature. */
1562  int  int
1563  fm_verify_pasted_detsig (listview_ctrl_t lv, HWND dlg)  fm_verify_pasted_detsig (listview_ctrl_t lv, HWND dlg)
1564  {  {
# Line 1406  fm_verify_pasted_detsig (listview_ctrl_t Line 1576  fm_verify_pasted_detsig (listview_ctrl_t
1576      /* XXX find a way to filter out bad signatures or just ignore all in      /* XXX find a way to filter out bad signatures or just ignore all in
1577             this case */             this case */
1578      fm_state_new (&ctx);      fm_state_new (&ctx);
1579      if ((i=listview_get_curr_pos (lv)) != -1) {      i = listview_get_curr_pos (lv);
1580        if (i= -1) {
1581          verify_pasted (lv, ctx, dat, i, dlg);          verify_pasted (lv, ctx, dat, i, dlg);
1582          fnd = 1;          fnd = 1;
1583      }      }
# Line 1438  get_output_file (fm_state_t c, const cha Line 1609  get_output_file (fm_state_t c, const cha
1609      else      else
1610          title = _("Selected Output File");          title = _("Selected Output File");
1611    
1612      if (strstr (name, ".sig") || strstr (name, ".asc") || strstr (name, ".gpg")) {      if (is_openpgp_ext (name)) {
1613          _snprintf (fname, sizeof (fname) - 1, "%s", name);          _snprintf (fname, sizeof (fname) - 1, "%s", name);
1614          fname[strlen (fname) - 4] = '\0';          fname[strlen (fname) - 4] = '\0';
1615          if (file_exist_check (fname) == 0 && detached)            if (file_exist_check (fname) == 0 && detached)  
# Line 1460  get_output_file (fm_state_t c, const cha Line 1631  get_output_file (fm_state_t c, const cha
1631      if (file) {          if (file) {    
1632          free_if_alloc (c->output);              free_if_alloc (c->output);    
1633          c->output = m_strdup (file);          c->output = m_strdup (file);
         if (!c->output)  
             BUG (NULL);  
1634      }      }
1635      else {      else {
1636          msg_box (c->dlg, _("Invalid file name. Exit"), _("Verify"), MB_ERR);          msg_box (c->dlg, _("Invalid file name. Exit"), _("Verify"), MB_ERR);
# Line 1470  get_output_file (fm_state_t c, const cha Line 1639  get_output_file (fm_state_t c, const cha
1639      if (detached)      if (detached)
1640          c->sigmode = GPGME_SIG_MODE_DETACH;          c->sigmode = GPGME_SIG_MODE_DETACH;
1641      else {      else {
1642          if (strstr (name, ".asc"))          if (stristr (name, ".asc"))
1643              c->sigmode = GPGME_SIG_MODE_CLEAR;              c->sigmode = GPGME_SIG_MODE_CLEAR;
1644          else          else
1645              c->sigmode = GPGME_SIG_MODE_NORMAL;              c->sigmode = GPGME_SIG_MODE_NORMAL;
# Line 1492  fm_verify (fm_state_t c, int detached, c Line 1661  fm_verify (fm_state_t c, int detached, c
1661      file_data_t in=NULL, out=NULL;      file_data_t in=NULL, out=NULL;
1662      int rc = 0;      int rc = 0;
1663    
1664      if (strstr (name, ".sig"))      if (stristr (name, ".sig"))
1665          detached = 1;          detached = 1;
1666    
1667      if (get_output_file (c, name, detached))      if (get_output_file (c, name, detached))
# Line 1500  fm_verify (fm_state_t c, int detached, c Line 1669  fm_verify (fm_state_t c, int detached, c
1669    
1670      memset (&log, 0, sizeof (log));      memset (&log, 0, sizeof (log));
1671      log.file = m_strdup (name);      log.file = m_strdup (name);
     if (!log.file)  
         BUG (NULL);  
1672      file_verify_create_dlg ();      file_verify_create_dlg ();
1673    
1674      err = gpg_file_data_new (name, 1, &in);      err = gpg_file_data_new (name, F_DATA_READ, &in);
1675      if (err)      if (err)
1676          goto leave;          goto leave;
1677      err = gpg_file_data_new (c->output, detached? 1 : 0, &out);      err = gpg_file_data_new (c->output,
1678                                 detached? F_DATA_READ : F_DATA_WRITE, &out);
1679      if (err)      if (err)
1680          goto leave;          goto leave;
1681    
# Line 1536  leave: Line 1704  leave:
1704          gpg_file_data_release (in);          gpg_file_data_release (in);
1705      if (out)      if (out)
1706          gpg_file_data_release (out);          gpg_file_data_release (out);
1707      if (log.file)      free_if_alloc (log.file);
         delete []log.file;  
1708      return rc;      return rc;
1709  }  }
1710    
1711    
1712    /* Import the keys from the file @name.
1713       Return value: 0 on success. */
1714  int  int
1715  fm_import (fm_state_t c, const char *name)  fm_import (fm_state_t c, const char *name)
1716  {  {
# Line 1553  fm_import (fm_state_t c, const char *nam Line 1722  fm_import (fm_state_t c, const char *nam
1722    
1723      free_if_alloc (c->output);      free_if_alloc (c->output);
1724      c->output = m_strdup (name);      c->output = m_strdup (name);
     if (!c->output)  
         BUG (NULL);  
1725    
1726      err = gpg_file_data_new (name, 1, &keydata);      err = gpg_file_data_new (name, F_DATA_READ, &keydata);
1727      if (err)      if (err)
1728          goto leave;          goto leave;
1729    
# Line 1572  fm_import (fm_state_t c, const char *nam Line 1739  fm_import (fm_state_t c, const char *nam
1739      res = gpgme_op_import_result (ctx);      res = gpgme_op_import_result (ctx);
1740      print_import_status (res);      print_import_status (res);
1741      if (res->no_user_id > 0) {      if (res->no_user_id > 0) {
1742          msg_box (c->dlg, _("Key without a self signature was dectected!\n"                msg_box (c->dlg, _("Key without a self signature was dectected!\n"
1743                             "(This key is NOT usable for encryption, etc)\n"                             "(This key is NOT usable for encryption, etc)\n"
1744                             "\n"                             "\n"
1745                             "Cannot import these key(s)!"), _("Import"), MB_INFO);                             "Cannot import these key(s)!"), _("Import"), MB_INFO);
# Line 1582  leave: Line 1749  leave:
1749      if (keydata)      if (keydata)
1750          gpg_file_data_release (keydata);          gpg_file_data_release (keydata);
1751      return rc;      return rc;
1752  } /* fm_import */  }
1753    
1754    
1755  /* Export the selected keys from the File Manager to a file. */  /* Export the selected keys from the File Manager to a file. */
1756  int  int
1757  fm_export (fm_state_t c)  fm_export (fm_state_t c)
1758  {  {    
     int rc = 0, id = 0;  
1759      gpgme_ctx_t ctx = c->ctx;      gpgme_ctx_t ctx = c->ctx;
1760      gpgme_error_t err;      gpgme_error_t err;
1761      gpgme_key_t *rset = c->recp;      gpgme_key_t *rset = c->recp;
1762      file_data_t keydata = NULL;      file_data_t keydata = NULL;
1763      const char *name, *s = NULL;      const char *name;
1764      char *p = NULL, *patt = NULL;      char *p = NULL, *patt = NULL;
1765        int rc = 0;
1766    
1767      if (!rset || !rset[0]) {      if (!rset || !rset[0]) {
1768          msg_box (c->dlg, _("No key was selected for export."), _("Export"), MB_ERR);          msg_box (c->dlg, _("No key was selected for export."),
1769                     _("Export"), MB_ERR);
1770          rc = WPTERR_GENERAL;          rc = WPTERR_GENERAL;
1771          goto leave;          goto leave;
1772      }      }
1773    
1774      if (rset[1] == NULL) { /* count == 1*/      if (rset[1] == NULL) /* count == 1*/
1775          gpgme_key_t k = rset[0];          p = km_gen_export_filename (rset[0]->subkeys->keyid+8, 0);
         const char *s = k->uids->name;  
         p = new char[strlen (s)+1+8];  
         if (!p)  
             BUG (NULL);  
         strcpy (p, s );  
         strcat (p, ".asc");  
     }  
1776    
1777      name = get_filename_dlg (c->dlg, FILE_SAVE, _("Choose Name for Key File"),      name = get_filesave_dlg (c->dlg, _("Choose Name for Key File"),
1778                               NULL, p? p : NULL);                               NULL, p? p : NULL);
                               
1779      if (!name)      if (!name)
1780          name = "keys.gpg";          name = reg_prefs.default_ext? "keys.pgp" : "keys.gpg";
1781    
1782      patt = gpg_keylist_to_pattern (rset, c->n_recp);      patt = gpg_keylist_to_pattern (rset, c->n_recp);
1783    
1784      err = gpg_file_data_new (name, 0, &keydata);      err = gpg_file_data_new (name, F_DATA_WRITE, &keydata);
1785      if (err)      if (err)
1786          goto leave;          goto leave;
1787    
# Line 1638  fm_export (fm_state_t c) Line 1798  fm_export (fm_state_t c)
1798  leave:  leave:
1799      if (keydata)      if (keydata)
1800          gpg_file_data_release (keydata);          gpg_file_data_release (keydata);
1801      if (patt)      safe_free (patt);
         free (patt);  
1802      free_if_alloc (p);      free_if_alloc (p);
           
1803      return rc;      return rc;
1804  }  }
1805    
# Line 1697  fm_parse_command_line (char *cmdl) Line 1855  fm_parse_command_line (char *cmdl)
1855    
1856          case PGP_SIG:          case PGP_SIG:
1857          case PGP_CLEARSIG:          case PGP_CLEARSIG:
             file_verify_use_event ();  
1858              if (type == PGP_SIG)                  if (type == PGP_SIG)    
1859                  detached = 1;                  detached = 1;
1860              fm_verify (ctx, detached, fn);              fm_verify (ctx, detached, fn);
1861              file_verify_wait ();              file_verify_wait ();
1862              break;              break;
1863    
1864            default:
1865                break;
1866          }          }
1867      }      }
1868    
# Line 1713  fm_parse_command_line (char *cmdl) Line 1873  fm_parse_command_line (char *cmdl)
1873  }  }
1874    
1875    
1876    /* Extract the last folder name from @name. */
1877  const char*  const char*
1878  default_dirname (const char *name)  default_dirname (const char *name)
1879  {  {
1880      char * p = strrchr( name, '\\' );      char *p = strrchr (name, '\\');
1881      if( !p )      if (!p)
1882          return NULL;          return NULL;
1883      return p+1;      return p+1;
1884  } /* default_dirname */  }
1885    
1886    
1887    /* Store all selected files from @lv in a zip archive
1888       and encrypt the zip archive then.
1889       Return value: 0 on success. */
1890  int  int
1891  fm_encrypt_directory( fm_state_t c, const char * name )  fm_encrypt_into_zip (fm_state_t ctx, listview_ctrl_t lv)
1892    {
1893        PK_FILE_LIST list=NULL;
1894        const char *outfile, *ext;
1895        char *out_enc;
1896        int nitems;
1897        int i, idx = -1;
1898        int rc;
1899    
1900        nitems = listview_count_items (lv, 0);
1901        if (!nitems) {
1902            msg_box (NULL, _("Encrypting into a ZIP archive makes sense with multiple files"),
1903                     _("File Manager"), MB_ERR);
1904            return WPTERR_GENERAL;
1905        }
1906    
1907        outfile = get_filesave_dlg (ctx->dlg, _("Choose File Name for Output"),
1908                                    NULL, "Encrypted_Files.zip");
1909        if (!outfile)
1910            return WPTERR_GENERAL;
1911    
1912        for (i=0; i < nitems; i++) {
1913            char name[300];
1914            if (!listview_get_item_state (lv, i))
1915                continue;
1916            if (idx == -1)
1917                idx = i;
1918            listview_get_item_text (lv, i, 1, name, sizeof (name)-1);
1919            pk_list_add (&list, name);
1920        }    
1921    
1922        pk_archiv_create (list, outfile);
1923        pk_list_free (list);
1924    
1925        rc = fm_encrypt (ctx, outfile, 0);
1926        DeleteFile (outfile);
1927        if (rc)
1928            return rc;
1929    
1930        ext = file_get_extension (ctx->ctx, ctx->sigmode)+1;
1931        out_enc = make_filename (NULL, outfile, ext);
1932        fm_set_status (lv, idx, FM_ENCRYPT, (gpgme_sig_mode_t)0, 1, out_enc);
1933        free_if_alloc (out_enc);
1934    
1935        for (i=0; i < nitems; i++) {
1936            if (i != idx && listview_get_item_state (lv, i))
1937                listview_del_item (lv, i);
1938        }
1939        return 0;
1940    }
1941    
1942    
1943    int
1944    fm_encrypt_directory (fm_state_t c, const char *name)
1945  {  {
1946      PK_FILE_LIST list = NULL;      PK_FILE_LIST list = NULL;
1947      WIN32_FIND_DATA findbuf;      WIN32_FIND_DATA findbuf;
1948      HANDLE hd;      HANDLE hd;
1949      const char * s;      const char *s;
1950      char * patt = NULL, * p;      char *patt = NULL, *p;
1951      int rc = 0;      int rc = 0;
1952            
1953      if( !is_directory( name ) )          if (!is_directory (name))
1954          return -1;          return -1;
1955      patt = new char[strlen( name ) + 4];      patt = new char[strlen (name) + 4];
1956      if( !patt )      if (!patt)
1957          BUG( NULL );          BUG (NULL);
1958      strcpy( patt, name );      strcpy (patt, name);
1959      strcat( patt, "\\*" );      strcat (patt, "\\*");
1960      hd = FindFirstFile( patt, &findbuf );          hd = FindFirstFile (patt, &findbuf);
1961      if( !hd ) {      if (!hd) {
1962          free_if_alloc( patt );            free_if_alloc (patt);
1963          return -1;                return WPTERR_GENERAL;
1964      }      }
1965      if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {      if (strcmp (findbuf.cFileName, ".") && strcmp (findbuf.cFileName, "..")) {
1966          p = make_filename( name, findbuf.cFileName, NULL );          p = make_filename (name, findbuf.cFileName, NULL);
1967          pk_list_add( &list, p );          pk_list_add (&list, p);
1968          free_if_alloc( p );          free_if_alloc (p);
1969      }      }
1970      while( FindNextFile( hd, &findbuf ) ) {      while( FindNextFile( hd, &findbuf ) ) {
1971          if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {          if( strcmp( findbuf.cFileName, "." ) && strcmp( findbuf.cFileName, ".." ) ) {
# Line 1757  fm_encrypt_directory( fm_state_t c, cons Line 1974  fm_encrypt_directory( fm_state_t c, cons
1974              free_if_alloc( p );              free_if_alloc( p );
1975          }          }
1976      }      }
1977      s = get_filename_dlg( c->dlg, FILE_SAVE, _("Choose a Name for the Archive"),      s = get_filesave_dlg (c->dlg, _("Choose a Name for the Archive"),
1978                            NULL, default_dirname( name ) );                            NULL, default_dirname (name));
1979      if( !s ) {      if( !s ) {
1980          msg_box( c->dlg, _("Invalid archive name. Exit."), _("Encrypt Directory"), MB_ERR );          msg_box (c->dlg, _("Invalid archive name. Exit."),
1981                     _("Encrypt Directory"), MB_ERR);
1982          rc = -1;          rc = -1;
1983          goto leave;          goto leave;
1984      }      }
1985    
1986      rc = pk_archiv_create( list, s );      rc = pk_archiv_create (list, s);
1987      if( rc )      if( rc )
1988          msg_box( c->dlg, _("Could not create zip archive."), _("Encrypt Directory"), MB_ERR );          msg_box (c->dlg, _("Could not create zip archive."),
1989                     _("Encrypt Directory"), MB_ERR);
1990      else {      else {
1991          fm_encrypt( c, s, 0 );          fm_encrypt (c, s, 0);
1992          unlink( s );          DeleteFile (s);
1993      }      }
1994  leave:  leave:
1995      FindClose (hd);      FindClose (hd);
1996      pk_list_free( list );      pk_list_free (list);
1997      free_if_alloc( patt );      free_if_alloc (patt);
1998      return rc;      return rc;
1999  } /* fm_encrypt_directory */  }
2000    
2001    
2002  static int CALLBACK  static int CALLBACK
2003  fm_cmp_cb( LPARAM first, LPARAM second, LPARAM sortby )  fm_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
2004  {  {
2005      const char * a = 0, * b = 0;      fm_model_t a, b;
2006        int cmpres = 0;
2007    
2008        a = (fm_model_t)first;
2009        b = (fm_model_t)second;
2010        if (!a || !b)
2011            return 0;
2012    
2013      switch( (int)sortby ) {      switch ((int)sortby) {
2014      case FM_SORT_STAT:      case FM_COL_STAT:
2015            cmpres = stricmp (a->status, b->status);
2016          break;          break;
2017      case FM_SORT_NAME:  
2018        case FM_COL_NAME:
2019            cmpres = stricmp (a->name, b->name);
2020          break;          break;
2021      case FM_SORT_OP:  
2022        case FM_COL_OP:
2023            if (a->op && b->op)
2024                cmpres = stricmp (a->op, b->op);
2025          break;          break;
2026      }      }
2027      return stricmp( a, b );      return cmpres;
2028  } /* fm_cmp_cb */  }
2029            
2030    
2031    /* Sort the list items from @lv with the mode given by @sortby. */
2032  int  int
2033  fm_sort( listview_ctrl_t lv, int sortby )  fm_sort (listview_ctrl_t lv, int sortby)
2034  {  {
2035      return listview_sort_items( lv, sortby, fm_cmp_cb );      return ListView_SortItems (lv->ctrl, fm_cmp_cb, (LPARAM)sortby);
2036  } /* fm_sort */  }
2037    
2038    
2039    /* Start the 'print md' dialog. Pass over the listview control
2040       @lv and the digest algo @mdalgo. */
2041  void  void
2042  fm_print_md( listview_ctrl_t lv, HWND dlg, int mdalgo )  fm_print_md (listview_ctrl_t lv, HWND dlg, int mdalgo)
2043  {  {
2044      struct md_file_s mdctx;      struct md_file_s mdctx;
2045    
2046      if( listview_count_items( lv, 0 ) == 0 )      if (listview_count_items (lv, 0) == 0)
2047          return;          return;
2048      memset (&mdctx, 0, sizeof (mdctx));      memset (&mdctx, 0, sizeof (mdctx));
2049      mdctx.lv = lv;      mdctx.lv = lv;
2050      mdctx.mdalgo = mdalgo;      mdctx.mdalgo = mdalgo;
2051      DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_MDSUM, dlg,      DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_MDSUM, dlg,
2052                      mdsum_dlg_proc, (LPARAM)&mdctx );                      mdsum_dlg_proc, (LPARAM)&mdctx);
2053  } /* fm_print_md */  }
2054    
2055    
2056    /* Send the selected file in @lv via MAPI to a mail recipient. */
2057  int  int
2058  fm_send_file (listview_ctrl_t lv)  fm_send_file (listview_ctrl_t lv)
2059  {  {
# Line 1826  fm_send_file (listview_ctrl_t lv) Line 2061  fm_send_file (listview_ctrl_t lv)
2061      int rc;      int rc;
2062    
2063      rc = listview_get_item_text (lv, -1, 1, buf, sizeof (buf)-1);      rc = listview_get_item_text (lv, -1, 1, buf, sizeof (buf)-1);
2064      if (rc == -1)      if (rc != -1)
2065          return 0;          mapi_send_ascfile (buf);
     /*mapi_send_ascfile (buf); XXX */  
2066      return 0;      return 0;
2067  }  }

Legend:
Removed from v.36  
changed lines
  Added in v.244

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26