core: Prepare for new key listing data send by gpg.
[gpgme.git] / tests / run-export.c
1 /* pgp-export.c  - Helper to run an export command
2    Copyright (C) 2008, 2009 g10 Code GmbH
3
4    This file is part of GPGME.
5
6    GPGME is free software; you can redistribute it and/or modify it
7    under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation; either version 2.1 of
9    the License, or (at your option) any later version.
10
11    GPGME is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this program; if not, see <https://www.gnu.org/licenses/>.
18 */
19
20 /* We need to include config.h so that we know whether we are building
21    with large file system (LFS) support. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include <gpgme.h>
31
32 #define PGM "run-export"
33
34 #include "run-support.h"
35
36
37 static int verbose;
38
39
40 static int
41 show_usage (int ex)
42 {
43   fputs ("usage: " PGM " [options] USERIDS\n\n"
44          "Options:\n"
45          "  --verbose        run in verbose mode\n"
46          "  --openpgp        use OpenPGP protocol (default)\n"
47          "  --cms            use X.509 protocol\n"
48          "  --extern         send keys to the keyserver (TAKE CARE!)\n"
49          "  --secret         export secret keys instead of public keys\n"
50          "  --raw            use PKCS#1 as secret key format\n"
51          "  --pkcs12         use PKCS#12 as secret key format\n"
52          , stderr);
53   exit (ex);
54 }
55
56 int
57 main (int argc, char **argv)
58 {
59   int last_argc = -1;
60   gpgme_error_t err;
61   gpgme_ctx_t ctx;
62   gpgme_key_t key;
63   gpgme_keylist_result_t result;
64   gpgme_key_t keyarray[100];
65   int keyidx = 0;
66   gpgme_data_t out;
67   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
68   gpgme_export_mode_t mode = 0;
69
70   if (argc)
71     { argc--; argv++; }
72
73   while (argc && last_argc != argc )
74     {
75       last_argc = argc;
76       if (!strcmp (*argv, "--"))
77         {
78           argc--; argv++;
79           break;
80         }
81       else if (!strcmp (*argv, "--help"))
82         show_usage (0);
83       else if (!strcmp (*argv, "--verbose"))
84         {
85           verbose = 1;
86           argc--; argv++;
87         }
88       else if (!strcmp (*argv, "--openpgp"))
89         {
90           protocol = GPGME_PROTOCOL_OpenPGP;
91           argc--; argv++;
92         }
93       else if (!strcmp (*argv, "--cms"))
94         {
95           protocol = GPGME_PROTOCOL_CMS;
96           argc--; argv++;
97         }
98       else if (!strcmp (*argv, "--extern"))
99         {
100           mode |= GPGME_EXPORT_MODE_EXTERN;
101           argc--; argv++;
102         }
103       else if (!strcmp (*argv, "--secret"))
104         {
105           mode |= GPGME_EXPORT_MODE_SECRET;
106           argc--; argv++;
107         }
108       else if (!strcmp (*argv, "--raw"))
109         {
110           mode |= GPGME_EXPORT_MODE_RAW;
111           argc--; argv++;
112         }
113       else if (!strcmp (*argv, "--pkcs12"))
114         {
115           mode |= GPGME_EXPORT_MODE_PKCS12;
116           argc--; argv++;
117         }
118       else if (!strncmp (*argv, "--", 2))
119         show_usage (1);
120
121     }
122
123   if (!argc)
124     show_usage (1);
125
126   init_gpgme (protocol);
127
128   err = gpgme_new (&ctx);
129   fail_if_err (err);
130   gpgme_set_protocol (ctx, protocol);
131
132   /* Lookup the keys.  */
133   err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0);
134   fail_if_err (err);
135
136   while (!(err = gpgme_op_keylist_next (ctx, &key)))
137     {
138       printf ("keyid: %s  (fpr: %s)\n",
139               key->subkeys?nonnull (key->subkeys->keyid):"?",
140               key->subkeys?nonnull (key->subkeys->fpr):"?");
141
142       if (keyidx < DIM (keyarray)-1)
143         keyarray[keyidx++] = key;
144       else
145         {
146           fprintf (stderr, PGM": too many keys"
147                    "- skipping this key\n");
148           gpgme_key_unref (key);
149         }
150     }
151   if (gpgme_err_code (err) != GPG_ERR_EOF)
152     fail_if_err (err);
153   err = gpgme_op_keylist_end (ctx);
154   fail_if_err (err);
155   keyarray[keyidx] = NULL;
156
157   result = gpgme_op_keylist_result (ctx);
158   if (result->truncated)
159     {
160       fprintf (stderr, PGM ": key listing unexpectedly truncated\n");
161       exit (1);
162     }
163
164   /* Now for the actual export.  */
165   if ((mode & GPGME_EXPORT_MODE_EXTERN))
166     printf ("sending keys to keyserver\n");
167   if ((mode & GPGME_EXPORT_MODE_SECRET))
168     printf ("exporting secret keys!\n");
169
170   err = gpgme_data_new (&out);
171   fail_if_err (err);
172
173   gpgme_set_armor (ctx, 1);
174   err = gpgme_op_export_keys (ctx, keyarray, mode,
175                               (mode & GPGME_KEYLIST_MODE_EXTERN)? NULL:out);
176   fail_if_err (err);
177
178   fflush (NULL);
179   if (!(mode & GPGME_KEYLIST_MODE_EXTERN))
180     {
181       fputs ("Begin Result:\n", stdout);
182       print_data (out);
183       fputs ("End Result.\n", stdout);
184     }
185
186   /* Cleanup.  */
187   gpgme_data_release (out);
188
189   for (keyidx=0; keyarray[keyidx]; keyidx++)
190     gpgme_key_unref (keyarray[keyidx]);
191
192   gpgme_release (ctx);
193   return 0;
194 }