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

Annotation of /trunk/Src/wptFileManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 214 - (hide annotations)
Sun May 14 18:40:36 2006 UTC (18 years, 9 months ago) by twoaday
File size: 49081 byte(s)
2006-05-14  Timo Schulz  <ts@g10code.de>
                                                                                
        * wptKeyCache.cpp (gpg_keycache_update_attr): Parse
        preferred keyserver URL.
        * wptHTTP.cpp (extractHostInfo): Fix segv.
        * wptGPGUtil.cpp (gpg_find_key_subpacket): Ignore default
        gpg.conf.
        * wptKeyserverSearchDlg.cpp (search_hkp_keys): Do not
        assume an existing user id.
        * wptPassphraseCB.cpp (passphrase_cb): Automatic cancel
        if no passphrase is available.

(for complete list of changes, see Src/ChangeLog)

About to release 0.12.1


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26