1 /* gpgme-tool.c - GnuPG Made Easy.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH
5 This file is part of GPGME.
7 GPGME is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of
10 the License, or (at your option) any later version.
12 GPGME is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
44 /* Minimal argp implementation. */
46 /* Differences to ARGP:
47 argp_program_version: Required.
48 argp_program_bug_address: Required.
49 argp_program_version_hook: Not supported.
50 argp_err_exit_status: Required.
51 struct argp: Children and help_filter not supported.
52 argp_domain: Not supported.
53 struct argp_option: Group not supported. Options are printed in
54 order given. Flags OPTION_ALIAS, OPTION_DOC and OPTION_NO_USAGE
56 argp_parse: No flags are supported (ARGP_PARSE_ARGV0, ARGP_NO_ERRS,
57 ARGP_NO_ARGS, ARGP_IN_ORDER, ARGP_NO_HELP, ARGP_NO_EXIT,
58 ARGP_LONG_ONLY, ARGP_SILENT). ARGP must not be NULL.
59 argp_help: Flag ARGP_HELP_LONG_ONLY not supported.
60 argp_state: argc, argv, next may not be modified and should not be used. */
62 extern const char *argp_program_version;
63 extern const char *argp_program_bug_address;
64 extern error_t argp_err_exit_status;
71 #define OPTION_ARG_OPTIONAL 0x1
72 #define OPTION_HIDDEN 0x2
81 const struct argp *const root_argp;
97 #define ARGP_ERR_UNKNOWN E2BIG
98 #define ARGP_KEY_ARG 0
99 #define ARGP_KEY_ARGS 0x1000006
100 #define ARGP_KEY_END 0x1000001
101 #define ARGP_KEY_NO_ARGS 0x1000002
102 #define ARGP_KEY_INIT 0x1000003
103 #define ARGP_KEY_FINI 0x1000007
104 #define ARGP_KEY_SUCCESS 0x1000004
105 #define ARGP_KEY_ERROR 0x1000005
106 typedef error_t (*argp_parser_t) (int key, char *arg, struct argp_state *state);
110 const struct argp_option *options;
111 argp_parser_t parser;
112 const char *args_doc;
115 const struct argp_child *children;
116 char *(*help_filter) (int key, const char *text, void *input);
117 const char *argp_domain;
120 #define ARGP_HELP_USAGE ARGP_HELP_SHORT_USAGE
121 #define ARGP_HELP_SHORT_USAGE 0x02
122 #define ARGP_HELP_SEE 0x04
123 #define ARGP_HELP_LONG 0x08
124 #define ARGP_HELP_PRE_DOC 0x10
125 #define ARGP_HELP_POST_DOC 0x20
126 #define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
127 #define ARGP_HELP_BUG_ADDR 0x40
128 #define ARGP_HELP_EXIT_ERR 0x100
129 #define ARGP_HELP_EXIT_OK 0x200
130 #define ARGP_HELP_STD_ERR (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
131 #define ARGP_HELP_STD_USAGE \
132 (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
133 #define ARGP_HELP_STD_HELP \
134 (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
135 | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
139 _argp_pname (char *name)
142 char *bname = strrchr (pname, '/');
144 bname = strrchr (pname, '\\');
152 _argp_state_help (const struct argp *argp, const struct argp_state *state,
153 FILE *stream, unsigned flags, char *name)
158 if (flags & ARGP_HELP_SHORT_USAGE)
159 fprintf (stream, "Usage: %s [OPTIONS...] %s\n", name, argp->args_doc);
160 if (flags & ARGP_HELP_SEE)
161 fprintf (stream, "Try `%s --help' or `%s --usage' for more information.\n",
163 if (flags & ARGP_HELP_PRE_DOC)
167 strncpy (buf, argp->doc, sizeof (buf));
168 buf[sizeof (buf) - 1] = '\0';
169 end = strchr (buf, '\v');
172 fprintf (stream, "%s\n%s", buf, buf[0] ? "\n" : "");
174 if (flags & ARGP_HELP_LONG)
176 const struct argp_option *opt = argp->options;
180 char spaces[NSPACES + 1] = " ";
182 fprintf (stream, " ");
184 if (isascii (opt->key))
186 fprintf (stream, "-%c", opt->key);
190 fprintf (stream, ", ");
196 fprintf (stream, "--%s", opt->name);
197 len += 2 + strlen (opt->name);
199 if (opt->arg && (opt->flags & OPTION_ARG_OPTIONAL))
201 fprintf (stream, "[=%s]", opt->arg);
202 len += 3 + strlen (opt->arg);
206 fprintf (stream, "=%s", opt->arg);
207 len += 1 + strlen (opt->arg);
211 spaces[NSPACES - len] = '\0';
212 fprintf (stream, "%s%s\n", spaces, opt->doc);
215 fprintf (stream, " -?, --help Give this help list\n");
216 fprintf (stream, " --usage Give a short usage "
219 if (flags & ARGP_HELP_POST_DOC)
223 strncpy (buf, argp->doc, sizeof (buf));
224 buf[sizeof (buf) - 1] = '\0';
225 end = strchr (buf, '\v');
230 fprintf (stream, "\n%s\n", end);
232 fprintf (stream, "\nMandatory or optional arguments to long options are also mandatory or optional\n");
233 fprintf (stream, "for any corresponding short options.\n");
235 if (flags & ARGP_HELP_BUG_ADDR)
236 fprintf (stream, "\nReport bugs to %s.\n", argp_program_bug_address);
238 if (flags & ARGP_HELP_EXIT_ERR)
239 exit (argp_err_exit_status);
240 if (flags & ARGP_HELP_EXIT_OK)
246 argp_usage (const struct argp_state *state)
248 _argp_state_help (state->root_argp, state, state->err_stream,
249 ARGP_HELP_STD_USAGE, state->name);
254 argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
256 _argp_state_help (state->root_argp, state, stream, flags, state->name);
261 argp_error (const struct argp_state *state, const char *fmt, ...)
265 fprintf (state->err_stream, "%s: ", state->name);
267 vfprintf (state->err_stream, fmt, ap);
269 fprintf (state->err_stream, "\n");
270 argp_state_help (state, state->err_stream, ARGP_HELP_STD_ERR);
271 exit (argp_err_exit_status);
276 argp_help (const struct argp *argp, FILE *stream, unsigned flags, char *name)
278 _argp_state_help (argp, NULL, stream, flags, name);
283 argp_parse (const struct argp *argp, int argc,
284 char **argv, unsigned flags, int *arg_index, void *input)
287 struct argp_state state = { argp, argc, argv, 1, flags, 0, 0, input,
288 NULL, NULL, _argp_pname (argv[0]),
289 stderr, stdout, NULL };
290 /* All non-option arguments are collected at the beginning of
291 &argv[1] during processing. This is a counter for their number. */
292 int non_opt_args = 0;
294 rc = argp->parser (ARGP_KEY_INIT, NULL, &state);
295 if (rc && rc != ARGP_ERR_UNKNOWN)
298 while (state.next < state.argc - non_opt_args)
300 int idx = state.next;
303 if (! strcasecmp (state.argv[idx], "--"))
309 if (state.quoted || state.argv[idx][0] != '-')
311 char *arg_saved = state.argv[idx];
313 memmove (&state.argv[idx], &state.argv[idx + 1],
314 (state.argc - 1 - idx) * sizeof (char *));
315 state.argv[argc - 1] = arg_saved;
318 else if (! strcasecmp (state.argv[idx], "--help")
319 || !strcmp (state.argv[idx], "-?"))
321 argp_state_help (&state, state.out_stream, ARGP_HELP_STD_HELP);
323 else if (! strcasecmp (state.argv[idx], "--usage"))
325 argp_state_help (&state, state.out_stream,
326 ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
328 else if (! strcasecmp (state.argv[idx], "--version")
329 || !strcmp (state.argv[idx], "-V"))
331 fprintf (state.out_stream, "%s\n", argp_program_version);
336 /* Search for option and call parser with its KEY. */
337 int key = ARGP_KEY_ARG; /* Just some dummy value. */
338 const struct argp_option *opt = argp->options;
342 /* Check for --opt=value syntax. */
343 arg = strchr (state.argv[idx], '=');
350 if (state.argv[idx][1] != '-')
351 key = state.argv[idx][1];
353 while (! found && opt->key)
356 || (key == ARGP_KEY_ARG
357 && ! strcasecmp (&state.argv[idx][2], opt->name)))
359 if (arg && !opt->arg)
360 argp_error (&state, "Option %s does not take an argument",
362 if (opt->arg && state.next < state.argc
363 && state.argv[idx + 1][0] != '-')
365 arg = state.argv[idx + 1];
368 if (opt->arg && !(opt->flags & OPTION_ARG_OPTIONAL))
369 argp_error (&state, "Option %s requires an argument",
372 rc = argp->parser (opt->key, arg, &state);
373 if (rc == ARGP_ERR_UNKNOWN)
382 argp_error (&state, "Unknown option %s", state.argv[idx]);
386 while (state.next < state.argc)
388 /* Call parser for all non-option args. */
389 int idx = state.next;
391 rc = argp->parser (ARGP_KEY_ARG, state.argv[idx], &state);
392 if (rc && rc != ARGP_ERR_UNKNOWN)
394 if (rc == ARGP_ERR_UNKNOWN)
396 int old_next = state.next;
397 rc = argp->parser (ARGP_KEY_ARGS, NULL, &state);
398 if (rc == ARGP_ERR_UNKNOWN)
400 argp_error (&state, "Too many arguments", state.argv[idx]);
403 if (! rc && state.next == old_next)
405 state.arg_num += state.argc - state.next;
406 state.next = state.argc;
413 if (state.arg_num == 0)
415 rc = argp->parser (ARGP_KEY_NO_ARGS, NULL, &state);
416 if (rc && rc != ARGP_ERR_UNKNOWN)
419 if (state.next == state.argc)
421 rc = argp->parser (ARGP_KEY_END, NULL, &state);
422 if (rc && rc != ARGP_ERR_UNKNOWN)
425 rc = argp->parser (ARGP_KEY_FINI, NULL, &state);
426 if (rc && rc != ARGP_ERR_UNKNOWN)
430 argp->parser (ARGP_KEY_SUCCESS, NULL, &state);
435 argp_error (&state, "unexpected error: %s", strerror (rc));
436 argp->parser (ARGP_KEY_ERROR, NULL, &state);
439 argp->parser (ARGP_KEY_FINI, NULL, &state);
442 *arg_index = state.next - 1;
451 char *program_name = "gpgme-tool";
461 log_error (int status, gpg_error_t errnum, const char *fmt, ...)
465 fprintf (log_stream, "%s: ", program_name);
467 vfprintf (log_stream, fmt, ap);
470 fprintf (log_stream, ": %s <%s>", gpg_strerror (errnum),
471 gpg_strsource (errnum));
472 fprintf (log_stream, "\n");
486 STATUS_INCLUDE_CERTS,
489 STATUS_ENCRYPT_RESULT
492 const char *status_string[] =
508 #define MAX_RECIPIENTS 10
509 gpgme_key_t recipients[MAX_RECIPIENTS + 1];
512 gpg_error_t (*write_status) (void *hook, const char *status, const char *msg);
513 void *write_status_hook;
514 gpg_error_t (*write_data) (void *hook, const void *buf, size_t len);
515 void *write_data_hook;
517 typedef struct gpgme_tool *gpgme_tool_t;
520 /* Forward declaration. */
521 void gt_write_status (gpgme_tool_t gt, status_t status, ...);
524 _gt_progress_cb (void *opaque, const char *what,
525 int type, int current, int total)
527 gpgme_tool_t gt = opaque;
530 snprintf (buf, sizeof (buf), "0x%02x %i %i", type, current, total);
531 gt_write_status (gt, STATUS_PROGRESS, what, buf);
536 _gt_gpgme_new (gpgme_tool_t gt, gpgme_ctx_t *ctx)
540 err = gpgme_new (ctx);
543 gpgme_set_progress_cb (*ctx, _gt_progress_cb, gt);
549 gt_init (gpgme_tool_t gt)
551 memset (gt, '\0', sizeof (*gt));
554 err = _gt_gpgme_new (gt, >->ctx);
556 log_error (1, err, "can't create gpgme context");
561 gt_signers_add (gpgme_tool_t gt, const char *fpr)
566 err = gpgme_get_key (gt->ctx, fpr, &key, 0);
570 return gpgme_signers_add (gt->ctx, key);
575 gt_signers_clear (gpgme_tool_t gt)
577 gpgme_signers_clear (gt->ctx);
583 gt_get_key (gpgme_tool_t gt, const char *pattern, gpgme_key_t *r_key)
590 if (!gt || !r_key || !pattern)
591 return gpg_error (GPG_ERR_INV_VALUE);
595 err = gpgme_new (&listctx);
600 gpgme_protocol_t proto;
601 gpgme_engine_info_t info;
603 /* Clone the relevant state. */
604 proto = gpgme_get_protocol (ctx);
605 /* The g13 protocol does not allow keylisting, we need to choose
607 if (proto == GPGME_PROTOCOL_G13)
608 proto = GPGME_PROTOCOL_OpenPGP;
610 gpgme_set_protocol (listctx, proto);
611 gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
612 info = gpgme_ctx_get_engine_info (ctx);
613 while (info && info->protocol != proto)
616 gpgme_ctx_set_engine_info (listctx, proto,
617 info->file_name, info->home_dir);
620 err = gpgme_op_keylist_start (listctx, pattern, 0);
622 err = gpgme_op_keylist_next (listctx, r_key);
626 err = gpgme_op_keylist_next (listctx, &key);
627 if (gpgme_err_code (err) == GPG_ERR_EOF)
632 && *r_key && (*r_key)->subkeys && (*r_key)->subkeys->fpr
633 && key && key->subkeys && key->subkeys->fpr
634 && !strcmp ((*r_key)->subkeys->fpr, key->subkeys->fpr))
636 /* The fingerprint is identical. We assume that this is
637 the same key and don't mark it as an ambiguous. This
638 problem may occur with corrupted keyrings and has
639 been noticed often with gpgsm. In fact gpgsm uses a
640 similar hack to sort out such duplicates but it can't
641 do that while listing keys. */
642 gpgme_key_unref (key);
647 gpgme_key_unref (key);
648 err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
650 gpgme_key_unref (*r_key);
653 gpgme_release (listctx);
656 gt_write_status (gt, STATUS_RECIPIENT,
657 ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
658 (*r_key)->subkeys->fpr : "invalid", NULL);
664 gt_recipients_add (gpgme_tool_t gt, const char *pattern)
669 if (gt->recipients_nr >= MAX_RECIPIENTS)
670 return gpg_error_from_errno (ENOMEM);
672 if (gpgme_get_protocol (gt->ctx) == GPGME_PROTOCOL_UISERVER)
673 err = gpgme_key_from_uid (&key, pattern);
675 err = gt_get_key (gt, pattern, &key);
679 gt->recipients[gt->recipients_nr++] = key;
685 gt_recipients_clear (gpgme_tool_t gt)
689 for (idx = 0; idx < gt->recipients_nr; idx++)
690 gpgme_key_unref (gt->recipients[idx]);
691 memset (gt->recipients, '\0', gt->recipients_nr * sizeof (gpgme_key_t));
692 gt->recipients_nr = 0;
697 gt_reset (gpgme_tool_t gt)
702 err = _gt_gpgme_new (gt, &ctx);
706 gpgme_release (gt->ctx);
708 gt_recipients_clear (gt);
714 gt_write_status (gpgme_tool_t gt, status_t status, ...)
723 va_start (ap, status);
726 while ((text = va_arg (ap, const char *)))
733 while (*text && n < sizeof (buf) - 2)
742 err = gt->write_status (gt->write_status_hook, status_string[status], buf);
744 log_error (1, err, "can't write status line");
749 gt_write_data (gpgme_tool_t gt, void *buf, size_t len)
751 return gt->write_data (gt->write_data_hook, buf, len);
756 gt_get_engine_info (gpgme_tool_t gt, gpgme_protocol_t proto)
758 gpgme_engine_info_t info;
759 info = gpgme_ctx_get_engine_info (gt->ctx);
762 if (proto == GPGME_PROTOCOL_UNKNOWN || proto == info->protocol)
763 gt_write_status (gt, STATUS_ENGINE,
764 gpgme_get_protocol_name (info->protocol),
765 info->file_name, info->version,
766 info->req_version, info->home_dir);
774 gt_protocol_from_name (const char *name)
776 if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_OpenPGP)))
777 return GPGME_PROTOCOL_OpenPGP;
778 if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_CMS)))
779 return GPGME_PROTOCOL_CMS;
780 if (! strcasecmp (name,gpgme_get_protocol_name (GPGME_PROTOCOL_GPGCONF)))
781 return GPGME_PROTOCOL_GPGCONF;
782 if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_ASSUAN)))
783 return GPGME_PROTOCOL_ASSUAN;
784 if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_G13)))
785 return GPGME_PROTOCOL_G13;
786 if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_UISERVER)))
787 return GPGME_PROTOCOL_UISERVER;
788 if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_DEFAULT)))
789 return GPGME_PROTOCOL_DEFAULT;
790 return GPGME_PROTOCOL_UNKNOWN;
795 gt_set_protocol (gpgme_tool_t gt, gpgme_protocol_t proto)
797 return gpgme_set_protocol (gt->ctx, proto);
802 gt_get_protocol (gpgme_tool_t gt)
804 gpgme_protocol_t proto = gpgme_get_protocol (gt->ctx);
806 gt_write_status (gt, STATUS_PROTOCOL, gpgme_get_protocol_name (proto),
814 gt_set_sub_protocol (gpgme_tool_t gt, gpgme_protocol_t proto)
816 return gpgme_set_sub_protocol (gt->ctx, proto);
821 gt_get_sub_protocol (gpgme_tool_t gt)
823 gpgme_protocol_t proto = gpgme_get_sub_protocol (gt->ctx);
825 gt_write_status (gt, STATUS_PROTOCOL, gpgme_get_protocol_name (proto),
833 gt_set_armor (gpgme_tool_t gt, int armor)
835 gpgme_set_armor (gt->ctx, armor);
841 gt_get_armor (gpgme_tool_t gt)
843 gt_write_status (gt, STATUS_ARMOR,
844 gpgme_get_armor (gt->ctx) ? "true" : "false", NULL);
851 gt_set_textmode (gpgme_tool_t gt, int textmode)
853 gpgme_set_textmode (gt->ctx, textmode);
859 gt_get_textmode (gpgme_tool_t gt)
861 gt_write_status (gt, STATUS_TEXTMODE,
862 gpgme_get_textmode (gt->ctx) ? "true" : "false", NULL);
869 gt_set_keylist_mode (gpgme_tool_t gt, gpgme_keylist_mode_t keylist_mode)
871 gpgme_set_keylist_mode (gt->ctx, keylist_mode);
877 gt_get_keylist_mode (gpgme_tool_t gt)
879 #define NR_KEYLIST_MODES 6
880 const char *modes[NR_KEYLIST_MODES + 1];
882 gpgme_keylist_mode_t mode = gpgme_get_keylist_mode (gt->ctx);
884 if (mode & GPGME_KEYLIST_MODE_LOCAL)
885 modes[idx++] = "local";
886 if (mode & GPGME_KEYLIST_MODE_EXTERN)
887 modes[idx++] = "extern";
888 if (mode & GPGME_KEYLIST_MODE_SIGS)
889 modes[idx++] = "sigs";
890 if (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS)
891 modes[idx++] = "sig_notations";
892 if (mode & GPGME_KEYLIST_MODE_EPHEMERAL)
893 modes[idx++] = "ephemeral";
894 if (mode & GPGME_KEYLIST_MODE_VALIDATE)
895 modes[idx++] = "validate";
898 gt_write_status (gt, STATUS_KEYLIST_MODE, modes[0], modes[1], modes[2],
899 modes[3], modes[4], modes[5], modes[6]);
906 gt_set_include_certs (gpgme_tool_t gt, int include_certs)
908 gpgme_set_include_certs (gt->ctx, include_certs);
914 gt_get_include_certs (gpgme_tool_t gt)
916 int include_certs = gpgme_get_include_certs (gt->ctx);
919 if (include_certs == GPGME_INCLUDE_CERTS_DEFAULT)
920 strcpy (buf, "default");
922 snprintf (buf, sizeof (buf), "%i", include_certs);
924 gt_write_status (gt, STATUS_INCLUDE_CERTS, buf, NULL);
931 gt_decrypt_verify (gpgme_tool_t gt, gpgme_data_t cipher, gpgme_data_t plain,
935 return gpgme_op_decrypt_verify (gt->ctx, cipher, plain);
937 return gpgme_op_decrypt (gt->ctx, cipher, plain);
942 gt_sign_encrypt (gpgme_tool_t gt, gpgme_encrypt_flags_t flags,
943 gpgme_data_t plain, gpgme_data_t cipher, int sign)
948 err = gpgme_op_encrypt (gt->ctx, gt->recipients, flags, plain, cipher);
950 err = gpgme_op_encrypt_sign (gt->ctx, gt->recipients, flags, plain, cipher);
952 gt_recipients_clear (gt);
959 gt_sign (gpgme_tool_t gt, gpgme_data_t plain, gpgme_data_t sig,
960 gpgme_sig_mode_t mode)
962 return gpgme_op_sign (gt->ctx, plain, sig, mode);
967 gt_verify (gpgme_tool_t gt, gpgme_data_t sig, gpgme_data_t sig_text,
970 return gpgme_op_verify (gt->ctx, sig, sig_text, plain);
975 gt_import (gpgme_tool_t gt, gpgme_data_t data)
977 return gpgme_op_import (gt->ctx, data);
982 gt_export (gpgme_tool_t gt, const char *pattern[], gpgme_export_mode_t mode,
985 return gpgme_op_export_ext (gt->ctx, pattern, mode, data);
990 gt_genkey (gpgme_tool_t gt, const char *parms, gpgme_data_t public,
993 return gpgme_op_genkey (gt->ctx, parms, public, secret);
998 gt_import_keys (gpgme_tool_t gt, char *fpr[])
1010 return gpg_error (GPG_ERR_INV_VALUE);
1012 keys = malloc ((cnt + 1) * sizeof (gpgme_key_t));
1014 return gpg_error_from_syserror ();
1016 for (idx = 0; idx < cnt; idx++)
1018 err = gpgme_get_key (gt->ctx, fpr[idx], &keys[idx], 0);
1025 err = gpgme_op_import_keys (gt->ctx, keys);
1030 gpgme_key_unref (keys[idx]);
1038 gt_delete (gpgme_tool_t gt, char *fpr, int allow_secret)
1043 err = gpgme_get_key (gt->ctx, fpr, &key, 0);
1047 err = gpgme_op_delete (gt->ctx, key, allow_secret);
1048 gpgme_key_unref (key);
1054 gt_keylist_start (gpgme_tool_t gt, const char *pattern[], int secret_only)
1056 return gpgme_op_keylist_ext_start (gt->ctx, pattern, secret_only, 0);
1061 gt_keylist_next (gpgme_tool_t gt, gpgme_key_t *key)
1063 return gpgme_op_keylist_next (gt->ctx, key);
1068 gt_getauditlog (gpgme_tool_t gt, gpgme_data_t output, unsigned int flags)
1070 return gpgme_op_getauditlog (gt->ctx, output, flags);
1075 gt_vfs_mount (gpgme_tool_t gt, const char *container_file,
1076 const char *mount_dir, int flags)
1080 err = gpgme_op_vfs_mount (gt->ctx, container_file, mount_dir, flags, &op_err);
1081 return err ? err : op_err;
1086 gt_vfs_create (gpgme_tool_t gt, const char *container_file, int flags)
1090 err = gpgme_op_vfs_create (gt->ctx, gt->recipients, container_file,
1092 gt_recipients_clear (gt);
1093 return err ? err : op_err;
1098 #define GT_RESULT_ENCRYPT 0x1
1099 #define GT_RESULT_DECRYPT 0x2
1100 #define GT_RESULT_SIGN 0x4
1101 #define GT_RESULT_VERIFY 0x8
1102 #define GT_RESULT_IMPORT 0x10
1103 #define GT_RESULT_GENKEY 0x20
1104 #define GT_RESULT_KEYLIST 0x40
1105 #define GT_RESULT_VFS_MOUNT 0x80
1106 #define GT_RESULT_ALL (~0U)
1109 gt_result (gpgme_tool_t gt, unsigned int flags)
1111 if (flags & GT_RESULT_ENCRYPT)
1113 gpgme_encrypt_result_t res = gpgme_op_encrypt_result (gt->ctx);
1116 gpgme_invalid_key_t invrec = res->invalid_recipients;
1119 gt_write_status (gt, STATUS_ENCRYPT_RESULT, "invalid_recipient",
1120 invrec->fpr, invrec->reason);
1121 invrec = invrec->next;
1125 if (flags & GT_RESULT_VFS_MOUNT)
1127 gpgme_vfs_mount_result_t res = gpgme_op_vfs_mount_result (gt->ctx);
1130 gt_write_data (gt, "vfs_mount\n", 10);
1131 gt_write_data (gt, "mount_dir:", 10);
1132 gt_write_data (gt, res->mount_dir, strlen (res->mount_dir));
1133 gt_write_data (gt, "\n", 1);
1148 assuan_context_t assuan_ctx;
1150 gpgme_data_encoding_t input_enc;
1151 gpgme_data_encoding_t output_enc;
1152 assuan_fd_t message_fd;
1153 gpgme_data_encoding_t message_enc;
1158 server_write_status (void *hook, const char *status, const char *msg)
1160 struct server *server = hook;
1161 return assuan_write_status (server->assuan_ctx, status, msg);
1166 server_write_data (void *hook, const void *buf, size_t len)
1168 struct server *server = hook;
1169 return assuan_send_data (server->assuan_ctx, buf, len);
1173 static gpgme_data_encoding_t
1174 server_data_encoding (const char *line)
1176 if (strstr (line, "--binary"))
1177 return GPGME_DATA_ENCODING_BINARY;
1178 if (strstr (line, "--base64"))
1179 return GPGME_DATA_ENCODING_BASE64;
1180 if (strstr (line, "--armor"))
1181 return GPGME_DATA_ENCODING_ARMOR;
1182 if (strstr (line, "--url"))
1183 return GPGME_DATA_ENCODING_URL;
1184 if (strstr (line, "--urlesc"))
1185 return GPGME_DATA_ENCODING_URLESC;
1186 if (strstr (line, "--url0"))
1187 return GPGME_DATA_ENCODING_URL0;
1188 return GPGME_DATA_ENCODING_NONE;
1192 static gpgme_error_t
1193 server_data_obj (assuan_fd_t fd, gpgme_data_encoding_t encoding,
1198 err = gpgme_data_new_from_fd (data, fd);
1201 return gpgme_data_set_encoding (*data, encoding);
1206 server_reset_fds (struct server *server)
1208 /* assuan closes the input and output FDs for us when doing a RESET,
1209 but we use this same function after commands, so repeat it
1211 assuan_close_input_fd (server->assuan_ctx);
1212 assuan_close_output_fd (server->assuan_ctx);
1213 if (server->message_fd != -1)
1215 /* FIXME: Assuan should provide a close function. */
1216 close (server->message_fd);
1217 server->message_fd = -1;
1219 server->input_enc = GPGME_DATA_ENCODING_NONE;
1220 server->output_enc = GPGME_DATA_ENCODING_NONE;
1221 server->message_enc = GPGME_DATA_ENCODING_NONE;
1226 reset_notify (assuan_context_t ctx, char *line)
1228 struct server *server = assuan_get_pointer (ctx);
1229 server_reset_fds (server);
1230 gt_reset (server->gt);
1234 static const char hlp_version[] =
1235 "VERSION [<string>]\n"
1237 "Call the function gpgme_check_version.";
1239 cmd_version (assuan_context_t ctx, char *line)
1243 const char *version = gpgme_check_version (line);
1244 return version ? 0 : gpg_error (GPG_ERR_SELFTEST_FAILED);
1248 const char *version = gpgme_check_version (NULL);
1249 return assuan_send_data (ctx, version, strlen (version));
1255 cmd_engine (assuan_context_t ctx, char *line)
1257 struct server *server = assuan_get_pointer (ctx);
1258 return gt_get_engine_info (server->gt, gt_protocol_from_name (line));
1262 static const char hlp_protocol[] =
1263 "PROTOCOL [<name>]\n"
1265 "With NAME, set the protocol. Without return the current protocol.";
1267 cmd_protocol (assuan_context_t ctx, char *line)
1269 struct server *server = assuan_get_pointer (ctx);
1271 return gt_set_protocol (server->gt, gt_protocol_from_name (line));
1273 return gt_get_protocol (server->gt);
1278 cmd_sub_protocol (assuan_context_t ctx, char *line)
1280 struct server *server = assuan_get_pointer (ctx);
1282 return gt_set_sub_protocol (server->gt, gt_protocol_from_name (line));
1284 return gt_get_sub_protocol (server->gt);
1289 cmd_armor (assuan_context_t ctx, char *line)
1291 struct server *server = assuan_get_pointer (ctx);
1296 if (! strcasecmp (line, "true") || ! strcasecmp (line, "yes")
1300 return gt_set_armor (server->gt, flag);
1303 return gt_get_armor (server->gt);
1308 cmd_textmode (assuan_context_t ctx, char *line)
1310 struct server *server = assuan_get_pointer (ctx);
1315 if (! strcasecmp (line, "true") || ! strcasecmp (line, "yes")
1319 return gt_set_textmode (server->gt, flag);
1322 return gt_get_textmode (server->gt);
1327 cmd_include_certs (assuan_context_t ctx, char *line)
1329 struct server *server = assuan_get_pointer (ctx);
1333 int include_certs = 0;
1335 if (! strcasecmp (line, "default"))
1336 include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
1338 include_certs = atoi (line);
1340 return gt_set_include_certs (server->gt, include_certs);
1343 return gt_get_include_certs (server->gt);
1348 cmd_keylist_mode (assuan_context_t ctx, char *line)
1350 struct server *server = assuan_get_pointer (ctx);
1354 gpgme_keylist_mode_t mode = 0;
1356 if (strstr (line, "local"))
1357 mode |= GPGME_KEYLIST_MODE_LOCAL;
1358 if (strstr (line, "extern"))
1359 mode |= GPGME_KEYLIST_MODE_EXTERN;
1360 if (strstr (line, "sigs"))
1361 mode |= GPGME_KEYLIST_MODE_SIGS;
1362 if (strstr (line, "sig_notations"))
1363 mode |= GPGME_KEYLIST_MODE_SIG_NOTATIONS;
1364 if (strstr (line, "ephemeral"))
1365 mode |= GPGME_KEYLIST_MODE_EPHEMERAL;
1366 if (strstr (line, "validate"))
1367 mode |= GPGME_KEYLIST_MODE_VALIDATE;
1369 return gt_set_keylist_mode (server->gt, mode);
1372 return gt_get_keylist_mode (server->gt);
1377 input_notify (assuan_context_t ctx, char *line)
1379 struct server *server = assuan_get_pointer (ctx);
1380 server->input_enc = server_data_encoding (line);
1386 output_notify (assuan_context_t ctx, char *line)
1388 struct server *server = assuan_get_pointer (ctx);
1389 server->output_enc = server_data_encoding (line);
1395 cmd_message (assuan_context_t ctx, char *line)
1397 struct server *server = assuan_get_pointer (ctx);
1401 err = assuan_command_parse_fd (ctx, line, &sysfd);
1404 server->message_fd = sysfd;
1405 server->message_enc = server_data_encoding (line);
1411 cmd_recipient (assuan_context_t ctx, char *line)
1413 struct server *server = assuan_get_pointer (ctx);
1415 return gt_recipients_add (server->gt, line);
1420 cmd_signer (assuan_context_t ctx, char *line)
1422 struct server *server = assuan_get_pointer (ctx);
1424 return gt_signers_add (server->gt, line);
1429 cmd_signers_clear (assuan_context_t ctx, char *line)
1431 struct server *server = assuan_get_pointer (ctx);
1433 return gt_signers_clear (server->gt);
1438 _cmd_decrypt_verify (assuan_context_t ctx, char *line, int verify)
1440 struct server *server = assuan_get_pointer (ctx);
1444 gpgme_data_t inp_data;
1445 gpgme_data_t out_data;
1447 inp_fd = assuan_get_input_fd (ctx);
1448 if (inp_fd == ASSUAN_INVALID_FD)
1449 return GPG_ERR_ASS_NO_INPUT;
1450 out_fd = assuan_get_output_fd (ctx);
1451 if (out_fd == ASSUAN_INVALID_FD)
1452 return GPG_ERR_ASS_NO_OUTPUT;
1454 err = server_data_obj (inp_fd, server->input_enc, &inp_data);
1457 err = server_data_obj (out_fd, server->output_enc, &out_data);
1460 gpgme_data_release (inp_data);
1464 err = gt_decrypt_verify (server->gt, inp_data, out_data, verify);
1466 gpgme_data_release (inp_data);
1467 gpgme_data_release (out_data);
1469 server_reset_fds (server);
1476 cmd_decrypt (assuan_context_t ctx, char *line)
1478 return _cmd_decrypt_verify (ctx, line, 0);
1483 cmd_decrypt_verify (assuan_context_t ctx, char *line)
1485 return _cmd_decrypt_verify (ctx, line, 1);
1490 _cmd_sign_encrypt (assuan_context_t ctx, char *line, int sign)
1492 struct server *server = assuan_get_pointer (ctx);
1496 gpgme_data_t inp_data = NULL;
1497 gpgme_data_t out_data = NULL;
1498 gpgme_encrypt_flags_t flags = 0;
1500 if (strstr (line, "--always-trust"))
1501 flags |= GPGME_ENCRYPT_ALWAYS_TRUST;
1502 if (strstr (line, "--no-encrypt-to"))
1503 flags |= GPGME_ENCRYPT_NO_ENCRYPT_TO;
1504 if (strstr (line, "--prepare"))
1505 flags |= GPGME_ENCRYPT_PREPARE;
1506 if (strstr (line, "--expect-sign"))
1507 flags |= GPGME_ENCRYPT_EXPECT_SIGN;
1509 inp_fd = assuan_get_input_fd (ctx);
1510 out_fd = assuan_get_output_fd (ctx);
1511 if (inp_fd != ASSUAN_INVALID_FD)
1513 err = server_data_obj (inp_fd, server->input_enc, &inp_data);
1517 if (out_fd != ASSUAN_INVALID_FD)
1519 err = server_data_obj (out_fd, server->output_enc, &out_data);
1522 gpgme_data_release (inp_data);
1527 err = gt_sign_encrypt (server->gt, flags, inp_data, out_data, sign);
1529 gpgme_data_release (inp_data);
1530 gpgme_data_release (out_data);
1532 server_reset_fds (server);
1539 cmd_encrypt (assuan_context_t ctx, char *line)
1541 return _cmd_sign_encrypt (ctx, line, 0);
1546 cmd_sign_encrypt (assuan_context_t ctx, char *line)
1548 return _cmd_sign_encrypt (ctx, line, 1);
1553 cmd_sign (assuan_context_t ctx, char *line)
1555 struct server *server = assuan_get_pointer (ctx);
1559 gpgme_data_t inp_data;
1560 gpgme_data_t out_data;
1561 gpgme_sig_mode_t mode = GPGME_SIG_MODE_NORMAL;
1563 if (strstr (line, "--clear"))
1564 mode = GPGME_SIG_MODE_CLEAR;
1565 if (strstr (line, "--detach"))
1566 mode = GPGME_SIG_MODE_DETACH;
1568 inp_fd = assuan_get_input_fd (ctx);
1569 if (inp_fd == ASSUAN_INVALID_FD)
1570 return GPG_ERR_ASS_NO_INPUT;
1571 out_fd = assuan_get_output_fd (ctx);
1572 if (out_fd == ASSUAN_INVALID_FD)
1573 return GPG_ERR_ASS_NO_OUTPUT;
1575 err = server_data_obj (inp_fd, server->input_enc, &inp_data);
1578 err = server_data_obj (out_fd, server->output_enc, &out_data);
1581 gpgme_data_release (inp_data);
1585 err = gt_sign (server->gt, inp_data, out_data, mode);
1587 gpgme_data_release (inp_data);
1588 gpgme_data_release (out_data);
1589 server_reset_fds (server);
1596 cmd_verify (assuan_context_t ctx, char *line)
1598 struct server *server = assuan_get_pointer (ctx);
1603 gpgme_data_t inp_data;
1604 gpgme_data_t msg_data = NULL;
1605 gpgme_data_t out_data = NULL;
1607 inp_fd = assuan_get_input_fd (ctx);
1608 if (inp_fd == ASSUAN_INVALID_FD)
1609 return GPG_ERR_ASS_NO_INPUT;
1610 msg_fd = server->message_fd;
1611 out_fd = assuan_get_output_fd (ctx);
1613 err = server_data_obj (inp_fd, server->input_enc, &inp_data);
1616 if (msg_fd != ASSUAN_INVALID_FD)
1618 err = server_data_obj (msg_fd, server->message_enc, &msg_data);
1621 gpgme_data_release (inp_data);
1625 if (out_fd != ASSUAN_INVALID_FD)
1627 err = server_data_obj (out_fd, server->output_enc, &out_data);
1630 gpgme_data_release (inp_data);
1631 gpgme_data_release (msg_data);
1636 err = gt_verify (server->gt, inp_data, msg_data, out_data);
1638 gpgme_data_release (inp_data);
1640 gpgme_data_release (msg_data);
1642 gpgme_data_release (out_data);
1644 server_reset_fds (server);
1651 cmd_import (assuan_context_t ctx, char *line)
1653 struct server *server = assuan_get_pointer (ctx);
1657 char *fprs[2] = { line, NULL };
1659 return gt_import_keys (server->gt, fprs);
1665 gpgme_data_t inp_data;
1667 inp_fd = assuan_get_input_fd (ctx);
1668 if (inp_fd == ASSUAN_INVALID_FD)
1669 return GPG_ERR_ASS_NO_INPUT;
1671 err = server_data_obj (inp_fd, server->input_enc, &inp_data);
1675 err = gt_import (server->gt, inp_data);
1677 gpgme_data_release (inp_data);
1678 server_reset_fds (server);
1686 cmd_export (assuan_context_t ctx, char *line)
1688 struct server *server = assuan_get_pointer (ctx);
1691 gpgme_data_t out_data;
1692 gpgme_export_mode_t mode = 0;
1693 const char *pattern[2];
1694 const char optstr[] = "--extern ";
1696 out_fd = assuan_get_output_fd (ctx);
1697 if (out_fd == ASSUAN_INVALID_FD)
1698 return GPG_ERR_ASS_NO_OUTPUT;
1699 err = server_data_obj (out_fd, server->output_enc, &out_data);
1703 if (strncasecmp (line, optstr, strlen (optstr)))
1705 mode |= GPGME_EXPORT_MODE_EXTERN;
1706 line += strlen (optstr);
1711 err = gt_export (server->gt, pattern, mode, out_data);
1713 gpgme_data_release (out_data);
1714 server_reset_fds (server);
1721 _cmd_genkey_write (gpgme_data_t data, const void *buf, size_t size)
1725 ssize_t writen = gpgme_data_write (data, buf, size);
1726 if (writen < 0 && errno != EAGAIN)
1727 return gpg_error_from_syserror ();
1728 else if (writen > 0)
1730 buf = (void *) (((char *) buf) + writen);
1739 cmd_genkey (assuan_context_t ctx, char *line)
1741 struct server *server = assuan_get_pointer (ctx);
1745 gpgme_data_t inp_data;
1746 gpgme_data_t out_data = NULL;
1747 gpgme_data_t parms_data = NULL;
1750 inp_fd = assuan_get_input_fd (ctx);
1751 if (inp_fd == ASSUAN_INVALID_FD)
1752 return GPG_ERR_ASS_NO_INPUT;
1753 out_fd = assuan_get_output_fd (ctx);
1755 err = server_data_obj (inp_fd, server->input_enc, &inp_data);
1758 if (out_fd != ASSUAN_INVALID_FD)
1760 err = server_data_obj (out_fd, server->output_enc, &out_data);
1763 gpgme_data_release (inp_data);
1768 /* Convert input data. */
1769 err = gpgme_data_new (&parms_data);
1775 ssize_t readn = gpgme_data_read (inp_data, buf, sizeof (buf));
1778 err = gpg_error_from_syserror ();
1781 else if (readn == 0)
1784 err = _cmd_genkey_write (parms_data, buf, readn);
1789 err = _cmd_genkey_write (parms_data, "", 1);
1792 parms = gpgme_data_release_and_get_mem (parms_data, NULL);
1796 err = gpg_error (GPG_ERR_GENERAL);
1800 err = gt_genkey (server->gt, parms, out_data, NULL);
1802 server_reset_fds (server);
1805 gpgme_data_release (inp_data);
1807 gpgme_data_release (out_data);
1809 gpgme_data_release (parms_data);
1816 cmd_delete (assuan_context_t ctx, char *line)
1818 struct server *server = assuan_get_pointer (ctx);
1819 int allow_secret = 0;
1820 const char optstr[] = "--allow-secret ";
1822 if (strncasecmp (line, optstr, strlen (optstr)))
1825 line += strlen (optstr);
1827 return gt_delete (server->gt, line, allow_secret);
1832 cmd_keylist (assuan_context_t ctx, char *line)
1834 struct server *server = assuan_get_pointer (ctx);
1836 int secret_only = 0;
1837 const char *pattern[2];
1838 const char optstr[] = "--secret-only ";
1840 if (strncasecmp (line, optstr, strlen (optstr)))
1843 line += strlen (optstr);
1848 err = gt_keylist_start (server->gt, pattern, secret_only);
1853 err = gt_keylist_next (server->gt, &key);
1854 if (gpg_err_code (err) == GPG_ERR_EOF)
1862 /* FIXME: More data. */
1863 snprintf (buf, sizeof (buf), "key:%s\n", key->subkeys->fpr);
1864 assuan_send_data (ctx, buf, strlen (buf));
1865 gpgme_key_unref (key);
1869 server_reset_fds (server);
1876 cmd_getauditlog (assuan_context_t ctx, char *line)
1878 struct server *server = assuan_get_pointer (ctx);
1881 gpgme_data_t out_data;
1883 out_fd = assuan_get_output_fd (ctx);
1884 if (out_fd == ASSUAN_INVALID_FD)
1885 return GPG_ERR_ASS_NO_OUTPUT;
1886 err = server_data_obj (out_fd, server->output_enc, &out_data);
1890 err = gt_getauditlog (server->gt, out_data, 0);
1892 gpgme_data_release (out_data);
1893 server_reset_fds (server);
1900 cmd_vfs_mount (assuan_context_t ctx, char *line)
1902 struct server *server = assuan_get_pointer (ctx);
1906 mount_dir = strchr (line, ' ');
1909 *(mount_dir++) = '\0';
1910 while (*mount_dir == ' ')
1914 err = gt_vfs_mount (server->gt, line, mount_dir, 0);
1921 cmd_vfs_create (assuan_context_t ctx, char *line)
1923 struct server *server = assuan_get_pointer (ctx);
1927 end = strchr (line, ' ');
1935 err = gt_vfs_create (server->gt, line, 0);
1942 cmd_result (assuan_context_t ctx, char *line)
1944 struct server *server = assuan_get_pointer (ctx);
1945 return gt_result (server->gt, GT_RESULT_ALL);
1949 /* STRERROR <err> */
1951 cmd_strerror (assuan_context_t ctx, char *line)
1957 snprintf (buf, sizeof (buf), "%s <%s>", gpgme_strerror (err),
1958 gpgme_strsource (err));
1959 return assuan_send_data (ctx, buf, strlen (buf));
1964 cmd_pubkey_algo_name (assuan_context_t ctx, char *line)
1966 gpgme_pubkey_algo_t algo;
1970 snprintf (buf, sizeof (buf), "%s", gpgme_pubkey_algo_name (algo));
1971 return assuan_send_data (ctx, buf, strlen (buf));
1976 cmd_hash_algo_name (assuan_context_t ctx, char *line)
1978 gpgme_hash_algo_t algo;
1982 snprintf (buf, sizeof (buf), "%s", gpgme_hash_algo_name (algo));
1983 return assuan_send_data (ctx, buf, strlen (buf));
1987 /* Tell the assuan library about our commands. */
1989 register_commands (assuan_context_t ctx)
1994 assuan_handler_t handler;
1995 const char * const help;
1997 // RESET, BYE are implicit.
1998 { "VERSION", cmd_version, hlp_version },
1999 // TODO: Set engine info.
2000 { "ENGINE", cmd_engine },
2001 { "PROTOCOL", cmd_protocol, hlp_protocol },
2002 { "SUB_PROTOCOL", cmd_sub_protocol },
2003 { "ARMOR", cmd_armor },
2004 { "TEXTMODE", cmd_textmode },
2005 { "INCLUDE_CERTS", cmd_include_certs },
2006 { "KEYLIST_MODE", cmd_keylist_mode },
2009 { "MESSAGE", cmd_message },
2010 { "RECIPIENT", cmd_recipient },
2011 { "SIGNER", cmd_signer },
2012 { "SIGNERS_CLEAR", cmd_signers_clear },
2013 // TODO: SIGNOTATION missing.
2014 // TODO: Could add wait interface if we allow more than one context
2015 // and add _START variants.
2016 // TODO: Could add data interfaces if we allow multiple data objects.
2017 { "DECRYPT", cmd_decrypt },
2018 { "DECRYPT_VERIFY", cmd_decrypt_verify },
2019 { "ENCRYPT", cmd_encrypt },
2020 { "ENCRYPT_SIGN", cmd_sign_encrypt },
2021 { "SIGN_ENCRYPT", cmd_sign_encrypt },
2022 { "SIGN", cmd_sign },
2023 { "VERIFY", cmd_verify },
2024 { "IMPORT", cmd_import },
2025 { "EXPORT", cmd_export },
2026 { "GENKEY", cmd_genkey },
2027 { "DELETE", cmd_delete },
2028 // TODO: EDIT, CARD_EDIT (with INQUIRE)
2029 { "KEYLIST", cmd_keylist },
2030 { "LISTKEYS", cmd_keylist },
2031 // TODO: TRUSTLIST, TRUSTLIST_EXT
2032 { "GETAUDITLOG", cmd_getauditlog },
2034 { "VFS_MOUNT", cmd_vfs_mount },
2035 { "MOUNT", cmd_vfs_mount },
2036 { "VFS_CREATE", cmd_vfs_create },
2037 { "CREATE", cmd_vfs_create },
2039 { "RESULT", cmd_result },
2040 { "STRERROR", cmd_strerror },
2041 { "PUBKEY_ALGO_NAME", cmd_pubkey_algo_name },
2042 { "HASH_ALGO_NAME", cmd_hash_algo_name },
2047 for (idx = 0; table[idx].name; idx++)
2049 err = assuan_register_command (ctx, table[idx].name, table[idx].handler,
2058 /* TODO: password callback can do INQUIRE. */
2060 gpgme_server (gpgme_tool_t gt)
2063 assuan_fd_t filedes[2];
2064 struct server server;
2065 static const char hello[] = ("GPGME-Tool " VERSION " ready");
2067 memset (&server, 0, sizeof (server));
2068 server.message_fd = -1;
2069 server.input_enc = GPGME_DATA_ENCODING_NONE;
2070 server.output_enc = GPGME_DATA_ENCODING_NONE;
2071 server.message_enc = GPGME_DATA_ENCODING_NONE;
2074 gt->write_status = server_write_status;
2075 gt->write_status_hook = &server;
2076 gt->write_data = server_write_data;
2077 gt->write_data_hook = &server;
2079 /* We use a pipe based server so that we can work from scripts.
2080 assuan_init_pipe_server will automagically detect when we are
2081 called with a socketpair and ignore FIELDES in this case. */
2082 filedes[0] = assuan_fdopen (0);
2083 filedes[1] = assuan_fdopen (1);
2084 err = assuan_new (&server.assuan_ctx);
2086 log_error (1, err, "can't create assuan context");
2088 assuan_set_pointer (server.assuan_ctx, &server);
2090 err = assuan_init_pipe_server (server.assuan_ctx, filedes);
2092 log_error (1, err, "can't initialize assuan server");
2093 err = register_commands (server.assuan_ctx);
2095 log_error (1, err, "can't register assuan commands");
2096 assuan_set_hello_line (server.assuan_ctx, hello);
2098 assuan_register_reset_notify (server.assuan_ctx, reset_notify);
2099 assuan_register_input_notify (server.assuan_ctx, input_notify);
2100 assuan_register_output_notify (server.assuan_ctx, output_notify);
2102 #define DBG_ASSUAN 0
2104 assuan_set_log_stream (server.assuan_ctx, log_stream);
2108 err = assuan_accept (server.assuan_ctx);
2113 log_error (0, err, "assuan accept problem");
2117 err = assuan_process (server.assuan_ctx);
2119 log_error (0, err, "assuan processing failed");
2122 assuan_release (server.assuan_ctx);
2127 /* MAIN PROGRAM STARTS HERE. */
2129 const char *argp_program_version = VERSION;
2130 const char *argp_program_bug_address = "bug-gpgme@gnupg.org";
2131 error_t argp_err_exit_status = 1;
2133 static char doc[] = "GPGME Tool -- invoke GPGME operations";
2134 static char args_doc[] = "COMMAND [OPTIONS...]";
2136 static struct argp_option options[] = {
2137 { "server", 's', 0, 0, "Server mode" },
2141 static error_t parse_options (int key, char *arg, struct argp_state *state);
2142 static struct argp argp = { options, parse_options, args_doc, doc };
2146 enum { CMD_DEFAULT, CMD_SERVER } cmd;
2150 args_init (struct args *args)
2152 memset (args, '\0', sizeof (*args));
2153 args->cmd = CMD_DEFAULT;
2158 parse_options (int key, char *arg, struct argp_state *state)
2160 struct args *args = state->input;
2165 args->cmd = CMD_SERVER;
2169 if (state->arg_num >= 2)
2171 printf ("Arg[%i] = %s\n", state->arg_num, arg);
2174 if (state->arg_num < 2)
2180 return ARGP_ERR_UNKNOWN;
2187 main (int argc, char *argv[])
2190 struct gpgme_tool gt;
2192 setlocale (LC_ALL, "");
2193 gpgme_check_version (NULL);
2194 gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
2196 gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
2200 argp_parse (&argp, argc, argv, 0, 0, &args);
2213 gpgme_release (gt.ctx);