a37d1f7b7842a42005916c0fdee6ce84ed5bdf77
[gpgme.git] / src / engine-gpg.c
1 /* engine-gpg.c - Gpg Engine.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4                  2009, 2010, 2012, 2013 g10 Code GmbH
5
6    This file is part of GPGME.
7
8    GPGME is free software; you can redistribute it and/or modify it
9    under the terms of the GNU Lesser General Public License as
10    published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    GPGME is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with this program; if not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33 #ifdef HAVE_LOCALE_H
34 #include <locale.h>
35 #endif
36
37 #include "gpgme.h"
38 #include "util.h"
39 #include "ops.h"
40 #include "wait.h"
41 #include "context.h"  /*temp hack until we have GpmeData methods to do I/O */
42 #include "priv-io.h"
43 #include "sema.h"
44 #include "debug.h"
45 #include "data.h"
46
47 #include "engine-backend.h"
48
49
50 /* This type is used to build a list of gpg arguments and data
51    sources/sinks.  */
52 struct arg_and_data_s
53 {
54   struct arg_and_data_s *next;
55   gpgme_data_t data;  /* If this is not NULL, use arg below.  */
56   int inbound;     /* True if this is used for reading from gpg.  */
57   int dup_to;
58   int print_fd;    /* Print the fd number and not the special form of it.  */
59   int *arg_locp;   /* Write back the argv idx of this argument when
60                       building command line to this location.  */
61   char arg[1];     /* Used if data above is not used.  */
62 };
63
64
65 struct fd_data_map_s
66 {
67   gpgme_data_t data;
68   int inbound;  /* true if this is used for reading from gpg */
69   int dup_to;
70   int fd;       /* the fd to use */
71   int peer_fd;  /* the other side of the pipe */
72   int arg_loc;  /* The index into the argv for translation purposes.  */
73   void *tag;
74 };
75
76
77 /* NB.: R_LINE is allocated an gpgrt function and thus gpgrt_free
78  * shall be used to release it.  This takes care of custom memory
79  * allocators and avoids problems on Windows with different runtimes
80  * used for libgpg-error/gpgrt and gpgme.  */
81 typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
82
83 struct engine_gpg
84 {
85   char *file_name;
86   char *version;
87
88   char *lc_messages;
89   char *lc_ctype;
90
91   struct arg_and_data_s *arglist;
92   struct arg_and_data_s **argtail;
93
94   struct
95   {
96     int fd[2];
97     int arg_loc;
98     size_t bufsize;
99     char *buffer;
100     size_t readpos;
101     int eof;
102     engine_status_handler_t fnc;
103     void *fnc_value;
104     gpgme_status_cb_t mon_cb;
105     void *mon_cb_value;
106     void *tag;
107   } status;
108
109   /* This is a kludge - see the comment at colon_line_handler.  */
110   struct
111   {
112     int fd[2];
113     int arg_loc;
114     size_t bufsize;
115     char *buffer;
116     size_t readpos;
117     int eof;
118     engine_colon_line_handler_t fnc;  /* this indicate use of this structrue */
119     void *fnc_value;
120     void *tag;
121     colon_preprocessor_t preprocess_fnc;
122   } colon;
123
124   char **argv;
125   struct fd_data_map_s *fd_data_map;
126
127   /* stuff needed for interactive (command) mode */
128   struct
129   {
130     int used;
131     int fd;
132     void *cb_data;
133     int idx;            /* Index in fd_data_map */
134     gpgme_status_code_t code;  /* last code */
135     char *keyword;       /* what has been requested (malloced) */
136     engine_command_handler_t fnc;
137     void *fnc_value;
138     /* The kludges never end.  This is used to couple command handlers
139        with output data in edit key mode.  */
140     gpgme_data_t linked_data;
141     int linked_idx;
142   } cmd;
143
144   struct gpgme_io_cbs io_cbs;
145   gpgme_pinentry_mode_t pinentry_mode;
146   char request_origin[10];
147
148   struct {
149     unsigned int no_symkey_cache : 1;
150   } flags;
151
152   /* NULL or the data object fed to --override_session_key-fd.  */
153   gpgme_data_t override_session_key;
154 };
155
156 typedef struct engine_gpg *engine_gpg_t;
157
158 \f
159 static void
160 gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data)
161 {
162   engine_gpg_t gpg = engine;
163
164   TRACE3 (DEBUG_ENGINE, "gpgme:gpg_io_event", gpg,
165           "event %p, type %d, type_data %p",
166           gpg->io_cbs.event, type, type_data);
167   if (gpg->io_cbs.event)
168     (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data);
169 }
170
171
172 static void
173 close_notify_handler (int fd, void *opaque)
174 {
175   engine_gpg_t gpg = opaque;
176   assert (fd != -1);
177
178   if (gpg->status.fd[0] == fd)
179     {
180       if (gpg->status.tag)
181         (*gpg->io_cbs.remove) (gpg->status.tag);
182       gpg->status.fd[0] = -1;
183     }
184   else if (gpg->status.fd[1] == fd)
185     gpg->status.fd[1] = -1;
186   else if (gpg->colon.fd[0] == fd)
187     {
188       if (gpg->colon.tag)
189         (*gpg->io_cbs.remove) (gpg->colon.tag);
190       gpg->colon.fd[0] = -1;
191     }
192   else if (gpg->colon.fd[1] == fd)
193     gpg->colon.fd[1] = -1;
194   else if (gpg->cmd.fd == fd)
195     gpg->cmd.fd = -1;
196   else if (gpg->fd_data_map)
197     {
198       int i;
199
200       for (i = 0; gpg->fd_data_map[i].data; i++)
201         {
202           if (gpg->fd_data_map[i].fd == fd)
203             {
204               if (gpg->fd_data_map[i].tag)
205                 (*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag);
206               gpg->fd_data_map[i].fd = -1;
207               break;
208             }
209           if (gpg->fd_data_map[i].peer_fd == fd)
210             {
211               gpg->fd_data_map[i].peer_fd = -1;
212               break;
213             }
214         }
215     }
216 }
217
218 /* If FRONT is true, push at the front of the list.  Use this for
219    options added late in the process.  */
220 static gpgme_error_t
221 _add_arg (engine_gpg_t gpg, const char *prefix, const char *arg, size_t arglen,
222           int front, int *arg_locp)
223 {
224   struct arg_and_data_s *a;
225   size_t prefixlen = prefix? strlen (prefix) : 0;
226
227   assert (gpg);
228   assert (arg);
229
230   a = malloc (sizeof *a + prefixlen + arglen);
231   if (!a)
232     return gpg_error_from_syserror ();
233
234   a->data = NULL;
235   a->dup_to = -1;
236   a->arg_locp = arg_locp;
237
238   if (prefixlen)
239     memcpy (a->arg, prefix, prefixlen);
240   memcpy (a->arg + prefixlen, arg, arglen);
241   a->arg[prefixlen + arglen] = 0;
242   if (front)
243     {
244       a->next = gpg->arglist;
245       if (!gpg->arglist)
246         {
247           /* If this is the first argument, we need to update the tail
248              pointer.  */
249           gpg->argtail = &a->next;
250         }
251       gpg->arglist = a;
252     }
253   else
254     {
255       a->next = NULL;
256       *gpg->argtail = a;
257       gpg->argtail = &a->next;
258     }
259
260   return 0;
261 }
262
263
264 static gpgme_error_t
265 add_arg_ext (engine_gpg_t gpg, const char *arg, int front)
266 {
267   return _add_arg (gpg, NULL, arg, strlen (arg), front, NULL);
268 }
269
270 static gpgme_error_t
271 add_arg_with_locp (engine_gpg_t gpg, const char *arg, int *locp)
272 {
273   return _add_arg (gpg, NULL, arg, strlen (arg), 0, locp);
274 }
275
276 static gpgme_error_t
277 add_arg (engine_gpg_t gpg, const char *arg)
278 {
279   return _add_arg (gpg, NULL, arg, strlen (arg), 0, NULL);
280 }
281
282 static gpgme_error_t
283 add_arg_pfx (engine_gpg_t gpg, const char *prefix, const char *arg)
284 {
285   return _add_arg (gpg, prefix, arg, strlen (arg), 0, NULL);
286 }
287
288 static gpgme_error_t
289 add_arg_len (engine_gpg_t gpg, const char *prefix,
290              const char *arg, size_t arglen)
291 {
292   return _add_arg (gpg, prefix, arg, arglen, 0, NULL);
293 }
294
295
296 static gpgme_error_t
297 add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
298 {
299   struct arg_and_data_s *a;
300
301   assert (gpg);
302   assert (data);
303
304   a = malloc (sizeof *a - 1);
305   if (!a)
306     return gpg_error_from_syserror ();
307   a->next = NULL;
308   a->data = data;
309   a->inbound = inbound;
310   a->arg_locp = NULL;
311
312   if (dup_to == -2)
313     {
314       a->print_fd = 1;
315       a->dup_to = -1;
316     }
317   else
318     {
319       a->print_fd = 0;
320       a->dup_to = dup_to;
321     }
322   *gpg->argtail = a;
323   gpg->argtail = &a->next;
324   return 0;
325 }
326
327
328 /* Return true if the engine's version is at least VERSION.  */
329 static int
330 have_gpg_version (engine_gpg_t gpg, const char *version)
331 {
332   return _gpgme_compare_versions (gpg->version, version);
333 }
334
335
336 \f
337 static char *
338 gpg_get_version (const char *file_name)
339 {
340   return _gpgme_get_program_version (file_name ? file_name
341                                      : _gpgme_get_default_gpg_name ());
342 }
343
344
345 static const char *
346 gpg_get_req_version (void)
347 {
348   return "1.4.0";
349 }
350
351
352 static void
353 free_argv (char **argv)
354 {
355   int i;
356
357   for (i = 0; argv[i]; i++)
358     free (argv[i]);
359   free (argv);
360 }
361
362
363 static void
364 free_fd_data_map (struct fd_data_map_s *fd_data_map)
365 {
366   int i;
367
368   if (!fd_data_map)
369     return;
370
371   for (i = 0; fd_data_map[i].data; i++)
372     {
373       if (fd_data_map[i].fd != -1)
374         _gpgme_io_close (fd_data_map[i].fd);
375       if (fd_data_map[i].peer_fd != -1)
376         _gpgme_io_close (fd_data_map[i].peer_fd);
377       /* Don't release data because this is only a reference.  */
378     }
379   free (fd_data_map);
380 }
381
382
383 static gpgme_error_t
384 gpg_cancel (void *engine)
385 {
386   engine_gpg_t gpg = engine;
387
388   if (!gpg)
389     return gpg_error (GPG_ERR_INV_VALUE);
390
391   /* If gpg may be waiting for a cmd, close the cmd fd first.  On
392      Windows, close operations block on the reader/writer thread.  */
393   if (gpg->cmd.used)
394     {
395       if (gpg->cmd.fd != -1)
396         _gpgme_io_close (gpg->cmd.fd);
397       else if (gpg->fd_data_map
398                && gpg->fd_data_map[gpg->cmd.idx].fd != -1)
399         _gpgme_io_close (gpg->fd_data_map[gpg->cmd.idx].fd);
400     }
401
402   if (gpg->status.fd[0] != -1)
403     _gpgme_io_close (gpg->status.fd[0]);
404   if (gpg->status.fd[1] != -1)
405     _gpgme_io_close (gpg->status.fd[1]);
406   if (gpg->colon.fd[0] != -1)
407     _gpgme_io_close (gpg->colon.fd[0]);
408   if (gpg->colon.fd[1] != -1)
409     _gpgme_io_close (gpg->colon.fd[1]);
410   if (gpg->fd_data_map)
411     {
412       free_fd_data_map (gpg->fd_data_map);
413       gpg->fd_data_map = NULL;
414     }
415
416   return 0;
417 }
418
419 static void
420 gpg_release (void *engine)
421 {
422   engine_gpg_t gpg = engine;
423
424   if (!gpg)
425     return;
426
427   gpg_cancel (engine);
428
429   if (gpg->file_name)
430     free (gpg->file_name);
431   if (gpg->version)
432     free (gpg->version);
433
434   if (gpg->lc_messages)
435     free (gpg->lc_messages);
436   if (gpg->lc_ctype)
437     free (gpg->lc_ctype);
438
439   while (gpg->arglist)
440     {
441       struct arg_and_data_s *next = gpg->arglist->next;
442
443       free (gpg->arglist);
444       gpg->arglist = next;
445     }
446
447   if (gpg->status.buffer)
448     free (gpg->status.buffer);
449   if (gpg->colon.buffer)
450     free (gpg->colon.buffer);
451   if (gpg->argv)
452     free_argv (gpg->argv);
453   if (gpg->cmd.keyword)
454     free (gpg->cmd.keyword);
455
456   gpgme_data_release (gpg->override_session_key);
457
458   free (gpg);
459 }
460
461
462 static gpgme_error_t
463 gpg_new (void **engine, const char *file_name, const char *home_dir,
464          const char *version)
465 {
466   engine_gpg_t gpg;
467   gpgme_error_t rc = 0;
468   char *dft_display = NULL;
469   char dft_ttyname[64];
470   char *dft_ttytype = NULL;
471   char *env_tty = NULL;
472
473   gpg = calloc (1, sizeof *gpg);
474   if (!gpg)
475     return gpg_error_from_syserror ();
476
477   if (file_name)
478     {
479       gpg->file_name = strdup (file_name);
480       if (!gpg->file_name)
481         {
482           rc = gpg_error_from_syserror ();
483           goto leave;
484         }
485     }
486
487   if (version)
488     {
489       gpg->version = strdup (version);
490       if (!gpg->version)
491         {
492           rc = gpg_error_from_syserror ();
493           goto leave;
494         }
495     }
496
497   gpg->argtail = &gpg->arglist;
498   gpg->status.fd[0] = -1;
499   gpg->status.fd[1] = -1;
500   gpg->colon.fd[0] = -1;
501   gpg->colon.fd[1] = -1;
502   gpg->cmd.fd = -1;
503   gpg->cmd.idx = -1;
504   gpg->cmd.linked_data = NULL;
505   gpg->cmd.linked_idx = -1;
506
507   /* Allocate the read buffer for the status pipe.  */
508   gpg->status.bufsize = 1024;
509   gpg->status.readpos = 0;
510   gpg->status.buffer = malloc (gpg->status.bufsize);
511   if (!gpg->status.buffer)
512     {
513       rc = gpg_error_from_syserror ();
514       goto leave;
515     }
516   /* In any case we need a status pipe - create it right here and
517      don't handle it with our generic gpgme_data_t mechanism.  */
518   if (_gpgme_io_pipe (gpg->status.fd, 1) == -1)
519     {
520       rc = gpg_error_from_syserror ();
521       goto leave;
522     }
523   if (_gpgme_io_set_close_notify (gpg->status.fd[0],
524                                   close_notify_handler, gpg)
525       || _gpgme_io_set_close_notify (gpg->status.fd[1],
526                                      close_notify_handler, gpg))
527     {
528       rc = gpg_error (GPG_ERR_GENERAL);
529       goto leave;
530     }
531   gpg->status.eof = 0;
532
533   if (home_dir)
534     {
535       rc = add_arg (gpg, "--homedir");
536       if (!rc)
537         rc = add_arg (gpg, home_dir);
538       if (rc)
539         goto leave;
540     }
541
542   rc = add_arg (gpg, "--status-fd");
543   if (rc)
544     goto leave;
545
546   {
547     char buf[25];
548     _gpgme_io_fd2str (buf, sizeof (buf), gpg->status.fd[1]);
549     rc = add_arg_with_locp (gpg, buf, &gpg->status.arg_loc);
550     if (rc)
551       goto leave;
552   }
553
554   rc = add_arg (gpg, "--no-tty");
555   if (!rc)
556     rc = add_arg (gpg, "--charset");
557   if (!rc)
558     rc = add_arg (gpg, "utf8");
559   if (!rc)
560     rc = add_arg (gpg, "--enable-progress-filter");
561   if (!rc && have_gpg_version (gpg, "2.1.11"))
562     rc = add_arg (gpg, "--exit-on-status-write-error");
563   if (rc)
564     goto leave;
565
566   rc = _gpgme_getenv ("DISPLAY", &dft_display);
567   if (rc)
568     goto leave;
569   if (dft_display)
570     {
571       rc = add_arg (gpg, "--display");
572       if (!rc)
573         rc = add_arg (gpg, dft_display);
574
575       free (dft_display);
576       if (rc)
577         goto leave;
578     }
579
580   rc = _gpgme_getenv ("GPG_TTY", &env_tty);
581   if (isatty (1) || env_tty || rc)
582     {
583       int err = 0;
584
585       if (rc)
586         goto leave;
587       else if (env_tty)
588         {
589           snprintf (dft_ttyname, sizeof (dft_ttyname), "%s", env_tty);
590           free (env_tty);
591         }
592       else
593         err = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
594
595       /* Even though isatty() returns 1, ttyname_r() may fail in many
596          ways, e.g., when /dev/pts is not accessible under chroot.  */
597       if (!err)
598         {
599           if (*dft_ttyname)
600             {
601               rc = add_arg (gpg, "--ttyname");
602               if (!rc)
603                 rc = add_arg (gpg, dft_ttyname);
604             }
605           else
606             rc = 0;
607           if (!rc)
608             {
609               rc = _gpgme_getenv ("TERM", &dft_ttytype);
610               if (rc)
611                 goto leave;
612
613               if (dft_ttytype)
614                 {
615                   rc = add_arg (gpg, "--ttytype");
616                   if (!rc)
617                     rc = add_arg (gpg, dft_ttytype);
618                 }
619
620               free (dft_ttytype);
621             }
622           if (rc)
623             goto leave;
624         }
625     }
626
627  leave:
628   if (rc)
629     gpg_release (gpg);
630   else
631     *engine = gpg;
632   return rc;
633 }
634
635
636 /* Copy flags from CTX into the engine object.  */
637 static void
638 gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
639 {
640   engine_gpg_t gpg = engine;
641
642   if (ctx->request_origin && have_gpg_version (gpg, "2.2.6"))
643     {
644       if (strlen (ctx->request_origin) + 1 > sizeof gpg->request_origin)
645         strcpy (gpg->request_origin, "xxx"); /* Too long  - force error */
646       else
647         strcpy (gpg->request_origin, ctx->request_origin);
648     }
649   else if (ctx->no_symkey_cache && have_gpg_version (gpg, "2.2.7"))
650     {
651       gpg->flags.no_symkey_cache = 1;
652     }
653   else
654     *gpg->request_origin = 0;
655 }
656
657
658 static gpgme_error_t
659 gpg_set_locale (void *engine, int category, const char *value)
660 {
661   engine_gpg_t gpg = engine;
662
663   if (0)
664     ;
665 #ifdef LC_CTYPE
666   else if (category == LC_CTYPE)
667     {
668       if (gpg->lc_ctype)
669         {
670           free (gpg->lc_ctype);
671           gpg->lc_ctype = NULL;
672         }
673       if (value)
674         {
675           gpg->lc_ctype = strdup (value);
676           if (!gpg->lc_ctype)
677             return gpg_error_from_syserror ();
678         }
679     }
680 #endif
681 #ifdef LC_MESSAGES
682   else if (category == LC_MESSAGES)
683     {
684       if (gpg->lc_messages)
685         {
686           free (gpg->lc_messages);
687           gpg->lc_messages = NULL;
688         }
689       if (value)
690         {
691           gpg->lc_messages = strdup (value);
692           if (!gpg->lc_messages)
693             return gpg_error_from_syserror ();
694         }
695     }
696 #endif /* LC_MESSAGES */
697   else
698     return gpg_error (GPG_ERR_INV_VALUE);
699
700   return 0;
701 }
702
703 /* This sets a status callback for monitoring status lines before they
704  * are passed to a caller set handler.  */
705 static void
706 gpg_set_status_cb (void *engine, gpgme_status_cb_t cb, void *cb_value)
707 {
708   engine_gpg_t gpg = engine;
709
710   gpg->status.mon_cb = cb;
711   gpg->status.mon_cb_value = cb_value;
712 }
713
714
715 /* Note, that the status_handler is allowed to modifiy the args
716    value.  */
717 static void
718 gpg_set_status_handler (void *engine, engine_status_handler_t fnc,
719                         void *fnc_value)
720 {
721   engine_gpg_t gpg = engine;
722
723   gpg->status.fnc = fnc;
724   gpg->status.fnc_value = fnc_value;
725 }
726
727 /* Kludge to process --with-colon output.  */
728 static gpgme_error_t
729 gpg_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc,
730                             void *fnc_value)
731 {
732   engine_gpg_t gpg = engine;
733
734   gpg->colon.bufsize = 1024;
735   gpg->colon.readpos = 0;
736   gpg->colon.buffer = malloc (gpg->colon.bufsize);
737   if (!gpg->colon.buffer)
738     return gpg_error_from_syserror ();
739
740   if (_gpgme_io_pipe (gpg->colon.fd, 1) == -1)
741     {
742       int saved_err = gpg_error_from_syserror ();
743       free (gpg->colon.buffer);
744       gpg->colon.buffer = NULL;
745       return saved_err;
746     }
747   if (_gpgme_io_set_close_notify (gpg->colon.fd[0], close_notify_handler, gpg)
748       || _gpgme_io_set_close_notify (gpg->colon.fd[1],
749                                      close_notify_handler, gpg))
750     return gpg_error (GPG_ERR_GENERAL);
751   gpg->colon.eof = 0;
752   gpg->colon.fnc = fnc;
753   gpg->colon.fnc_value = fnc_value;
754   return 0;
755 }
756
757
758 static gpgme_error_t
759 command_handler (void *opaque, int fd)
760 {
761   struct io_cb_data *data = (struct io_cb_data *) opaque;
762   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
763   gpgme_error_t err;
764   int processed = 0;
765   assert (gpg->cmd.used);
766   assert (gpg->cmd.code);
767   assert (gpg->cmd.fnc);
768
769   err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd,
770                       &processed);
771
772   gpg->cmd.code = 0;
773   /* And sleep again until read_status will wake us up again.  */
774   /* XXX We must check if there are any more fds active after removing
775      this one.  */
776   (*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag);
777   gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
778   gpg->fd_data_map[gpg->cmd.idx].fd = -1;
779
780   if (err)
781     return err;
782
783   /* We always need to send at least a newline character.  */
784   if (!processed)
785     _gpgme_io_write (fd, "\n", 1);
786
787   return 0;
788 }
789
790
791
792 /* The Fnc will be called to get a value for one of the commands with
793    a key KEY.  If the Code passed to FNC is 0, the function may release
794    resources associated with the returned value from another call.  To
795    match such a second call to a first call, the returned value from
796    the first call is passed as keyword.  */
797 static gpgme_error_t
798 gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
799                          void *fnc_value, gpgme_data_t linked_data)
800 {
801   engine_gpg_t gpg = engine;
802   gpgme_error_t rc;
803
804   rc = add_arg (gpg, "--command-fd");
805   if (rc)
806     return rc;
807
808   /* This is a hack.  We don't have a real data object.  The only
809      thing that matters is that we use something unique, so we use the
810      address of the cmd structure in the gpg object.  */
811   rc = add_data (gpg, (void *) &gpg->cmd, -2, 0);
812   if (rc)
813     return rc;
814
815   gpg->cmd.fnc = fnc;
816   gpg->cmd.cb_data = (void *) &gpg->cmd;
817   gpg->cmd.fnc_value = fnc_value;
818   gpg->cmd.linked_data = linked_data;
819   gpg->cmd.used = 1;
820   return 0;
821 }
822
823
824 static gpgme_error_t
825 build_argv (engine_gpg_t gpg, const char *pgmname)
826 {
827   gpgme_error_t err;
828   struct arg_and_data_s *a;
829   struct fd_data_map_s *fd_data_map;
830   size_t datac=0, argc=0;
831   char **argv;
832   int need_special = 0;
833   int use_agent = 0;
834   char *p;
835
836   if (_gpgme_in_gpg_one_mode ())
837     {
838       /* In GnuPG-1 mode we don't want to use the agent with a
839          malformed environment variable.  This is only a very basic
840          test but sufficient to make our life in the regression tests
841          easier.  With GnuPG-2 the agent is anyway required and on
842          modern installations GPG_AGENT_INFO is optional.  */
843       err = _gpgme_getenv ("GPG_AGENT_INFO", &p);
844       if (err)
845         return err;
846       use_agent = (p && strchr (p, ':'));
847       if (p)
848         free (p);
849     }
850
851   if (gpg->argv)
852     {
853       free_argv (gpg->argv);
854       gpg->argv = NULL;
855     }
856   if (gpg->fd_data_map)
857     {
858       free_fd_data_map (gpg->fd_data_map);
859       gpg->fd_data_map = NULL;
860     }
861
862   argc++;       /* For argv[0].  */
863   for (a = gpg->arglist; a; a = a->next)
864     {
865       argc++;
866       if (a->data)
867         {
868           /*fprintf (stderr, "build_argv: data\n" );*/
869           datac++;
870           if (a->dup_to == -1 && !a->print_fd)
871             need_special = 1;
872         }
873       else
874         {
875           /*   fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/
876         }
877     }
878   if (need_special)
879     argc++;
880   if (use_agent)
881     argc++;
882   if (gpg->pinentry_mode)
883     argc++;
884   if (!gpg->cmd.used)
885     argc++;     /* --batch */
886   argc += 3;    /* --no-sk-comments, --request-origin, --no-symkey-cache */
887
888   argv = calloc (argc + 1, sizeof *argv);
889   if (!argv)
890     return gpg_error_from_syserror ();
891   fd_data_map = calloc (datac + 1, sizeof *fd_data_map);
892   if (!fd_data_map)
893     {
894       int saved_err = gpg_error_from_syserror ();
895       free_argv (argv);
896       return saved_err;
897     }
898
899   argc = datac = 0;
900   argv[argc] = strdup (_gpgme_get_basename (pgmname)); /* argv[0] */
901   if (!argv[argc])
902     {
903       int saved_err = gpg_error_from_syserror ();
904       free (fd_data_map);
905       free_argv (argv);
906       return saved_err;
907     }
908   argc++;
909   if (need_special)
910     {
911       argv[argc] = strdup ("--enable-special-filenames");
912       if (!argv[argc])
913         {
914           int saved_err = gpg_error_from_syserror ();
915           free (fd_data_map);
916           free_argv (argv);
917           return saved_err;
918         }
919       argc++;
920     }
921   if (use_agent)
922     {
923       argv[argc] = strdup ("--use-agent");
924       if (!argv[argc])
925         {
926           int saved_err = gpg_error_from_syserror ();
927           free (fd_data_map);
928           free_argv (argv);
929           return saved_err;
930         }
931       argc++;
932     }
933
934   if (*gpg->request_origin)
935     {
936       argv[argc] = _gpgme_strconcat ("--request-origin=",
937                                      gpg->request_origin, NULL);
938       if (!argv[argc])
939         {
940           int saved_err = gpg_error_from_syserror ();
941           free (fd_data_map);
942           free_argv (argv);
943           return saved_err;
944         }
945       argc++;
946     }
947
948   if (gpg->flags.no_symkey_cache)
949     {
950       argv[argc] = strdup ("--no-symkey-cache");
951       if (!argv[argc])
952         {
953           int saved_err = gpg_error_from_syserror ();
954           free (fd_data_map);
955           free_argv (argv);
956           return saved_err;
957         }
958       argc++;
959     }
960
961   if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
962     {
963       const char *s = NULL;
964       switch (gpg->pinentry_mode)
965         {
966         case GPGME_PINENTRY_MODE_DEFAULT: break;
967         case GPGME_PINENTRY_MODE_ASK:     s = "--pinentry-mode=ask"; break;
968         case GPGME_PINENTRY_MODE_CANCEL:  s = "--pinentry-mode=cancel"; break;
969         case GPGME_PINENTRY_MODE_ERROR:   s = "--pinentry-mode=error"; break;
970         case GPGME_PINENTRY_MODE_LOOPBACK:s = "--pinentry-mode=loopback"; break;
971         }
972       if (s)
973         {
974           argv[argc] = strdup (s);
975           if (!argv[argc])
976             {
977               int saved_err = gpg_error_from_syserror ();
978               free (fd_data_map);
979               free_argv (argv);
980               return saved_err;
981             }
982           argc++;
983         }
984     }
985
986   if (!gpg->cmd.used)
987     {
988       argv[argc] = strdup ("--batch");
989       if (!argv[argc])
990         {
991           int saved_err = gpg_error_from_syserror ();
992           free (fd_data_map);
993           free_argv (argv);
994           return saved_err;
995         }
996       argc++;
997     }
998   argv[argc] = strdup ("--no-sk-comments");
999   if (!argv[argc])
1000     {
1001       int saved_err = gpg_error_from_syserror ();
1002       free (fd_data_map);
1003       free_argv (argv);
1004       return saved_err;
1005     }
1006   argc++;
1007   for (a = gpg->arglist; a; a = a->next)
1008     {
1009       if (a->arg_locp)
1010         *(a->arg_locp) = argc;
1011
1012       if (a->data)
1013         {
1014           /* Create a pipe to pass it down to gpg.  */
1015           fd_data_map[datac].inbound = a->inbound;
1016
1017           /* Create a pipe.  */
1018           {
1019             int fds[2];
1020
1021             if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0)
1022                 == -1)
1023               {
1024                 int saved_errno = errno;
1025                 free (fd_data_map);
1026                 free_argv (argv);
1027                 return gpg_error (saved_errno);
1028               }
1029             if (_gpgme_io_set_close_notify (fds[0],
1030                                             close_notify_handler, gpg)
1031                 || _gpgme_io_set_close_notify (fds[1],
1032                                                close_notify_handler,
1033                                                gpg))
1034               {
1035                 /* We leak fd_data_map and the fds.  This is not easy
1036                    to avoid and given that we reach this here only
1037                    after a malloc failure for a small object, it is
1038                    probably better not to do anything.  */
1039                 return gpg_error (GPG_ERR_GENERAL);
1040               }
1041             /* If the data_type is FD, we have to do a dup2 here.  */
1042             if (fd_data_map[datac].inbound)
1043               {
1044                 fd_data_map[datac].fd       = fds[0];
1045                 fd_data_map[datac].peer_fd  = fds[1];
1046               }
1047             else
1048               {
1049                 fd_data_map[datac].fd       = fds[1];
1050                 fd_data_map[datac].peer_fd  = fds[0];
1051               }
1052           }
1053
1054           /* Hack to get hands on the fd later.  */
1055           if (gpg->cmd.used)
1056             {
1057               if (gpg->cmd.cb_data == a->data)
1058                 {
1059                   assert (gpg->cmd.idx == -1);
1060                   gpg->cmd.idx = datac;
1061                 }
1062               else if (gpg->cmd.linked_data == a->data)
1063                 {
1064                   assert (gpg->cmd.linked_idx == -1);
1065                   gpg->cmd.linked_idx = datac;
1066                 }
1067             }
1068
1069           fd_data_map[datac].data = a->data;
1070           fd_data_map[datac].dup_to = a->dup_to;
1071
1072           if (a->dup_to == -1)
1073             {
1074               char *ptr;
1075               int buflen = 25;
1076
1077               argv[argc] = malloc (buflen);
1078               if (!argv[argc])
1079                 {
1080                   int saved_err = gpg_error_from_syserror ();
1081                   free (fd_data_map);
1082                   free_argv (argv);
1083                   return saved_err;
1084                 }
1085
1086               ptr = argv[argc];
1087               if (!a->print_fd)
1088                 {
1089                   *(ptr++) = '-';
1090                   *(ptr++) = '&';
1091                   buflen -= 2;
1092                 }
1093
1094               _gpgme_io_fd2str (ptr, buflen, fd_data_map[datac].peer_fd);
1095               fd_data_map[datac].arg_loc = argc;
1096               argc++;
1097             }
1098           datac++;
1099         }
1100       else
1101         {
1102           argv[argc] = strdup (a->arg);
1103           if (!argv[argc])
1104             {
1105               int saved_err = gpg_error_from_syserror ();
1106               free (fd_data_map);
1107               free_argv (argv);
1108               return saved_err;
1109             }
1110             argc++;
1111         }
1112     }
1113
1114   gpg->argv = argv;
1115   gpg->fd_data_map = fd_data_map;
1116   return 0;
1117 }
1118
1119
1120 static gpgme_error_t
1121 add_io_cb (engine_gpg_t gpg, int fd, int dir, gpgme_io_cb_t handler, void *data,
1122            void **tag)
1123 {
1124   gpgme_error_t err;
1125
1126   err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag);
1127   if (err)
1128     return err;
1129   if (!dir)
1130     /* FIXME Kludge around poll() problem.  */
1131     err = _gpgme_io_set_nonblocking (fd);
1132   return err;
1133 }
1134
1135
1136 /* Handle the status output of GnuPG.  This function does read entire
1137    lines and passes them as C strings to the callback function (we can
1138    use C Strings because the status output is always UTF-8 encoded).
1139    Of course we have to buffer the lines to cope with long lines
1140    e.g. with a large user ID.  Note: We can optimize this to only cope
1141    with status line code we know about and skip all other stuff
1142    without buffering (i.e. without extending the buffer).  */
1143 static gpgme_error_t
1144 read_status (engine_gpg_t gpg)
1145 {
1146   char *p;
1147   int nread;
1148   size_t bufsize = gpg->status.bufsize;
1149   char *buffer = gpg->status.buffer;
1150   size_t readpos = gpg->status.readpos;
1151   gpgme_error_t err;
1152
1153   assert (buffer);
1154   if (bufsize - readpos < 256)
1155     {
1156       /* Need more room for the read.  */
1157       bufsize += 1024;
1158       buffer = realloc (buffer, bufsize);
1159       if (!buffer)
1160         return gpg_error_from_syserror ();
1161     }
1162
1163   nread = _gpgme_io_read (gpg->status.fd[0],
1164                           buffer + readpos, bufsize-readpos);
1165   if (nread == -1)
1166     return gpg_error_from_syserror ();
1167
1168   if (!nread)
1169     {
1170       err = 0;
1171       gpg->status.eof = 1;
1172       if (gpg->status.mon_cb)
1173         err = gpg->status.mon_cb (gpg->status.mon_cb_value, "", "");
1174       if (gpg->status.fnc)
1175         {
1176           char emptystring[1] = {0};
1177           err = gpg->status.fnc (gpg->status.fnc_value,
1178                                  GPGME_STATUS_EOF, emptystring);
1179           if (gpg_err_code (err) == GPG_ERR_FALSE)
1180             err = 0; /* Drop special error code.  */
1181         }
1182
1183       return err;
1184     }
1185
1186   while (nread > 0)
1187     {
1188       for (p = buffer + readpos; nread; nread--, p++)
1189         {
1190           if (*p == '\n')
1191             {
1192               /* (we require that the last line is terminated by a LF) */
1193               if (p > buffer && p[-1] == '\r')
1194                 p[-1] = 0;
1195               *p = 0;
1196               if (!strncmp (buffer, "[GNUPG:] ", 9)
1197                   && buffer[9] >= 'A' && buffer[9] <= 'Z')
1198                 {
1199                   char *rest;
1200                   gpgme_status_code_t r;
1201
1202                   rest = strchr (buffer + 9, ' ');
1203                   if (!rest)
1204                     rest = p; /* Set to an empty string.  */
1205                   else
1206                     *rest++ = 0;
1207
1208                   r = _gpgme_parse_status (buffer + 9);
1209                   if (gpg->status.mon_cb && r != GPGME_STATUS_PROGRESS)
1210                     {
1211                       /* Note that we call the monitor even if we do
1212                        * not know the status code (r < 0).  */
1213                       err = gpg->status.mon_cb (gpg->status.mon_cb_value,
1214                                                 buffer + 9, rest);
1215                       if (err)
1216                         return err;
1217                     }
1218                   if (r >= 0)
1219                     {
1220                       if (gpg->cmd.used
1221                           && (r == GPGME_STATUS_GET_BOOL
1222                               || r == GPGME_STATUS_GET_LINE
1223                               || r == GPGME_STATUS_GET_HIDDEN))
1224                         {
1225                           gpg->cmd.code = r;
1226                           if (gpg->cmd.keyword)
1227                             free (gpg->cmd.keyword);
1228                           gpg->cmd.keyword = strdup (rest);
1229                           if (!gpg->cmd.keyword)
1230                             return gpg_error_from_syserror ();
1231                           /* This should be the last thing we have
1232                              received and the next thing will be that
1233                              the command handler does its action.  */
1234                           if (nread > 1)
1235                             TRACE0 (DEBUG_CTX, "gpgme:read_status", 0,
1236                                     "error: unexpected data");
1237
1238                           add_io_cb (gpg, gpg->cmd.fd, 0,
1239                                      command_handler, gpg,
1240                                      &gpg->fd_data_map[gpg->cmd.idx].tag);
1241                           gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
1242                           gpg->cmd.fd = -1;
1243                         }
1244                       else if (gpg->status.fnc)
1245                         {
1246                           err = gpg->status.fnc (gpg->status.fnc_value,
1247                                                  r, rest);
1248                           if (gpg_err_code (err) == GPG_ERR_FALSE)
1249                             err = 0; /* Drop special error code.  */
1250                           if (err)
1251                             return err;
1252                         }
1253
1254                       if (r == GPGME_STATUS_END_STREAM)
1255                         {
1256                           if (gpg->cmd.used)
1257                             {
1258                               /* Before we can actually add the
1259                                  command fd, we might have to flush
1260                                  the linked output data pipe.  */
1261                               if (gpg->cmd.linked_idx != -1
1262                                   && gpg->fd_data_map[gpg->cmd.linked_idx].fd
1263                                   != -1)
1264                                 {
1265                                   struct io_select_fd_s fds;
1266                                   fds.fd =
1267                                     gpg->fd_data_map[gpg->cmd.linked_idx].fd;
1268                                   fds.for_read = 1;
1269                                   fds.for_write = 0;
1270                                   fds.opaque = NULL;
1271                                   do
1272                                     {
1273                                       fds.signaled = 0;
1274                                       _gpgme_io_select (&fds, 1, 1);
1275                                       if (fds.signaled)
1276                                         _gpgme_data_inbound_handler
1277                                           (gpg->cmd.linked_data, fds.fd);
1278                                     }
1279                                   while (fds.signaled);
1280                                 }
1281
1282                               /* XXX We must check if there are any
1283                                  more fds active after removing this
1284                                  one.  */
1285                               (*gpg->io_cbs.remove)
1286                                 (gpg->fd_data_map[gpg->cmd.idx].tag);
1287                               gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
1288                               gpg->fd_data_map[gpg->cmd.idx].fd = -1;
1289                             }
1290                         }
1291                     }
1292                 }
1293               /* To reuse the buffer for the next line we have to
1294                  shift the remaining data to the buffer start and
1295                  restart the loop Hmmm: We can optimize this function
1296                  by looking forward in the buffer to see whether a
1297                  second complete line is available and in this case
1298                  avoid the memmove for this line.  */
1299               nread--; p++;
1300               if (nread)
1301                 memmove (buffer, p, nread);
1302               readpos = 0;
1303               break; /* the for loop */
1304             }
1305           else
1306             readpos++;
1307         }
1308     }
1309
1310   /* Update the gpg object.  */
1311   gpg->status.bufsize = bufsize;
1312   gpg->status.buffer = buffer;
1313   gpg->status.readpos = readpos;
1314   return 0;
1315 }
1316
1317
1318 static gpgme_error_t
1319 status_handler (void *opaque, int fd)
1320 {
1321   struct io_cb_data *data = (struct io_cb_data *) opaque;
1322   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1323   int err;
1324
1325   assert (fd == gpg->status.fd[0]);
1326   err = read_status (gpg);
1327   if (err)
1328     return err;
1329   if (gpg->status.eof)
1330     _gpgme_io_close (fd);
1331   return 0;
1332 }
1333
1334
1335 static gpgme_error_t
1336 read_colon_line (engine_gpg_t gpg)
1337 {
1338   char *p;
1339   int nread;
1340   size_t bufsize = gpg->colon.bufsize;
1341   char *buffer = gpg->colon.buffer;
1342   size_t readpos = gpg->colon.readpos;
1343
1344   assert (buffer);
1345   if (bufsize - readpos < 256)
1346     {
1347       /* Need more room for the read.  */
1348       bufsize += 1024;
1349       buffer = realloc (buffer, bufsize);
1350       if (!buffer)
1351         return gpg_error_from_syserror ();
1352     }
1353
1354   nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos);
1355   if (nread == -1)
1356     return gpg_error_from_syserror ();
1357
1358   if (!nread)
1359     {
1360       gpg->colon.eof = 1;
1361       assert (gpg->colon.fnc);
1362       gpg->colon.fnc (gpg->colon.fnc_value, NULL);
1363       return 0;
1364     }
1365
1366   while (nread > 0)
1367     {
1368       for (p = buffer + readpos; nread; nread--, p++)
1369         {
1370           if ( *p == '\n' )
1371             {
1372               /* (we require that the last line is terminated by a LF)
1373                  and we skip empty lines.  Note: we use UTF8 encoding
1374                  and escaping of special characters.  We require at
1375                  least one colon to cope with some other printed
1376                  information.  */
1377               *p = 0;
1378               if (*buffer && strchr (buffer, ':'))
1379                 {
1380                   char *line = NULL;
1381
1382                   if (gpg->colon.preprocess_fnc)
1383                     {
1384                       gpgme_error_t err;
1385
1386                       err = gpg->colon.preprocess_fnc (buffer, &line);
1387                       if (err)
1388                         return err;
1389                     }
1390
1391                   assert (gpg->colon.fnc);
1392                   if (line)
1393                     {
1394                       char *linep = line;
1395                       char *endp;
1396
1397                       do
1398                         {
1399                           endp = strchr (linep, '\n');
1400                           if (endp)
1401                             *endp++ = 0;
1402                           gpg->colon.fnc (gpg->colon.fnc_value, linep);
1403                           linep = endp;
1404                         }
1405                       while (linep && *linep);
1406
1407                       gpgrt_free (line);
1408                     }
1409                   else
1410                     gpg->colon.fnc (gpg->colon.fnc_value, buffer);
1411                 }
1412
1413               /* To reuse the buffer for the next line we have to
1414                  shift the remaining data to the buffer start and
1415                  restart the loop Hmmm: We can optimize this function
1416                  by looking forward in the buffer to see whether a
1417                  second complete line is available and in this case
1418                  avoid the memmove for this line.  */
1419               nread--; p++;
1420               if (nread)
1421                 memmove (buffer, p, nread);
1422               readpos = 0;
1423               break; /* The for loop.  */
1424             }
1425           else
1426             readpos++;
1427         }
1428     }
1429
1430   /* Update the gpg object.  */
1431   gpg->colon.bufsize = bufsize;
1432   gpg->colon.buffer  = buffer;
1433   gpg->colon.readpos = readpos;
1434   return 0;
1435 }
1436
1437
1438 /* This colonline handler thing is not the clean way to do it.  It
1439    might be better to enhance the gpgme_data_t object to act as a wrapper
1440    for a callback.  Same goes for the status thing.  For now we use
1441    this thing here because it is easier to implement.  */
1442 static gpgme_error_t
1443 colon_line_handler (void *opaque, int fd)
1444 {
1445   struct io_cb_data *data = (struct io_cb_data *) opaque;
1446   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1447   gpgme_error_t rc = 0;
1448
1449   assert (fd == gpg->colon.fd[0]);
1450   rc = read_colon_line (gpg);
1451   if (rc)
1452     return rc;
1453   if (gpg->colon.eof)
1454     _gpgme_io_close (fd);
1455   return 0;
1456 }
1457
1458
1459 static gpgme_error_t
1460 start (engine_gpg_t gpg)
1461 {
1462   gpgme_error_t rc;
1463   int i, n;
1464   int status;
1465   struct spawn_fd_item_s *fd_list;
1466   pid_t pid;
1467   const char *pgmname;
1468
1469   if (!gpg)
1470     return gpg_error (GPG_ERR_INV_VALUE);
1471
1472   if (!gpg->file_name && !_gpgme_get_default_gpg_name ())
1473     return trace_gpg_error (GPG_ERR_INV_ENGINE);
1474
1475   if (gpg->lc_ctype)
1476     {
1477       rc = add_arg_ext (gpg, gpg->lc_ctype, 1);
1478       if (!rc)
1479         rc = add_arg_ext (gpg, "--lc-ctype", 1);
1480       if (rc)
1481         return rc;
1482     }
1483
1484   if (gpg->lc_messages)
1485     {
1486       rc = add_arg_ext (gpg, gpg->lc_messages, 1);
1487       if (!rc)
1488         rc = add_arg_ext (gpg, "--lc-messages", 1);
1489       if (rc)
1490         return rc;
1491     }
1492
1493   pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name ();
1494   rc = build_argv (gpg, pgmname);
1495   if (rc)
1496     return rc;
1497
1498   /* status_fd, colon_fd and end of list.  */
1499   n = 3;
1500   for (i = 0; gpg->fd_data_map[i].data; i++)
1501     n++;
1502   fd_list = calloc (n, sizeof *fd_list);
1503   if (! fd_list)
1504     return gpg_error_from_syserror ();
1505
1506   /* Build the fd list for the child.  */
1507   n = 0;
1508   fd_list[n].fd = gpg->status.fd[1];
1509   fd_list[n].dup_to = -1;
1510   fd_list[n].arg_loc = gpg->status.arg_loc;
1511   n++;
1512   if (gpg->colon.fnc)
1513     {
1514       fd_list[n].fd = gpg->colon.fd[1];
1515       fd_list[n].dup_to = 1;
1516       n++;
1517     }
1518   for (i = 0; gpg->fd_data_map[i].data; i++)
1519     {
1520       fd_list[n].fd = gpg->fd_data_map[i].peer_fd;
1521       fd_list[n].dup_to = gpg->fd_data_map[i].dup_to;
1522       fd_list[n].arg_loc = gpg->fd_data_map[i].arg_loc;
1523       n++;
1524     }
1525   fd_list[n].fd = -1;
1526   fd_list[n].dup_to = -1;
1527
1528   status = _gpgme_io_spawn (pgmname, gpg->argv,
1529                             (IOSPAWN_FLAG_DETACHED |IOSPAWN_FLAG_ALLOW_SET_FG),
1530                             fd_list, NULL, NULL, &pid);
1531   {
1532     int saved_err = gpg_error_from_syserror ();
1533     free (fd_list);
1534     if (status == -1)
1535       return saved_err;
1536   }
1537
1538   /*_gpgme_register_term_handler ( closure, closure_value, pid );*/
1539
1540   rc = add_io_cb (gpg, gpg->status.fd[0], 1, status_handler, gpg,
1541                   &gpg->status.tag);
1542   if (rc)
1543     /* FIXME: kill the child */
1544     return rc;
1545
1546   if (gpg->colon.fnc)
1547     {
1548       assert (gpg->colon.fd[0] != -1);
1549       rc = add_io_cb (gpg, gpg->colon.fd[0], 1, colon_line_handler, gpg,
1550                       &gpg->colon.tag);
1551       if (rc)
1552         /* FIXME: kill the child */
1553         return rc;
1554     }
1555
1556   for (i = 0; gpg->fd_data_map[i].data; i++)
1557     {
1558       if (gpg->cmd.used && i == gpg->cmd.idx)
1559         {
1560           /* Park the cmd fd.  */
1561           gpg->cmd.fd = gpg->fd_data_map[i].fd;
1562           gpg->fd_data_map[i].fd = -1;
1563         }
1564       else
1565         {
1566           rc = add_io_cb (gpg, gpg->fd_data_map[i].fd,
1567                           gpg->fd_data_map[i].inbound,
1568                           gpg->fd_data_map[i].inbound
1569                           ? _gpgme_data_inbound_handler
1570                           : _gpgme_data_outbound_handler,
1571                           gpg->fd_data_map[i].data, &gpg->fd_data_map[i].tag);
1572
1573           if (rc)
1574             /* FIXME: kill the child */
1575             return rc;
1576         }
1577     }
1578
1579   gpg_io_event (gpg, GPGME_EVENT_START, NULL);
1580
1581   /* fixme: check what data we can release here */
1582   return 0;
1583 }
1584
1585
1586 /* Add the --input-size-hint option if requested.  */
1587 static gpgme_error_t
1588 add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
1589 {
1590   gpgme_error_t err;
1591   gpgme_off_t value = _gpgme_data_get_size_hint (data);
1592   char numbuf[50];  /* Large enough for even 2^128 in base-10.  */
1593   char *p;
1594
1595   if (!value || !have_gpg_version (gpg, "2.1.15"))
1596     return 0;
1597
1598   err = add_arg (gpg, "--input-size-hint");
1599   if (!err)
1600     {
1601       p = numbuf + sizeof numbuf;
1602       *--p = 0;
1603       do
1604         {
1605           *--p = '0' + (value % 10);
1606           value /= 10;
1607         }
1608       while (value);
1609       err = add_arg (gpg, p);
1610     }
1611   return err;
1612 }
1613
1614
1615 static gpgme_error_t
1616 gpg_decrypt (void *engine,
1617              gpgme_decrypt_flags_t flags,
1618              gpgme_data_t ciph, gpgme_data_t plain,
1619              int export_session_key, const char *override_session_key,
1620              int auto_key_retrieve)
1621 {
1622   engine_gpg_t gpg = engine;
1623   gpgme_error_t err;
1624
1625   err = add_arg (gpg, "--decrypt");
1626
1627   if (!err && (flags & GPGME_DECRYPT_UNWRAP))
1628     {
1629       if (!have_gpg_version (gpg, "2.1.12"))
1630         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1631       else
1632         err = add_arg (gpg, "--unwrap");
1633     }
1634
1635   if (!err && export_session_key)
1636     err = add_arg (gpg, "--show-session-key");
1637
1638   if (!err && auto_key_retrieve)
1639     err = add_arg (gpg, "--auto-key-retrieve");
1640
1641   if (!err && override_session_key && *override_session_key)
1642     {
1643       if (have_gpg_version (gpg, "2.1.16"))
1644         {
1645           gpgme_data_release (gpg->override_session_key);
1646           TRACE2 (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
1647                   override_session_key,
1648                   strlen (override_session_key));
1649
1650           err = gpgme_data_new_from_mem (&gpg->override_session_key,
1651                                          override_session_key,
1652                                          strlen (override_session_key), 1);
1653           if (!err)
1654             {
1655               err = add_arg (gpg, "--override-session-key-fd");
1656               if (!err)
1657                 err = add_data (gpg, gpg->override_session_key, -2, 0);
1658             }
1659         }
1660       else
1661         {
1662           /* Using that option may leak the session key via ps(1).  */
1663           err = add_arg (gpg, "--override-session-key");
1664           if (!err)
1665             err = add_arg (gpg, override_session_key);
1666         }
1667     }
1668
1669   /* Tell the gpg object about the data.  */
1670   if (!err)
1671     err = add_arg (gpg, "--output");
1672   if (!err)
1673     err = add_arg (gpg, "-");
1674   if (!err)
1675     err = add_data (gpg, plain, 1, 1);
1676   if (!err)
1677     err = add_input_size_hint (gpg, ciph);
1678   if (!err)
1679     err = add_arg (gpg, "--");
1680   if (!err)
1681     err = add_data (gpg, ciph, -1, 0);
1682
1683   if (!err)
1684     err = start (gpg);
1685   return err;
1686 }
1687
1688 static gpgme_error_t
1689 gpg_delete (void *engine, gpgme_key_t key, unsigned int flags)
1690 {
1691   engine_gpg_t gpg = engine;
1692   gpgme_error_t err = 0;
1693   int allow_secret = flags & GPGME_DELETE_ALLOW_SECRET;
1694   int force = flags & GPGME_DELETE_FORCE;
1695
1696   if (force)
1697     err = add_arg (gpg, "--yes");
1698   if (!err)
1699     err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key"
1700                    : "--delete-key");
1701   if (!err)
1702     err = add_arg (gpg, "--");
1703   if (!err)
1704     {
1705       if (!key->subkeys || !key->subkeys->fpr)
1706         return gpg_error (GPG_ERR_INV_VALUE);
1707       else
1708         err = add_arg (gpg, key->subkeys->fpr);
1709     }
1710
1711   if (!err)
1712     err = start (gpg);
1713   return err;
1714 }
1715
1716
1717 static gpgme_error_t
1718 gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags)
1719 {
1720   engine_gpg_t gpg = engine;
1721   gpgme_error_t err;
1722
1723   (void)flags;
1724
1725   if (!key || !key->subkeys || !key->subkeys->fpr)
1726     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1727
1728   err = add_arg (gpg, "--passwd");
1729   if (!err)
1730     err = add_arg (gpg, key->subkeys->fpr);
1731   if (!err)
1732     err = start (gpg);
1733   return err;
1734 }
1735
1736
1737 static gpgme_error_t
1738 append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1739 {
1740   gpgme_error_t err = 0;
1741   int i;
1742   gpgme_key_t key;
1743
1744   for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
1745     {
1746       const char *s = key->subkeys ? key->subkeys->keyid : NULL;
1747       if (s)
1748         {
1749           if (!err)
1750             err = add_arg (gpg, "-u");
1751           if (!err)
1752             err = add_arg (gpg, s);
1753         }
1754       gpgme_key_unref (key);
1755       if (err)
1756         break;
1757     }
1758   return err;
1759 }
1760
1761
1762 static gpgme_error_t
1763 append_args_from_sender (engine_gpg_t gpg, gpgme_ctx_t ctx)
1764 {
1765   gpgme_error_t err;
1766
1767   if (ctx->sender && have_gpg_version (gpg, "2.1.15"))
1768     {
1769       err = add_arg (gpg, "--sender");
1770       if (!err)
1771         err = add_arg (gpg, ctx->sender);
1772     }
1773   else
1774     err = 0;
1775   return err;
1776 }
1777
1778
1779 static gpgme_error_t
1780 append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1781 {
1782   gpgme_error_t err = 0;
1783   gpgme_sig_notation_t notation;
1784
1785   notation = gpgme_sig_notation_get (ctx);
1786
1787   while (!err && notation)
1788     {
1789       if (notation->name
1790           && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
1791         err = gpg_error (GPG_ERR_INV_VALUE);
1792       else if (notation->name)
1793         {
1794           char *arg;
1795
1796           /* Maximum space needed is one byte for the "critical" flag,
1797              the name, one byte for '=', the value, and a terminating
1798              '\0'.  */
1799
1800           arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1);
1801           if (!arg)
1802             err = gpg_error_from_syserror ();
1803
1804           if (!err)
1805             {
1806               char *argp = arg;
1807
1808               if (notation->critical)
1809                 *(argp++) = '!';
1810
1811               memcpy (argp, notation->name, notation->name_len);
1812               argp += notation->name_len;
1813
1814               *(argp++) = '=';
1815
1816               /* We know that notation->name is '\0' terminated.  */
1817               strcpy (argp, notation->value);
1818             }
1819
1820           if (!err)
1821             err = add_arg (gpg, "--sig-notation");
1822           if (!err)
1823             err = add_arg (gpg, arg);
1824
1825           if (arg)
1826             free (arg);
1827         }
1828       else
1829         {
1830           /* This is a policy URL.  */
1831
1832           char *value;
1833
1834           if (notation->critical)
1835             {
1836               value = malloc (1 + notation->value_len + 1);
1837               if (!value)
1838                 err = gpg_error_from_syserror ();
1839               else
1840                 {
1841                   value[0] = '!';
1842                   /* We know that notation->value is '\0' terminated.  */
1843                   strcpy (&value[1], notation->value);
1844                 }
1845             }
1846           else
1847             value = notation->value;
1848
1849           if (!err)
1850             err = add_arg (gpg, "--sig-policy-url");
1851           if (!err)
1852             err = add_arg (gpg, value);
1853
1854           if (value != notation->value)
1855             free (value);
1856         }
1857
1858       notation = notation->next;
1859     }
1860   return err;
1861 }
1862
1863
1864 static gpgme_error_t
1865 gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
1866           gpgme_ctx_t ctx /* FIXME */)
1867 {
1868   engine_gpg_t gpg = engine;
1869   gpgme_error_t err;
1870
1871   err = add_arg (gpg, "--with-colons");
1872   if (!err)
1873     err = append_args_from_signers (gpg, ctx);
1874   if (!err)
1875   err = add_arg (gpg, type == 0 ? "--edit-key" : "--card-edit");
1876   if (!err)
1877     err = add_data (gpg, out, 1, 1);
1878   if (!err)
1879     err = add_arg (gpg, "--");
1880   if (!err && type == 0)
1881     {
1882       const char *s = key->subkeys ? key->subkeys->fpr : NULL;
1883       if (!s)
1884         err = gpg_error (GPG_ERR_INV_VALUE);
1885       else
1886         err = add_arg (gpg, s);
1887     }
1888   if (!err)
1889     err = start (gpg);
1890
1891   return err;
1892 }
1893
1894
1895 static gpgme_error_t
1896 append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
1897 {
1898   gpgme_error_t err = 0;
1899   int i = 0;
1900
1901   while (recp[i])
1902     {
1903       if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
1904         err = gpg_error (GPG_ERR_INV_VALUE);
1905       if (!err)
1906         err = add_arg (gpg, "-r");
1907       if (!err)
1908         err = add_arg (gpg, recp[i]->subkeys->fpr);
1909       if (err)
1910         break;
1911       i++;
1912     }
1913   return err;
1914 }
1915
1916
1917 static gpgme_error_t
1918 gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
1919              gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
1920 {
1921   engine_gpg_t gpg = engine;
1922   gpgme_error_t err = 0;
1923
1924   if (recp)
1925     err = add_arg (gpg, "--encrypt");
1926
1927   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
1928     err = add_arg (gpg, "--symmetric");
1929
1930   if (!err && use_armor)
1931     err = add_arg (gpg, "--armor");
1932
1933   if (!err && (flags & GPGME_ENCRYPT_WRAP))
1934     {
1935       /* gpg is current not able to detect already compressed
1936        * packets.  Thus when using
1937        *   gpg --unwrap -d | gpg --no-literal -e
1938        * the encryption would add an additional compression layer.
1939        * We better suppress that.  */
1940       flags |= GPGME_ENCRYPT_NO_COMPRESS;
1941       err = add_arg (gpg, "--no-literal");
1942     }
1943
1944   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1945     err = add_arg (gpg, "--compress-algo=none");
1946
1947   if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
1948     err = add_arg (gpg, "--throw-keyids");
1949
1950   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
1951       && have_gpg_version (gpg, "2.1.14"))
1952     err = add_arg (gpg, "--mimemode");
1953
1954   if (recp)
1955     {
1956       /* If we know that all recipients are valid (full or ultimate trust)
1957          we can suppress further checks.  */
1958       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
1959         err = add_arg (gpg, "--always-trust");
1960
1961       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
1962         err = add_arg (gpg, "--no-encrypt-to");
1963
1964       if (!err)
1965         err = append_args_from_recipients (gpg, recp);
1966     }
1967
1968   /* Tell the gpg object about the data.  */
1969   if (!err)
1970     err = add_arg (gpg, "--output");
1971   if (!err)
1972     err = add_arg (gpg, "-");
1973   if (!err)
1974     err = add_data (gpg, ciph, 1, 1);
1975   if (gpgme_data_get_file_name (plain))
1976     {
1977       if (!err)
1978         err = add_arg (gpg, "--set-filename");
1979       if (!err)
1980         err = add_arg (gpg, gpgme_data_get_file_name (plain));
1981     }
1982   if (!err)
1983     err = add_input_size_hint (gpg, plain);
1984   if (!err)
1985     err = add_arg (gpg, "--");
1986   if (!err)
1987     err = add_data (gpg, plain, -1, 0);
1988
1989   if (!err)
1990     err = start (gpg);
1991
1992   return err;
1993 }
1994
1995
1996 static gpgme_error_t
1997 gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
1998                   gpgme_encrypt_flags_t flags, gpgme_data_t plain,
1999                   gpgme_data_t ciph, int use_armor,
2000                   gpgme_ctx_t ctx /* FIXME */)
2001 {
2002   engine_gpg_t gpg = engine;
2003   gpgme_error_t err = 0;
2004
2005   if (recp)
2006     err = add_arg (gpg, "--encrypt");
2007
2008   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
2009     err = add_arg (gpg, "--symmetric");
2010
2011   if (!err)
2012     err = add_arg (gpg, "--sign");
2013   if (!err && use_armor)
2014     err = add_arg (gpg, "--armor");
2015
2016   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
2017     err = add_arg (gpg, "--compress-algo=none");
2018
2019   if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
2020     err = add_arg (gpg, "--throw-keyids");
2021
2022   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
2023       && have_gpg_version (gpg, "2.1.14"))
2024     err = add_arg (gpg, "--mimemode");
2025
2026   if (recp)
2027     {
2028       /* If we know that all recipients are valid (full or ultimate trust)
2029          we can suppress further checks.  */
2030       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
2031         err = add_arg (gpg, "--always-trust");
2032
2033       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
2034         err = add_arg (gpg, "--no-encrypt-to");
2035
2036       if (!err)
2037         err = append_args_from_recipients (gpg, recp);
2038     }
2039
2040   if (!err)
2041     err = append_args_from_signers (gpg, ctx);
2042
2043   if (!err)
2044     err = append_args_from_sender (gpg, ctx);
2045
2046   if (!err)
2047     err = append_args_from_sig_notations (gpg, ctx);
2048
2049   /* Tell the gpg object about the data.  */
2050   if (!err)
2051     err = add_arg (gpg, "--output");
2052   if (!err)
2053     err = add_arg (gpg, "-");
2054   if (!err)
2055     err = add_data (gpg, ciph, 1, 1);
2056   if (gpgme_data_get_file_name (plain))
2057     {
2058       if (!err)
2059         err = add_arg (gpg, "--set-filename");
2060       if (!err)
2061         err = add_arg (gpg, gpgme_data_get_file_name (plain));
2062     }
2063   if (!err)
2064     err = add_input_size_hint (gpg, plain);
2065   if (!err)
2066     err = add_arg (gpg, "--");
2067   if (!err)
2068     err = add_data (gpg, plain, -1, 0);
2069
2070   if (!err)
2071     err = start (gpg);
2072
2073   return err;
2074 }
2075
2076
2077 static gpgme_error_t
2078 export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
2079                gpgme_data_t keydata, int use_armor)
2080 {
2081   gpgme_error_t err = 0;
2082
2083   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
2084                 |GPGME_EXPORT_MODE_MINIMAL
2085                 |GPGME_EXPORT_MODE_SECRET)))
2086     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2087
2088   if ((mode & GPGME_EXPORT_MODE_MINIMAL))
2089     err = add_arg (gpg, "--export-options=export-minimal");
2090
2091   if (err)
2092     ;
2093   else if ((mode & GPGME_EXPORT_MODE_EXTERN))
2094     {
2095       err = add_arg (gpg, "--send-keys");
2096     }
2097   else
2098     {
2099       if ((mode & GPGME_EXPORT_MODE_SECRET))
2100         err = add_arg (gpg, "--export-secret-keys");
2101       else
2102         err = add_arg (gpg, "--export");
2103       if (!err && use_armor)
2104         err = add_arg (gpg, "--armor");
2105       if (!err)
2106         err = add_data (gpg, keydata, 1, 1);
2107     }
2108   if (!err)
2109     err = add_arg (gpg, "--");
2110
2111   return err;
2112 }
2113
2114
2115 static gpgme_error_t
2116 gpg_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
2117             gpgme_data_t keydata, int use_armor)
2118 {
2119   engine_gpg_t gpg = engine;
2120   gpgme_error_t err;
2121
2122   err = export_common (gpg, mode, keydata, use_armor);
2123
2124   if (!err && pattern && *pattern)
2125     err = add_arg (gpg, pattern);
2126
2127   if (!err)
2128     err = start (gpg);
2129
2130   return err;
2131 }
2132
2133
2134 static gpgme_error_t
2135 gpg_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
2136                 gpgme_data_t keydata, int use_armor)
2137 {
2138   engine_gpg_t gpg = engine;
2139   gpgme_error_t err;
2140
2141   err = export_common (gpg, mode, keydata, use_armor);
2142
2143   if (pattern)
2144     {
2145       while (!err && *pattern && **pattern)
2146         err = add_arg (gpg, *(pattern++));
2147     }
2148
2149   if (!err)
2150     err = start (gpg);
2151
2152   return err;
2153 }
2154
2155
2156 \f
2157 /* Helper to add algo, usage, and expire to the list of args.  */
2158 static gpgme_error_t
2159 gpg_add_algo_usage_expire (engine_gpg_t gpg,
2160                            const char *algo,
2161                            unsigned long expires,
2162                            unsigned int flags)
2163 {
2164   gpg_error_t err;
2165
2166   /* This condition is only required to allow the use of gpg < 2.1.16 */
2167   if (algo
2168       || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
2169                    | GPGME_CREATE_CERT | GPGME_CREATE_AUTH
2170                    | GPGME_CREATE_NOEXPIRE))
2171       || expires)
2172     {
2173       err = add_arg (gpg, algo? algo : "default");
2174       if (!err)
2175         {
2176           char tmpbuf[5*4+1];
2177           snprintf (tmpbuf, sizeof tmpbuf, "%s%s%s%s",
2178                     (flags & GPGME_CREATE_SIGN)? " sign":"",
2179                     (flags & GPGME_CREATE_ENCR)? " encr":"",
2180                     (flags & GPGME_CREATE_CERT)? " cert":"",
2181                     (flags & GPGME_CREATE_AUTH)? " auth":"");
2182           err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
2183         }
2184       if (!err)
2185         {
2186           if ((flags & GPGME_CREATE_NOEXPIRE))
2187             err = add_arg (gpg, "never");
2188           else if (expires == 0)
2189             err = add_arg (gpg, "-");
2190           else
2191             {
2192               char tmpbuf[8+20];
2193               snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
2194               err = add_arg (gpg, tmpbuf);
2195             }
2196         }
2197     }
2198   else
2199     err = 0;
2200
2201   return err;
2202 }
2203
2204
2205 static gpgme_error_t
2206 gpg_createkey_from_param (engine_gpg_t gpg,
2207                           gpgme_data_t help_data, unsigned int extraflags)
2208 {
2209   gpgme_error_t err;
2210
2211   err = add_arg (gpg, "--gen-key");
2212   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2213     err = add_arg (gpg, "--armor");
2214   if (!err)
2215     err = add_arg (gpg, "--");
2216   if (!err)
2217     err = add_data (gpg, help_data, -1, 0);
2218   if (!err)
2219     err = start (gpg);
2220   return err;
2221 }
2222
2223
2224 static gpgme_error_t
2225 gpg_createkey (engine_gpg_t gpg,
2226                const char *userid, const char *algo,
2227                unsigned long expires,
2228                unsigned int flags,
2229                unsigned int extraflags)
2230 {
2231   gpgme_error_t err;
2232
2233   err = add_arg (gpg, "--quick-gen-key");
2234   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2235     err = add_arg (gpg, "--armor");
2236   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2237     {
2238       err = add_arg (gpg, "--passphrase");
2239       if (!err)
2240         err = add_arg (gpg, "");
2241       if (!err)
2242         err = add_arg (gpg, "--batch");
2243     }
2244   if (!err && (flags & GPGME_CREATE_FORCE))
2245     err = add_arg (gpg, "--yes");
2246   if (!err)
2247     err = add_arg (gpg, "--");
2248   if (!err)
2249     err = add_arg (gpg, userid);
2250
2251   if (!err)
2252     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2253
2254   if (!err)
2255     err = start (gpg);
2256   return err;
2257 }
2258
2259
2260 static gpgme_error_t
2261 gpg_addkey (engine_gpg_t gpg,
2262             const char *algo,
2263             unsigned long expires,
2264             gpgme_key_t key,
2265             unsigned int flags,
2266             unsigned int extraflags)
2267 {
2268   gpgme_error_t err;
2269
2270   if (!key || !key->fpr)
2271     return gpg_error (GPG_ERR_INV_ARG);
2272
2273   err = add_arg (gpg, "--quick-addkey");
2274   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2275     err = add_arg (gpg, "--armor");
2276   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2277     {
2278       err = add_arg (gpg, "--passphrase");
2279       if (!err)
2280         err = add_arg (gpg, "");
2281       if (!err)
2282         err = add_arg (gpg, "--batch");
2283     }
2284   if (!err)
2285     err = add_arg (gpg, "--");
2286   if (!err)
2287     err = add_arg (gpg, key->fpr);
2288
2289   if (!err)
2290     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2291
2292   if (!err)
2293     err = start (gpg);
2294   return err;
2295 }
2296
2297
2298 static gpgme_error_t
2299 gpg_adduid (engine_gpg_t gpg,
2300             gpgme_key_t key,
2301             const char *userid,
2302             unsigned int extraflags)
2303 {
2304   gpgme_error_t err;
2305
2306   if (!key || !key->fpr || !userid)
2307     return gpg_error (GPG_ERR_INV_ARG);
2308
2309   if ((extraflags & GENKEY_EXTRAFLAG_SETPRIMARY))
2310     {
2311       if (!have_gpg_version (gpg, "2.1.20"))
2312         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2313       else
2314         err = add_arg (gpg, "--quick-set-primary-uid");
2315     }
2316   else if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
2317     err = add_arg (gpg, "--quick-revuid");
2318   else
2319     err = add_arg (gpg, "--quick-adduid");
2320
2321   if (!err)
2322     err = add_arg (gpg, "--");
2323   if (!err)
2324     err = add_arg (gpg, key->fpr);
2325   if (!err)
2326     err = add_arg (gpg, userid);
2327
2328   if (!err)
2329     err = start (gpg);
2330   return err;
2331 }
2332
2333
2334 static gpgme_error_t
2335 gpg_genkey (void *engine,
2336             const char *userid, const char *algo,
2337             unsigned long reserved, unsigned long expires,
2338             gpgme_key_t key, unsigned int flags,
2339             gpgme_data_t help_data, unsigned int extraflags,
2340             gpgme_data_t pubkey, gpgme_data_t seckey)
2341 {
2342   engine_gpg_t gpg = engine;
2343   gpgme_error_t err;
2344
2345   (void)reserved;
2346
2347   if (!gpg)
2348     return gpg_error (GPG_ERR_INV_VALUE);
2349
2350   /* If HELP_DATA is given the use of the old interface
2351    * (gpgme_op_genkey) has been requested.  The other modes are:
2352    *
2353    *  USERID && !KEY          - Create a new keyblock.
2354    * !USERID &&  KEY          - Add a new subkey to KEY (gpg >= 2.1.14)
2355    *  USERID &&  KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
2356    *                            or set a flag on a user id.
2357    */
2358   if (help_data)
2359     {
2360       /* We need a special mechanism to get the fd of a pipe here, so
2361          that we can use this for the %pubring and %secring
2362          parameters.  We don't have this yet, so we implement only the
2363          adding to the standard keyrings.  */
2364       if (pubkey || seckey)
2365         err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2366       else
2367         err = gpg_createkey_from_param (gpg, help_data, extraflags);
2368     }
2369   else if (!have_gpg_version (gpg, "2.1.13"))
2370     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2371   else if (userid && !key)
2372     err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags);
2373   else if (!userid && key)
2374     err = gpg_addkey (gpg, algo, expires, key, flags, extraflags);
2375   else if (userid && key && !algo)
2376     err = gpg_adduid (gpg, key, userid, extraflags);
2377   else
2378     err = gpg_error (GPG_ERR_INV_VALUE);
2379
2380   return err;
2381 }
2382
2383 /* Return the next DELIM delimited string from DATA as a C-string.
2384    The caller needs to provide the address of a pointer variable which
2385    he has to set to NULL before the first call.  After the last call
2386    to this function, this function needs to be called once more with
2387    DATA set to NULL so that the function can release its internal
2388    state.  After that the pointer variable is free for use again.
2389    Note that we use a delimiter and thus a trailing delimiter is not
2390    required.  DELIM may not be changed after the first call. */
2391 static const char *
2392 string_from_data (gpgme_data_t data, int delim,
2393                   void **helpptr, gpgme_error_t *r_err)
2394 {
2395 #define MYBUFLEN 2000 /* Fixme: We don't support URLs longer than that.  */
2396   struct {
2397     int  eof_seen;
2398     int  nbytes;      /* Length of the last returned string including
2399                          the delimiter. */
2400     int  buflen;      /* Valid length of BUF.  */
2401     char buf[MYBUFLEN+1];  /* Buffer with one byte extra space.  */
2402   } *self;
2403   char *p;
2404   int nread;
2405
2406   *r_err = 0;
2407   if (!data)
2408     {
2409       if (*helpptr)
2410         {
2411           free (*helpptr);
2412           *helpptr = NULL;
2413         }
2414       return NULL;
2415     }
2416
2417   if (*helpptr)
2418     self = *helpptr;
2419   else
2420     {
2421       self = malloc (sizeof *self);
2422       if (!self)
2423         {
2424           *r_err = gpg_error_from_syserror ();
2425           return NULL;
2426         }
2427       *helpptr = self;
2428       self->eof_seen = 0;
2429       self->nbytes = 0;
2430       self->buflen = 0;
2431     }
2432
2433   if (self->eof_seen)
2434     return NULL;
2435
2436   assert (self->nbytes <= self->buflen);
2437   memmove (self->buf, self->buf + self->nbytes, self->buflen - self->nbytes);
2438   self->buflen -= self->nbytes;
2439   self->nbytes = 0;
2440
2441   do
2442     {
2443       /* Fixme: This is fairly infective scanning because we may scan
2444          the buffer several times.  */
2445       p = memchr (self->buf, delim, self->buflen);
2446       if (p)
2447         {
2448           *p = 0;
2449           self->nbytes = p - self->buf + 1;
2450           return self->buf;
2451         }
2452
2453       if ( !(MYBUFLEN - self->buflen) )
2454         {
2455           /* Not enough space - URL too long.  */
2456           *r_err = gpg_error (GPG_ERR_TOO_LARGE);
2457           return NULL;
2458         }
2459
2460       nread = gpgme_data_read (data, self->buf + self->buflen,
2461                                MYBUFLEN - self->buflen);
2462       if (nread < 0)
2463         {
2464           *r_err = gpg_error_from_syserror ();
2465           return NULL;
2466         }
2467       self->buflen += nread;
2468     }
2469   while (nread);
2470
2471   /* EOF reached.  If we have anything in the buffer, append a Nul and
2472      return it. */
2473   self->eof_seen = 1;
2474   if (self->buflen)
2475     {
2476       self->buf[self->buflen] = 0;  /* (we allocated one extra byte)  */
2477       return self->buf;
2478     }
2479   return NULL;
2480 #undef MYBUFLEN
2481 }
2482
2483
2484
2485 static gpgme_error_t
2486 gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
2487 {
2488   engine_gpg_t gpg = engine;
2489   gpgme_error_t err;
2490   int idx;
2491   gpgme_data_encoding_t dataenc;
2492
2493   if (keydata && keyarray)
2494     return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
2495
2496   dataenc = gpgme_data_get_encoding (keydata);
2497
2498   if (keyarray)
2499     {
2500       err = add_arg (gpg, "--recv-keys");
2501       if (!err)
2502         err = add_arg (gpg, "--");
2503       for (idx=0; !err && keyarray[idx]; idx++)
2504         {
2505           if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP)
2506             ;
2507           else if (!keyarray[idx]->subkeys)
2508             ;
2509           else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr)
2510             err = add_arg (gpg, keyarray[idx]->subkeys->fpr);
2511           else if (*keyarray[idx]->subkeys->keyid)
2512             err = add_arg (gpg, keyarray[idx]->subkeys->keyid);
2513         }
2514     }
2515   else if (dataenc == GPGME_DATA_ENCODING_URL
2516            || dataenc == GPGME_DATA_ENCODING_URL0)
2517     {
2518       void *helpptr;
2519       const char *string;
2520       gpgme_error_t xerr;
2521       int delim = (dataenc == GPGME_DATA_ENCODING_URL)? '\n': 0;
2522
2523       /* FIXME: --fetch-keys is probably not correct because it can't
2524          grok all kinds of URLs.  On Unix it should just work but on
2525          Windows we will build the command line and that may fail for
2526          some embedded control characters.  It is anyway limited to
2527          the maximum size of the command line.  We need another
2528          command which can take its input from a file.  Maybe we
2529          should use an option to gpg to modify such commands (ala
2530          --multifile).  */
2531       err = add_arg (gpg, "--fetch-keys");
2532       if (!err)
2533         err = add_arg (gpg, "--");
2534       helpptr = NULL;
2535       while (!err
2536              && (string = string_from_data (keydata, delim, &helpptr, &xerr)))
2537         err = add_arg (gpg, string);
2538       if (!err)
2539         err = xerr;
2540       string_from_data (NULL, delim, &helpptr, &xerr);
2541     }
2542   else if (dataenc == GPGME_DATA_ENCODING_URLESC)
2543     {
2544       /* Already escaped URLs are not yet supported.  */
2545       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2546     }
2547   else
2548     {
2549       err = add_arg (gpg, "--import");
2550       if (!err)
2551         err = add_arg (gpg, "--");
2552       if (!err)
2553         err = add_data (gpg, keydata, -1, 0);
2554     }
2555
2556   if (!err)
2557     err = start (gpg);
2558
2559   return err;
2560 }
2561
2562
2563 /* The output for external keylistings in GnuPG is different from all
2564    the other key listings.  We catch this here with a special
2565    preprocessor that reformats the colon handler lines.  */
2566 static gpgme_error_t
2567 gpg_keylist_preprocess (char *line, char **r_line)
2568 {
2569   enum
2570     {
2571       RT_NONE, RT_INFO, RT_PUB, RT_UID
2572     }
2573   rectype = RT_NONE;
2574 #define NR_FIELDS 16
2575   char *field[NR_FIELDS];
2576   int fields = 0;
2577   size_t n;
2578
2579   *r_line = NULL;
2580
2581   while (line && fields < NR_FIELDS)
2582     {
2583       field[fields++] = line;
2584       line = strchr (line, ':');
2585       if (line)
2586         *(line++) = '\0';
2587     }
2588
2589   if (!strcmp (field[0], "info"))
2590     rectype = RT_INFO;
2591   else if (!strcmp (field[0], "pub"))
2592     rectype = RT_PUB;
2593   else if (!strcmp (field[0], "uid"))
2594     rectype = RT_UID;
2595   else
2596     rectype = RT_NONE;
2597
2598   switch (rectype)
2599     {
2600     case RT_INFO:
2601       /* FIXME: Eventually, check the version number at least.  */
2602       return 0;
2603
2604     case RT_PUB:
2605       if (fields < 7)
2606         return 0;
2607
2608       /* The format is:
2609
2610          pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
2611
2612          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2613          HTTP Keyserver Protocol (draft).  Modern versions of the SKS
2614          keyserver return the fingerprint instead of the keyid.  We
2615          detect this here and use the v4 fingerprint format to convert
2616          it to a key id.
2617
2618          We want:
2619          pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
2620       */
2621
2622       n = strlen (field[1]);
2623       if (n > 16)
2624         {
2625           if (gpgrt_asprintf (r_line,
2626                         "pub:o%s:%s:%s:%s:%s:%s::::::::\n"
2627                         "fpr:::::::::%s:",
2628                         field[6], field[3], field[2], field[1] + n - 16,
2629                         field[4], field[5], field[1]) < 0)
2630             return gpg_error_from_syserror ();
2631         }
2632       else
2633         {
2634           if (gpgrt_asprintf (r_line,
2635                         "pub:o%s:%s:%s:%s:%s:%s::::::::",
2636                         field[6], field[3], field[2], field[1],
2637                         field[4], field[5]) < 0)
2638             return gpg_error_from_syserror ();
2639         }
2640
2641       return 0;
2642
2643     case RT_UID:
2644       /* The format is:
2645
2646          uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
2647
2648          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2649          HTTP Keyserver Protocol (draft).
2650
2651          For an ldap keyserver the format is:
2652          uid:<escaped uid string>
2653
2654          We want:
2655          uid:o<flags>::::<creatdate>:<expdate>:::<c-coded uid>:
2656       */
2657
2658       {
2659         /* The user ID is percent escaped, but we want c-coded.
2660            Because we have to replace each '%HL' by '\xHL', we need at
2661            most 4/3 th the number of bytes.  But because we also need
2662            to escape the backslashes we allocate twice as much.  */
2663         char *uid = malloc (2 * strlen (field[1]) + 1);
2664         char *src;
2665         char *dst;
2666
2667         if (! uid)
2668           return gpg_error_from_syserror ();
2669         src = field[1];
2670         dst = uid;
2671         while (*src)
2672           {
2673             if (*src == '%')
2674               {
2675                 *(dst++) = '\\';
2676                 *(dst++) = 'x';
2677                 src++;
2678                 /* Copy the next two bytes unconditionally.  */
2679                 if (*src)
2680                   *(dst++) = *(src++);
2681                 if (*src)
2682                   *(dst++) = *(src++);
2683               }
2684             else if (*src == '\\')
2685               {
2686                 *dst++ = '\\';
2687                 *dst++ = '\\';
2688                 src++;
2689               }
2690             else
2691               *(dst++) = *(src++);
2692           }
2693         *dst = '\0';
2694
2695         if (fields < 4)
2696           {
2697             if (gpgrt_asprintf (r_line, "uid:o::::::::%s:", uid) < 0)
2698               return gpg_error_from_syserror ();
2699           }
2700         else
2701           {
2702             if (gpgrt_asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
2703                                 field[4], field[2], field[3], uid) < 0)
2704               return gpg_error_from_syserror ();
2705           }
2706       }
2707       return 0;
2708
2709     case RT_NONE:
2710       /* Unknown record.  */
2711       break;
2712     }
2713   return 0;
2714
2715 }
2716
2717
2718 static gpg_error_t
2719 gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
2720                            gpgme_keylist_mode_t mode)
2721 {
2722   gpg_error_t err;
2723
2724   err = add_arg (gpg, "--with-colons");
2725
2726   /* Since gpg 2.1.15 fingerprints are always printed, thus there is
2727    * no more need to explicitly request them.  */
2728   if (!have_gpg_version (gpg, "2.1.15"))
2729     {
2730       if (!err)
2731         err = add_arg (gpg, "--fixed-list-mode");
2732       if (!err)
2733         err = add_arg (gpg, "--with-fingerprint");
2734       if (!err)
2735         err = add_arg (gpg, "--with-fingerprint");
2736     }
2737
2738   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
2739       && have_gpg_version (gpg, "2.1.16"))
2740     err = add_arg (gpg, "--with-tofu-info");
2741
2742   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
2743     err = add_arg (gpg, "--with-secret");
2744
2745   if (!err
2746       && (mode & GPGME_KEYLIST_MODE_SIGS)
2747       && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
2748     {
2749       err = add_arg (gpg, "--list-options");
2750       if (!err)
2751         err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
2752     }
2753
2754   if (!err)
2755     {
2756       if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
2757         {
2758           if (secret_only)
2759             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2760           else if ( (mode & GPGME_KEYLIST_MODE_LOCAL))
2761             {
2762               /* The local+extern mode is special.  It works only with
2763                  gpg >= 2.0.10.  FIXME: We should check that we have
2764                  such a version to that we can return a proper error
2765                  code.  The problem is that we don't know the context
2766                  here and thus can't access the cached version number
2767                  for the engine info structure.  */
2768               err = add_arg (gpg, "--locate-keys");
2769               if ((mode & GPGME_KEYLIST_MODE_SIGS))
2770                 err = add_arg (gpg, "--with-sig-check");
2771             }
2772           else
2773             {
2774               err = add_arg (gpg, "--search-keys");
2775               gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
2776             }
2777         }
2778       else
2779         {
2780           err = add_arg (gpg, secret_only ? "--list-secret-keys"
2781                          : ((mode & GPGME_KEYLIST_MODE_SIGS)
2782                             ? "--check-sigs" : "--list-keys"));
2783         }
2784     }
2785
2786   if (!err)
2787     err = add_arg (gpg, "--");
2788
2789   return err;
2790 }
2791
2792
2793 static gpgme_error_t
2794 gpg_keylist (void *engine, const char *pattern, int secret_only,
2795              gpgme_keylist_mode_t mode, int engine_flags)
2796 {
2797   engine_gpg_t gpg = engine;
2798   gpgme_error_t err;
2799
2800   (void)engine_flags;
2801
2802   err = gpg_keylist_build_options (gpg, secret_only, mode);
2803
2804   if (!err && pattern && *pattern)
2805     err = add_arg (gpg, pattern);
2806
2807   if (!err)
2808     err = start (gpg);
2809
2810   return err;
2811 }
2812
2813
2814 static gpgme_error_t
2815 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
2816                  int reserved, gpgme_keylist_mode_t mode, int engine_flags)
2817 {
2818   engine_gpg_t gpg = engine;
2819   gpgme_error_t err;
2820
2821   (void)engine_flags;
2822
2823   if (reserved)
2824     return gpg_error (GPG_ERR_INV_VALUE);
2825
2826   err = gpg_keylist_build_options (gpg, secret_only, mode);
2827
2828   if (pattern)
2829     {
2830       while (!err && *pattern && **pattern)
2831         err = add_arg (gpg, *(pattern++));
2832     }
2833
2834   if (!err)
2835     err = start (gpg);
2836
2837   return err;
2838 }
2839
2840
2841 static gpgme_error_t
2842 gpg_keylist_data (void *engine, gpgme_data_t data)
2843 {
2844   engine_gpg_t gpg = engine;
2845   gpgme_error_t err;
2846
2847   if (!have_gpg_version (gpg, "2.1.14"))
2848     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2849
2850   err = add_arg (gpg, "--with-colons");
2851   if (!err)
2852     err = add_arg (gpg, "--with-fingerprint");
2853   if (!err)
2854     err = add_arg (gpg, "--import-options");
2855   if (!err)
2856     err = add_arg (gpg, "import-show");
2857   if (!err)
2858     err = add_arg (gpg, "--dry-run");
2859   if (!err)
2860     err = add_arg (gpg, "--import");
2861   if (!err)
2862     err = add_arg (gpg, "--");
2863   if (!err)
2864     err = add_data (gpg, data, -1, 0);
2865
2866   if (!err)
2867     err = start (gpg);
2868
2869   return err;
2870 }
2871
2872
2873 static gpgme_error_t
2874 gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
2875              unsigned long expire, unsigned int flags,
2876              gpgme_ctx_t ctx)
2877 {
2878   engine_gpg_t gpg = engine;
2879   gpgme_error_t err;
2880   const char *s;
2881
2882   if (!key || !key->fpr)
2883     return gpg_error (GPG_ERR_INV_ARG);
2884
2885   if (!have_gpg_version (gpg, "2.1.12"))
2886     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2887
2888   if ((flags & GPGME_KEYSIGN_LOCAL))
2889     err = add_arg (gpg, "--quick-lsign-key");
2890   else
2891     err = add_arg (gpg, "--quick-sign-key");
2892
2893   if (!err)
2894     err = append_args_from_signers (gpg, ctx);
2895
2896   /* If an expiration time has been given use that.  If none has been
2897    * given the default from gpg.conf is used.  To make sure not to set
2898    * an expiration time at all the flag GPGME_KEYSIGN_NOEXPIRE can be
2899    * used.  */
2900   if (!err && (expire || (flags & GPGME_KEYSIGN_NOEXPIRE)))
2901     {
2902       char tmpbuf[8+20];
2903
2904       if ((flags & GPGME_KEYSIGN_NOEXPIRE))
2905         expire = 0;
2906       snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expire);
2907       err = add_arg (gpg, "--default-cert-expire");
2908       if (!err)
2909         err = add_arg (gpg, tmpbuf);
2910     }
2911
2912   if (!err)
2913     err = add_arg (gpg, "--");
2914
2915   if (!err)
2916     err = add_arg (gpg, key->fpr);
2917   if (!err && userid)
2918     {
2919       if ((flags & GPGME_KEYSIGN_LFSEP))
2920         {
2921           for (; !err && (s = strchr (userid, '\n')); userid = s + 1)
2922             if ((s - userid))
2923               err = add_arg_len (gpg, "=", userid, s - userid);
2924           if (!err && *userid)
2925             err = add_arg_pfx (gpg, "=", userid);
2926         }
2927       else
2928         err = add_arg_pfx (gpg, "=", userid);
2929     }
2930
2931   if (!err)
2932     err = start (gpg);
2933
2934   return err;
2935 }
2936
2937
2938 static gpgme_error_t
2939 gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
2940 {
2941   engine_gpg_t gpg = engine;
2942   gpgme_error_t err;
2943   const char *policystr = NULL;
2944
2945   if (!key || !key->fpr)
2946     return gpg_error (GPG_ERR_INV_ARG);
2947
2948   switch (policy)
2949     {
2950     case GPGME_TOFU_POLICY_NONE:                           break;
2951     case GPGME_TOFU_POLICY_AUTO:    policystr = "auto";    break;
2952     case GPGME_TOFU_POLICY_GOOD:    policystr = "good";    break;
2953     case GPGME_TOFU_POLICY_BAD:     policystr = "bad";     break;
2954     case GPGME_TOFU_POLICY_ASK:     policystr = "ask";     break;
2955     case GPGME_TOFU_POLICY_UNKNOWN: policystr = "unknown"; break;
2956     }
2957   if (!policystr)
2958     return gpg_error (GPG_ERR_INV_VALUE);
2959
2960   if (!have_gpg_version (gpg, "2.1.10"))
2961     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2962
2963   err = add_arg (gpg, "--tofu-policy");
2964   if (!err)
2965     err = add_arg (gpg, "--");
2966   if (!err)
2967     err = add_arg (gpg, policystr);
2968   if (!err)
2969     err = add_arg (gpg, key->fpr);
2970
2971   if (!err)
2972     err = start (gpg);
2973
2974   return err;
2975 }
2976
2977
2978 static gpgme_error_t
2979 gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
2980           gpgme_sig_mode_t mode, int use_armor, int use_textmode,
2981           int include_certs, gpgme_ctx_t ctx /* FIXME */)
2982 {
2983   engine_gpg_t gpg = engine;
2984   gpgme_error_t err;
2985
2986   (void)include_certs;
2987
2988   if (mode == GPGME_SIG_MODE_CLEAR)
2989     err = add_arg (gpg, "--clearsign");
2990   else
2991     {
2992       err = add_arg (gpg, "--sign");
2993       if (!err && mode == GPGME_SIG_MODE_DETACH)
2994         err = add_arg (gpg, "--detach");
2995       if (!err && use_armor)
2996         err = add_arg (gpg, "--armor");
2997       if (!err)
2998         {
2999           if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
3000               && have_gpg_version (gpg, "2.1.14"))
3001             err = add_arg (gpg, "--mimemode");
3002           else if (use_textmode)
3003             err = add_arg (gpg, "--textmode");
3004         }
3005     }
3006
3007   if (!err)
3008     err = append_args_from_signers (gpg, ctx);
3009   if (!err)
3010     err = append_args_from_sender (gpg, ctx);
3011   if (!err)
3012     err = append_args_from_sig_notations (gpg, ctx);
3013
3014   if (gpgme_data_get_file_name (in))
3015     {
3016       if (!err)
3017         err = add_arg (gpg, "--set-filename");
3018       if (!err)
3019         err = add_arg (gpg, gpgme_data_get_file_name (in));
3020     }
3021
3022   /* Tell the gpg object about the data.  */
3023   if (!err)
3024     err = add_input_size_hint (gpg, in);
3025   if (!err)
3026     err = add_arg (gpg, "--");
3027   if (!err)
3028     err = add_data (gpg, in, -1, 0);
3029   if (!err)
3030     err = add_data (gpg, out, 1, 1);
3031
3032   if (!err)
3033     err = start (gpg);
3034
3035   return err;
3036 }
3037
3038 static gpgme_error_t
3039 gpg_trustlist (void *engine, const char *pattern)
3040 {
3041   engine_gpg_t gpg = engine;
3042   gpgme_error_t err;
3043
3044   err = add_arg (gpg, "--with-colons");
3045   if (!err)
3046     err = add_arg (gpg, "--list-trust-path");
3047
3048   /* Tell the gpg object about the data.  */
3049   if (!err)
3050     err = add_arg (gpg, "--");
3051   if (!err)
3052     err = add_arg (gpg, pattern);
3053
3054   if (!err)
3055     err = start (gpg);
3056
3057   return err;
3058 }
3059
3060
3061 static gpgme_error_t
3062 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
3063             gpgme_data_t plaintext, gpgme_ctx_t ctx)
3064 {
3065   engine_gpg_t gpg = engine;
3066   gpgme_error_t err;
3067
3068   err = append_args_from_sender (gpg, ctx);
3069   if (!err && ctx->auto_key_retrieve)
3070     err = add_arg (gpg, "--auto-key-retrieve");
3071
3072   if (err)
3073     ;
3074   else if (plaintext)
3075     {
3076       /* Normal or cleartext signature.  */
3077       err = add_arg (gpg, "--output");
3078       if (!err)
3079         err = add_arg (gpg, "-");
3080       if (!err)
3081         err = add_input_size_hint (gpg, sig);
3082       if (!err)
3083         err = add_arg (gpg, "--");
3084       if (!err)
3085         err = add_data (gpg, sig, -1, 0);
3086       if (!err)
3087         err = add_data (gpg, plaintext, 1, 1);
3088     }
3089   else
3090     {
3091       err = add_arg (gpg, "--verify");
3092       if (!err)
3093         err = add_input_size_hint (gpg, signed_text);
3094       if (!err)
3095         err = add_arg (gpg, "--");
3096       if (!err)
3097         err = add_data (gpg, sig, -1, 0);
3098       if (!err && signed_text)
3099         err = add_data (gpg, signed_text, -1, 0);
3100     }
3101
3102   if (!err)
3103     err = start (gpg);
3104
3105   return err;
3106 }
3107
3108
3109 static void
3110 gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
3111 {
3112   engine_gpg_t gpg = engine;
3113
3114   gpg->io_cbs = *io_cbs;
3115 }
3116
3117
3118 static gpgme_error_t
3119 gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
3120 {
3121   engine_gpg_t gpg = engine;
3122
3123   gpg->pinentry_mode = mode;
3124   return 0;
3125 }
3126
3127
3128 \f
3129 struct engine_ops _gpgme_engine_ops_gpg =
3130   {
3131     /* Static functions.  */
3132     _gpgme_get_default_gpg_name,
3133     NULL,
3134     gpg_get_version,
3135     gpg_get_req_version,
3136     gpg_new,
3137
3138     /* Member functions.  */
3139     gpg_release,
3140     NULL,                               /* reset */
3141     gpg_set_status_cb,
3142     gpg_set_status_handler,
3143     gpg_set_command_handler,
3144     gpg_set_colon_line_handler,
3145     gpg_set_locale,
3146     NULL,                               /* set_protocol */
3147     gpg_set_engine_flags,               /* set_engine_flags */
3148     gpg_decrypt,
3149     gpg_delete,
3150     gpg_edit,
3151     gpg_encrypt,
3152     gpg_encrypt_sign,
3153     gpg_export,
3154     gpg_export_ext,
3155     gpg_genkey,
3156     gpg_import,
3157     gpg_keylist,
3158     gpg_keylist_ext,
3159     gpg_keylist_data,
3160     gpg_keysign,
3161     gpg_tofu_policy,    /* tofu_policy */
3162     gpg_sign,
3163     gpg_trustlist,
3164     gpg_verify,
3165     NULL,               /* getauditlog */
3166     NULL,               /* opassuan_transact */
3167     NULL,               /* conf_load */
3168     NULL,               /* conf_save */
3169     NULL,               /* conf_dir */
3170     NULL,               /* query_swdb */
3171     gpg_set_io_cbs,
3172     gpg_io_event,
3173     gpg_cancel,
3174     NULL,               /* cancel_op */
3175     gpg_passwd,
3176     gpg_set_pinentry_mode,
3177     NULL                /* opspawn */
3178   };