gpg-connect-agent: Make it easier to connect to the dirmngr.
[gnupg.git] / tools / gpg-connect-agent.c
1 /* gpg-connect-agent.c - Tool to connect to the agent.
2  * Copyright (C) 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
3  * Copyright (C) 2014 Werner Koch
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <ctype.h>
28 #include <assuan.h>
29 #include <unistd.h>
30 #include <assert.h>
31
32 #include "i18n.h"
33 #include "../common/util.h"
34 #include "../common/asshelp.h"
35 #include "../common/sysutils.h"
36 #include "../common/membuf.h"
37 #include "../common/ttyio.h"
38 #ifdef HAVE_W32_SYSTEM
39 #  include "../common/exechelp.h"
40 #endif
41 #include "../common/init.h"
42
43
44 #define CONTROL_D ('D' - 'A' + 1)
45 #define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
46
47 /* Constants to identify the commands and options. */
48 enum cmd_and_opt_values
49   {
50     aNull = 0,
51     oQuiet      = 'q',
52     oVerbose    = 'v',
53     oRawSocket  = 'S',
54     oTcpSocket  = 'T',
55     oExec       = 'E',
56     oRun        = 'r',
57     oSubst      = 's',
58
59     oNoVerbose  = 500,
60     oHomedir,
61     oAgentProgram,
62     oDirmngrProgram,
63     oHex,
64     oDecode,
65     oNoExtConnect,
66     oDirmngr
67
68   };
69
70
71 /* The list of commands and options. */
72 static ARGPARSE_OPTS opts[] = {
73   ARGPARSE_group (301, N_("@\nOptions:\n ")),
74
75   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
76   ARGPARSE_s_n (oQuiet, "quiet",     N_("quiet")),
77   ARGPARSE_s_n (oHex,   "hex",       N_("print data out hex encoded")),
78   ARGPARSE_s_n (oDecode,"decode",    N_("decode received data lines")),
79   ARGPARSE_s_n (oDirmngr,"dirmngr",  N_("connect to the dirmngr")),
80   ARGPARSE_s_s (oRawSocket, "raw-socket",
81                 N_("|NAME|connect to Assuan socket NAME")),
82   ARGPARSE_s_s (oTcpSocket, "tcp-socket",
83                 N_("|ADDR|connect to Assuan server at ADDR")),
84   ARGPARSE_s_n (oExec, "exec",
85                 N_("run the Assuan server given on the command line")),
86   ARGPARSE_s_n (oNoExtConnect, "no-ext-connect",
87                 N_("do not use extended connect mode")),
88   ARGPARSE_s_s (oRun,  "run",
89                 N_("|FILE|run commands from FILE on startup")),
90   ARGPARSE_s_n (oSubst, "subst",     N_("run /subst on startup")),
91
92   ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
93   ARGPARSE_s_s (oHomedir, "homedir", "@" ),
94   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
95   ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
96
97   ARGPARSE_end ()
98 };
99
100
101 /* We keep all global options in the structure OPT.  */
102 struct
103 {
104   int verbose;          /* Verbosity level.  */
105   int quiet;            /* Be extra quiet.  */
106   const char *homedir;  /* Configuration directory name */
107   const char *agent_program;  /* Value of --agent-program.  */
108   const char *dirmngr_program;  /* Value of --dirmngr-program.  */
109   int hex;              /* Print data lines in hex format. */
110   int decode;           /* Decode received data lines.  */
111   int use_dirmngr;      /* Use the dirmngr and not gpg-agent.  */
112   const char *raw_socket; /* Name of socket to connect in raw mode. */
113   const char *tcp_socket; /* Name of server to connect in tcp mode. */
114   int exec;             /* Run the pgm given on the command line. */
115   unsigned int connect_flags;    /* Flags used for connecting. */
116   int enable_varsubst;  /* Set if variable substitution is enabled.  */
117   int trim_leading_spaces;
118 } opt;
119
120
121
122 /* Definitions for /definq commands and a global linked list with all
123    the definitions. */
124 struct definq_s
125 {
126   struct definq_s *next;
127   char *name;     /* Name of inquiry or NULL for any name. */
128   int is_var;     /* True if FILE is a variable name. */
129   int is_prog;    /* True if FILE is a program to run. */
130   char file[1];   /* Name of file or program. */
131 };
132 typedef struct definq_s *definq_t;
133
134 static definq_t definq_list;
135 static definq_t *definq_list_tail = &definq_list;
136
137
138 /* Variable definitions and glovbal table.  */
139 struct variable_s
140 {
141   struct variable_s *next;
142   char *value;  /* Malloced value - always a string.  */
143   char name[1]; /* Name of the variable.  */
144 };
145 typedef struct variable_s *variable_t;
146
147 static variable_t variable_table;
148
149
150 /* To implement loops we store entire lines in a linked list.  */
151 struct loopline_s
152 {
153   struct loopline_s *next;
154   char line[1];
155 };
156 typedef struct loopline_s *loopline_t;
157
158
159 /* This is used to store the pid of the server.  */
160 static pid_t server_pid = (pid_t)(-1);
161
162 /* The current datasink file or NULL.  */
163 static FILE *current_datasink;
164
165 /* A list of open file descriptors. */
166 static struct
167 {
168   int inuse;
169 #ifdef HAVE_W32_SYSTEM
170   HANDLE handle;
171 #endif
172 } open_fd_table[256];
173
174
175 /*-- local prototypes --*/
176 static char *substitute_line_copy (const char *buffer);
177 static int read_and_print_response (assuan_context_t ctx, int withhash,
178                                     int *r_goterr);
179 static assuan_context_t start_agent (void);
180
181
182
183 \f
184 /* Print usage information and and provide strings for help. */
185 static const char *
186 my_strusage( int level )
187 {
188   const char *p;
189
190   switch (level)
191     {
192     case 11: p = "@GPG@-connect-agent (@GNUPG@)";
193       break;
194     case 13: p = VERSION; break;
195     case 17: p = PRINTABLE_OS_NAME; break;
196     case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
197
198     case 1:
199     case 40: p = _("Usage: @GPG@-connect-agent [options] (-h for help)");
200       break;
201     case 41:
202       p = _("Syntax: @GPG@-connect-agent [options]\n"
203             "Connect to a running agent and send commands\n");
204       break;
205     case 31: p = "\nHome: "; break;
206     case 32: p = opt.homedir; break;
207     case 33: p = "\n"; break;
208
209     default: p = NULL; break;
210     }
211   return p;
212 }
213
214
215 static char *
216 gnu_getcwd (void)
217 {
218   char *buffer;
219   size_t size = 100;
220
221   for (;;)
222     {
223       buffer = xmalloc (size+1);
224 #ifdef HAVE_W32CE_SYSTEM
225       strcpy (buffer, "/");
226       return buffer;
227 #else
228       if (getcwd (buffer, size) == buffer)
229         return buffer;
230       xfree (buffer);
231       if (errno != ERANGE)
232         return NULL;
233       size *= 2;
234 #endif
235     }
236 }
237
238
239 /* Unescape STRING and returned the malloced result.  The surrounding
240    quotes must already be removed from STRING.  */
241 static char *
242 unescape_string (const char *string)
243 {
244   const unsigned char *s;
245   int esc;
246   size_t n;
247   char *buffer;
248   unsigned char *d;
249
250   n = 0;
251   for (s = (const unsigned char*)string, esc=0; *s; s++)
252     {
253       if (esc)
254         {
255           switch (*s)
256             {
257             case 'b':
258             case 't':
259             case 'v':
260             case 'n':
261             case 'f':
262             case 'r':
263             case '"':
264             case '\'':
265             case '\\': n++; break;
266             case 'x':
267               if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
268                 n++;
269               break;
270
271             default:
272               if (s[1] && s[2]
273                   && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
274                 n++;
275               break;
276             }
277           esc = 0;
278         }
279       else if (*s == '\\')
280         esc = 1;
281       else
282         n++;
283     }
284
285   buffer = xmalloc (n+1);
286   d = (unsigned char*)buffer;
287   for (s = (const unsigned char*)string, esc=0; *s; s++)
288     {
289       if (esc)
290         {
291           switch (*s)
292             {
293             case 'b':  *d++ = '\b'; break;
294             case 't':  *d++ = '\t'; break;
295             case 'v':  *d++ = '\v'; break;
296             case 'n':  *d++ = '\n'; break;
297             case 'f':  *d++ = '\f'; break;
298             case 'r':  *d++ = '\r'; break;
299             case '"':  *d++ = '\"'; break;
300             case '\'': *d++ = '\''; break;
301             case '\\': *d++ = '\\'; break;
302             case 'x':
303               if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
304                 {
305                   s++;
306                   *d++ = xtoi_2 (s);
307                   s++;
308                 }
309               break;
310
311             default:
312               if (s[1] && s[2]
313                   && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
314                 {
315                   *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
316                   s += 2;
317                 }
318               break;
319             }
320           esc = 0;
321         }
322       else if (*s == '\\')
323         esc = 1;
324       else
325         *d++ = *s;
326     }
327   *d = 0;
328   return buffer;
329 }
330
331
332 /* Do the percent unescaping and return a newly malloced string.
333    If WITH_PLUS is set '+' characters will be changed to space. */
334 static char *
335 unpercent_string (const char *string, int with_plus)
336 {
337   const unsigned char *s;
338   unsigned char *buffer, *p;
339   size_t n;
340
341   n = 0;
342   for (s=(const unsigned char *)string; *s; s++)
343     {
344       if (*s == '%' && s[1] && s[2])
345         {
346           s++;
347           n++;
348           s++;
349         }
350       else if (with_plus && *s == '+')
351         n++;
352       else
353         n++;
354     }
355
356   buffer = xmalloc (n+1);
357   p = buffer;
358   for (s=(const unsigned char *)string; *s; s++)
359     {
360       if (*s == '%' && s[1] && s[2])
361         {
362           s++;
363           *p++ = xtoi_2 (s);
364           s++;
365         }
366       else if (with_plus && *s == '+')
367         *p++ = ' ';
368       else
369         *p++ = *s;
370     }
371   *p = 0;
372   return (char*)buffer;
373 }
374
375
376
377
378 \f
379 static const char *
380 set_var (const char *name, const char *value)
381 {
382   variable_t var;
383
384   for (var = variable_table; var; var = var->next)
385     if (!strcmp (var->name, name))
386       break;
387   if (!var)
388     {
389       var = xmalloc (sizeof *var + strlen (name));
390       var->value = NULL;
391       strcpy (var->name, name);
392       var->next = variable_table;
393       variable_table = var;
394     }
395   xfree (var->value);
396   var->value = value? xstrdup (value) : NULL;
397   return var->value;
398 }
399
400
401 static void
402 set_int_var (const char *name, int value)
403 {
404   char numbuf[35];
405
406   snprintf (numbuf, sizeof numbuf, "%d", value);
407   set_var (name, numbuf);
408 }
409
410
411 /* Return the value of a variable.  That value is valid until a
412    variable of the name is changed.  Return NULL if not found.  Note
413    that envvars are copied to our variable list at the first access
414    and not at oprogram start.  */
415 static const char *
416 get_var (const char *name)
417 {
418   variable_t var;
419   const char *s;
420
421   if (!*name)
422     return "";
423   for (var = variable_table; var; var = var->next)
424     if (!strcmp (var->name, name))
425       break;
426   if (!var && (s = getenv (name)))
427     return set_var (name, s);
428   if (!var || !var->value)
429     return NULL;
430   return var->value;
431 }
432
433
434 /* Perform some simple arithmentic operations.  Caller must release
435    the return value.  On error the return value is NULL.  */
436 static char *
437 arithmetic_op (int operator, const char *operands)
438 {
439   long result, value;
440   char numbuf[35];
441
442   while ( spacep (operands) )
443     operands++;
444   if (!*operands)
445     return NULL;
446   result = strtol (operands, NULL, 0);
447   while (*operands && !spacep (operands) )
448     operands++;
449   if (operator == '!')
450     result = !result;
451
452   while (*operands)
453     {
454       while ( spacep (operands) )
455         operands++;
456       if (!*operands)
457         break;
458       value = strtol (operands, NULL, 0);
459       while (*operands && !spacep (operands) )
460         operands++;
461       switch (operator)
462         {
463         case '+': result += value; break;
464         case '-': result -= value; break;
465         case '*': result *= value; break;
466         case '/':
467           if (!value)
468             return NULL;
469           result /= value;
470           break;
471         case '%':
472           if (!value)
473             return NULL;
474           result %= value;
475           break;
476         case '!': result = !value; break;
477         case '|': result = result || value; break;
478         case '&': result = result && value; break;
479         default:
480           log_error ("unknown arithmetic operator '%c'\n", operator);
481           return NULL;
482         }
483     }
484   snprintf (numbuf, sizeof numbuf, "%ld", result);
485   return xstrdup (numbuf);
486 }
487
488
489
490 /* Extended version of get_var.  This returns a malloced string and
491    understand the function syntax: "func args".
492
493    Defined functions are
494
495      get - Return a value described by the next argument:
496            cwd        - The current working directory.
497            homedir    - The gnupg homedir.
498            sysconfdir - GnuPG's system configuration directory.
499            bindir     - GnuPG's binary directory.
500            libdir     - GnuPG's library directory.
501            libexecdir - GnuPG's library directory for executable files.
502            datadir    - GnuPG's data directory.
503            serverpid  - The PID of the current server.
504
505      unescape ARGS
506            Remove C-style escapes from string.  Note that "\0" and
507            "\x00" terminate the string implictly.  Use "\x7d" to
508            represent the closing brace.  The args start right after
509            the first space after the function name.
510
511      unpercent ARGS
512      unpercent+ ARGS
513            Remove percent style ecaping from string.  Note that "%00
514            terminates the string implicitly.  Use "%7d" to represetn
515            the closing brace.  The args start right after the first
516            space after the function name.  "unpercent+" also maps '+'
517            to space.
518
519      percent ARGS
520      percent+ ARGS
521            Escape the args using the percent style.  Tabs, formfeeds,
522            linefeeds and carriage returns are also escaped.
523            "percent+" also maps spaces to plus characters.
524
525      errcode ARG
526            Assuming ARG is an integer, return the gpg-error code.
527
528      errsource ARG
529            Assuming ARG is an integer, return the gpg-error source.
530
531      errstring ARG
532            Assuming ARG is an integer return a formatted fpf error string.
533
534
535    Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
536
537   */
538 static char *
539 get_var_ext (const char *name)
540 {
541   static int recursion_count;
542   const char *s;
543   char *result;
544   char *p;
545   char *free_me = NULL;
546   int intvalue;
547
548   if (recursion_count > 50)
549     {
550       log_error ("variables nested too deeply\n");
551       return NULL;
552     }
553
554   recursion_count++;
555   free_me = opt.enable_varsubst? substitute_line_copy (name) : NULL;
556   if (free_me)
557     name = free_me;
558   for (s=name; *s && !spacep (s); s++)
559     ;
560   if (!*s)
561     {
562       s = get_var (name);
563       result = s? xstrdup (s): NULL;
564     }
565   else if ( (s - name) == 3 && !strncmp (name, "get", 3))
566     {
567       while ( spacep (s) )
568         s++;
569       if (!strcmp (s, "cwd"))
570         {
571           result = gnu_getcwd ();
572           if (!result)
573             log_error ("getcwd failed: %s\n", strerror (errno));
574         }
575       else if (!strcmp (s, "homedir"))
576         result = make_filename (opt.homedir, NULL);
577       else if (!strcmp (s, "sysconfdir"))
578         result = xstrdup (gnupg_sysconfdir ());
579       else if (!strcmp (s, "bindir"))
580         result = xstrdup (gnupg_bindir ());
581       else if (!strcmp (s, "libdir"))
582         result = xstrdup (gnupg_libdir ());
583       else if (!strcmp (s, "libexecdir"))
584         result = xstrdup (gnupg_libexecdir ());
585       else if (!strcmp (s, "datadir"))
586         result = xstrdup (gnupg_datadir ());
587       else if (!strcmp (s, "serverpid"))
588         result = xasprintf ("%d", (int)server_pid);
589       else
590         {
591           log_error ("invalid argument '%s' for variable function 'get'\n", s);
592           log_info  ("valid are: cwd, "
593                      "{home,bin,lib,libexec,data}dir, serverpid\n");
594           result = NULL;
595         }
596     }
597   else if ( (s - name) == 8 && !strncmp (name, "unescape", 8))
598     {
599       s++;
600       result = unescape_string (s);
601     }
602   else if ( (s - name) == 9 && !strncmp (name, "unpercent", 9))
603     {
604       s++;
605       result = unpercent_string (s, 0);
606     }
607   else if ( (s - name) == 10 && !strncmp (name, "unpercent+", 10))
608     {
609       s++;
610       result = unpercent_string (s, 1);
611     }
612   else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
613     {
614       s++;
615       result = percent_escape (s, "\t\r\n\f\v");
616     }
617   else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
618     {
619       s++;
620       result = percent_escape (s, "\t\r\n\f\v");
621       for (p=result; *p; p++)
622         if (*p == ' ')
623           *p = '+';
624     }
625   else if ( (s - name) == 7 && !strncmp (name, "errcode", 7))
626     {
627       s++;
628       intvalue = (int)strtol (s, NULL, 0);
629       result = xasprintf ("%d", gpg_err_code (intvalue));
630     }
631   else if ( (s - name) == 9 && !strncmp (name, "errsource", 9))
632     {
633       s++;
634       intvalue = (int)strtol (s, NULL, 0);
635       result = xasprintf ("%d", gpg_err_source (intvalue));
636     }
637   else if ( (s - name) == 9 && !strncmp (name, "errstring", 9))
638     {
639       s++;
640       intvalue = (int)strtol (s, NULL, 0);
641       result = xasprintf ("%s <%s>",
642                           gpg_strerror (intvalue), gpg_strsource (intvalue));
643     }
644   else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name))
645     {
646       result = arithmetic_op (*name, s+1);
647     }
648   else
649     {
650       log_error ("unknown variable function '%.*s'\n", (int)(s-name), name);
651       result = NULL;
652     }
653
654   xfree (free_me);
655   recursion_count--;
656   return result;
657 }
658
659
660 /* Substitute variables in LINE and return a new allocated buffer if
661    required.  The function might modify LINE if the expanded version
662    fits into it.  */
663 static char *
664 substitute_line (char *buffer)
665 {
666   char *line = buffer;
667   char *p, *pend;
668   const char *value;
669   size_t valuelen, n;
670   char *result = NULL;
671   char *freeme = NULL;
672
673   while (*line)
674     {
675       p = strchr (line, '$');
676       if (!p)
677         return result; /* No more variables.  */
678
679       if (p[1] == '$') /* Escaped dollar sign. */
680         {
681           memmove (p, p+1, strlen (p+1)+1);
682           line = p + 1;
683           continue;
684         }
685       if (p[1] == '{')
686         {
687           int count = 0;
688
689           for (pend=p+2; *pend; pend++)
690             {
691               if (*pend == '{')
692                 count++;
693               else if (*pend == '}')
694                 {
695                   if (--count < 0)
696                     break;
697                 }
698             }
699           if (!*pend)
700             return result; /* Unclosed - don't substitute.  */
701         }
702       else
703         {
704           for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
705             ;
706         }
707       if (p[1] == '{' && *pend == '}')
708         {
709           int save = *pend;
710           *pend = 0;
711           freeme = get_var_ext (p+2);
712           value = freeme;
713           *pend++ = save;
714         }
715       else if (*pend)
716         {
717           int save = *pend;
718           *pend = 0;
719           value = get_var (p+1);
720           *pend = save;
721         }
722       else
723         value = get_var (p+1);
724       if (!value)
725         value = "";
726       valuelen = strlen (value);
727       if (valuelen <= pend - p)
728         {
729           memcpy (p, value, valuelen);
730           p += valuelen;
731           n = pend - p;
732           if (n)
733             memmove (p, p+n, strlen (p+n)+1);
734           line = p;
735         }
736       else
737         {
738           char *src = result? result : buffer;
739           char *dst;
740
741           dst = xmalloc (strlen (src) + valuelen + 1);
742           n = p - src;
743           memcpy (dst, src, n);
744           memcpy (dst + n, value, valuelen);
745           n += valuelen;
746           strcpy (dst + n, pend);
747           line = dst + n;
748           xfree (result);
749           result = dst;
750         }
751       xfree (freeme);
752       freeme = NULL;
753     }
754   return result;
755 }
756
757 /* Same as substitute_line but do not modify BUFFER.  */
758 static char *
759 substitute_line_copy (const char *buffer)
760 {
761   char *result, *p;
762
763   p = xstrdup (buffer?buffer:"");
764   result = substitute_line (p);
765   if (!result)
766     result = p;
767   else
768     xfree (p);
769   return result;
770 }
771
772
773 static void
774 assign_variable (char *line, int syslet)
775 {
776   char *name, *p, *tmp, *free_me, *buffer;
777
778   /* Get the  name. */
779   name = line;
780   for (p=name; *p && !spacep (p); p++)
781     ;
782   if (*p)
783     *p++ = 0;
784   while (spacep (p))
785     p++;
786
787   if (!*p)
788     set_var (name, NULL); /* Remove variable.  */
789   else if (syslet)
790     {
791       free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
792       if (free_me)
793         p = free_me;
794       buffer = xmalloc (4 + strlen (p) + 1);
795       strcpy (stpcpy (buffer, "get "), p);
796       tmp = get_var_ext (buffer);
797       xfree (buffer);
798       set_var (name, tmp);
799       xfree (tmp);
800       xfree (free_me);
801     }
802   else
803     {
804       tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
805       if (tmp)
806         {
807           set_var (name, tmp);
808           xfree (tmp);
809         }
810       else
811         set_var (name, p);
812     }
813 }
814
815
816 static void
817 show_variables (void)
818 {
819   variable_t var;
820
821   for (var = variable_table; var; var = var->next)
822     if (var->value)
823       printf ("%-20s %s\n", var->name, var->value);
824 }
825
826
827 /* Store an inquire response pattern.  Note, that this function may
828    change the content of LINE.  We assume that leading white spaces
829    are already removed. */
830 static void
831 add_definq (char *line, int is_var, int is_prog)
832 {
833   definq_t d;
834   char *name, *p;
835
836   /* Get name. */
837   name = line;
838   for (p=name; *p && !spacep (p); p++)
839     ;
840   if (*p)
841     *p++ = 0;
842   while (spacep (p))
843     p++;
844
845   d = xmalloc (sizeof *d + strlen (p) );
846   strcpy (d->file, p);
847   d->is_var  = is_var;
848   d->is_prog = is_prog;
849   if ( !strcmp (name, "*"))
850     d->name = NULL;
851   else
852     d->name = xstrdup (name);
853
854   d->next = NULL;
855   *definq_list_tail = d;
856   definq_list_tail = &d->next;
857 }
858
859
860 /* Show all inquiry defintions. */
861 static void
862 show_definq (void)
863 {
864   definq_t d;
865
866   for (d=definq_list; d; d = d->next)
867     if (d->name)
868       printf ("%-20s %c %s\n",
869               d->name, d->is_var? 'v' : d->is_prog? 'p':'f', d->file);
870   for (d=definq_list; d; d = d->next)
871     if (!d->name)
872       printf ("%-20s %c %s\n", "*",
873               d->is_var? 'v': d->is_prog? 'p':'f', d->file);
874 }
875
876
877 /* Clear all inquiry definitions. */
878 static void
879 clear_definq (void)
880 {
881   while (definq_list)
882     {
883       definq_t tmp = definq_list->next;
884       xfree (definq_list->name);
885       xfree (definq_list);
886       definq_list = tmp;
887     }
888   definq_list_tail = &definq_list;
889 }
890
891
892 static void
893 do_sendfd (assuan_context_t ctx, char *line)
894 {
895   FILE *fp;
896   char *name, *mode, *p;
897   int rc, fd;
898
899   /* Get file name. */
900   name = line;
901   for (p=name; *p && !spacep (p); p++)
902     ;
903   if (*p)
904     *p++ = 0;
905   while (spacep (p))
906     p++;
907
908   /* Get mode.  */
909   mode = p;
910   if (!*mode)
911     mode = "r";
912   else
913     {
914       for (p=mode; *p && !spacep (p); p++)
915         ;
916       if (*p)
917         *p++ = 0;
918     }
919
920   /* Open and send. */
921   fp = fopen (name, mode);
922   if (!fp)
923     {
924       log_error ("can't open '%s' in \"%s\" mode: %s\n",
925                  name, mode, strerror (errno));
926       return;
927     }
928   fd = fileno (fp);
929
930   if (opt.verbose)
931     log_error ("file '%s' opened in \"%s\" mode, fd=%d\n",
932                name, mode, fd);
933
934   rc = assuan_sendfd (ctx, INT2FD (fd) );
935   if (rc)
936     log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
937   fclose (fp);
938 }
939
940
941 static void
942 do_recvfd (assuan_context_t ctx, char *line)
943 {
944   (void)ctx;
945   (void)line;
946   log_info ("This command has not yet been implemented\n");
947 }
948
949
950 static void
951 do_open (char *line)
952 {
953   FILE *fp;
954   char *varname, *name, *mode, *p;
955   int fd;
956
957 #ifdef HAVE_W32_SYSTEM
958   if (server_pid == (pid_t)(-1))
959     {
960       log_error ("the pid of the server is unknown\n");
961       log_info ("use command \"/serverpid\" first\n");
962       return;
963     }
964 #endif
965
966   /* Get variable name. */
967   varname = line;
968   for (p=varname; *p && !spacep (p); p++)
969     ;
970   if (*p)
971     *p++ = 0;
972   while (spacep (p))
973     p++;
974
975   /* Get file name. */
976   name = p;
977   for (p=name; *p && !spacep (p); p++)
978     ;
979   if (*p)
980     *p++ = 0;
981   while (spacep (p))
982     p++;
983
984   /* Get mode.  */
985   mode = p;
986   if (!*mode)
987     mode = "r";
988   else
989     {
990       for (p=mode; *p && !spacep (p); p++)
991         ;
992       if (*p)
993         *p++ = 0;
994     }
995
996   /* Open and send. */
997   fp = fopen (name, mode);
998   if (!fp)
999     {
1000       log_error ("can't open '%s' in \"%s\" mode: %s\n",
1001                  name, mode, strerror (errno));
1002       return;
1003     }
1004   fd = fileno (fp);
1005   if (fd >= 0 && fd < DIM (open_fd_table))
1006     {
1007       open_fd_table[fd].inuse = 1;
1008 #ifdef HAVE_W32CE_SYSTEM
1009 # warning fixme: implement our pipe emulation.
1010 #endif
1011 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
1012       {
1013         HANDLE prochandle, handle, newhandle;
1014
1015         handle = (void*)_get_osfhandle (fd);
1016
1017         prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
1018         if (!prochandle)
1019           {
1020             log_error ("failed to open the server process\n");
1021             close (fd);
1022             return;
1023           }
1024
1025         if (!DuplicateHandle (GetCurrentProcess(), handle,
1026                               prochandle, &newhandle, 0,
1027                               TRUE, DUPLICATE_SAME_ACCESS ))
1028           {
1029             log_error ("failed to duplicate the handle\n");
1030             close (fd);
1031             CloseHandle (prochandle);
1032             return;
1033           }
1034         CloseHandle (prochandle);
1035         open_fd_table[fd].handle = newhandle;
1036       }
1037       if (opt.verbose)
1038         log_info ("file '%s' opened in \"%s\" mode, fd=%d  (libc=%d)\n",
1039                    name, mode, (int)open_fd_table[fd].handle, fd);
1040       set_int_var (varname, (int)open_fd_table[fd].handle);
1041 #else
1042       if (opt.verbose)
1043         log_info ("file '%s' opened in \"%s\" mode, fd=%d\n",
1044                    name, mode, fd);
1045       set_int_var (varname, fd);
1046 #endif
1047     }
1048   else
1049     {
1050       log_error ("can't put fd %d into table\n", fd);
1051       close (fd);
1052     }
1053 }
1054
1055
1056 static void
1057 do_close (char *line)
1058 {
1059   int fd = atoi (line);
1060
1061 #ifdef HAVE_W32_SYSTEM
1062   int i;
1063
1064   for (i=0; i < DIM (open_fd_table); i++)
1065     if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1066       break;
1067   if (i < DIM (open_fd_table))
1068     fd = i;
1069   else
1070     {
1071       log_error ("given fd (system handle) has not been opened\n");
1072       return;
1073     }
1074 #endif
1075
1076   if (fd < 0 || fd >= DIM (open_fd_table))
1077     {
1078       log_error ("invalid fd\n");
1079       return;
1080     }
1081
1082   if (!open_fd_table[fd].inuse)
1083     {
1084       log_error ("given fd has not been opened\n");
1085       return;
1086     }
1087 #ifdef HAVE_W32_SYSTEM
1088   CloseHandle (open_fd_table[fd].handle); /* Close duped handle.  */
1089 #endif
1090   close (fd);
1091   open_fd_table[fd].inuse = 0;
1092 }
1093
1094
1095 static void
1096 do_showopen (void)
1097 {
1098   int i;
1099
1100   for (i=0; i < DIM (open_fd_table); i++)
1101     if (open_fd_table[i].inuse)
1102       {
1103 #ifdef HAVE_W32_SYSTEM
1104         printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
1105 #else
1106         printf ("%-15d\n", i);
1107 #endif
1108       }
1109 }
1110
1111
1112
1113 static gpg_error_t
1114 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1115 {
1116   membuf_t *mb = opaque;
1117   put_membuf (mb, buffer, length);
1118   return 0;
1119 }
1120
1121 /* Get the pid of the server and store it locally.  */
1122 static void
1123 do_serverpid (assuan_context_t ctx)
1124 {
1125   int rc;
1126   membuf_t mb;
1127   char *buffer;
1128
1129   init_membuf (&mb, 100);
1130   rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
1131                         NULL, NULL, NULL, NULL);
1132   put_membuf (&mb, "", 1);
1133   buffer = get_membuf (&mb, NULL);
1134   if (rc || !buffer)
1135     log_error ("command \"%s\" failed: %s\n",
1136                "GETINFO pid", gpg_strerror (rc));
1137   else
1138     {
1139       server_pid = (pid_t)strtoul (buffer, NULL, 10);
1140       if (opt.verbose)
1141         log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1142     }
1143   xfree (buffer);
1144 }
1145
1146
1147 /* Return true if the command is either "HELP" or "SCD HELP".  */
1148 static int
1149 help_cmd_p (const char *line)
1150 {
1151   if (!ascii_strncasecmp (line, "SCD", 3)
1152       && (spacep (line+3) || !line[3]))
1153     {
1154       for (line += 3; spacep (line); line++)
1155         ;
1156     }
1157
1158   return (!ascii_strncasecmp (line, "HELP", 4)
1159           && (spacep (line+4) || !line[4]));
1160 }
1161
1162
1163 /* gpg-connect-agent's entry point. */
1164 int
1165 main (int argc, char **argv)
1166 {
1167   ARGPARSE_ARGS pargs;
1168   int no_more_options = 0;
1169   assuan_context_t ctx;
1170   char *line, *p;
1171   char *tmpline;
1172   size_t linesize;
1173   int rc;
1174   int cmderr;
1175   const char *opt_run = NULL;
1176   FILE *script_fp = NULL;
1177   int use_tty, keep_line;
1178   struct {
1179     int collecting;
1180     loopline_t head;
1181     loopline_t *tail;
1182     loopline_t current;
1183     unsigned int nestlevel;
1184     int oneshot;
1185     char *condition;
1186   } loopstack[20];
1187   int        loopidx;
1188   char **cmdline_commands = NULL;
1189
1190   gnupg_rl_initialize ();
1191   set_strusage (my_strusage);
1192   log_set_prefix ("gpg-connect-agent", 1);
1193
1194   /* Make sure that our subsystems are ready.  */
1195   i18n_init();
1196   init_common_subsystems (&argc, &argv);
1197
1198   assuan_set_gpg_err_source (0);
1199
1200
1201   opt.homedir = default_homedir ();
1202   opt.connect_flags = 1;
1203
1204   /* Parse the command line. */
1205   pargs.argc  = &argc;
1206   pargs.argv  = &argv;
1207   pargs.flags =  1;  /* Do not remove the args.  */
1208   while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
1209     {
1210       switch (pargs.r_opt)
1211         {
1212         case oQuiet:     opt.quiet = 1; break;
1213         case oVerbose:   opt.verbose++; break;
1214         case oNoVerbose: opt.verbose = 0; break;
1215         case oHomedir:   opt.homedir = pargs.r.ret_str; break;
1216         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
1217         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
1218         case oHex:       opt.hex = 1; break;
1219         case oDecode:    opt.decode = 1; break;
1220         case oDirmngr:   opt.use_dirmngr = 1; break;
1221         case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
1222         case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break;
1223         case oExec:      opt.exec = 1; break;
1224         case oNoExtConnect: opt.connect_flags &= ~(1); break;
1225         case oRun:       opt_run = pargs.r.ret_str; break;
1226         case oSubst:
1227           opt.enable_varsubst = 1;
1228           opt.trim_leading_spaces = 1;
1229           break;
1230
1231         default: pargs.err = 2; break;
1232         }
1233     }
1234
1235   if (log_get_errorcount (0))
1236     exit (2);
1237
1238
1239   /* Print a warning if an argument looks like an option.  */
1240   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
1241     {
1242       int i;
1243
1244       for (i=0; i < argc; i++)
1245         if (argv[i][0] == '-' && argv[i][1] == '-')
1246           log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
1247     }
1248
1249
1250   use_tty = (gnupg_isatty (fileno (stdin)) && gnupg_isatty (fileno (stdout)));
1251
1252   if (opt.exec)
1253     {
1254       if (!argc)
1255         {
1256           log_error (_("option \"%s\" requires a program "
1257                        "and optional arguments\n"), "--exec" );
1258           exit (1);
1259         }
1260     }
1261   else if (argc)
1262     cmdline_commands = argv;
1263
1264   if (opt.exec && opt.raw_socket)
1265     {
1266       opt.raw_socket = NULL;
1267       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1268                 "--raw-socket", "--exec");
1269     }
1270   if (opt.exec && opt.tcp_socket)
1271     {
1272       opt.tcp_socket = NULL;
1273       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1274                 "--tcp-socket", "--exec");
1275     }
1276   if (opt.tcp_socket && opt.raw_socket)
1277     {
1278       opt.tcp_socket = NULL;
1279       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1280                 "--tcp-socket", "--raw-socket");
1281     }
1282
1283   if (opt_run && !(script_fp = fopen (opt_run, "r")))
1284     {
1285       log_error ("cannot open run file '%s': %s\n",
1286                  opt_run, strerror (errno));
1287       exit (1);
1288     }
1289
1290
1291   if (opt.exec)
1292     {
1293       assuan_fd_t no_close[3];
1294
1295       no_close[0] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
1296       no_close[1] = assuan_fd_from_posix_fd (log_get_fd ());
1297       no_close[2] = ASSUAN_INVALID_FD;
1298
1299       rc = assuan_new (&ctx);
1300       if (rc)
1301         {
1302           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1303           exit (1);
1304         }
1305
1306       rc = assuan_pipe_connect
1307         (ctx, *argv, (const char **)argv, no_close, NULL, NULL,
1308          (opt.connect_flags & 1) ? ASSUAN_PIPE_CONNECT_FDPASSING : 0);
1309       if (rc)
1310         {
1311           log_error ("assuan_pipe_connect_ext failed: %s\n",
1312                      gpg_strerror (rc));
1313           exit (1);
1314         }
1315
1316       if (opt.verbose)
1317         log_info ("server '%s' started\n", *argv);
1318
1319     }
1320   else if (opt.raw_socket)
1321     {
1322       rc = assuan_new (&ctx);
1323       if (rc)
1324         {
1325           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1326           exit (1);
1327         }
1328
1329       rc = assuan_socket_connect
1330         (ctx, opt.raw_socket, 0,
1331          (opt.connect_flags & 1) ? ASSUAN_SOCKET_CONNECT_FDPASSING : 0);
1332       if (rc)
1333         {
1334           log_error ("can't connect to socket '%s': %s\n",
1335                      opt.raw_socket, gpg_strerror (rc));
1336           exit (1);
1337         }
1338
1339       if (opt.verbose)
1340         log_info ("connection to socket '%s' established\n", opt.raw_socket);
1341     }
1342   else if (opt.tcp_socket)
1343     {
1344       char *url;
1345
1346       url = xstrconcat ("assuan://", opt.tcp_socket, NULL);
1347
1348       rc = assuan_new (&ctx);
1349       if (rc)
1350         {
1351           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1352           exit (1);
1353         }
1354
1355       rc = assuan_socket_connect (ctx, opt.tcp_socket, 0, 0);
1356       if (rc)
1357         {
1358           log_error ("can't connect to server '%s': %s\n",
1359                      opt.tcp_socket, gpg_strerror (rc));
1360           exit (1);
1361         }
1362
1363       if (opt.verbose)
1364         log_info ("connection to socket '%s' established\n", url);
1365
1366       xfree (url);
1367     }
1368   else
1369     ctx = start_agent ();
1370
1371   /* See whether there is a line pending from the server (in case
1372      assuan did not run the initial handshaking).  */
1373   if (assuan_pending_line (ctx))
1374     {
1375       rc = read_and_print_response (ctx, 0, &cmderr);
1376       if (rc)
1377         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1378     }
1379
1380
1381   for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1382     loopstack[loopidx].collecting = 0;
1383   loopidx = -1;
1384   line = NULL;
1385   linesize = 0;
1386   keep_line = 1;
1387   for (;;)
1388     {
1389       int n;
1390       size_t maxlength = 2048;
1391
1392       assert (loopidx < (int)DIM (loopstack));
1393       if (loopidx >= 0 && loopstack[loopidx].current)
1394         {
1395           keep_line = 0;
1396           xfree (line);
1397           line = xstrdup (loopstack[loopidx].current->line);
1398           n = strlen (line);
1399           /* Never go beyond of the final /end.  */
1400           if (loopstack[loopidx].current->next)
1401             loopstack[loopidx].current = loopstack[loopidx].current->next;
1402           else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1403             ;
1404           else
1405             log_fatal ("/end command vanished\n");
1406         }
1407       else if (cmdline_commands && *cmdline_commands && !script_fp)
1408         {
1409           keep_line = 0;
1410           xfree (line);
1411           line = xstrdup (*cmdline_commands);
1412           cmdline_commands++;
1413           n = strlen (line);
1414           if (n >= maxlength)
1415             maxlength = 0;
1416         }
1417       else if (use_tty && !script_fp)
1418         {
1419           keep_line = 0;
1420           xfree (line);
1421           line = tty_get ("> ");
1422           n = strlen (line);
1423           if (n==1 && *line == CONTROL_D)
1424             n = 0;
1425           if (n >= maxlength)
1426             maxlength = 0;
1427         }
1428       else
1429         {
1430           if (!keep_line)
1431             {
1432               xfree (line);
1433               line = NULL;
1434               linesize = 0;
1435               keep_line = 1;
1436             }
1437           n = read_line (script_fp? script_fp:stdin,
1438                          &line, &linesize, &maxlength);
1439         }
1440       if (n < 0)
1441         {
1442           log_error (_("error reading input: %s\n"), strerror (errno));
1443           if (script_fp)
1444             {
1445               fclose (script_fp);
1446               script_fp = NULL;
1447               log_error ("stopping script execution\n");
1448               continue;
1449             }
1450           exit (1);
1451         }
1452       if (!n)
1453         {
1454           /* EOF */
1455           if (script_fp)
1456             {
1457               fclose (script_fp);
1458               script_fp = NULL;
1459               if (opt.verbose)
1460                 log_info ("end of script\n");
1461               continue;
1462             }
1463           break;
1464         }
1465       if (!maxlength)
1466         {
1467           log_error (_("line too long - skipped\n"));
1468           continue;
1469         }
1470       if (memchr (line, 0, n))
1471         log_info (_("line shortened due to embedded Nul character\n"));
1472       if (line[n-1] == '\n')
1473         line[n-1] = 0;
1474
1475       if (opt.trim_leading_spaces)
1476         {
1477           const char *s = line;
1478
1479           while (spacep (s))
1480             s++;
1481           if (s != line)
1482             {
1483               for (p=line; *s;)
1484                 *p++ = *s++;
1485               *p = 0;
1486               n = p - line;
1487             }
1488         }
1489
1490       if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1491         {
1492           loopline_t ll;
1493
1494           ll = xmalloc (sizeof *ll + strlen (line));
1495           ll->next = NULL;
1496           strcpy (ll->line, line);
1497           *loopstack[loopidx+1].tail = ll;
1498           loopstack[loopidx+1].tail = &ll->next;
1499
1500           if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1501             loopstack[loopidx+1].nestlevel--;
1502           else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1503             loopstack[loopidx+1].nestlevel++;
1504
1505           if (loopstack[loopidx+1].nestlevel)
1506             continue;
1507           /* We reached the corresponding /end.  */
1508           loopstack[loopidx+1].collecting = 0;
1509           loopidx++;
1510         }
1511
1512       if (*line == '/')
1513         {
1514           /* Handle control commands. */
1515           char *cmd = line+1;
1516
1517           for (p=cmd; *p && !spacep (p); p++)
1518             ;
1519           if (*p)
1520             *p++ = 0;
1521           while (spacep (p))
1522             p++;
1523           if (!strcmp (cmd, "let"))
1524             {
1525               assign_variable (p, 0);
1526             }
1527           else if (!strcmp (cmd, "slet"))
1528             {
1529               /* Deprecated - never used in a released version.  */
1530               assign_variable (p, 1);
1531             }
1532           else if (!strcmp (cmd, "showvar"))
1533             {
1534               show_variables ();
1535             }
1536           else if (!strcmp (cmd, "definq"))
1537             {
1538               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1539               if (tmpline)
1540                 {
1541                   add_definq (tmpline, 1, 0);
1542                   xfree (tmpline);
1543                 }
1544               else
1545                 add_definq (p, 1, 0);
1546             }
1547           else if (!strcmp (cmd, "definqfile"))
1548             {
1549               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1550               if (tmpline)
1551                 {
1552                   add_definq (tmpline, 0, 0);
1553                   xfree (tmpline);
1554                 }
1555               else
1556                 add_definq (p, 0, 0);
1557             }
1558           else if (!strcmp (cmd, "definqprog"))
1559             {
1560               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1561               if (tmpline)
1562                 {
1563                   add_definq (tmpline, 0, 1);
1564                   xfree (tmpline);
1565                 }
1566               else
1567                 add_definq (p, 0, 1);
1568             }
1569           else if (!strcmp (cmd, "datafile"))
1570             {
1571               const char *fname;
1572
1573               if (current_datasink)
1574                 {
1575                   if (current_datasink != stdout)
1576                     fclose (current_datasink);
1577                   current_datasink = NULL;
1578                 }
1579               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1580               fname = tmpline? tmpline : p;
1581               if (fname && !strcmp (fname, "-"))
1582                 current_datasink = stdout;
1583               else if (fname && *fname)
1584                 {
1585                   current_datasink = fopen (fname, "wb");
1586                   if (!current_datasink)
1587                     log_error ("can't open '%s': %s\n",
1588                                fname, strerror (errno));
1589                 }
1590               xfree (tmpline);
1591             }
1592           else if (!strcmp (cmd, "showdef"))
1593             {
1594               show_definq ();
1595             }
1596           else if (!strcmp (cmd, "cleardef"))
1597             {
1598               clear_definq ();
1599             }
1600           else if (!strcmp (cmd, "echo"))
1601             {
1602               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1603               if (tmpline)
1604                 {
1605                   puts (tmpline);
1606                   xfree (tmpline);
1607                 }
1608               else
1609                 puts (p);
1610             }
1611           else if (!strcmp (cmd, "sendfd"))
1612             {
1613               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1614               if (tmpline)
1615                 {
1616                   do_sendfd (ctx, tmpline);
1617                   xfree (tmpline);
1618                 }
1619               else
1620                 do_sendfd (ctx, p);
1621               continue;
1622             }
1623           else if (!strcmp (cmd, "recvfd"))
1624             {
1625               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1626               if (tmpline)
1627                 {
1628                   do_recvfd (ctx, tmpline);
1629                   xfree (tmpline);
1630                 }
1631               else
1632                 do_recvfd (ctx, p);
1633               continue;
1634             }
1635           else if (!strcmp (cmd, "open"))
1636             {
1637               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1638               if (tmpline)
1639                 {
1640                   do_open (tmpline);
1641                   xfree (tmpline);
1642                 }
1643               else
1644                 do_open (p);
1645             }
1646           else if (!strcmp (cmd, "close"))
1647             {
1648               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1649               if (tmpline)
1650                 {
1651                   do_close (tmpline);
1652                   xfree (tmpline);
1653                 }
1654               else
1655                 do_close (p);
1656             }
1657           else if (!strcmp (cmd, "showopen"))
1658             {
1659               do_showopen ();
1660             }
1661           else if (!strcmp (cmd, "serverpid"))
1662             {
1663               do_serverpid (ctx);
1664             }
1665           else if (!strcmp (cmd, "hex"))
1666             opt.hex = 1;
1667           else if (!strcmp (cmd, "nohex"))
1668             opt.hex = 0;
1669           else if (!strcmp (cmd, "decode"))
1670             opt.decode = 1;
1671           else if (!strcmp (cmd, "nodecode"))
1672             opt.decode = 0;
1673           else if (!strcmp (cmd, "subst"))
1674             {
1675               opt.enable_varsubst = 1;
1676               opt.trim_leading_spaces = 1;
1677             }
1678           else if (!strcmp (cmd, "nosubst"))
1679             opt.enable_varsubst = 0;
1680           else if (!strcmp (cmd, "run"))
1681             {
1682               char *p2;
1683
1684               for (p2=p; *p2 && !spacep (p2); p2++)
1685                 ;
1686               if (*p2)
1687                 *p2++ = 0;
1688               while (spacep (p2))
1689                 p++;
1690               if (*p2)
1691                 {
1692                   log_error ("syntax error in run command\n");
1693                   if (script_fp)
1694                     {
1695                       fclose (script_fp);
1696                       script_fp = NULL;
1697                     }
1698                 }
1699               else if (script_fp)
1700                 {
1701                   log_error ("cannot nest run commands - stop\n");
1702                   fclose (script_fp);
1703                   script_fp = NULL;
1704                 }
1705               else if (!(script_fp = fopen (p, "r")))
1706                 {
1707                   log_error ("cannot open run file '%s': %s\n",
1708                              p, strerror (errno));
1709                 }
1710               else if (opt.verbose)
1711                 log_info ("running commands from '%s'\n", p);
1712             }
1713           else if (!strcmp (cmd, "while"))
1714             {
1715               if (loopidx+2 >= (int)DIM(loopstack))
1716                 {
1717                   log_error ("blocks are nested too deep\n");
1718                   /* We should better die or break all loop in this
1719                      case as recovering from this error won't be
1720                      easy.  */
1721                 }
1722               else
1723                 {
1724                   loopstack[loopidx+1].head = NULL;
1725                   loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1726                   loopstack[loopidx+1].current = NULL;
1727                   loopstack[loopidx+1].nestlevel = 1;
1728                   loopstack[loopidx+1].oneshot = 0;
1729                   loopstack[loopidx+1].condition = xstrdup (p);
1730                   loopstack[loopidx+1].collecting = 1;
1731                 }
1732             }
1733           else if (!strcmp (cmd, "if"))
1734             {
1735               if (loopidx+2 >= (int)DIM(loopstack))
1736                 {
1737                   log_error ("blocks are nested too deep\n");
1738                 }
1739               else
1740                 {
1741                   /* Note that we need to evaluate the condition right
1742                      away and not just at the end of the block as we
1743                      do with a WHILE. */
1744                   loopstack[loopidx+1].head = NULL;
1745                   loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1746                   loopstack[loopidx+1].current = NULL;
1747                   loopstack[loopidx+1].nestlevel = 1;
1748                   loopstack[loopidx+1].oneshot = 1;
1749                   loopstack[loopidx+1].condition = substitute_line_copy (p);
1750                   loopstack[loopidx+1].collecting = 1;
1751                 }
1752             }
1753           else if (!strcmp (cmd, "end"))
1754             {
1755               if (loopidx < 0)
1756                 log_error ("stray /end command encountered - ignored\n");
1757               else
1758                 {
1759                   char *tmpcond;
1760                   const char *value;
1761                   long condition;
1762
1763                   /* Evaluate the condition.  */
1764                   tmpcond = xstrdup (loopstack[loopidx].condition);
1765                   if (loopstack[loopidx].oneshot)
1766                     {
1767                       xfree (loopstack[loopidx].condition);
1768                       loopstack[loopidx].condition = xstrdup ("0");
1769                     }
1770                   tmpline = substitute_line (tmpcond);
1771                   value = tmpline? tmpline : tmpcond;
1772                   /* "true" or "yes" are commonly used to mean TRUE;
1773                      all other strings will evaluate to FALSE due to
1774                      the strtoul.  */
1775                   if (!ascii_strcasecmp (value, "true")
1776                       || !ascii_strcasecmp (value, "yes"))
1777                     condition = 1;
1778                   else
1779                     condition = strtol (value, NULL, 0);
1780                   xfree (tmpline);
1781                   xfree (tmpcond);
1782
1783                   if (condition)
1784                     {
1785                       /* Run loop.  */
1786                       loopstack[loopidx].current = loopstack[loopidx].head;
1787                     }
1788                   else
1789                     {
1790                       /* Cleanup.  */
1791                       while (loopstack[loopidx].head)
1792                         {
1793                           loopline_t tmp = loopstack[loopidx].head->next;
1794                           xfree (loopstack[loopidx].head);
1795                           loopstack[loopidx].head = tmp;
1796                         }
1797                       loopstack[loopidx].tail = NULL;
1798                       loopstack[loopidx].current = NULL;
1799                       loopstack[loopidx].nestlevel = 0;
1800                       loopstack[loopidx].collecting = 0;
1801                       loopstack[loopidx].oneshot = 0;
1802                       xfree (loopstack[loopidx].condition);
1803                       loopstack[loopidx].condition = NULL;
1804                       loopidx--;
1805                     }
1806                 }
1807             }
1808           else if (!strcmp (cmd, "bye"))
1809             {
1810               break;
1811             }
1812           else if (!strcmp (cmd, "sleep"))
1813             {
1814               gnupg_sleep (1);
1815             }
1816           else if (!strcmp (cmd, "help"))
1817             {
1818               puts (
1819 "Available commands:\n"
1820 "/echo ARGS             Echo ARGS.\n"
1821 "/let  NAME VALUE       Set variable NAME to VALUE.\n"
1822 "/showvar               Show all variables.\n"
1823 "/definq NAME VAR       Use content of VAR for inquiries with NAME.\n"
1824 "/definqfile NAME FILE  Use content of FILE for inquiries with NAME.\n"
1825 "/definqprog NAME PGM   Run PGM for inquiries with NAME.\n"
1826 "/datafile [NAME]       Write all D line content to file NAME.\n"
1827 "/showdef               Print all definitions.\n"
1828 "/cleardef              Delete all definitions.\n"
1829 "/sendfd FILE MODE      Open FILE and pass descriptor to server.\n"
1830 "/recvfd                Receive FD from server and print.\n"
1831 "/open VAR FILE MODE    Open FILE and assign the file descriptor to VAR.\n"
1832 "/close FD              Close file with descriptor FD.\n"
1833 "/showopen              Show descriptors of all open files.\n"
1834 "/serverpid             Retrieve the pid of the server.\n"
1835 "/[no]hex               Enable hex dumping of received data lines.\n"
1836 "/[no]decode            Enable decoding of received data lines.\n"
1837 "/[no]subst             Enable variable substitution.\n"
1838 "/run FILE              Run commands from FILE.\n"
1839 "/if VAR                Begin conditional block controlled by VAR.\n"
1840 "/while VAR             Begin loop controlled by VAR.\n"
1841 "/end                   End loop or condition\n"
1842 "/bye                   Terminate gpg-connect-agent.\n"
1843 "/help                  Print this help.");
1844             }
1845           else
1846             log_error (_("unknown command '%s'\n"), cmd );
1847
1848           continue;
1849         }
1850
1851       if (opt.verbose && script_fp)
1852         puts (line);
1853
1854       tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1855       if (tmpline)
1856         {
1857           rc = assuan_write_line (ctx, tmpline);
1858           xfree (tmpline);
1859         }
1860       else
1861         rc = assuan_write_line (ctx, line);
1862       if (rc)
1863         {
1864           log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1865           break;
1866         }
1867       if (*line == '#' || !*line)
1868         continue; /* Don't expect a response for a comment line. */
1869
1870       rc = read_and_print_response (ctx, help_cmd_p (line), &cmderr);
1871       if (rc)
1872         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1873       if ((rc || cmderr) && script_fp)
1874         {
1875           log_error ("stopping script execution\n");
1876           fclose (script_fp);
1877           script_fp = NULL;
1878         }
1879
1880
1881       /* FIXME: If the last command was BYE or the server died for
1882          some other reason, we won't notice until we get the next
1883          input command.  Probing the connection with a non-blocking
1884          read could help to notice termination or other problems
1885          early.  */
1886     }
1887
1888   if (opt.verbose)
1889     log_info ("closing connection to agent\n");
1890
1891   return 0;
1892 }
1893
1894
1895 /* Handle an Inquire from the server.  Return False if it could not be
1896    handled; in this case the caller shll complete the operation.  LINE
1897    is the complete line as received from the server.  This function
1898    may change the content of LINE. */
1899 static int
1900 handle_inquire (assuan_context_t ctx, char *line)
1901 {
1902   const char *name;
1903   definq_t d;
1904   FILE *fp = NULL;
1905   char buffer[1024];
1906   int rc, n;
1907
1908   /* Skip the command and trailing spaces. */
1909   for (; *line && !spacep (line); line++)
1910     ;
1911   while (spacep (line))
1912     line++;
1913   /* Get the name. */
1914   name = line;
1915   for (; *line && !spacep (line); line++)
1916     ;
1917   if (*line)
1918     *line++ = 0;
1919
1920   /* Now match it against our list.  The second loop is there to
1921      detect the match-all entry. */
1922   for (d=definq_list; d; d = d->next)
1923     if (d->name && !strcmp (d->name, name))
1924         break;
1925   if (!d)
1926     for (d=definq_list; d; d = d->next)
1927       if (!d->name)
1928         break;
1929   if (!d)
1930     {
1931       if (opt.verbose)
1932         log_info ("no handler for inquiry '%s' found\n", name);
1933       return 0;
1934     }
1935
1936   if (d->is_var)
1937     {
1938       char *tmpvalue = get_var_ext (d->file);
1939       rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
1940       xfree (tmpvalue);
1941       if (rc)
1942         log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1943     }
1944   else
1945     {
1946       if (d->is_prog)
1947         {
1948 #ifdef HAVE_W32CE_SYSTEM
1949           fp = NULL;
1950 #else
1951           fp = popen (d->file, "r");
1952 #endif
1953           if (!fp)
1954             log_error ("error executing '%s': %s\n",
1955                        d->file, strerror (errno));
1956           else if (opt.verbose)
1957             log_error ("handling inquiry '%s' by running '%s'\n",
1958                        name, d->file);
1959         }
1960       else
1961         {
1962           fp = fopen (d->file, "rb");
1963           if (!fp)
1964             log_error ("error opening '%s': %s\n", d->file, strerror (errno));
1965           else if (opt.verbose)
1966             log_error ("handling inquiry '%s' by returning content of '%s'\n",
1967                        name, d->file);
1968         }
1969       if (!fp)
1970         return 0;
1971
1972       while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
1973         {
1974           rc = assuan_send_data (ctx, buffer, n);
1975           if (rc)
1976             {
1977               log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1978               break;
1979             }
1980         }
1981       if (ferror (fp))
1982         log_error ("error reading from '%s': %s\n", d->file, strerror (errno));
1983     }
1984
1985   rc = assuan_send_data (ctx, NULL, 0);
1986   if (rc)
1987     log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1988
1989   if (d->is_var)
1990     ;
1991   else if (d->is_prog)
1992     {
1993 #ifndef HAVE_W32CE_SYSTEM
1994       if (pclose (fp))
1995         log_error ("error running '%s': %s\n", d->file, strerror (errno));
1996 #endif
1997     }
1998   else
1999     fclose (fp);
2000   return 1;
2001 }
2002
2003
2004 /* Read all response lines from server and print them.  Returns 0 on
2005    success or an assuan error code.  If WITHHASH istrue, comment lines
2006    are printed.  Sets R_GOTERR to true if the command did not returned
2007    OK.  */
2008 static int
2009 read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
2010 {
2011   char *line;
2012   size_t linelen;
2013   gpg_error_t rc;
2014   int i, j;
2015   int need_lf = 0;
2016
2017   *r_goterr = 0;
2018   for (;;)
2019     {
2020       do
2021         {
2022           rc = assuan_read_line (ctx, &line, &linelen);
2023           if (rc)
2024             return rc;
2025
2026           if ((withhash || opt.verbose > 1) && *line == '#')
2027             {
2028               fwrite (line, linelen, 1, stdout);
2029               putchar ('\n');
2030             }
2031         }
2032       while (*line == '#' || !linelen);
2033
2034       if (linelen >= 1
2035           && line[0] == 'D' && line[1] == ' ')
2036         {
2037           if (current_datasink)
2038             {
2039               const unsigned char *s;
2040               int c = 0;
2041
2042               for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2043                 {
2044                   if (*s == '%' && j+2 < linelen)
2045                     {
2046                       s++; j++;
2047                       c = xtoi_2 ( s );
2048                       s++; j++;
2049                     }
2050                   else
2051                     c = *s;
2052                   putc (c, current_datasink);
2053                 }
2054             }
2055           else if (opt.hex)
2056             {
2057               for (i=2; i < linelen; )
2058                 {
2059                   int save_i = i;
2060
2061                   printf ("D[%04X] ", i-2);
2062                   for (j=0; j < 16 ; j++, i++)
2063                     {
2064                       if (j == 8)
2065                         putchar (' ');
2066                       if (i < linelen)
2067                         printf (" %02X", ((unsigned char*)line)[i]);
2068                       else
2069                         fputs ("   ", stdout);
2070                     }
2071                   fputs ("   ", stdout);
2072                   i= save_i;
2073                   for (j=0; j < 16; j++, i++)
2074                     {
2075                       unsigned int c = ((unsigned char*)line)[i];
2076                       if ( i >= linelen )
2077                         putchar (' ');
2078                       else if (isascii (c) && isprint (c) && !iscntrl (c))
2079                         putchar (c);
2080                       else
2081                         putchar ('.');
2082                     }
2083                   putchar ('\n');
2084                 }
2085             }
2086           else if (opt.decode)
2087             {
2088               const unsigned char *s;
2089               int need_d = 1;
2090               int c = 0;
2091
2092               for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2093                 {
2094                   if (need_d)
2095                     {
2096                       fputs ("D ", stdout);
2097                       need_d = 0;
2098                     }
2099                   if (*s == '%' && j+2 < linelen)
2100                     {
2101                       s++; j++;
2102                       c = xtoi_2 ( s );
2103                       s++; j++;
2104                     }
2105                   else
2106                     c = *s;
2107                   if (c == '\n')
2108                     need_d = 1;
2109                   putchar (c);
2110                 }
2111               need_lf = (c != '\n');
2112             }
2113           else
2114             {
2115               fwrite (line, linelen, 1, stdout);
2116               putchar ('\n');
2117             }
2118         }
2119       else
2120         {
2121           if (need_lf)
2122             {
2123               if (!current_datasink || current_datasink != stdout)
2124                 putchar ('\n');
2125               need_lf = 0;
2126             }
2127
2128           if (linelen >= 1
2129               && line[0] == 'S'
2130               && (line[1] == '\0' || line[1] == ' '))
2131             {
2132               if (!current_datasink || current_datasink != stdout)
2133                 {
2134                   fwrite (line, linelen, 1, stdout);
2135                   putchar ('\n');
2136                 }
2137             }
2138           else if (linelen >= 2
2139                    && line[0] == 'O' && line[1] == 'K'
2140                    && (line[2] == '\0' || line[2] == ' '))
2141             {
2142               if (!current_datasink || current_datasink != stdout)
2143                 {
2144                   fwrite (line, linelen, 1, stdout);
2145                   putchar ('\n');
2146                 }
2147               set_int_var ("?", 0);
2148               return 0;
2149             }
2150           else if (linelen >= 3
2151                    && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2152                    && (line[3] == '\0' || line[3] == ' '))
2153             {
2154               int errval;
2155
2156               errval = strtol (line+3, NULL, 10);
2157               if (!errval)
2158                 errval = -1;
2159               set_int_var ("?", errval);
2160               if (!current_datasink || current_datasink != stdout)
2161                 {
2162                   fwrite (line, linelen, 1, stdout);
2163                   putchar ('\n');
2164                 }
2165               *r_goterr = 1;
2166               return 0;
2167             }
2168           else if (linelen >= 7
2169                    && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2170                    && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2171                    && line[6] == 'E'
2172                    && (line[7] == '\0' || line[7] == ' '))
2173             {
2174               if (!current_datasink || current_datasink != stdout)
2175                 {
2176                   fwrite (line, linelen, 1, stdout);
2177                   putchar ('\n');
2178                 }
2179               if (!handle_inquire (ctx, line))
2180                 assuan_write_line (ctx, "CANCEL");
2181             }
2182           else if (linelen >= 3
2183                    && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2184                    && (line[3] == '\0' || line[3] == ' '))
2185             {
2186               if (!current_datasink || current_datasink != stdout)
2187                 {
2188                   fwrite (line, linelen, 1, stdout);
2189                   putchar ('\n');
2190                 }
2191               /* Received from server, thus more responses are expected.  */
2192             }
2193           else
2194             return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2195         }
2196     }
2197 }
2198
2199
2200
2201
2202 /* Connect to the agent and send the standard options.  */
2203 static assuan_context_t
2204 start_agent (void)
2205 {
2206   gpg_error_t err;
2207   assuan_context_t ctx;
2208   session_env_t session_env;
2209
2210   session_env = session_env_new ();
2211   if (!session_env)
2212     log_fatal ("error allocating session environment block: %s\n",
2213                strerror (errno));
2214   if (opt.use_dirmngr)
2215     err = start_new_dirmngr (&ctx,
2216                              GPG_ERR_SOURCE_DEFAULT,
2217                              opt.homedir,
2218                              opt.dirmngr_program,
2219                              !opt.quiet, 0,
2220                              NULL, NULL);
2221   else
2222     err = start_new_gpg_agent (&ctx,
2223                                GPG_ERR_SOURCE_DEFAULT,
2224                                opt.homedir,
2225                                opt.agent_program,
2226                                NULL, NULL,
2227                                session_env,
2228                                !opt.quiet, 0,
2229                                NULL, NULL);
2230
2231   session_env_release (session_env);
2232   if (err)
2233     {
2234       log_error (_("error sending standard options: %s\n"), gpg_strerror (err));
2235       exit (1);
2236     }
2237
2238   return ctx;
2239 }