Reworked passing of envars to Pinentry.
[gnupg.git] / tools / gpg-connect-agent.c
blob90f54a44d2763bab3922f8acbdef5e3ac0b99525
1 /* gpg-connect-agent.c - Tool to connect to the agent.
2 * Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
20 #include <config.h>
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>
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
42 #define CONTROL_D ('D' - 'A' + 1)
43 #define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
45 /* Constants to identify the commands and options. */
46 enum cmd_and_opt_values
48 aNull = 0,
49 oQuiet = 'q',
50 oVerbose = 'v',
51 oRawSocket = 'S',
52 oExec = 'E',
53 oRun = 'r',
54 oSubst = 's',
56 oNoVerbose = 500,
57 oHomedir,
58 oHex,
59 oDecode,
60 oNoExtConnect
65 /* The list of commands and options. */
66 static ARGPARSE_OPTS opts[] = {
67 ARGPARSE_group (301, N_("@\nOptions:\n ")),
69 ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
70 ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")),
71 ARGPARSE_s_n (oHex, "hex", N_("print data out hex encoded")),
72 ARGPARSE_s_n (oDecode,"decode", N_("decode received data lines")),
73 ARGPARSE_s_s (oRawSocket, "raw-socket",
74 N_("|NAME|connect to Assuan socket NAME")),
75 ARGPARSE_s_n (oExec, "exec",
76 N_("run the Assuan server given on the command line")),
77 ARGPARSE_s_n (oNoExtConnect, "no-ext-connect",
78 N_("do not use extended connect mode")),
79 ARGPARSE_s_s (oRun, "run",
80 N_("|FILE|run commands from FILE on startup")),
81 ARGPARSE_s_n (oSubst, "subst", N_("run /subst on startup")),
83 ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
84 ARGPARSE_s_s (oHomedir, "homedir", "@" ),
86 ARGPARSE_end ()
90 /* We keep all global options in the structure OPT. */
91 struct
93 int verbose; /* Verbosity level. */
94 int quiet; /* Be extra quiet. */
95 const char *homedir; /* Configuration directory name */
96 int hex; /* Print data lines in hex format. */
97 int decode; /* Decode received data lines. */
98 const char *raw_socket; /* Name of socket to connect in raw mode. */
99 int exec; /* Run the pgm given on the command line. */
100 unsigned int connect_flags; /* Flags used for connecting. */
101 int enable_varsubst; /* Set if variable substitution is enabled. */
102 int trim_leading_spaces;
103 } opt;
107 /* Definitions for /definq commands and a global linked list with all
108 the definitions. */
109 struct definq_s
111 struct definq_s *next;
112 char *name; /* Name of inquiry or NULL for any name. */
113 int is_var; /* True if FILE is a variable name. */
114 int is_prog; /* True if FILE is a program to run. */
115 char file[1]; /* Name of file or program. */
117 typedef struct definq_s *definq_t;
119 static definq_t definq_list;
120 static definq_t *definq_list_tail = &definq_list;
123 /* Variable definitions and glovbal table. */
124 struct variable_s
126 struct variable_s *next;
127 char *value; /* Malloced value - always a string. */
128 char name[1]; /* Name of the variable. */
130 typedef struct variable_s *variable_t;
132 static variable_t variable_table;
135 /* To implement loops we store entire lines in a linked list. */
136 struct loopline_s
138 struct loopline_s *next;
139 char line[1];
141 typedef struct loopline_s *loopline_t;
144 /* This is used to store the pid of the server. */
145 static pid_t server_pid = (pid_t)(-1);
147 /* The current datasink file or NULL. */
148 static FILE *current_datasink;
150 /* A list of open file descriptors. */
151 static struct
153 int inuse;
154 #ifdef HAVE_W32_SYSTEM
155 HANDLE handle;
156 #endif
157 } open_fd_table[256];
160 /*-- local prototypes --*/
161 static char *substitute_line_copy (const char *buffer);
162 static int read_and_print_response (assuan_context_t ctx, int *r_goterr);
163 static assuan_context_t start_agent (void);
168 /* Print usage information and and provide strings for help. */
169 static const char *
170 my_strusage( int level )
172 const char *p;
174 switch (level)
176 case 11: p = "gpg-connect-agent (GnuPG)";
177 break;
178 case 13: p = VERSION; break;
179 case 17: p = PRINTABLE_OS_NAME; break;
180 case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
181 break;
182 case 1:
183 case 40: p = _("Usage: gpg-connect-agent [options] (-h for help)");
184 break;
185 case 41:
186 p = _("Syntax: gpg-connect-agent [options]\n"
187 "Connect to a running agent and send commands\n");
188 break;
189 case 31: p = "\nHome: "; break;
190 case 32: p = opt.homedir; break;
191 case 33: p = "\n"; break;
193 default: p = NULL; break;
195 return p;
199 static char *
200 gnu_getcwd (void)
202 char *buffer;
203 size_t size = 100;
205 for (;;)
207 buffer = xmalloc (size+1);
208 if (getcwd (buffer, size) == buffer)
209 return buffer;
210 xfree (buffer);
211 if (errno != ERANGE)
212 return NULL;
213 size *= 2;
218 /* Unescape STRING and returned the malloced result. The surrounding
219 quotes must already be removed from STRING. */
220 static char *
221 unescape_string (const char *string)
223 const unsigned char *s;
224 int esc;
225 size_t n;
226 char *buffer;
227 unsigned char *d;
229 n = 0;
230 for (s = (const unsigned char*)string, esc=0; *s; s++)
232 if (esc)
234 switch (*s)
236 case 'b':
237 case 't':
238 case 'v':
239 case 'n':
240 case 'f':
241 case 'r':
242 case '"':
243 case '\'':
244 case '\\': n++; break;
245 case 'x':
246 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
247 n++;
248 break;
250 default:
251 if (s[1] && s[2]
252 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
253 n++;
254 break;
256 esc = 0;
258 else if (*s == '\\')
259 esc = 1;
260 else
261 n++;
264 buffer = xmalloc (n+1);
265 d = (unsigned char*)buffer;
266 for (s = (const unsigned char*)string, esc=0; *s; s++)
268 if (esc)
270 switch (*s)
272 case 'b': *d++ = '\b'; break;
273 case 't': *d++ = '\t'; break;
274 case 'v': *d++ = '\v'; break;
275 case 'n': *d++ = '\n'; break;
276 case 'f': *d++ = '\f'; break;
277 case 'r': *d++ = '\r'; break;
278 case '"': *d++ = '\"'; break;
279 case '\'': *d++ = '\''; break;
280 case '\\': *d++ = '\\'; break;
281 case 'x':
282 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
284 s++;
285 *d++ = xtoi_2 (s);
286 s++;
288 break;
290 default:
291 if (s[1] && s[2]
292 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
294 *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
295 s += 2;
297 break;
299 esc = 0;
301 else if (*s == '\\')
302 esc = 1;
303 else
304 *d++ = *s;
306 *d = 0;
307 return buffer;
311 /* Do the percent unescaping and return a newly malloced string.
312 If WITH_PLUS is set '+' characters will be changed to space. */
313 static char *
314 unpercent_string (const char *string, int with_plus)
316 const unsigned char *s;
317 unsigned char *buffer, *p;
318 size_t n;
320 n = 0;
321 for (s=(const unsigned char *)string; *s; s++)
323 if (*s == '%' && s[1] && s[2])
325 s++;
326 n++;
327 s++;
329 else if (with_plus && *s == '+')
330 n++;
331 else
332 n++;
335 buffer = xmalloc (n+1);
336 p = buffer;
337 for (s=(const unsigned char *)string; *s; s++)
339 if (*s == '%' && s[1] && s[2])
341 s++;
342 *p++ = xtoi_2 (s);
343 s++;
345 else if (with_plus && *s == '+')
346 *p++ = ' ';
347 else
348 *p++ = *s;
350 *p = 0;
351 return (char*)buffer;
358 static const char *
359 set_var (const char *name, const char *value)
361 variable_t var;
363 for (var = variable_table; var; var = var->next)
364 if (!strcmp (var->name, name))
365 break;
366 if (!var)
368 var = xmalloc (sizeof *var + strlen (name));
369 var->value = NULL;
370 strcpy (var->name, name);
371 var->next = variable_table;
372 variable_table = var;
374 xfree (var->value);
375 var->value = value? xstrdup (value) : NULL;
376 return var->value;
380 static void
381 set_int_var (const char *name, int value)
383 char numbuf[35];
385 snprintf (numbuf, sizeof numbuf, "%d", value);
386 set_var (name, numbuf);
390 /* Return the value of a variable. That value is valid until a
391 variable of the name is changed. Return NULL if not found. Note
392 that envvars are copied to our variable list at the first access
393 and not at oprogram start. */
394 static const char *
395 get_var (const char *name)
397 variable_t var;
398 const char *s;
400 if (!*name)
401 return "";
402 for (var = variable_table; var; var = var->next)
403 if (!strcmp (var->name, name))
404 break;
405 if (!var && (s = getenv (name)))
406 return set_var (name, s);
407 if (!var || !var->value)
408 return NULL;
409 return var->value;
413 /* Perform some simple arithmentic operations. Caller must release
414 the return value. On error the return value is NULL. */
415 static char *
416 arithmetic_op (int operator, const char *operands)
418 long result, value;
419 char numbuf[35];
421 while ( spacep (operands) )
422 operands++;
423 if (!*operands)
424 return NULL;
425 result = strtol (operands, NULL, 0);
426 while (*operands && !spacep (operands) )
427 operands++;
428 if (operator == '!')
429 result = !result;
431 while (*operands)
433 while ( spacep (operands) )
434 operands++;
435 if (!*operands)
436 break;
437 value = strtol (operands, NULL, 0);
438 while (*operands && !spacep (operands) )
439 operands++;
440 switch (operator)
442 case '+': result += value; break;
443 case '-': result -= value; break;
444 case '*': result *= value; break;
445 case '/':
446 if (!value)
447 return NULL;
448 result /= value;
449 break;
450 case '%':
451 if (!value)
452 return NULL;
453 result %= value;
454 break;
455 case '!': result = !value; break;
456 case '|': result = result || value; break;
457 case '&': result = result && value; break;
458 default:
459 log_error ("unknown arithmetic operator `%c'\n", operator);
460 return NULL;
463 snprintf (numbuf, sizeof numbuf, "%ld", result);
464 return xstrdup (numbuf);
469 /* Extended version of get_var. This returns a malloced string and
470 understand the function syntax: "func args".
472 Defined functions are
474 get - Return a value described by the next argument:
475 cwd - The current working directory.
476 homedir - The gnupg homedir.
477 sysconfdir - GnuPG's system configuration directory.
478 bindir - GnuPG's binary directory.
479 libdir - GnuPG's library directory.
480 libexecdir - GnuPG's library directory for executable files.
481 datadir - GnuPG's data directory.
482 serverpid - The PID of the current server.
484 unescape ARGS
485 Remove C-style escapes from string. Note that "\0" and
486 "\x00" terminate the string implictly. Use "\x7d" to
487 represent the closing brace. The args start right after
488 the first space after the function name.
490 unpercent ARGS
491 unpercent+ ARGS
492 Remove percent style ecaping from string. Note that "%00
493 terminates the string implicitly. Use "%7d" to represetn
494 the closing brace. The args start right after the first
495 space after the function name. "unpercent+" also maps '+'
496 to space.
498 percent ARGS
499 percent+ ARGS
500 Escape the args using the percent style. Tabs, formfeeds,
501 linefeeds and carriage returns are also escaped.
502 "percent+" also maps spaces to plus characters.
504 errcode ARG
505 Assuming ARG is an integer, return the gpg-error code.
507 errsource ARG
508 Assuming ARG is an integer, return the gpg-error source.
510 errstring ARG
511 Assuming ARG is an integer return a formatted fpf error string.
514 Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
517 static char *
518 get_var_ext (const char *name)
520 static int recursion_count;
521 const char *s;
522 char *result;
523 char *p;
524 char *free_me = NULL;
525 int intvalue;
527 if (recursion_count > 50)
529 log_error ("variables nested too deeply\n");
530 return NULL;
533 recursion_count++;
534 free_me = opt.enable_varsubst? substitute_line_copy (name) : NULL;
535 if (free_me)
536 name = free_me;
537 for (s=name; *s && !spacep (s); s++)
539 if (!*s)
541 s = get_var (name);
542 result = s? xstrdup (s): NULL;
544 else if ( (s - name) == 3 && !strncmp (name, "get", 3))
546 while ( spacep (s) )
547 s++;
548 if (!strcmp (s, "cwd"))
550 result = gnu_getcwd ();
551 if (!result)
552 log_error ("getcwd failed: %s\n", strerror (errno));
554 else if (!strcmp (s, "homedir"))
555 result = make_filename (opt.homedir, NULL);
556 else if (!strcmp (s, "sysconfdir"))
557 result = xstrdup (gnupg_sysconfdir ());
558 else if (!strcmp (s, "bindir"))
559 result = xstrdup (gnupg_bindir ());
560 else if (!strcmp (s, "libdir"))
561 result = xstrdup (gnupg_libdir ());
562 else if (!strcmp (s, "libexecdir"))
563 result = xstrdup (gnupg_libexecdir ());
564 else if (!strcmp (s, "datadir"))
565 result = xstrdup (gnupg_datadir ());
566 else if (!strcmp (s, "serverpid"))
567 result = xasprintf ("%d", (int)server_pid);
568 else
570 log_error ("invalid argument `%s' for variable function `get'\n", s);
571 log_info ("valid are: cwd, "
572 "{home,bin,lib,libexec,data}dir, serverpid\n");
573 result = NULL;
576 else if ( (s - name) == 8 && !strncmp (name, "unescape", 8))
578 s++;
579 result = unescape_string (s);
581 else if ( (s - name) == 9 && !strncmp (name, "unpercent", 9))
583 s++;
584 result = unpercent_string (s, 0);
586 else if ( (s - name) == 10 && !strncmp (name, "unpercent+", 10))
588 s++;
589 result = unpercent_string (s, 1);
591 else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
593 s++;
594 result = percent_escape (s, "\t\r\n\f\v");
596 else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
598 s++;
599 result = percent_escape (s, "\t\r\n\f\v");
600 for (p=result; *p; p++)
601 if (*p == ' ')
602 *p = '+';
604 else if ( (s - name) == 7 && !strncmp (name, "errcode", 7))
606 s++;
607 intvalue = (int)strtol (s, NULL, 0);
608 result = xasprintf ("%d", gpg_err_code (intvalue));
610 else if ( (s - name) == 9 && !strncmp (name, "errsource", 9))
612 s++;
613 intvalue = (int)strtol (s, NULL, 0);
614 result = xasprintf ("%d", gpg_err_source (intvalue));
616 else if ( (s - name) == 9 && !strncmp (name, "errstring", 9))
618 s++;
619 intvalue = (int)strtol (s, NULL, 0);
620 result = xasprintf ("%s <%s>",
621 gpg_strerror (intvalue), gpg_strsource (intvalue));
623 else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name))
625 result = arithmetic_op (*name, s+1);
627 else
629 log_error ("unknown variable function `%.*s'\n", (int)(s-name), name);
630 result = NULL;
633 xfree (free_me);
634 recursion_count--;
635 return result;
639 /* Substitute variables in LINE and return a new allocated buffer if
640 required. The function might modify LINE if the expanded version
641 fits into it. */
642 static char *
643 substitute_line (char *buffer)
645 char *line = buffer;
646 char *p, *pend;
647 const char *value;
648 size_t valuelen, n;
649 char *result = NULL;
650 char *freeme = NULL;
652 while (*line)
654 p = strchr (line, '$');
655 if (!p)
656 return result; /* No more variables. */
658 if (p[1] == '$') /* Escaped dollar sign. */
660 memmove (p, p+1, strlen (p+1)+1);
661 line = p + 1;
662 continue;
664 if (p[1] == '{')
666 int count = 0;
668 for (pend=p+2; *pend; pend++)
670 if (*pend == '{')
671 count++;
672 else if (*pend == '}')
674 if (--count < 0)
675 break;
678 if (!*pend)
679 return result; /* Unclosed - don't substitute. */
681 else
683 for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
686 if (p[1] == '{' && *pend == '}')
688 int save = *pend;
689 *pend = 0;
690 freeme = get_var_ext (p+2);
691 value = freeme;
692 *pend++ = save;
694 else if (*pend)
696 int save = *pend;
697 *pend = 0;
698 value = get_var (p+1);
699 *pend = save;
701 else
702 value = get_var (p+1);
703 if (!value)
704 value = "";
705 valuelen = strlen (value);
706 if (valuelen <= pend - p)
708 memcpy (p, value, valuelen);
709 p += valuelen;
710 n = pend - p;
711 if (n)
712 memmove (p, p+n, strlen (p+n)+1);
713 line = p;
715 else
717 char *src = result? result : buffer;
718 char *dst;
720 dst = xmalloc (strlen (src) + valuelen + 1);
721 n = p - src;
722 memcpy (dst, src, n);
723 memcpy (dst + n, value, valuelen);
724 n += valuelen;
725 strcpy (dst + n, pend);
726 line = dst + n;
727 xfree (result);
728 result = dst;
730 xfree (freeme);
731 freeme = NULL;
733 return result;
736 /* Same as substitute_line but do not modify BUFFER. */
737 static char *
738 substitute_line_copy (const char *buffer)
740 char *result, *p;
742 p = xstrdup (buffer?buffer:"");
743 result = substitute_line (p);
744 if (!result)
745 result = p;
746 else
747 xfree (p);
748 return result;
752 static void
753 assign_variable (char *line, int syslet)
755 char *name, *p, *tmp, *free_me, *buffer;
757 /* Get the name. */
758 name = line;
759 for (p=name; *p && !spacep (p); p++)
761 if (*p)
762 *p++ = 0;
763 while (spacep (p))
764 p++;
766 if (!*p)
767 set_var (name, NULL); /* Remove variable. */
768 else if (syslet)
770 free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
771 if (free_me)
772 p = free_me;
773 buffer = xmalloc (4 + strlen (p) + 1);
774 strcpy (stpcpy (buffer, "get "), p);
775 tmp = get_var_ext (buffer);
776 xfree (buffer);
777 set_var (name, tmp);
778 xfree (tmp);
779 xfree (free_me);
781 else
783 tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
784 if (tmp)
786 set_var (name, tmp);
787 xfree (tmp);
789 else
790 set_var (name, p);
795 static void
796 show_variables (void)
798 variable_t var;
800 for (var = variable_table; var; var = var->next)
801 if (var->value)
802 printf ("%-20s %s\n", var->name, var->value);
806 /* Store an inquire response pattern. Note, that this function may
807 change the content of LINE. We assume that leading white spaces
808 are already removed. */
809 static void
810 add_definq (char *line, int is_var, int is_prog)
812 definq_t d;
813 char *name, *p;
815 /* Get name. */
816 name = line;
817 for (p=name; *p && !spacep (p); p++)
819 if (*p)
820 *p++ = 0;
821 while (spacep (p))
822 p++;
824 d = xmalloc (sizeof *d + strlen (p) );
825 strcpy (d->file, p);
826 d->is_var = is_var;
827 d->is_prog = is_prog;
828 if ( !strcmp (name, "*"))
829 d->name = NULL;
830 else
831 d->name = xstrdup (name);
833 d->next = NULL;
834 *definq_list_tail = d;
835 definq_list_tail = &d->next;
839 /* Show all inquiry defintions. */
840 static void
841 show_definq (void)
843 definq_t d;
845 for (d=definq_list; d; d = d->next)
846 if (d->name)
847 printf ("%-20s %c %s\n",
848 d->name, d->is_var? 'v' : d->is_prog? 'p':'f', d->file);
849 for (d=definq_list; d; d = d->next)
850 if (!d->name)
851 printf ("%-20s %c %s\n", "*",
852 d->is_var? 'v': d->is_prog? 'p':'f', d->file);
856 /* Clear all inquiry definitions. */
857 static void
858 clear_definq (void)
860 while (definq_list)
862 definq_t tmp = definq_list->next;
863 xfree (definq_list->name);
864 xfree (definq_list);
865 definq_list = tmp;
867 definq_list_tail = &definq_list;
871 static void
872 do_sendfd (assuan_context_t ctx, char *line)
874 FILE *fp;
875 char *name, *mode, *p;
876 int rc, fd;
878 /* Get file name. */
879 name = line;
880 for (p=name; *p && !spacep (p); p++)
882 if (*p)
883 *p++ = 0;
884 while (spacep (p))
885 p++;
887 /* Get mode. */
888 mode = p;
889 if (!*mode)
890 mode = "r";
891 else
893 for (p=mode; *p && !spacep (p); p++)
895 if (*p)
896 *p++ = 0;
899 /* Open and send. */
900 fp = fopen (name, mode);
901 if (!fp)
903 log_error ("can't open `%s' in \"%s\" mode: %s\n",
904 name, mode, strerror (errno));
905 return;
907 fd = fileno (fp);
909 if (opt.verbose)
910 log_error ("file `%s' opened in \"%s\" mode, fd=%d\n",
911 name, mode, fd);
913 rc = assuan_sendfd (ctx, INT2FD (fd) );
914 if (rc)
915 log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
916 fclose (fp);
920 static void
921 do_recvfd (assuan_context_t ctx, char *line)
923 (void)ctx;
924 (void)line;
925 log_info ("This command has not yet been implemented\n");
929 static void
930 do_open (char *line)
932 FILE *fp;
933 char *varname, *name, *mode, *p;
934 int fd;
936 #ifdef HAVE_W32_SYSTEM
937 if (server_pid == (pid_t)(-1))
939 log_error ("the pid of the server is unknown\n");
940 log_info ("use command \"/serverpid\" first\n");
941 return;
943 #endif
945 /* Get variable name. */
946 varname = line;
947 for (p=varname; *p && !spacep (p); p++)
949 if (*p)
950 *p++ = 0;
951 while (spacep (p))
952 p++;
954 /* Get file name. */
955 name = p;
956 for (p=name; *p && !spacep (p); p++)
958 if (*p)
959 *p++ = 0;
960 while (spacep (p))
961 p++;
963 /* Get mode. */
964 mode = p;
965 if (!*mode)
966 mode = "r";
967 else
969 for (p=mode; *p && !spacep (p); p++)
971 if (*p)
972 *p++ = 0;
975 /* Open and send. */
976 fp = fopen (name, mode);
977 if (!fp)
979 log_error ("can't open `%s' in \"%s\" mode: %s\n",
980 name, mode, strerror (errno));
981 return;
983 fd = fileno (fp);
984 if (fd >= 0 && fd < DIM (open_fd_table))
986 open_fd_table[fd].inuse = 1;
987 #ifdef HAVE_W32_SYSTEM
989 HANDLE prochandle, handle, newhandle;
991 handle = (void*)_get_osfhandle (fd);
993 prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
994 if (!prochandle)
996 log_error ("failed to open the server process\n");
997 close (fd);
998 return;
1001 if (!DuplicateHandle (GetCurrentProcess(), handle,
1002 prochandle, &newhandle, 0,
1003 TRUE, DUPLICATE_SAME_ACCESS ))
1005 log_error ("failed to duplicate the handle\n");
1006 close (fd);
1007 CloseHandle (prochandle);
1008 return;
1010 CloseHandle (prochandle);
1011 open_fd_table[fd].handle = newhandle;
1013 if (opt.verbose)
1014 log_info ("file `%s' opened in \"%s\" mode, fd=%d (libc=%d)\n",
1015 name, mode, (int)open_fd_table[fd].handle, fd);
1016 set_int_var (varname, (int)open_fd_table[fd].handle);
1017 #else
1018 if (opt.verbose)
1019 log_info ("file `%s' opened in \"%s\" mode, fd=%d\n",
1020 name, mode, fd);
1021 set_int_var (varname, fd);
1022 #endif
1024 else
1026 log_error ("can't put fd %d into table\n", fd);
1027 close (fd);
1032 static void
1033 do_close (char *line)
1035 int fd = atoi (line);
1037 #ifdef HAVE_W32_SYSTEM
1038 int i;
1040 for (i=0; i < DIM (open_fd_table); i++)
1041 if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1042 break;
1043 if (i < DIM (open_fd_table))
1044 fd = i;
1045 else
1047 log_error ("given fd (system handle) has not been opened\n");
1048 return;
1050 #endif
1052 if (fd < 0 || fd >= DIM (open_fd_table))
1054 log_error ("invalid fd\n");
1055 return;
1058 if (!open_fd_table[fd].inuse)
1060 log_error ("given fd has not been opened\n");
1061 return;
1063 #ifdef HAVE_W32_SYSTEM
1064 CloseHandle (open_fd_table[fd].handle); /* Close duped handle. */
1065 #endif
1066 close (fd);
1067 open_fd_table[fd].inuse = 0;
1071 static void
1072 do_showopen (void)
1074 int i;
1076 for (i=0; i < DIM (open_fd_table); i++)
1077 if (open_fd_table[i].inuse)
1079 #ifdef HAVE_W32_SYSTEM
1080 printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
1081 #else
1082 printf ("%-15d\n", i);
1083 #endif
1089 static int
1090 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1092 membuf_t *mb = opaque;
1093 put_membuf (mb, buffer, length);
1094 return 0;
1097 /* Get the pid of the server and store it locally. */
1098 static void
1099 do_serverpid (assuan_context_t ctx)
1101 int rc;
1102 membuf_t mb;
1103 char *buffer;
1105 init_membuf (&mb, 100);
1106 rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
1107 NULL, NULL, NULL, NULL);
1108 put_membuf (&mb, "", 1);
1109 buffer = get_membuf (&mb, NULL);
1110 if (rc || !buffer)
1111 log_error ("command \"%s\" failed: %s\n",
1112 "GETINFO pid", gpg_strerror (rc));
1113 else
1115 server_pid = (pid_t)strtoul (buffer, NULL, 10);
1116 if (opt.verbose)
1117 log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1119 xfree (buffer);
1123 /* gpg-connect-agent's entry point. */
1125 main (int argc, char **argv)
1127 ARGPARSE_ARGS pargs;
1128 int no_more_options = 0;
1129 assuan_context_t ctx;
1130 char *line, *p;
1131 char *tmpline;
1132 size_t linesize;
1133 int rc;
1134 int cmderr;
1135 const char *opt_run = NULL;
1136 FILE *script_fp = NULL;
1137 int use_tty, keep_line;
1138 struct {
1139 int collecting;
1140 loopline_t head;
1141 loopline_t *tail;
1142 loopline_t current;
1143 unsigned int nestlevel;
1144 int oneshot;
1145 char *condition;
1146 } loopstack[20];
1147 int loopidx;
1148 char **cmdline_commands = NULL;
1150 gnupg_rl_initialize ();
1151 set_strusage (my_strusage);
1152 log_set_prefix ("gpg-connect-agent", 1);
1154 /* Make sure that our subsystems are ready. */
1155 i18n_init();
1156 init_common_subsystems ();
1158 assuan_set_assuan_err_source (0);
1161 opt.homedir = default_homedir ();
1162 opt.connect_flags = 1; /* Use extended connect mode. */
1164 /* Parse the command line. */
1165 pargs.argc = &argc;
1166 pargs.argv = &argv;
1167 pargs.flags = 1; /* Do not remove the args. */
1168 while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
1170 switch (pargs.r_opt)
1172 case oQuiet: opt.quiet = 1; break;
1173 case oVerbose: opt.verbose++; break;
1174 case oNoVerbose: opt.verbose = 0; break;
1175 case oHomedir: opt.homedir = pargs.r.ret_str; break;
1176 case oHex: opt.hex = 1; break;
1177 case oDecode: opt.decode = 1; break;
1178 case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
1179 case oExec: opt.exec = 1; break;
1180 case oNoExtConnect: opt.connect_flags &= ~(1); break;
1181 case oRun: opt_run = pargs.r.ret_str; break;
1182 case oSubst:
1183 opt.enable_varsubst = 1;
1184 opt.trim_leading_spaces = 1;
1185 break;
1187 default: pargs.err = 2; break;
1191 if (log_get_errorcount (0))
1192 exit (2);
1194 use_tty = (isatty ( fileno (stdin)) && isatty (fileno (stdout)));
1196 if (opt.exec)
1198 if (!argc)
1200 log_error (_("option \"%s\" requires a program "
1201 "and optional arguments\n"), "--exec" );
1202 exit (1);
1205 else if (argc)
1206 cmdline_commands = argv;
1208 if (opt.exec && opt.raw_socket)
1209 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1210 "--raw-socket", "--exec");
1212 if (opt_run && !(script_fp = fopen (opt_run, "r")))
1214 log_error ("cannot open run file `%s': %s\n",
1215 opt_run, strerror (errno));
1216 exit (1);
1220 if (opt.exec)
1222 int no_close[3];
1224 no_close[0] = fileno (stderr);
1225 no_close[1] = log_get_fd ();
1226 no_close[2] = -1;
1227 rc = assuan_pipe_connect_ext (&ctx, *argv, (const char **)argv,
1228 no_close, NULL, NULL,
1229 opt.connect_flags);
1230 if (rc)
1232 log_error ("assuan_pipe_connect_ext failed: %s\n",
1233 gpg_strerror (rc));
1234 exit (1);
1237 if (opt.verbose)
1238 log_info ("server `%s' started\n", *argv);
1241 else if (opt.raw_socket)
1243 rc = assuan_socket_connect_ext (&ctx, opt.raw_socket, 0,
1244 opt.connect_flags);
1245 if (rc)
1247 log_error ("can't connect to socket `%s': %s\n",
1248 opt.raw_socket, gpg_strerror (rc));
1249 exit (1);
1252 if (opt.verbose)
1253 log_info ("connection to socket `%s' established\n", opt.raw_socket);
1255 else
1256 ctx = start_agent ();
1258 /* See whether there is a line pending from the server (in case
1259 assuan did not run the initial handshaking). */
1260 if (assuan_pending_line (ctx))
1262 rc = read_and_print_response (ctx, &cmderr);
1263 if (rc)
1264 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1268 for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1269 loopstack[loopidx].collecting = 0;
1270 loopidx = -1;
1271 line = NULL;
1272 linesize = 0;
1273 keep_line = 1;
1274 for (;;)
1276 int n;
1277 size_t maxlength = 2048;
1279 assert (loopidx < (int)DIM (loopstack));
1280 if (loopidx >= 0 && loopstack[loopidx].current)
1282 keep_line = 0;
1283 xfree (line);
1284 line = xstrdup (loopstack[loopidx].current->line);
1285 n = strlen (line);
1286 /* Never go beyond of the final /end. */
1287 if (loopstack[loopidx].current->next)
1288 loopstack[loopidx].current = loopstack[loopidx].current->next;
1289 else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1291 else
1292 log_fatal ("/end command vanished\n");
1294 else if (cmdline_commands && *cmdline_commands && !script_fp)
1296 keep_line = 0;
1297 xfree (line);
1298 line = xstrdup (*cmdline_commands);
1299 cmdline_commands++;
1300 n = strlen (line);
1301 if (n >= maxlength)
1302 maxlength = 0;
1304 else if (use_tty && !script_fp)
1306 keep_line = 0;
1307 xfree (line);
1308 line = tty_get ("> ");
1309 n = strlen (line);
1310 if (n==1 && *line == CONTROL_D)
1311 n = 0;
1312 if (n >= maxlength)
1313 maxlength = 0;
1315 else
1317 if (!keep_line)
1319 xfree (line);
1320 line = NULL;
1321 linesize = 0;
1322 keep_line = 1;
1324 n = read_line (script_fp? script_fp:stdin,
1325 &line, &linesize, &maxlength);
1327 if (n < 0)
1329 log_error (_("error reading input: %s\n"), strerror (errno));
1330 if (script_fp)
1332 fclose (script_fp);
1333 script_fp = NULL;
1334 log_error ("stopping script execution\n");
1335 continue;
1337 exit (1);
1339 if (!n)
1341 /* EOF */
1342 if (script_fp)
1344 fclose (script_fp);
1345 script_fp = NULL;
1346 if (opt.verbose)
1347 log_info ("end of script\n");
1348 continue;
1350 break;
1352 if (!maxlength)
1354 log_error (_("line too long - skipped\n"));
1355 continue;
1357 if (memchr (line, 0, n))
1358 log_info (_("line shortened due to embedded Nul character\n"));
1359 if (line[n-1] == '\n')
1360 line[n-1] = 0;
1362 if (opt.trim_leading_spaces)
1364 const char *s = line;
1366 while (spacep (s))
1367 s++;
1368 if (s != line)
1370 for (p=line; *s;)
1371 *p++ = *s++;
1372 *p = 0;
1373 n = p - line;
1377 if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1379 loopline_t ll;
1381 ll = xmalloc (sizeof *ll + strlen (line));
1382 ll->next = NULL;
1383 strcpy (ll->line, line);
1384 *loopstack[loopidx+1].tail = ll;
1385 loopstack[loopidx+1].tail = &ll->next;
1387 if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1388 loopstack[loopidx+1].nestlevel--;
1389 else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1390 loopstack[loopidx+1].nestlevel++;
1392 if (loopstack[loopidx+1].nestlevel)
1393 continue;
1394 /* We reached the corresponding /end. */
1395 loopstack[loopidx+1].collecting = 0;
1396 loopidx++;
1399 if (*line == '/')
1401 /* Handle control commands. */
1402 char *cmd = line+1;
1404 for (p=cmd; *p && !spacep (p); p++)
1406 if (*p)
1407 *p++ = 0;
1408 while (spacep (p))
1409 p++;
1410 if (!strcmp (cmd, "let"))
1412 assign_variable (p, 0);
1414 else if (!strcmp (cmd, "slet"))
1416 /* Deprecated - never used in a released version. */
1417 assign_variable (p, 1);
1419 else if (!strcmp (cmd, "showvar"))
1421 show_variables ();
1423 else if (!strcmp (cmd, "definq"))
1425 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1426 if (tmpline)
1428 add_definq (tmpline, 1, 0);
1429 xfree (tmpline);
1431 else
1432 add_definq (p, 1, 0);
1434 else if (!strcmp (cmd, "definqfile"))
1436 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1437 if (tmpline)
1439 add_definq (tmpline, 0, 0);
1440 xfree (tmpline);
1442 else
1443 add_definq (p, 0, 0);
1445 else if (!strcmp (cmd, "definqprog"))
1447 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1448 if (tmpline)
1450 add_definq (tmpline, 0, 1);
1451 xfree (tmpline);
1453 else
1454 add_definq (p, 0, 1);
1456 else if (!strcmp (cmd, "datafile"))
1458 const char *fname;
1460 if (current_datasink)
1462 if (current_datasink != stdout)
1463 fclose (current_datasink);
1464 current_datasink = NULL;
1466 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1467 fname = tmpline? tmpline : p;
1468 if (fname && !strcmp (fname, "-"))
1469 current_datasink = stdout;
1470 else if (fname && *fname)
1472 current_datasink = fopen (fname, "wb");
1473 if (!current_datasink)
1474 log_error ("can't open `%s': %s\n",
1475 fname, strerror (errno));
1477 xfree (tmpline);
1479 else if (!strcmp (cmd, "showdef"))
1481 show_definq ();
1483 else if (!strcmp (cmd, "cleardef"))
1485 clear_definq ();
1487 else if (!strcmp (cmd, "echo"))
1489 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1490 if (tmpline)
1492 puts (tmpline);
1493 xfree (tmpline);
1495 else
1496 puts (p);
1498 else if (!strcmp (cmd, "sendfd"))
1500 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1501 if (tmpline)
1503 do_sendfd (ctx, tmpline);
1504 xfree (tmpline);
1506 else
1507 do_sendfd (ctx, p);
1508 continue;
1510 else if (!strcmp (cmd, "recvfd"))
1512 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1513 if (tmpline)
1515 do_recvfd (ctx, tmpline);
1516 xfree (tmpline);
1518 else
1519 do_recvfd (ctx, p);
1520 continue;
1522 else if (!strcmp (cmd, "open"))
1524 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1525 if (tmpline)
1527 do_open (tmpline);
1528 xfree (tmpline);
1530 else
1531 do_open (p);
1533 else if (!strcmp (cmd, "close"))
1535 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1536 if (tmpline)
1538 do_close (tmpline);
1539 xfree (tmpline);
1541 else
1542 do_close (p);
1544 else if (!strcmp (cmd, "showopen"))
1546 do_showopen ();
1548 else if (!strcmp (cmd, "serverpid"))
1550 do_serverpid (ctx);
1552 else if (!strcmp (cmd, "hex"))
1553 opt.hex = 1;
1554 else if (!strcmp (cmd, "nohex"))
1555 opt.hex = 0;
1556 else if (!strcmp (cmd, "decode"))
1557 opt.decode = 1;
1558 else if (!strcmp (cmd, "nodecode"))
1559 opt.decode = 0;
1560 else if (!strcmp (cmd, "subst"))
1562 opt.enable_varsubst = 1;
1563 opt.trim_leading_spaces = 1;
1565 else if (!strcmp (cmd, "nosubst"))
1566 opt.enable_varsubst = 0;
1567 else if (!strcmp (cmd, "run"))
1569 char *p2;
1571 for (p2=p; *p2 && !spacep (p2); p2++)
1573 if (*p2)
1574 *p2++ = 0;
1575 while (spacep (p2))
1576 p++;
1577 if (*p2)
1579 log_error ("syntax error in run command\n");
1580 if (script_fp)
1582 fclose (script_fp);
1583 script_fp = NULL;
1586 else if (script_fp)
1588 log_error ("cannot nest run commands - stop\n");
1589 fclose (script_fp);
1590 script_fp = NULL;
1592 else if (!(script_fp = fopen (p, "r")))
1594 log_error ("cannot open run file `%s': %s\n",
1595 p, strerror (errno));
1597 else if (opt.verbose)
1598 log_info ("running commands from `%s'\n", p);
1600 else if (!strcmp (cmd, "while"))
1602 if (loopidx+2 >= (int)DIM(loopstack))
1604 log_error ("blocks are nested too deep\n");
1605 /* We should better die or break all loop in this
1606 case as recovering from this error won't be
1607 easy. */
1609 else
1611 loopstack[loopidx+1].head = NULL;
1612 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1613 loopstack[loopidx+1].current = NULL;
1614 loopstack[loopidx+1].nestlevel = 1;
1615 loopstack[loopidx+1].oneshot = 0;
1616 loopstack[loopidx+1].condition = xstrdup (p);
1617 loopstack[loopidx+1].collecting = 1;
1620 else if (!strcmp (cmd, "if"))
1622 if (loopidx+2 >= (int)DIM(loopstack))
1624 log_error ("blocks are nested too deep\n");
1626 else
1628 /* Note that we need to evaluate the condition right
1629 away and not just at the end of the block as we
1630 do with a WHILE. */
1631 loopstack[loopidx+1].head = NULL;
1632 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1633 loopstack[loopidx+1].current = NULL;
1634 loopstack[loopidx+1].nestlevel = 1;
1635 loopstack[loopidx+1].oneshot = 1;
1636 loopstack[loopidx+1].condition = substitute_line_copy (p);
1637 loopstack[loopidx+1].collecting = 1;
1640 else if (!strcmp (cmd, "end"))
1642 if (loopidx < 0)
1643 log_error ("stray /end command encountered - ignored\n");
1644 else
1646 char *tmpcond;
1647 const char *value;
1648 long condition;
1650 /* Evaluate the condition. */
1651 tmpcond = xstrdup (loopstack[loopidx].condition);
1652 if (loopstack[loopidx].oneshot)
1654 xfree (loopstack[loopidx].condition);
1655 loopstack[loopidx].condition = xstrdup ("0");
1657 tmpline = substitute_line (tmpcond);
1658 value = tmpline? tmpline : tmpcond;
1659 condition = strtol (value, NULL, 0);
1660 xfree (tmpline);
1661 xfree (tmpcond);
1663 if (condition)
1665 /* Run loop. */
1666 loopstack[loopidx].current = loopstack[loopidx].head;
1668 else
1670 /* Cleanup. */
1671 while (loopstack[loopidx].head)
1673 loopline_t tmp = loopstack[loopidx].head->next;
1674 xfree (loopstack[loopidx].head);
1675 loopstack[loopidx].head = tmp;
1677 loopstack[loopidx].tail = NULL;
1678 loopstack[loopidx].current = NULL;
1679 loopstack[loopidx].nestlevel = 0;
1680 loopstack[loopidx].collecting = 0;
1681 loopstack[loopidx].oneshot = 0;
1682 xfree (loopstack[loopidx].condition);
1683 loopstack[loopidx].condition = NULL;
1684 loopidx--;
1688 else if (!strcmp (cmd, "bye"))
1690 break;
1692 else if (!strcmp (cmd, "sleep"))
1694 gnupg_sleep (1);
1696 else if (!strcmp (cmd, "help"))
1698 puts (
1699 "Available commands:\n"
1700 "/echo ARGS Echo ARGS.\n"
1701 "/let NAME VALUE Set variable NAME to VALUE.\n"
1702 "/showvar Show all variables.\n"
1703 "/definq NAME VAR Use content of VAR for inquiries with NAME.\n"
1704 "/definqfile NAME FILE Use content of FILE for inquiries with NAME.\n"
1705 "/definqprog NAME PGM Run PGM for inquiries with NAME.\n"
1706 "/datafile [NAME] Write all D line content to file NAME.\n"
1707 "/showdef Print all definitions.\n"
1708 "/cleardef Delete all definitions.\n"
1709 "/sendfd FILE MODE Open FILE and pass descriptor to server.\n"
1710 "/recvfd Receive FD from server and print.\n"
1711 "/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n"
1712 "/close FD Close file with descriptor FD.\n"
1713 "/showopen Show descriptors of all open files.\n"
1714 "/serverpid Retrieve the pid of the server.\n"
1715 "/[no]hex Enable hex dumping of received data lines.\n"
1716 "/[no]decode Enable decoding of received data lines.\n"
1717 "/[no]subst Enable variable substitution.\n"
1718 "/run FILE Run commands from FILE.\n"
1719 "/if VAR Begin conditional block controlled by VAR.\n"
1720 "/while VAR Begin loop controlled by VAR.\n"
1721 "/end End loop or condition\n"
1722 "/bye Terminate gpg-connect-agent.\n"
1723 "/help Print this help.");
1725 else
1726 log_error (_("unknown command `%s'\n"), cmd );
1728 continue;
1731 if (opt.verbose && script_fp)
1732 puts (line);
1734 tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1735 if (tmpline)
1737 rc = assuan_write_line (ctx, tmpline);
1738 xfree (tmpline);
1740 else
1741 rc = assuan_write_line (ctx, line);
1742 if (rc)
1744 log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1745 break;
1747 if (*line == '#' || !*line)
1748 continue; /* Don't expect a response for a comment line. */
1750 rc = read_and_print_response (ctx, &cmderr);
1751 if (rc)
1752 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1753 if ((rc || cmderr) && script_fp)
1755 log_error ("stopping script execution\n");
1756 fclose (script_fp);
1757 script_fp = NULL;
1761 /* FIXME: If the last command was BYE or the server died for
1762 some other reason, we won't notice until we get the next
1763 input command. Probing the connection with a non-blocking
1764 read could help to notice termination or other problems
1765 early. */
1768 if (opt.verbose)
1769 log_info ("closing connection to agent\n");
1771 return 0;
1775 /* Handle an Inquire from the server. Return False if it could not be
1776 handled; in this case the caller shll complete the operation. LINE
1777 is the complete line as received from the server. This function
1778 may change the content of LINE. */
1779 static int
1780 handle_inquire (assuan_context_t ctx, char *line)
1782 const char *name;
1783 definq_t d;
1784 FILE *fp = NULL;
1785 char buffer[1024];
1786 int rc, n;
1788 /* Skip the command and trailing spaces. */
1789 for (; *line && !spacep (line); line++)
1791 while (spacep (line))
1792 line++;
1793 /* Get the name. */
1794 name = line;
1795 for (; *line && !spacep (line); line++)
1797 if (*line)
1798 *line++ = 0;
1800 /* Now match it against our list. The second loop is there to
1801 detect the match-all entry. */
1802 for (d=definq_list; d; d = d->next)
1803 if (d->name && !strcmp (d->name, name))
1804 break;
1805 if (!d)
1806 for (d=definq_list; d; d = d->next)
1807 if (!d->name)
1808 break;
1809 if (!d)
1811 if (opt.verbose)
1812 log_info ("no handler for inquiry `%s' found\n", name);
1813 return 0;
1816 if (d->is_var)
1818 char *tmpvalue = get_var_ext (d->file);
1819 rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
1820 xfree (tmpvalue);
1821 if (rc)
1822 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1824 else
1826 if (d->is_prog)
1828 fp = popen (d->file, "r");
1829 if (!fp)
1830 log_error ("error executing `%s': %s\n",
1831 d->file, strerror (errno));
1832 else if (opt.verbose)
1833 log_error ("handling inquiry `%s' by running `%s'\n",
1834 name, d->file);
1836 else
1838 fp = fopen (d->file, "rb");
1839 if (!fp)
1840 log_error ("error opening `%s': %s\n", d->file, strerror (errno));
1841 else if (opt.verbose)
1842 log_error ("handling inquiry `%s' by returning content of `%s'\n",
1843 name, d->file);
1845 if (!fp)
1846 return 0;
1848 while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
1850 rc = assuan_send_data (ctx, buffer, n);
1851 if (rc)
1853 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1854 break;
1857 if (ferror (fp))
1858 log_error ("error reading from `%s': %s\n", d->file, strerror (errno));
1861 rc = assuan_send_data (ctx, NULL, 0);
1862 if (rc)
1863 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1865 if (d->is_var)
1867 else if (d->is_prog)
1869 if (pclose (fp))
1870 log_error ("error running `%s': %s\n", d->file, strerror (errno));
1872 else
1873 fclose (fp);
1874 return 1;
1878 /* Read all response lines from server and print them. Returns 0 on
1879 success or an assuan error code. Set R_GOTERR to true if the
1880 command did not returned OK. */
1881 static int
1882 read_and_print_response (assuan_context_t ctx, int *r_goterr)
1884 char *line;
1885 size_t linelen;
1886 assuan_error_t rc;
1887 int i, j;
1888 int need_lf = 0;
1890 *r_goterr = 0;
1891 for (;;)
1895 rc = assuan_read_line (ctx, &line, &linelen);
1896 if (rc)
1897 return rc;
1899 if (opt.verbose > 1 && *line == '#')
1901 fwrite (line, linelen, 1, stdout);
1902 putchar ('\n');
1905 while (*line == '#' || !linelen);
1907 if (linelen >= 1
1908 && line[0] == 'D' && line[1] == ' ')
1910 if (current_datasink)
1912 const unsigned char *s;
1913 int c = 0;
1915 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
1917 if (*s == '%' && j+2 < linelen)
1919 s++; j++;
1920 c = xtoi_2 ( s );
1921 s++; j++;
1923 else
1924 c = *s;
1925 putc (c, current_datasink);
1928 else if (opt.hex)
1930 for (i=2; i < linelen; )
1932 int save_i = i;
1934 printf ("D[%04X] ", i-2);
1935 for (j=0; j < 16 ; j++, i++)
1937 if (j == 8)
1938 putchar (' ');
1939 if (i < linelen)
1940 printf (" %02X", ((unsigned char*)line)[i]);
1941 else
1942 fputs (" ", stdout);
1944 fputs (" ", stdout);
1945 i= save_i;
1946 for (j=0; j < 16; j++, i++)
1948 unsigned int c = ((unsigned char*)line)[i];
1949 if ( i >= linelen )
1950 putchar (' ');
1951 else if (isascii (c) && isprint (c) && !iscntrl (c))
1952 putchar (c);
1953 else
1954 putchar ('.');
1956 putchar ('\n');
1959 else if (opt.decode)
1961 const unsigned char *s;
1962 int need_d = 1;
1963 int c = 0;
1965 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
1967 if (need_d)
1969 fputs ("D ", stdout);
1970 need_d = 0;
1972 if (*s == '%' && j+2 < linelen)
1974 s++; j++;
1975 c = xtoi_2 ( s );
1976 s++; j++;
1978 else
1979 c = *s;
1980 if (c == '\n')
1981 need_d = 1;
1982 putchar (c);
1984 need_lf = (c != '\n');
1986 else
1988 fwrite (line, linelen, 1, stdout);
1989 putchar ('\n');
1992 else
1994 if (need_lf)
1996 if (!current_datasink || current_datasink != stdout)
1997 putchar ('\n');
1998 need_lf = 0;
2001 if (linelen >= 1
2002 && line[0] == 'S'
2003 && (line[1] == '\0' || line[1] == ' '))
2005 if (!current_datasink || current_datasink != stdout)
2007 fwrite (line, linelen, 1, stdout);
2008 putchar ('\n');
2011 else if (linelen >= 2
2012 && line[0] == 'O' && line[1] == 'K'
2013 && (line[2] == '\0' || line[2] == ' '))
2015 if (!current_datasink || current_datasink != stdout)
2017 fwrite (line, linelen, 1, stdout);
2018 putchar ('\n');
2020 set_int_var ("?", 0);
2021 return 0;
2023 else if (linelen >= 3
2024 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2025 && (line[3] == '\0' || line[3] == ' '))
2027 int errval;
2029 errval = strtol (line+3, NULL, 10);
2030 if (!errval)
2031 errval = -1;
2032 set_int_var ("?", errval);
2033 if (!current_datasink || current_datasink != stdout)
2035 fwrite (line, linelen, 1, stdout);
2036 putchar ('\n');
2038 *r_goterr = 1;
2039 return 0;
2041 else if (linelen >= 7
2042 && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2043 && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2044 && line[6] == 'E'
2045 && (line[7] == '\0' || line[7] == ' '))
2047 if (!current_datasink || current_datasink != stdout)
2049 fwrite (line, linelen, 1, stdout);
2050 putchar ('\n');
2052 if (!handle_inquire (ctx, line))
2053 assuan_write_line (ctx, "CANCEL");
2055 else if (linelen >= 3
2056 && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2057 && (line[3] == '\0' || line[3] == ' '))
2059 if (!current_datasink || current_datasink != stdout)
2061 fwrite (line, linelen, 1, stdout);
2062 putchar ('\n');
2064 /* Received from server, thus more responses are expected. */
2066 else
2067 return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2075 /* Connect to the agent and send the standard options. */
2076 static assuan_context_t
2077 start_agent (void)
2079 int rc = 0;
2080 char *infostr, *p;
2081 assuan_context_t ctx;
2082 session_env_t session_env;
2084 session_env = session_env_new ();
2085 if (!session_env)
2086 log_fatal ("error allocating session environment block: %s\n",
2087 strerror (errno));
2089 infostr = getenv ("GPG_AGENT_INFO");
2090 if (!infostr || !*infostr)
2092 char *sockname;
2094 /* Check whether we can connect at the standard socket. */
2095 sockname = make_filename (opt.homedir, "S.gpg-agent", NULL);
2096 rc = assuan_socket_connect (&ctx, sockname, 0);
2098 #ifdef HAVE_W32_SYSTEM
2099 /* If we failed to connect under Windows, we fire up the agent. */
2100 if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
2102 const char *agent_program;
2103 const char *argv[3];
2104 int save_rc = rc;
2106 if (opt.verbose)
2107 log_info (_("no running gpg-agent - starting one\n"));
2108 agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
2110 argv[0] = "--daemon";
2111 argv[1] = "--use-standard-socket";
2112 argv[2] = NULL;
2114 rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
2115 if (rc)
2116 log_debug ("failed to start agent `%s': %s\n",
2117 agent_program, gpg_strerror (rc));
2118 else
2120 /* Give the agent some time to prepare itself. */
2121 gnupg_sleep (3);
2122 /* Now try again to connect the agent. */
2123 rc = assuan_socket_connect (&ctx, sockname, 0);
2125 if (rc)
2126 rc = save_rc;
2128 #endif /*HAVE_W32_SYSTEM*/
2129 xfree (sockname);
2131 else
2133 int prot;
2134 int pid;
2136 infostr = xstrdup (infostr);
2137 if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
2139 log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
2140 xfree (infostr);
2141 exit (1);
2143 *p++ = 0;
2144 pid = atoi (p);
2145 while (*p && *p != PATHSEP_C)
2146 p++;
2147 prot = *p? atoi (p+1) : 0;
2148 if (prot != 1)
2150 log_error (_("gpg-agent protocol version %d is not supported\n"),
2151 prot);
2152 xfree (infostr);
2153 exit (1);
2156 rc = assuan_socket_connect (&ctx, infostr, pid);
2157 xfree (infostr);
2160 if (rc)
2162 log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
2163 exit (1);
2166 if (opt.verbose)
2167 log_info ("connection to agent established\n");
2169 rc = assuan_transact (ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
2170 if (rc)
2172 log_error (_("error sending %s command: %s\n"), "RESET",
2173 gpg_strerror (rc));
2174 exit (1);
2177 rc = send_pinentry_environment (ctx, GPG_ERR_SOURCE_DEFAULT,
2178 NULL, NULL, session_env);
2179 if (rc)
2181 log_error (_("error sending standard options: %s\n"), gpg_strerror (rc));
2182 exit (1);
2185 return ctx;