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

Annotation of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 256 - (hide annotations)
Sat Aug 5 10:31:06 2006 UTC (18 years, 6 months ago) by twoaday
File size: 50294 byte(s)
1.0.0pre3 release.


1 werner 36 /* wptFileManager.cpp - File Manager routines
2 twoaday 195 * Copyright (C) 2001-2006 Timo Schulz
3 werner 36 * Copyright (C) 2005 g10 Code GmbH
4     *
5     * This file is part of WinPT.
6     *
7     * WinPT is free software; you can redistribute it and/or
8     * modify it under the terms of the GNU General Public License
9     * as published by the Free Software Foundation; either version 2
10     * of the License, or (at your option) any later version.
11     *
12     * WinPT is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     * General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with WinPT; if not, write to the Free Software Foundation,
19     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21 twoaday 129
22 werner 42 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24     #endif
25    
26 werner 36 #include <sys/types.h>
27     #include <windows.h>
28     #include <commdlg.h>
29     #include <io.h>
30 twoaday 41 #include <stdio.h>
31 werner 36
32 werner 47 #include "resource.h"
33 werner 36 #include "wptTypes.h"
34     #include "wptGPG.h"
35     #include "wptAgent.h"
36     #include "wptCommonCtl.h"
37     #include "wptContext.h"
38     #include "wptErrors.h"
39     #include "wptKeylist.h"
40     #include "wptFileManager.h"
41     #include "wptNLS.h"
42     #include "wptW32API.h"
43     #include "wptVersion.h"
44     #include "wptDlgs.h"
45     #include "wptZIP.h"
46     #include "wptUTF8.h"
47     #include "wptRegistry.h"
48     #include "wptImport.h"
49 werner 48 #include "wptCrypto.h"
50 twoaday 129 #include "wptKeyManager.h"
51 werner 36 #include "openpgp.h"
52    
53    
54     void progress_cleanup (progress_filter_s *pfx);
55     BOOL CALLBACK file_secdel_confirm_dlg_proc (HWND dlg, UINT msg,
56     WPARAM wparam, LPARAM lparam);
57     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,
59     int prev_was_bad, int fd);
60 twoaday 220 void verify_show_signature_state (gpgme_signature_t sig);
61 werner 36
62    
63 twoaday 195 static const char *mm_files[] = {".mov", ".avi", ".mpg", ".mpeg",
64 werner 36 ".mp3", ".wav", ".mid", ".wma",
65     ".gif", ".jpg", ".png", ".jpeg", ".dib", 0};
66    
67    
68 twoaday 244 /* 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 werner 36 /* Check if the drive given by @fname is a floppy disc.
99 twoaday 41 Return value: -1 for success. */
100 werner 36 static int
101 twoaday 41 is_floppy_disc (const char *fname)
102 werner 36 {
103 twoaday 41 char drv[32] = {0};
104     int max = sizeof (drv)-1;
105 werner 36 int i=0;
106    
107     if (!strstr (fname, ":\\"))
108     return 0;
109    
110 twoaday 41 while (fname && *fname && *fname != '\\' && i < max)
111 werner 36 drv[i++] = *fname++;
112     drv[i++] = '\\';
113     drv[i++] = '\0';
114     i = GetDriveType (drv);
115     if (i == DRIVE_REMOVABLE)
116     return -1;
117     return 0;
118     }
119    
120    
121     /* Ask the user to overwrite file @fname.
122     Return value: 0 for cancel. */
123 twoaday 41 static int
124 werner 36 overwrite_file (const char *fname)
125     {
126     int id;
127    
128     if (file_exist_check (fname))
129     return -1;
130     id = log_box (_("File Manager"), MB_YESNO,
131     _("\"%s\" already exists.\n"
132     "Replace existing file?"), fname);
133     return id == IDNO ? 0 : -1;
134     }
135    
136    
137     /* Removes 'critical' attributes from the file @fname.
138     If @force is 1, the user is not asked for permission. */
139 twoaday 172 void
140 werner 36 remove_crit_file_attrs (const char *fname, int force)
141     {
142 twoaday 193 DWORD fattr;
143 twoaday 41 int id = 0;
144 werner 36
145     if (file_exist_check (fname))
146     return; /* Does not exist */
147    
148 twoaday 41 fattr = GetFileAttributes (fname);
149     if ((fattr & FILE_ATTRIBUTE_READONLY) && force)
150     id = IDYES;
151     else if (fattr & FILE_ATTRIBUTE_READONLY)
152 werner 36 id = log_box (_("File Manager"), MB_YESNO,
153     _("\"%s\" has read-only attribute.\n"
154     "Set attribute to normal?"), fname);
155 twoaday 41 if (id == IDYES) {
156     if (!SetFileAttributes (fname, FILE_ATTRIBUTE_NORMAL))
157     msg_box (NULL, _("Could not reset file attribute to normal."),
158     _("File Manager"), MB_ERR);
159 werner 36 }
160     }
161    
162    
163 twoaday 41 /* Return 1 if the given path @fname is a directory, 0 otherwise. */
164     static int
165 werner 36 is_directory (const char *fname)
166 twoaday 41 {
167 werner 36 return GetFileAttributes (fname) & FILE_ATTRIBUTE_DIRECTORY? 1 : 0;
168     }
169    
170    
171 twoaday 219 /* Return -1 if the given name @name is a valid GPG extension. */
172     int
173 werner 36 is_openpgp_ext (const char *name)
174     {
175 twoaday 226 if (stristr (name, ".gpg") ||
176     stristr (name, ".asc") ||
177     stristr (name, ".sig") ||
178     stristr (name, ".pgp"))
179 werner 36 return -1;
180     return 0;
181     }
182    
183    
184     static int
185     is_multi_media (const char * name)
186     {
187     const char * val;
188     char * p;
189     int i;
190     int ans=0;
191    
192     i = get_reg_winpt_single (CFG_NOZIP_MMEDIA);
193     if (i == -1)
194     {
195     ans = msg_box (NULL, _("Multi-Media files are already compressed, GPG would compress\n"
196 twoaday 248 "them anyway and this takes a lot of time.\n"
197 werner 36 "It is possible to disable compression for these files.\n"
198     "Do you want to disable it?"),
199     _("File Manager"), MB_YESNO|MB_INFO);
200     set_reg_winpt_single (CFG_NOZIP_MMEDIA, ans == IDYES? 1 : 0);
201     if (ans == IDNO)
202     return 0;
203     }
204     else if (i == 0)
205     return 0;
206    
207     p = strrchr (name, '.');
208     if (!p)
209     return 0;
210 twoaday 41 for (i=0; (val = mm_files[i]); i++) {
211 werner 36 if (!stricmp (p, val))
212     return -1;
213     }
214     return 0;
215     }
216    
217    
218 twoaday 41 /* Return a GPG file extension which depends on the operation
219     mode in @ctx and the sig mode @sigmode. */
220 werner 36 const char*
221     file_get_extension (gpgme_ctx_t ctx, gpgme_sig_mode_t sigmode)
222     {
223     int use_armor = gpgme_get_armor (ctx);
224    
225     if (use_armor || sigmode == GPGME_SIG_MODE_CLEAR)
226     return ".asc";
227     if (!use_armor && sigmode == GPGME_SIG_MODE_DETACH)
228     return ".sig";
229 twoaday 218 return reg_prefs.default_ext == 1? ".pgp" : ".gpg";
230 werner 36 }
231    
232    
233 twoaday 41 /* Quote a file to avoid shell problems with spaces in the files. */
234 werner 36 char*
235     fm_quote_file (const char * name)
236     {
237     char * p;
238     size_t len = strlen (name) + 8;
239    
240     if (*name == '"')
241     return m_strdup (name); /* avoid double quotes */
242     p = new char[len + 1];
243     if (!p)
244     BUG (0);
245     _snprintf (p, len, "\"%s\"", name);
246    
247     return p;
248 twoaday 41 }
249 werner 36
250    
251    
252     /* Check the armor type of the file @fname and return
253     a string representation of it. */
254 twoaday 195 static const char*
255 werner 36 fm_check_armor_type (const char *fname, int *r_type)
256     {
257 twoaday 195 FILE *fp;
258     char header[768], *p;
259 werner 36
260     if (r_type)
261     *r_type = PGP_NONE;
262     fp = fopen (fname, "rb");
263     if (!fp)
264     return "UNKNOWN";
265     p = fgets (header, sizeof (header) - 1, fp);
266     fclose (fp);
267     if (!p)
268     return "UNKNOWN";
269    
270     if (strncmp (header, "-----", 5))
271     goto leave;
272     if (strstr( header, "BEGIN PGP PUBLIC KEY" )) {
273     if (r_type) *r_type = PGP_PUBKEY;
274     return "PUBKEY";
275     }
276     else if (strstr (header, "BEGIN PGP PRIVATE KEY") ||
277     strstr (header, "BEGIN PGP SECRET KEY")) {
278     if (r_type) *r_type = PGP_SECKEY;
279     return "SECKEY";
280     }
281     else if (strstr (header, "BEGIN PGP MESSAGE")) {
282     if (r_type) *r_type = PGP_MESSAGE;
283     return "ENCRYPTED";
284     }
285     else if (strstr( header, "BEGIN PGP SIGNED MESSAGE")) {
286     if (r_type) *r_type = PGP_CLEARSIG;
287     return "SIGNED-CLEAR";
288     }
289     else if (strstr(header, "BEGIN PGP SIGNATURE")) {
290     if (r_type) *r_type = PGP_SIG;
291     return "SIGNED-DETACH";
292     }
293    
294     leave:
295     return "UNKNOWN";
296     }
297    
298    
299     /* Extract file type from @fname. If @r_type is valid,
300     it contains the PGP type on success. */
301 twoaday 105 static const char*
302 werner 36 fm_get_file_type (const char *fname, int *r_type)
303     {
304     gpg_iobuf_t inp;
305     armor_filter_context_t afx;
306 twoaday 41 PACKET *pkt;
307     const char *s = NULL;
308 twoaday 105 size_t count = 0, compr = 0;
309 twoaday 77 int rc = 0;
310 werner 36
311     if (r_type)
312     *r_type = PGP_NONE;
313     if (!fname) {
314 twoaday 41 log_debug ("fm_get_file_type: !fname\r\n");
315 werner 36 return NULL;
316     }
317    
318     if (is_floppy_disc (fname))
319     return fm_check_armor_type (fname, r_type);
320    
321     inp = gpg_iobuf_open (fname);
322     if (!inp) {
323 twoaday 77 const char *err = winpt_strerror (WPTERR_FILE_OPEN);
324     log_box (_("File Manager"), MB_ERR, "\"%s\": %s", fname, err);
325 werner 36 return NULL;
326     }
327     gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */
328     if (gpg_iobuf_get_filelength (inp) > 32000000 /* 32MB */
329     && !is_openpgp_ext (fname)) {
330     gpg_iobuf_close (inp);
331     return "UNKNOWN";
332     }
333    
334     if (gpg_use_armor_filter(inp)) {
335     memset (&afx, 0, sizeof (afx));
336     gpg_iobuf_push_filter (inp, gpg_armor_filter, &afx);
337     }
338 twoaday 41 pkt = (PACKET *)calloc (1, sizeof *pkt);
339     if (!pkt)
340     BUG (NULL);
341 werner 36 gpg_init_packet (pkt);
342     while (!(rc = gpg_parse_packet (inp, pkt))) {
343     switch (pkt->pkttype) {
344     case PKT_PUBKEY_ENC:
345     s = "ENCRYPTED";rc = -2;
346     if (r_type) *r_type = PGP_MESSAGE;
347     break;
348     case PKT_SYMKEY_ENC:
349     case PKT_ENCRYPTED:
350     s = "SYMKEYENC";rc = -2;
351     if (r_type) *r_type = PGP_MESSAGE;
352     break;
353     case PKT_SIGNATURE:
354     case PKT_ONEPASS_SIG:
355     s = "SIGNED"; rc = -2;
356     if (r_type) *r_type = PGP_SIG;
357     break;
358     case PKT_PUBLIC_KEY:
359     s = "PUBKEY"; rc = -2;
360     if (r_type) *r_type = PGP_PUBKEY;
361     break;
362     case PKT_SECRET_KEY:
363     s = "SECKEY"; rc = -2;
364     if (r_type) *r_type = PGP_SECKEY;
365     break;
366 twoaday 88
367 twoaday 105 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 twoaday 69 default:
377     break;
378 werner 36 }
379 twoaday 105 count++;
380 werner 36 gpg_free_packet (pkt);
381     gpg_init_packet (pkt);
382     if (rc == -2)
383     break; /* found */
384     }
385     safe_free (pkt);
386     gpg_iobuf_close (inp);
387     if (!s)
388     s = fm_check_armor_type (fname, r_type);
389     if (!s)
390     s = "UNKNOWN";
391 twoaday 105 if (!strcmp (s, "SIGNED") && !compr
392 werner 36 && strcmp (fm_check_armor_type (fname, r_type), "SIGNED-CLEAR ")) {
393     if (r_type) *r_type = PGP_SIG;
394     s = "SIGNED-DETACH";
395     }
396     return s;
397     }
398    
399    
400 twoaday 244 /* Build the File Manager dialog context. */
401     void
402     fm_build (fm_info_t *r_fm, HWND ctrl)
403 werner 36 {
404 twoaday 208 int i;
405 twoaday 244 fm_info_t fm;
406 twoaday 105 struct listview_column_s col[] = {
407 werner 36 {0, 80, (char *)_("Status") },
408     {1, 256, (char *)_("Name") },
409     {2, 128, (char *)_("Operation") },
410 twoaday 195 {0, 0, NULL}
411 werner 36 };
412 twoaday 244
413     fm = new fm_info_s;
414     memset (fm, 0, sizeof *fm);
415     listview_new (&fm->lv, ctrl);
416 twoaday 105 for (i = 0; col[i].width; i++)
417 twoaday 244 listview_add_column (fm->lv, &col[i]);
418     listview_set_ext_style (fm->lv);
419     fm->model = NULL; /*init*/
420     *r_fm = fm;
421 twoaday 105 }
422 werner 36
423    
424 twoaday 244 /* Release the file model. */
425     static void
426     fm_model_release (fm_model_t mod)
427 werner 36 {
428 twoaday 244 fm_model_t m;
429    
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 werner 36 }
438 twoaday 105 }
439 werner 36
440    
441 twoaday 244 /* 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 werner 36 int
466     fm_state_new (fm_state_t * ctx)
467     {
468 twoaday 195 fm_state_s *c;
469 werner 36
470     c = new fm_state_s;
471     if (!c)
472     BUG (0);
473 twoaday 41 memset (c, 0, sizeof *c);
474 twoaday 211 if (gpgme_new (&c->ctx))
475 werner 36 BUG (0);
476     *ctx = c;
477     return 0;
478 twoaday 195 }
479 werner 36
480    
481     /* Release the FM state handle @c. */
482     void
483     fm_state_release (fm_state_t c)
484     {
485     if (!c)
486     return;
487     if (c->ctx) {
488     gpgme_release (c->ctx);
489     c->ctx = NULL;
490     }
491 twoaday 105 safe_free (c->recp);
492 werner 36 free_if_alloc (c->opaque);
493     free_if_alloc (c->output);
494 twoaday 195 delete c;
495 werner 36 }
496    
497 twoaday 195
498 twoaday 226 /* Check if file @file is already in the list (view). */
499 werner 36 static int
500 twoaday 226 fm_check_for_entry (listview_ctrl_t lv, const char *file)
501 werner 36 {
502 twoaday 244 char name[MAX_PATH+128];
503 werner 36 int i;
504    
505     memset (name, 0, sizeof (name));
506 twoaday 226 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 twoaday 244 if (!strcmp (name, file))
509 werner 36 return 1; /* found */
510     }
511    
512     return 0;
513 twoaday 195 }
514 werner 36
515    
516     static int
517 twoaday 244 fm_set_ftype (listview_ctrl_t lv, fm_model_t *fm, const char *name)
518 werner 36 {
519 twoaday 244 fm_model_t m;
520 werner 36 const char *type;
521     int rc;
522    
523     rc = fm_check_for_entry (lv, name);
524     if (rc)
525     return 0;
526 twoaday 244 m = new fm_model_s;
527     memset (m, 0, sizeof *m);
528 werner 36 type = fm_get_file_type (name, NULL);
529     if (!type || !strcmp (type, "UNKNOWN"))
530     type = gnupg_check_file_ext (name, NULL);
531 twoaday 244 listview_add_item2 (lv, " ", (void*)m);
532 twoaday 226 listview_add_sub_item (lv, 0, FM_COL_STAT, type);
533     listview_add_sub_item (lv, 0, FM_COL_NAME, name);
534 twoaday 244 m->name = m_strdup (name);
535     m->status = m_strdup (type);
536     m->op = NULL;
537     fm_model_add_file (fm, m);
538 werner 36 return 0;
539     }
540    
541    
542 twoaday 195 /* Add all files from the directory @path to the list view @lv. */
543 werner 36 static int
544 twoaday 244 fm_add_dir_files (listview_ctrl_t lv, fm_model_t *fm, char *path)
545 werner 36 {
546     struct _finddata_t fd;
547 twoaday 226 char *p;
548 werner 36 long hd;
549    
550     strcat (path, "\\*");
551     hd = _findfirst (path, &fd);
552     do {
553 twoaday 226 p = new char [strlen (path) + strlen (fd.name)+1];
554 werner 36 if (!p)
555     BUG (0);
556     memcpy (p, path, strlen (path)-1);
557     p[strlen (path)-1] = 0;
558     strcat (p, fd.name);
559     if (!is_directory (p))
560 twoaday 244 fm_set_ftype (lv, fm, p);
561 werner 36 free_if_alloc (p);
562     } while (_findnext (hd, &fd) == 0);
563     _findclose (hd);
564     return 0;
565     }
566    
567    
568     /* Add the drag & drop files from @dd_files to the
569     list view control @lv. */
570     int
571 twoaday 244 fm_add_dropped_files (fm_info_t fm, HDROP dd_files)
572 werner 36 {
573     char name[384+4];
574 twoaday 77 int nfiles;
575     int rc = 0;
576     int i;
577 werner 36
578     memset (name, 0, sizeof (name));
579     nfiles = DragQueryFile (dd_files, 0xFFFFFFFF, NULL, 0);
580     for (i = 0; i < nfiles; i++) {
581     DragQueryFile (dd_files, i, name, sizeof (name) -1);
582     if (is_directory (name))
583 twoaday 244 rc = fm_add_dir_files (fm->lv, &fm->model, name);
584 werner 36 else
585 twoaday 244 rc = fm_set_ftype (fm->lv, &fm->model, name);
586 werner 36 if (rc == -1)
587 twoaday 41 break; /* XXX: fixme? */
588 werner 36 }
589 twoaday 167 DragFinish (dd_files);
590 werner 36 return rc;
591     }
592    
593    
594 twoaday 41 /* 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 twoaday 244 add_single_file (listview_ctrl_t lv, fm_model_t *fm, const char *name)
599 twoaday 41 {
600 twoaday 244 fm_model_t m;
601 twoaday 41 const char *type;
602     int rc = 0;
603 twoaday 244
604 twoaday 41 type = fm_get_file_type (name, NULL);
605     if (!type)
606     return WPTERR_FILE_OPEN;
607 twoaday 244 m = new fm_model_s;
608     memset (m, 0, sizeof *m);
609 twoaday 41 if (!strcmp (type, "UNKNOWN"))
610 twoaday 195 type = gnupg_check_file_ext (name, NULL);
611 twoaday 244 rc = listview_add_item2 (lv, "", (void*)m);
612 twoaday 195 if (!rc) {
613 twoaday 226 listview_add_sub_item (lv, 0, FM_COL_STAT, type);
614     listview_add_sub_item (lv, 0, FM_COL_NAME, name);
615 twoaday 41 }
616 twoaday 244 m->status = m_strdup (type);
617     m->name = m_strdup (name);
618     m->op = NULL;
619     fm_model_add_file (fm, m);
620 twoaday 41 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 werner 36 int
627 twoaday 244 fm_add_opened_files (fm_info_t fm, HWND dlg)
628 werner 36 {
629     OPENFILENAME open;
630 twoaday 41 char file[512], name[MAX_PATH+1];
631     char *path = NULL;
632     const char *s;
633     int i, len=0, n=0;
634     int rc=0;
635    
636 werner 36 memset (&open, 0, sizeof (open));
637     open.lStructSize = sizeof (OPENFILENAME);
638     open.hInstance = glob_hinst;
639     open.lpstrTitle = _("File Open");
640 twoaday 167 open.lpstrFilter = "All Files (*.*)\0*.*\0\0";
641 werner 36 open.hwndOwner = dlg;
642     open.lpstrFile = file;
643     open.nMaxFile = sizeof (file) - 1;
644 twoaday 41 open.Flags = OFN_ALLOWMULTISELECT|OFN_EXPLORER ;
645 werner 36
646 twoaday 41 memset (file, 0, sizeof file);
647     if (!GetOpenFileName (&open))
648     return 0;
649    
650 twoaday 226 /* It is possible that multiple files are returned
651     and then they are separated by \0 chars. */
652 twoaday 41 s = file;
653     len = sizeof (file)-1;
654     for (;;) {
655     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 twoaday 226 path = m_strdup (name);
667 twoaday 41 else {
668     char *p = make_filename (path, name, NULL);
669 twoaday 244 rc = add_single_file (fm->lv, &fm->model, p);
670 twoaday 226 free_if_alloc (p);
671 twoaday 41 }
672     n++;
673 werner 36 }
674 twoaday 41 if (n == 1) /* single file selected. */
675 twoaday 244 rc = add_single_file (fm->lv, &fm->model, path);
676 twoaday 226 free_if_alloc (path);
677 werner 36 return rc;
678     }
679    
680    
681     int
682 twoaday 214 fm_assume_onepass_sig (const char *fname)
683 twoaday 197 {
684 werner 36 armor_filter_context_t afx;
685     gpg_iobuf_t fp;
686 twoaday 197 gpgme_data_t dat;
687     PACKET *pkt;
688     char tmpfile[MAX_PATH+1];
689 werner 36 int check = 0;
690    
691 twoaday 197 pkt = (PACKET *)calloc (1, sizeof *pkt);
692 werner 36 if (!fname) {
693 twoaday 197 get_temp_name (tmpfile, sizeof (tmpfile)-1, "gpgme.tmp");
694 werner 36 gpg_data_new_from_clipboard (&dat, 0);
695 twoaday 197 gpg_data_release_and_set_file (dat, tmpfile);
696 werner 36
697 twoaday 197 fp = gpg_iobuf_open (tmpfile);
698 werner 36 if (!fp)
699     return 0;
700     gpg_iobuf_ioctl (fp, 3, 1, NULL);
701     if (gpg_use_armor_filter(fp)) {
702     memset (&afx, 0, sizeof (afx));
703     gpg_iobuf_push_filter (fp, gpg_armor_filter, &afx);
704     }
705     gpg_init_packet (pkt);
706     if (!gpg_parse_packet (fp, pkt)
707     && pkt->pkttype == PKT_COMPRESSED)
708     check = 1;
709     gpg_free_packet (pkt);
710     gpg_iobuf_close (fp);
711 twoaday 226 DeleteFile (tmpfile);
712 werner 36 }
713     /* XXX: implement it for real files */
714 twoaday 197 safe_free (pkt);
715 werner 36 return check;
716     }
717    
718    
719     int
720     fm_get_current_pos (listview_ctrl_t lv)
721     {
722     int i = 0, items;
723    
724     items = listview_count_items (lv, 0);
725     if (!items)
726     return -1;
727 twoaday 197 else if (items == 1) {
728 werner 36 listview_select_one (lv, 0);
729     return 0;
730     }
731 twoaday 197 else if (items > 1) {
732 werner 36 i = listview_get_curr_pos (lv);
733 twoaday 197 if (i == -1) {
734     msg_box (lv->ctrl, _("Please select a file."),
735     _("File Manager"), MB_ERR);
736 werner 36 return -1;
737     }
738     return i;
739     }
740    
741     return -1;
742 twoaday 197 }
743 werner 36
744    
745     static int
746 twoaday 197 fm_check_detached_sig (listview_ctrl_t lv, int pos)
747 werner 36 {
748     char type[128];
749    
750 twoaday 197 listview_get_item_text (lv, pos, 0, type, sizeof (type)-1);
751     return !strcmp (type, "SIGNED-DETACH")? 1 : 0;
752     }
753 werner 36
754    
755     int
756     fm_check_file_type (listview_ctrl_t lv, int pos, int fm_cmd)
757     {
758     char status[128];
759     int rc = 0;
760    
761     listview_get_item_text (lv, pos, 0, status, sizeof (status) - 1);
762    
763     switch (fm_cmd) {
764     case FM_ENCRYPT:
765     case FM_ENCRYPT_DIR:
766     case FM_SIGNENCRYPT:
767     if (strcmp (status, "ENCRYPTED")
768     && strcmp (status, "SYMKEYENC"))
769     rc = 1;
770     break;
771    
772     case FM_DECRYPT:
773 twoaday 226 if (!strcmp (status, "DATA") ||
774     !strcmp (status, "ENCRYPTED") ||
775     !strcmp (status, "SYMKEYENC") ||
776     !strcmp (status, "ARMORED"))
777 werner 36 rc = 1;
778     break;
779    
780     case FM_SIGN:
781     if( strncmp( status, "SIGNED", 6 ) )
782     rc = 1;
783     break;
784    
785     case FM_VERIFY:
786     if( !strncmp( status, "SIGNED", 6 )
787     || !strcmp( status, "COMPRESSED" ) )
788     rc = 1;
789     break;
790    
791     case FM_SYMENC:
792     if( strcmp( status, "SYMKEYENC" ) )
793     rc = 1;
794     break;
795    
796     case FM_IMPORT:
797     if( !strcmp( status, "PUBKEY" )
798     || !strcmp( status, "SECKEY" ) )
799     rc = 1;
800     break;
801    
802     case FM_WIPE:
803     case FM_LIST:
804     rc = 1;
805     break;
806     }
807    
808     return rc;
809 twoaday 197 }
810 werner 36
811    
812 twoaday 88 /* Set the file status of the given command @fm_cmd.
813     @success is 0 on success. */
814 werner 36 static void
815 twoaday 88 fm_set_status (listview_ctrl_t lv, int pos, int fm_cmd,
816     gpgme_sig_mode_t sigmode, int success, const char *output)
817 werner 36 {
818     char status[128], operat[128];
819     int update = 1;
820     const char *s;
821    
822 twoaday 88 if (fm_cmd == FM_LIST)
823 werner 36 return;
824     success ? s = "SUCCESS" : s = "FAILED";
825 twoaday 88 strcpy (operat, s);
826 werner 36
827     switch (fm_cmd) {
828     case FM_ENCRYPT:
829     case FM_ENCRYPT_DIR:
830 twoaday 88 case FM_SIGNENCRYPT: strcpy (status, "ENCRYPTED"); break;
831     case FM_DECRYPT: strcpy (status, "UNKNOWN"); break;
832     case FM_SIGN:
833     if (sigmode == GPGME_SIG_MODE_DETACH)
834     strcpy (status, "SIGNED-DETACH");
835 twoaday 119 else if (sigmode == GPGME_SIG_MODE_CLEAR)
836     strcpy (status, "SIGNED-CLEAR");
837 twoaday 88 else
838     strcpy (status, "SIGNED");
839     break;
840 werner 36 case FM_VERIFY: update = 0; break;
841 twoaday 88 case FM_SYMENC: strcpy (status, "SYMKEYENC"); break;
842 werner 36 case FM_IMPORT: update = 0; break;
843 twoaday 88 case FM_WIPE: strcpy (status, "WIPED"); break;
844     default: strcpy (status, "UNKNOWN"); break;
845 werner 36 }
846    
847 twoaday 119 if (success && update) {
848     listview_add_sub_item (lv, pos, 0, status);
849     listview_add_sub_item (lv, pos, 1, output);
850 werner 36 }
851     listview_add_sub_item( lv, pos, 2, operat );
852 twoaday 88 }
853 werner 36
854    
855     int
856     fm_clearsign_8bit (listview_ctrl_t lv, fm_state_s *ctx)
857     {
858     FILE *f;
859 twoaday 234 BYTE buf[32];
860 werner 36 char name[256];
861     int i, n, cnt=0;
862    
863     if (ctx->sigmode != GPGME_SIG_MODE_CLEAR)
864     return 0;
865 twoaday 226 listview_get_item_text (lv, -1, FM_COL_NAME, name, sizeof (name)-1);
866 werner 36 if (stristr (name, ".TXT"))
867     return 0;
868     f = fopen (name, "rb");
869     if (!f)
870     return -1; /* should never happen */
871     n = fread (buf, 1, 32, f);
872 twoaday 226 fclose (f);
873 werner 36 for (i = 0; i < n; i++) {
874     if (buf[i] == 0x00 || buf[i] > 170)
875     cnt++;
876     }
877     if (!cnt)
878     return 0;
879     n = -1;
880 twoaday 197 i = log_box (_("File Manager"), MB_WARN|MB_YESNO,
881 werner 36 _("\"%s\" does not seems to be a text file.\n"
882     "Do you really want to clearsign it?"), name);
883     if (i == IDYES)
884     n = 0;
885     return n;
886     }
887    
888 twoaday 197
889 werner 36 int
890     fm_parse_files (listview_ctrl_t lv, HWND dlg, int cmd)
891     {
892     struct secdel_confirm_s confirm = {0};
893     struct progress_filter_s pfx, pfx2;
894     fm_state_s * ctx;
895     int fm_cmd, sig_detached = 0;
896     int rc = 0, i, n, ndel = 0;
897     char fname[512], status[128];
898    
899     switch (cmd) {
900     case ID_FILEMISC_ENCRYPT: fm_cmd = FM_ENCRYPT; break;
901 twoaday 77 case ID_FILEMISC_ENCRYPT_ZIP:fm_cmd = FM_ENCRYPT_ZIP; break;
902 werner 36 case ID_FILEMISC_DECRYPT: fm_cmd = FM_DECRYPT; break;
903     case ID_FILEMISC_SYMENC: fm_cmd = FM_SYMENC; break;
904     case ID_FILEMISC_SIGN: fm_cmd = FM_SIGN; break;
905     case ID_FILEMISC_VERIFY: fm_cmd = FM_VERIFY; break;
906     case ID_FILEMISC_IMPORT: fm_cmd = FM_IMPORT; break;
907     case ID_FILEMISC_WIPE: fm_cmd = FM_WIPE; break;
908     case ID_FILEMISC_LIST: fm_cmd = FM_LIST; break;
909     case ID_FILEMISC_SIGNENC: fm_cmd = FM_SIGNENCRYPT; break;
910     default: return 1; /* unknown command */
911     }
912    
913     if (fm_get_current_pos (lv) == -1)
914 twoaday 77 return WPTERR_GENERAL;
915 werner 36 rc = fm_state_new (&ctx);
916     if (rc)
917     BUG (0);
918     ctx->dlg = dlg;
919    
920     // XXX: for file operations the progress dialog will be
921     // reloaded somewhere and thus a 'dummy' dialog remains
922    
923     /* we use it here to make sure that pfx_cleanup will not use
924     any weird values. */
925     memset (&pfx, 0, sizeof (pfx));
926     ctx->prog_cb = NULL;
927     if (cmd != FM_VERIFY && cmd != FM_SIGN /*&& reg_prefs.fm.progress > 0*/) {
928     pfx.hwnd = dlg;
929     /*gpgme_set_progress_cb (ctx->ctx, progress_callback, &pfx);*/
930     /*ctx->prog_cb = &pfx;*/
931     }
932    
933     /* Commands we need before we can perform the main command */
934     switch (fm_cmd) {
935 twoaday 77 case FM_ENCRYPT_ZIP:
936 werner 36 case FM_ENCRYPT:
937     case FM_SIGNENCRYPT:
938     if (fm_cmd == FM_SIGNENCRYPT)
939     ctx->req_signer = 1;
940 twoaday 105 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_ENCRYPT,
941     ctx->dlg, file_encrypt_dlg_proc, (LPARAM)ctx);
942 werner 36 if (ctx->cancel == 1) {
943 twoaday 105 rc = WPTERR_GENERAL;
944 werner 36 goto leave;
945     }
946     break;
947    
948     case FM_SIGN:
949     DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_FILE_SIGN, dlg,
950     file_sign_dlg_proc, (LPARAM) ctx);
951     if (ctx->cancel == 1 || fm_clearsign_8bit (lv, ctx)) {
952     rc = WPTERR_GENERAL;
953     goto leave;
954     }
955     break;
956    
957     case FM_WIPE:
958     memset (&pfx2, 0, sizeof (pfx2));
959     secure_unlink_set_cb (progress_callback, &pfx2);
960     break;
961     }
962    
963     for( i = 0, n = 0; i < listview_count_items( lv, 0 ); i++ ) {
964     if( !listview_get_item_state( lv, i ) )
965     continue;
966     listview_get_item_text( lv, i, 0, status, sizeof (status) -1 );
967     if (!strcmp( status, "ENCRYPTED" ) && fm_cmd == FM_DECRYPT)
968     n++;
969     if (!strcmp( status, "UNKNOWN" ) && fm_cmd == FM_SIGN)
970     n++;
971     if (fm_cmd == FM_WIPE)
972     ndel++;
973     }
974    
975     if (n > 1 && fm_cmd != FM_SYMENC)
976     ctx->cache_cb = 1;
977    
978     if (fm_cmd == FM_WIPE && ndel > 0) {
979     memset (&confirm, 0, sizeof confirm);
980     confirm.lv_files = lv;
981     DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILES_SECDEL, ctx->dlg,
982 twoaday 77 file_secdel_confirm_dlg_proc, (LPARAM)&confirm);
983 werner 36 if (!confirm.yes)
984     goto leave;
985     }
986 twoaday 119
987 twoaday 77 if (fm_cmd == FM_ENCRYPT_ZIP)
988     fm_encrypt_into_zip (ctx, lv);
989    
990     for (i = 0; i < listview_count_items (lv, 0); i++) {
991 twoaday 177 if (!listview_get_item_state (lv, i))
992 werner 36 continue;
993 twoaday 177 listview_get_item_text (lv, i, 1, fname, sizeof (fname) - 1);
994 twoaday 119 if( file_exist_check (fname) && !is_directory (fname)) {
995     log_box (_("File Manager"), MB_ERR,
996     _("\"%s\" does not exist"), fname);
997 werner 36 continue;
998     }
999 twoaday 119 if (is_directory (fname))
1000 werner 36 fm_cmd = FM_ENCRYPT_DIR;
1001 twoaday 119 if (!fm_check_file_type (lv, i, fm_cmd))
1002 werner 36 continue;
1003 twoaday 119 sig_detached = fm_check_detached_sig (lv, i);
1004 twoaday 77 switch (fm_cmd) {
1005 werner 36 case FM_LIST: rc = fm_list( fname, dlg ); break;
1006     case FM_WIPE: rc = fm_wipe( fname ); break;
1007     case FM_ENCRYPT: rc = fm_encrypt( ctx, fname, 0 ); break;
1008     case FM_ENCRYPT_DIR: rc = fm_encrypt_directory( ctx, fname ); break;
1009     case FM_SIGNENCRYPT: rc = fm_encrypt( ctx, fname, 1 ); break;
1010     case FM_DECRYPT: rc = fm_decrypt( ctx, fname ); break;
1011     case FM_SIGN: rc = fm_sign( ctx, fname ); break;
1012 twoaday 177 case FM_SYMENC: rc = fm_sym_encrypt (ctx, fname); break;
1013 werner 36 case FM_VERIFY: rc = fm_verify (ctx, sig_detached, fname);break;
1014     case FM_IMPORT:
1015     free_if_alloc (ctx->opaque);
1016     ctx->opaque = m_strdup (fname);
1017 twoaday 177 DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
1018     file_import_dlg_proc, (LPARAM)ctx);
1019 werner 36 if (ctx->cancel == 1)
1020     continue;
1021     rc = fm_import (ctx, fname);
1022     break;
1023     }
1024 twoaday 177 if (ctx->cancel == 1) {
1025     ctx->cancel = 0;
1026     continue;
1027     }
1028 twoaday 88 fm_set_status (lv, i, fm_cmd, ctx->sigmode, !rc, ctx->output);
1029 werner 36 free_if_alloc (ctx->output);
1030     progress_cleanup (&pfx);
1031     }
1032 twoaday 77
1033 werner 36 if (fm_cmd == FM_WIPE) {
1034     secure_unlink_set_cb (NULL, NULL);
1035     progress_cleanup (&pfx2);
1036     }
1037     if (ctx->cache_cb) {
1038     release_gpg_passphrase_cb (&ctx->pass_cb);
1039     ctx->cache_cb = 0; /* make sure it's only used for this session! */
1040     }
1041    
1042     /* remove wipe files from the list */
1043     n = listview_count_items (lv, 0);
1044     while (n--) {
1045     listview_get_item_text (lv, n, 0, status, sizeof (status) - 1);
1046 twoaday 77 if (!strcmp (status, "WIPED"))
1047 werner 36 listview_del_item (lv, n);
1048     }
1049    
1050     leave:
1051     if (!rc)
1052     fm_state_release (ctx);
1053     progress_cleanup (&pfx);
1054     return rc;
1055     } /* fm_parse_files */
1056    
1057    
1058     /* Wipe the given file @name with the delete mode
1059     from the configuration.
1060     Return value: 0 on success. */
1061     int
1062     fm_wipe (const char *name)
1063     {
1064     int rc;
1065    
1066     SetCursor (LoadCursor (NULL, IDC_WAIT));
1067     remove_crit_file_attrs (name, 1);
1068     rc = secure_unlink (name, reg_prefs.wipe_mode);
1069     SetCursor (LoadCursor (NULL, IDC_ARROW));
1070     return rc;
1071     }
1072    
1073    
1074     /* Dump out the given PGP packets from file @name in a dialog. */
1075     int
1076     fm_list (const char *name, HWND dlg)
1077     {
1078     dialog_box_param( glob_hinst, (LPCTSTR)IDD_WINPT_FILE_STAT, dlg,
1079     file_stat_dlg_proc, (LPARAM)name, _("File Status"),
1080     IDS_WINPT_FILE_STAT );
1081     return 0;
1082     }
1083    
1084    
1085     static int
1086     ask_filename (fm_state_t c, const char *msg, char **dst)
1087     {
1088 twoaday 226 const char *s;
1089 werner 36
1090 twoaday 77 s = get_filesave_dlg (c->dlg, msg, NULL, NULL);
1091 werner 36 if (!s)
1092     return WPTERR_GENERAL;
1093    
1094     if (dst != NULL)
1095     free_if_alloc (*dst);
1096     free_if_alloc (c->output);
1097     c->output = m_strdup (s);
1098     if (dst)
1099     *dst = fm_quote_file (s);
1100     return 0;
1101     }
1102    
1103    
1104     int
1105     fm_encrypt (fm_state_t c, const char *name, int sign)
1106     {
1107     gpgme_error_t err;
1108     gpgme_key_t key = NULL;
1109     gpgme_ctx_t ctx = c->ctx;
1110     file_data_t in=NULL, out=NULL;
1111     char *keyid = NULL, ext[5];
1112 twoaday 69 /*int no_compr = 0;*/
1113 werner 36 int rc = 0;
1114    
1115     c->output = new char[strlen (name) + 5 + 1];
1116     if (!c->output)
1117     BUG (0);
1118     strcpy (ext, file_get_extension (ctx, c->sigmode));
1119     strcpy (c->output, name);
1120 twoaday 105 strcat (c->output, ext);
1121 werner 36
1122     if (!overwrite_file (c->output)) {
1123 twoaday 226 rc = ask_filename (c, _("Enter Filename for Encrypted File"), NULL);
1124 werner 36 if (rc)
1125     goto leave;
1126     }
1127    
1128 twoaday 105 err = gpg_file_data_new (name, F_DATA_READ, &in);
1129 werner 36 if (err)
1130     goto leave;
1131 twoaday 105 remove_crit_file_attrs (c->output, 0);
1132     err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);
1133 werner 36 if (err)
1134     goto leave;
1135    
1136     /*
1137     if (c->prog_cb) {
1138     c->prog_cb->what = name;
1139     gpg_file_data_set_cb (in, c->prog_cb);
1140     }
1141     */
1142    
1143 twoaday 105 /* XXX: disable compression for multi-media files.
1144 werner 36 no_compr = is_multi_media (name);
1145     gpgme_control (ctx, GPGME_CTRL_NO_COMPR, no_compr);
1146     */
1147    
1148     if (sign) {
1149     if (gpgme_signers_enum (ctx, 0) == NULL) {
1150     keyid = get_gnupg_default_key ();
1151     if (!keyid) {
1152     msg_box (c->dlg, _("Could not get default secret key."),
1153     _("Signing"), MB_ERR);
1154     rc = WPTERR_GENERAL;
1155     goto leave;
1156     }
1157     if (get_seckey (keyid, &key))
1158     BUG (0);
1159     gpgme_signers_add (ctx, key);
1160     }
1161     else {
1162 twoaday 77 gpgme_key_t sigkey = gpgme_signers_enum (ctx, 0);
1163     if (sigkey && sigkey->subkeys) {
1164     keyid = m_strdup (sigkey->subkeys->keyid);
1165 werner 36 }
1166     }
1167     if (!c->init_cb || !c->cache_cb) {
1168     set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_SIGN,
1169     c->dlg, _("Signing"));
1170     c->init_cb = 1;
1171     }
1172     op_begin ();
1173     err = gpgme_op_encrypt_sign (ctx, c->recp, GPGME_ENCRYPT_ALWAYS_TRUST,
1174     in->dat, out->dat);
1175     op_end ();
1176     if (!c->cache_cb)
1177     release_gpg_passphrase_cb (&c->pass_cb);
1178     if (c->pass_cb.cancel) {
1179     rc = WPTERR_GENERAL;
1180     goto leave;
1181     }
1182     if (err) {
1183     msg_box (c->dlg, gpgme_strerror (err), _("Sign"), MB_ERR);
1184     if (gpgme_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
1185     agent_del_cache (keyid);
1186     rc = WPTERR_GENERAL;
1187     goto leave;
1188     }
1189     }
1190     else {
1191     op_begin ();
1192     err = gpgme_op_encrypt (ctx, c->recp, GPGME_ENCRYPT_ALWAYS_TRUST,
1193     in->dat, out->dat);
1194     op_end ();
1195     if (err) {
1196     msg_box (c->dlg, gpgme_strerror (err), _("Encrypt"), MB_ERR);
1197     rc = WPTERR_GENERAL;
1198     goto leave;
1199     }
1200     }
1201    
1202     leave:
1203     if (in)
1204     gpg_file_data_release (in);
1205     if (out)
1206     gpg_file_data_release (out);
1207 twoaday 77 free_if_alloc (keyid);
1208 twoaday 76 if (!rc && c->wipe)
1209     secure_unlink (name, WIPE_MODE_SIMPLE);
1210 werner 36 return rc;
1211     }
1212    
1213    
1214     int
1215     fm_sym_encrypt (fm_state_t c, const char * name)
1216     {
1217     gpgme_ctx_t ctx = c->ctx;
1218     gpgme_error_t err;
1219     file_data_t in=NULL, out=NULL;
1220     int rc = 0, cancel = 0;
1221 twoaday 226 char ext[5], *pass;
1222 werner 36
1223 twoaday 226 pass = request_passphrase2 (_("Symmetric Encryption"), 0, &cancel);
1224 twoaday 177 if (cancel) {
1225     c->cancel = 1;
1226 werner 36 return 0;
1227 twoaday 177 }
1228 werner 36
1229 twoaday 226 /* XXX: a convenient feature could be to select the preferred
1230     symmetric algorithm. */
1231 werner 36 c->output = new char[strlen (name) + 5 + 1];
1232     if (!c->output)
1233     BUG (0);
1234     strcpy (ext, file_get_extension (ctx, c->sigmode));
1235     strcpy (c->output, name);
1236     strcat (c->output, ext);
1237    
1238     if (overwrite_file (c->output) == 0) {
1239     rc = WPTERR_GENERAL;
1240     goto leave;
1241     }
1242    
1243 twoaday 226 gpgme_set_passphrase_cb (ctx, sym_passphrase_cb, pass);
1244 werner 36 err = gpg_file_data_new (name, 1, &in);
1245     if (err)
1246     goto leave;
1247     err = gpg_file_data_new (c->output, 0, &out);
1248     if (err)
1249     goto leave;
1250    
1251     op_begin ();
1252     err = gpgme_op_encrypt (ctx, NULL, GPGME_ENCRYPT_ALWAYS_TRUST,
1253     in->dat, out->dat);
1254     op_end ();
1255     if (err) {
1256     msg_box (c->dlg, gpgme_strerror (err), _("Symmetric"), MB_ERR);
1257     rc = WPTERR_GENERAL;
1258     goto leave;
1259     }
1260     if (file_exist_check (c->output)) {
1261     msg_box (c->dlg, _("Encryption failed."), _("Symmetric"), MB_ERR);
1262     rc = WPTERR_GENERAL;
1263     }
1264    
1265     leave:
1266     if (in)
1267     gpg_file_data_release (in);
1268     if (out)
1269     gpg_file_data_release (out);
1270     sfree_if_alloc (pass);
1271     return rc;
1272 twoaday 105 }
1273 werner 36
1274    
1275     /* Check the recipients if we have at least one secret key. */
1276     bool
1277 twoaday 217 is_seckey_available (gpgme_recipient_t rset)
1278 werner 36 {
1279     gpgme_recipient_t r;
1280 twoaday 217 winpt_key_s key;
1281 werner 36
1282 twoaday 105 for (r=rset; r; r = r->next) {
1283 werner 36 if (gpgme_err_code (r->status) == GPG_ERR_NO_SECKEY)
1284     continue;
1285     else {
1286 twoaday 217 memset (&key, 0, sizeof (key));
1287 werner 36 /* extra check to make sure the key is available right now. */
1288 twoaday 217 if (!winpt_get_seckey (r->keyid, &key)) {
1289     winpt_release_pubkey (&key);
1290 werner 36 return true;
1291 twoaday 217 }
1292     winpt_release_pubkey (&key);
1293 werner 36 }
1294     }
1295     return false;
1296     }
1297    
1298    
1299 twoaday 195 /* If the decrypt result contains the original file name,
1300     we use it instead of the artificial "output - .gpg" string. */
1301     static int
1302 twoaday 197 restore_original_name (const char *output, const char *file_name)
1303 twoaday 195 {
1304     char *dir;
1305     char *orig;
1306     int rc = 0;
1307    
1308     dir = strrchr (output, '\\');
1309     if (!dir)
1310 twoaday 197 orig = strdup (file_name);
1311 twoaday 195 else {
1312 twoaday 197 orig = (char*)calloc (1, strlen (file_name)+ 1 +
1313 twoaday 195 strlen (output)+1);
1314     if (!orig)
1315     BUG (0);
1316     memcpy (orig, output, (dir-output)+1);
1317 twoaday 197 strcat (orig, file_name);
1318 twoaday 195 }
1319 twoaday 214 /* XXX: we need to find out if the string needs to be utf8 decoded. */
1320 twoaday 195 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 werner 36 /* Decrypt the file @name. */
1331     int
1332     fm_decrypt (fm_state_t c, const char *name)
1333     {
1334     gpgme_error_t err;
1335     gpgme_ctx_t ctx = c->ctx;
1336     gpgme_decrypt_result_t res;
1337     gpgme_verify_result_t sigres;
1338 twoaday 195 file_data_t in = NULL, out = NULL;
1339 werner 36 int rc = 0;
1340    
1341     if (!c->init_cb || !c->cache_cb) {
1342 twoaday 119 set_gpg_passphrase_cb (&c->pass_cb, c->ctx, GPG_CMD_DECRYPT,
1343 werner 36 c->dlg, _("Decryption"));
1344 twoaday 119 c->init_cb = 1;
1345     }
1346 werner 36
1347     c->output = m_strdup (name);
1348     if (is_openpgp_ext (c->output))
1349     c->output[strlen (c->output)-4] = '\0';
1350     else {
1351 twoaday 41 const char *s;
1352     s = get_filesave_dlg (c->dlg, _("Choose Filename for Output"),
1353     NULL, NULL);
1354 werner 36 if (s) {
1355     free_if_alloc (c->output);
1356     c->output = m_strdup (s);
1357     }
1358     }
1359    
1360     if (overwrite_file (c->output) == 0) {
1361 twoaday 226 rc = ask_filename (c, _("Enter Filename for Plaintext File"), NULL);
1362 werner 36 if (rc)
1363     goto leave;
1364 twoaday 105 }
1365 werner 36
1366 twoaday 214 /* 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 twoaday 105 err = gpg_file_data_new (name, F_DATA_READ, &in);
1371 werner 36 if (err)
1372     goto leave;
1373 twoaday 105 remove_crit_file_attrs (c->output, 0);
1374     err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);
1375 werner 36 if (err)
1376     goto leave;
1377 twoaday 214
1378 werner 36 op_begin ();
1379     err = gpgme_op_decrypt_verify (ctx, in->dat, out->dat);
1380     op_end ();
1381     if (!c->cache_cb)
1382     release_gpg_passphrase_cb (&c->pass_cb);
1383     if (c->pass_cb.cancel) {
1384     rc = WPTERR_GENERAL;
1385     goto leave;
1386     }
1387    
1388     res = gpgme_op_decrypt_result (ctx);
1389 twoaday 217 if (res && res->recipients && !is_seckey_available (res->recipients)) {
1390 twoaday 256 const char *keyid = get_keyid_from_fpr (res->recipients->keyid);
1391     char *p = get_key_userid (keyid);
1392 werner 36 gpgme_pubkey_algo_t pkalgo = res->recipients->pubkey_algo;
1393    
1394 twoaday 195 log_box (_("Decryption"), MB_ERR,
1395 twoaday 256 _("Encrypted with %s key, ID 0x%s.%s\n"
1396 werner 36 "Decryption failed: secret key not available."),
1397 twoaday 256 get_key_pubalgo (pkalgo), keyid, p);
1398 werner 36 rc = WPTERR_GENERAL;
1399     free_if_alloc (p);
1400     goto leave;
1401     }
1402     else if (err) {
1403     msg_box (c->dlg, gpgme_strerror (err), _("Decrypt"), MB_ERR);
1404     rc = WPTERR_GENERAL;
1405     goto leave;
1406     }
1407     if (file_exist_check (c->output)) {
1408 twoaday 105 log_box ("Decrypt", MB_ERR,
1409     _("Decryption failed.\n%s: does not exist."), c->output);
1410 werner 36 rc = WPTERR_GENERAL;
1411 twoaday 195 goto leave;
1412 werner 36 }
1413 twoaday 195 else if (res && res->file_name) {
1414 twoaday 214 char *file;
1415 twoaday 217 int id = IDNO;
1416 twoaday 214
1417     file = strrchr (c->output, '\\');
1418     if (!file)
1419     file = c->output;
1420     else
1421     file++;
1422 twoaday 217 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 twoaday 214 res->file_name, file);
1427 twoaday 195 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 werner 36 sigres = gpgme_op_verify_result (ctx);
1435     if (sigres && sigres->signatures)
1436 twoaday 220 verify_show_signature_state (sigres->signatures);
1437 werner 36
1438     leave:
1439     if (in)
1440     gpg_file_data_release (in);
1441     if (out)
1442     gpg_file_data_release (out);
1443 twoaday 119
1444 werner 36 return rc;
1445     }
1446    
1447    
1448     int
1449     fm_sign (fm_state_t c, const char * name)
1450 twoaday 105 {
1451 werner 36 gpgme_ctx_t ctx = c->ctx;
1452     gpgme_error_t err;
1453     file_data_t in=NULL, out=NULL;
1454     char ext[5];
1455 twoaday 105 int rc = 0;
1456 werner 36
1457     if (!c->init_cb || !c->cache_cb) {
1458 twoaday 119 set_gpg_passphrase_cb (&c->pass_cb, c->ctx,
1459     GPG_CMD_SIGN, c->dlg, _("Signing"));
1460 werner 36 c->init_cb = 1;
1461     }
1462    
1463     free_if_alloc (c->output);
1464     c->output = new char[strlen (name) + 5 + 1];
1465 twoaday 105 if (!c->output)
1466     BUG (NULL);
1467 werner 36 strcpy (ext, file_get_extension (ctx, c->sigmode));
1468     strcpy (c->output, name);
1469     strcat (c->output, ext);
1470    
1471     if (!overwrite_file (c->output)) {
1472 twoaday 226 rc = ask_filename (c, _("Enter Filename for Signed File"), NULL);
1473 werner 36 if (rc)
1474     goto leave;
1475     }
1476 twoaday 105
1477     err = gpg_file_data_new (name, F_DATA_READ, &in);
1478 werner 36 if (err)
1479     goto leave;
1480 twoaday 105 remove_crit_file_attrs (c->output, 0);
1481     err = gpg_file_data_new (c->output, F_DATA_WRITE, &out);
1482 werner 36 if (err)
1483     goto leave;
1484    
1485     op_begin ();
1486     err = gpgme_op_sign (ctx, in->dat, out->dat, c->sigmode);
1487     op_end ();
1488 twoaday 105 if (!c->cache_cb)
1489 werner 36 release_gpg_passphrase_cb (&c->pass_cb);
1490 twoaday 105 if (c->pass_cb.cancel) {
1491 werner 36 rc = WPTERR_GENERAL;
1492     goto leave;
1493     }
1494 twoaday 105 if (err) {
1495     msg_box (c->dlg, gpgme_strerror (err), _("Sign"), MB_ERR);
1496 werner 36 rc = WPTERR_GENERAL;
1497     goto leave;
1498     }
1499    
1500     leave:
1501     if (in)
1502     gpg_file_data_release (in);
1503     if (out)
1504     gpg_file_data_release (out);
1505     return rc;
1506     }
1507    
1508    
1509 twoaday 105 static void
1510 werner 36 fm_add_sig_stat (file_sig_ctx_t log)
1511     {
1512 twoaday 208 struct winpt_key_s key;
1513 werner 36 const char *kid;
1514    
1515 twoaday 208 memset (&key, 0, sizeof (key));
1516     kid = get_keyid_from_fpr (log->sig->fpr);
1517     log->use_uid = 0;
1518     if (!winpt_get_pubkey (kid, &key)) {
1519     log->user_id = key.ext->uids->uid;
1520 werner 36 log->use_uid = 1;
1521     }
1522     file_verify_add_state (log);
1523 twoaday 256 winpt_release_pubkey (&key);
1524 werner 36 }
1525    
1526    
1527 twoaday 105 /* Verify a detached signature from the clipboard. */
1528 werner 36 static int
1529 twoaday 105 verify_pasted (listview_ctrl_t lv, fm_state_t ctx,
1530     const char *dat, int pos, HWND dlg)
1531 werner 36 {
1532 twoaday 105 FILE *fp;
1533 werner 36 char stat[32];
1534 twoaday 105 char file[256], *fname = NULL;
1535     int del_end = 0;
1536 werner 36
1537 twoaday 226 listview_get_item_text (lv, pos, FM_COL_STAT, stat, sizeof (stat)-1);
1538     listview_get_item_text (lv, pos, FM_COL_NAME, file, sizeof (file)-1);
1539 werner 36 if (strcmp (stat, "UNKNOWN"))
1540     return 0;
1541     fname = make_filename (NULL, file, "asc");
1542     if (file_exist_check (fname) != 0) {
1543     fp = fopen (fname, "wb");
1544     if (fp == NULL) {
1545 twoaday 226 log_box (_("File Manager"), MB_ERR, "Could not create '%s'", fname);
1546 werner 36 free_if_alloc (fname);
1547 twoaday 105 return WPTERR_GENERAL;
1548     }
1549 werner 36 fwrite (dat, 1, strlen (dat), fp);
1550     fclose (fp);
1551     del_end = 1;
1552     }
1553     fm_verify (ctx, 1, fname);
1554     if (del_end)
1555 twoaday 226 DeleteFile (fname);
1556 werner 36 free_if_alloc (fname);
1557     return 0;
1558     }
1559    
1560    
1561 twoaday 105 /* Figure out if the clipboard contains a detached signature. */
1562 werner 36 int
1563     fm_verify_pasted_detsig (listview_ctrl_t lv, HWND dlg)
1564     {
1565     fm_state_t ctx = NULL;
1566     char * dat=NULL;
1567     int i, fnd = 0;
1568    
1569     dat = get_clip_text (NULL);
1570     if (!dat || !strstr (dat, "BEGIN PGP SIGNATURE")) {
1571     msg_box (dlg, _("Could not find detached signature in the clipboard."),
1572     _("File Manager"), MB_ERR);
1573     free_if_alloc (dat);
1574     return WPTERR_GENERAL;
1575     }
1576     /* XXX find a way to filter out bad signatures or just ignore all in
1577     this case */
1578     fm_state_new (&ctx);
1579 twoaday 105 i = listview_get_curr_pos (lv);
1580     if (i= -1) {
1581 werner 36 verify_pasted (lv, ctx, dat, i, dlg);
1582     fnd = 1;
1583     }
1584     else {
1585     for (i=0; i < listview_count_items (lv, 0); i++) {
1586     verify_pasted (lv, ctx, dat, i, dlg);
1587     fnd = 1;
1588     }
1589     }
1590     if (!fnd)
1591     msg_box (dlg, _("No files to check."), _("File Manager"), MB_INFO);
1592     free_if_alloc (dat);
1593     fm_state_release (ctx);
1594     return 0;
1595     }
1596    
1597    
1598     /* Extract automatically the output file name from @name.
1599     If @detached is 1, a detached sig is assumed. */
1600     static int
1601     get_output_file (fm_state_t c, const char *name, int detached)
1602     {
1603     const char *file = NULL;
1604     const char *title;
1605     char fname[384];
1606    
1607     if (detached)
1608     title = _("Select Data File");
1609     else
1610     title = _("Selected Output File");
1611    
1612 twoaday 226 if (is_openpgp_ext (name)) {
1613 werner 36 _snprintf (fname, sizeof (fname) - 1, "%s", name);
1614     fname[strlen (fname) - 4] = '\0';
1615     if (file_exist_check (fname) == 0 && detached)
1616     file = fname;
1617     else if (!detached) {
1618     /* If the signature is clear or normal, make sure we do not
1619     overwrite the original file if it exists. */
1620     if (file_exist_check (fname) == 0 && !overwrite_file (fname)) {
1621     file = get_filesave_dlg (c->dlg, title, NULL, NULL);
1622     if (!file)
1623     return WPTERR_GENERAL;
1624     }
1625     else
1626     file = fname;
1627     }
1628     }
1629     if (!file)
1630     file = get_fileopen_dlg (c->dlg, title, NULL, NULL);
1631     if (file) {
1632     free_if_alloc (c->output);
1633     c->output = m_strdup (file);
1634     }
1635     else {
1636     msg_box (c->dlg, _("Invalid file name. Exit"), _("Verify"), MB_ERR);
1637     return WPTERR_GENERAL;
1638     }
1639     if (detached)
1640     c->sigmode = GPGME_SIG_MODE_DETACH;
1641     else {
1642 twoaday 197 if (stristr (name, ".asc"))
1643 werner 36 c->sigmode = GPGME_SIG_MODE_CLEAR;
1644     else
1645     c->sigmode = GPGME_SIG_MODE_NORMAL;
1646     }
1647     return 0;
1648     }
1649    
1650    
1651     /* Verify the signature from the file @name. If @detached 1,
1652     it is assumed that a detached signature should be checked. */
1653     int
1654     fm_verify (fm_state_t c, int detached, const char *name)
1655     {
1656     gpgme_ctx_t ctx = c->ctx;
1657     gpgme_error_t err;
1658     gpgme_signature_t s;
1659     gpgme_verify_result_t res;
1660     struct file_sig_ctx_s log;
1661     file_data_t in=NULL, out=NULL;
1662     int rc = 0;
1663    
1664 twoaday 197 if (stristr (name, ".sig"))
1665 werner 36 detached = 1;
1666    
1667     if (get_output_file (c, name, detached))
1668     return WPTERR_GENERAL;
1669    
1670     memset (&log, 0, sizeof (log));
1671     log.file = m_strdup (name);
1672     file_verify_create_dlg ();
1673    
1674 twoaday 105 err = gpg_file_data_new (name, F_DATA_READ, &in);
1675 werner 36 if (err)
1676     goto leave;
1677 twoaday 105 err = gpg_file_data_new (c->output,
1678     detached? F_DATA_READ : F_DATA_WRITE, &out);
1679 werner 36 if (err)
1680     goto leave;
1681    
1682     op_begin ();
1683     if (c->sigmode == GPGME_SIG_MODE_DETACH)
1684     err = gpgme_op_verify (ctx, in->dat, out->dat, NULL);
1685     else
1686     err = gpgme_op_verify (ctx, in->dat, in->dat, out->dat);
1687     op_end ();
1688     if (err) {
1689     msg_box (c->dlg, gpgme_strerror (err), _("Verify"), MB_ERR);
1690     rc = WPTERR_GENERAL;
1691     goto leave;
1692     }
1693    
1694     res = gpgme_op_verify_result (ctx);
1695     for (s=res->signatures; s; s=s->next) {
1696     log.sig = s;
1697     fm_add_sig_stat (&log);
1698     }
1699     if (!c->output)
1700     c->output = m_strdup (name); /* for later use */
1701    
1702     leave:
1703     if (in)
1704     gpg_file_data_release (in);
1705     if (out)
1706     gpg_file_data_release (out);
1707 twoaday 105 free_if_alloc (log.file);
1708 werner 36 return rc;
1709     }
1710    
1711    
1712 twoaday 105 /* Import the keys from the file @name.
1713     Return value: 0 on success. */
1714 werner 36 int
1715     fm_import (fm_state_t c, const char *name)
1716     {
1717     gpgme_ctx_t ctx = c->ctx;
1718     gpgme_error_t err;
1719     gpgme_import_result_t res;
1720     file_data_t keydata = NULL;
1721     int rc = 0;
1722    
1723     free_if_alloc (c->output);
1724     c->output = m_strdup (name);
1725    
1726 twoaday 105 err = gpg_file_data_new (name, F_DATA_READ, &keydata);
1727 werner 36 if (err)
1728     goto leave;
1729    
1730     op_begin ();
1731     err = gpgme_op_import (ctx, keydata->dat);
1732     op_end ();
1733     if (err) {
1734     msg_box (c->dlg, gpgme_strerror (err), _("Import"), MB_ERR);
1735     rc = WPTERR_GENERAL;
1736     goto leave;
1737     }
1738    
1739     res = gpgme_op_import_result (ctx);
1740     print_import_status (res);
1741     if (res->no_user_id > 0) {
1742 twoaday 105 msg_box (c->dlg, _("Key without a self signature was dectected!\n"
1743 werner 36 "(This key is NOT usable for encryption, etc)\n"
1744     "\n"
1745     "Cannot import these key(s)!"), _("Import"), MB_INFO);
1746     }
1747    
1748     leave:
1749     if (keydata)
1750     gpg_file_data_release (keydata);
1751     return rc;
1752 twoaday 105 }
1753 werner 36
1754    
1755     /* Export the selected keys from the File Manager to a file. */
1756     int
1757     fm_export (fm_state_t c)
1758 twoaday 197 {
1759 werner 36 gpgme_ctx_t ctx = c->ctx;
1760     gpgme_error_t err;
1761     gpgme_key_t *rset = c->recp;
1762     file_data_t keydata = NULL;
1763 twoaday 94 const char *name;
1764 werner 36 char *p = NULL, *patt = NULL;
1765 twoaday 197 int rc = 0;
1766 werner 36
1767     if (!rset || !rset[0]) {
1768 twoaday 226 msg_box (c->dlg, _("No key was selected for export."),
1769     _("Export"), MB_ERR);
1770 werner 36 rc = WPTERR_GENERAL;
1771     goto leave;
1772     }
1773    
1774 twoaday 105 if (rset[1] == NULL) /* count == 1*/
1775 twoaday 129 p = km_gen_export_filename (rset[0]->subkeys->keyid+8, 0);
1776 werner 36
1777 twoaday 77 name = get_filesave_dlg (c->dlg, _("Choose Name for Key File"),
1778 werner 36 NULL, p? p : NULL);
1779     if (!name)
1780 twoaday 218 name = reg_prefs.default_ext? "keys.pgp" : "keys.gpg";
1781 werner 36
1782     patt = gpg_keylist_to_pattern (rset, c->n_recp);
1783    
1784 twoaday 105 err = gpg_file_data_new (name, F_DATA_WRITE, &keydata);
1785 werner 36 if (err)
1786     goto leave;
1787    
1788     op_begin ();
1789     err = gpgme_op_export (ctx, patt, 0, keydata->dat);
1790     op_end ();
1791     if (err) {
1792     msg_box (c->dlg, gpgme_strerror (err), _("Export"), MB_ERR);
1793     rc = WPTERR_GENERAL;
1794     goto leave;
1795     }
1796     log_box (_("GnuPG status"), MB_OK, _("Finished (Output: %s)"), name);
1797    
1798     leave:
1799     if (keydata)
1800     gpg_file_data_release (keydata);
1801 twoaday 197 safe_free (patt);
1802 werner 36 free_if_alloc (p);
1803     return rc;
1804     }
1805    
1806    
1807     /* Parse the command line and process the given file. */
1808     int
1809     fm_parse_command_line (char *cmdl)
1810     {
1811     fm_state_t ctx;
1812     const char *s;
1813     char *p, *fn = NULL;
1814     int count = 0, detached = 0;
1815     int type;
1816    
1817     if (!cmdl || !*cmdl)
1818     return 0;
1819    
1820     fm_state_new (&ctx);
1821     ctx->dlg = GetActiveWindow ();
1822     ctx->cache_cb = 1;
1823    
1824     p = cmdl;
1825     if (p && *p > 32 && !stristr (p, "winpt.exe")
1826     && !strstr (p, "--" )) {
1827     count++;
1828     if (*p == '"') { /* need to remove quotes */
1829     fn = new char[strlen (p)];
1830     if (!fn)
1831     BUG (NULL);
1832     memcpy (fn, p+1, strlen (p) - 2);
1833     fn[strlen (p) -2] = '\0';
1834     }
1835     else
1836     fn = m_strdup (p);
1837     s = fm_get_file_type (fn, &type);
1838     if (!s || !strcmp (s, "UNKNOWN"))
1839     s = gnupg_check_file_ext (fn, &type);
1840     if (type == PGP_NONE) {
1841     log_box (_("File Manager"), MB_ERR,
1842     _("%s: no valid OpenPGP data found."), p);
1843     free_if_alloc (fn);
1844     return count;
1845     }
1846     switch (type) {
1847     case PGP_MESSAGE:
1848     fm_decrypt (ctx, fn);
1849     break;
1850    
1851     case PGP_PUBKEY:
1852     case PGP_SECKEY:
1853     fm_import (ctx, fn);
1854     break;
1855    
1856     case PGP_SIG:
1857     case PGP_CLEARSIG:
1858     if (type == PGP_SIG)
1859     detached = 1;
1860     fm_verify (ctx, detached, fn);
1861     file_verify_wait ();
1862 twoaday 77 break;
1863 twoaday 88
1864 twoaday 77 default:
1865     break;
1866 werner 36 }
1867     }
1868    
1869     wipememory (&ctx->pass_cb, sizeof (ctx->pass_cb));
1870     free_if_alloc (fn);
1871     fm_state_release (ctx);
1872     return count;
1873     }
1874    
1875    
1876 twoaday 105 /* Extract the last folder name from @name. */
1877 werner 36 const char*
1878     default_dirname (const char *name)
1879     {
1880 twoaday 105 char *p = strrchr (name, '\\');
1881     if (!p)
1882 werner 36 return NULL;
1883     return p+1;
1884 twoaday 105 }
1885 werner 36
1886    
1887 twoaday 77 /* Store all selected files from @lv in a zip archive
1888     and encrypt the zip archive then.
1889     Return value: 0 on success. */
1890 werner 36 int
1891 twoaday 77 fm_encrypt_into_zip (fm_state_t ctx, listview_ctrl_t lv)
1892     {
1893     PK_FILE_LIST list=NULL;
1894 twoaday 197 const char *outfile, *ext;
1895 twoaday 77 char *out_enc;
1896 twoaday 197 int nitems;
1897 twoaday 77 int i, idx = -1;
1898     int rc;
1899    
1900 twoaday 197 nitems = listview_count_items (lv, 0);
1901 twoaday 77 if (!nitems) {
1902     msg_box (NULL, _("Encrypting into a ZIP archive makes sense with multiple files"),
1903     _("File Manager"), MB_ERR);
1904 twoaday 105 return WPTERR_GENERAL;
1905 twoaday 77 }
1906    
1907 twoaday 105 outfile = get_filesave_dlg (ctx->dlg, _("Choose File Name for Output"),
1908     NULL, "Encrypted_Files.zip");
1909 twoaday 77 if (!outfile)
1910 twoaday 105 return WPTERR_GENERAL;
1911 twoaday 77
1912     for (i=0; i < nitems; i++) {
1913 twoaday 256 char name[MAX_PATH+32];
1914    
1915 twoaday 77 if (!listview_get_item_state (lv, i))
1916     continue;
1917     if (idx == -1)
1918     idx = i;
1919     listview_get_item_text (lv, i, 1, name, sizeof (name)-1);
1920     pk_list_add (&list, name);
1921     }
1922    
1923     pk_archiv_create (list, outfile);
1924     pk_list_free (list);
1925    
1926     rc = fm_encrypt (ctx, outfile, 0);
1927     DeleteFile (outfile);
1928     if (rc)
1929     return rc;
1930    
1931 twoaday 197 ext = file_get_extension (ctx->ctx, ctx->sigmode)+1;
1932     out_enc = make_filename (NULL, outfile, ext);
1933 twoaday 88 fm_set_status (lv, idx, FM_ENCRYPT, (gpgme_sig_mode_t)0, 1, out_enc);
1934 twoaday 77 free_if_alloc (out_enc);
1935    
1936 twoaday 256 for (i=nitems; i > -1; i--) {
1937 twoaday 77 if (i != idx && listview_get_item_state (lv, i))
1938     listview_del_item (lv, i);
1939     }
1940     return 0;
1941     }
1942    
1943    
1944     int
1945 twoaday 105 fm_encrypt_directory (fm_state_t c, const char *name)
1946 twoaday 256 {
1947 werner 36 WIN32_FIND_DATA findbuf;
1948     HANDLE hd;
1949 twoaday 256 PK_FILE_LIST list = NULL;
1950 twoaday 226 const char *s;
1951     char *patt = NULL, *p;
1952 werner 36 int rc = 0;
1953    
1954 twoaday 105 if (!is_directory (name))
1955 werner 36 return -1;
1956 twoaday 105 patt = new char[strlen (name) + 4];
1957     if (!patt)
1958     BUG (NULL);
1959     strcpy (patt, name);
1960     strcat (patt, "\\*");
1961     hd = FindFirstFile (patt, &findbuf);
1962     if (!hd) {
1963     free_if_alloc (patt);
1964     return WPTERR_GENERAL;
1965 werner 36 }
1966 twoaday 226 if (strcmp (findbuf.cFileName, ".") && strcmp (findbuf.cFileName, "..")) {
1967     p = make_filename (name, findbuf.cFileName, NULL);
1968     pk_list_add (&list, p);
1969     free_if_alloc (p);
1970 werner 36 }
1971 twoaday 256 while (FindNextFile (hd, &findbuf)) {
1972     if (strcmp (findbuf.cFileName, ".") && strcmp (findbuf.cFileName, "..")) {
1973     p = make_filename (name, findbuf.cFileName, NULL);
1974     pk_list_add (&list, p);
1975     free_if_alloc (p);
1976 werner 36 }
1977     }
1978 twoaday 105 s = get_filesave_dlg (c->dlg, _("Choose a Name for the Archive"),
1979     NULL, default_dirname (name));
1980 twoaday 256 if (!s) {
1981 twoaday 226 msg_box (c->dlg, _("Invalid archive name. Exit."),
1982     _("Encrypt Directory"), MB_ERR);
1983 werner 36 rc = -1;
1984     goto leave;
1985     }
1986    
1987 twoaday 226 rc = pk_archiv_create (list, s);
1988 twoaday 256 if (rc)
1989 twoaday 226 msg_box (c->dlg, _("Could not create zip archive."),
1990     _("Encrypt Directory"), MB_ERR);
1991 werner 36 else {
1992 twoaday 226 fm_encrypt (c, s, 0);
1993     DeleteFile (s);
1994 werner 36 }
1995     leave:
1996     FindClose (hd);
1997 twoaday 226 pk_list_free (list);
1998     free_if_alloc (patt);
1999 werner 36 return rc;
2000 twoaday 105 }
2001 werner 36
2002    
2003     static int CALLBACK
2004 twoaday 105 fm_cmp_cb (LPARAM first, LPARAM second, LPARAM sortby)
2005 werner 36 {
2006 twoaday 244 fm_model_t a, b;
2007     int cmpres = 0;
2008 werner 36
2009 twoaday 244 a = (fm_model_t)first;
2010     b = (fm_model_t)second;
2011     if (!a || !b)
2012     return 0;
2013    
2014 twoaday 197 switch ((int)sortby) {
2015 twoaday 244 case FM_COL_STAT:
2016     cmpres = stricmp (a->status, b->status);
2017 werner 36 break;
2018 twoaday 244
2019     case FM_COL_NAME:
2020     cmpres = stricmp (a->name, b->name);
2021 werner 36 break;
2022 twoaday 244
2023     case FM_COL_OP:
2024     if (a->op && b->op)
2025     cmpres = stricmp (a->op, b->op);
2026 werner 36 break;
2027     }
2028 twoaday 244 return cmpres;
2029 twoaday 105 }
2030 werner 36
2031 twoaday 244
2032 twoaday 105 /* Sort the list items from @lv with the mode given by @sortby. */
2033 werner 36 int
2034 twoaday 105 fm_sort (listview_ctrl_t lv, int sortby)
2035 werner 36 {
2036 twoaday 244 return ListView_SortItems (lv->ctrl, fm_cmp_cb, (LPARAM)sortby);
2037 twoaday 105 }
2038 werner 36
2039    
2040 twoaday 105 /* Start the 'print md' dialog. Pass over the listview control
2041     @lv and the digest algo @mdalgo. */
2042 werner 36 void
2043 twoaday 105 fm_print_md (listview_ctrl_t lv, HWND dlg, int mdalgo)
2044 werner 36 {
2045     struct md_file_s mdctx;
2046    
2047 twoaday 105 if (listview_count_items (lv, 0) == 0)
2048 werner 36 return;
2049     memset (&mdctx, 0, sizeof (mdctx));
2050     mdctx.lv = lv;
2051     mdctx.mdalgo = mdalgo;
2052 twoaday 105 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_FILE_MDSUM, dlg,
2053     mdsum_dlg_proc, (LPARAM)&mdctx);
2054     }
2055 werner 36
2056    
2057 twoaday 77 /* Send the selected file in @lv via MAPI to a mail recipient. */
2058 werner 36 int
2059     fm_send_file (listview_ctrl_t lv)
2060     {
2061 twoaday 256 char name[128];
2062 werner 36 int rc;
2063    
2064 twoaday 256 rc = listview_get_item_text (lv, -1, FM_COL_NAME, name, sizeof (name)-1);
2065 twoaday 77 if (rc != -1)
2066 twoaday 256 mapi_send_ascfile (name);
2067 werner 36 return 0;
2068     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26