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