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