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