1 /* import.c - Import a key.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003 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 General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (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 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GPGME; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
35 struct _gpgme_op_import_result result;
37 /* A pointer to the next pointer of the last import status in the
38 list. This makes appending new imports painless while preserving
40 gpgme_import_status_t *lastp;
45 release_op_data (void *hook)
47 op_data_t opd = (op_data_t) hook;
48 gpgme_import_status_t import = opd->result.imports;
52 gpgme_import_status_t next = import->next;
61 gpgme_op_import_result (gpgme_ctx_t ctx)
67 err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL);
77 parse_import (char *args, gpgme_import_status_t *import_status, int problem)
79 gpgme_import_status_t import;
83 import = malloc (sizeof (*import));
85 return gpg_error_from_errno (errno);
89 nr = strtol (args, &tail, 0);
90 if (errno || args == tail || *tail != ' ')
92 /* The crypto backend does not behave. */
94 return gpg_error (GPG_ERR_INV_ENGINE);
105 import->result = gpg_error (GPG_ERR_GENERAL);
109 import->result = gpg_error (GPG_ERR_BAD_CERT);
113 import->result = gpg_error (GPG_ERR_MISSING_CERT);
117 import->result = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
124 import->result = gpg_error (GPG_ERR_NO_ERROR);
130 tail = strchr (args, ' ');
134 import->fpr = strdup (args);
137 int saved_errno = errno;
139 return gpg_error_from_errno (saved_errno);
142 *import_status = import;
149 parse_import_res (char *args, gpgme_import_result_t result)
155 #define PARSE_NEXT(x) \
156 (x) = strtol (args, &tail, 0); \
157 if (errno || args == tail || *tail != ' ') \
158 /* The crypto backend does not behave. */ \
159 return gpg_error (GPG_ERR_INV_ENGINE); \
162 PARSE_NEXT (result->considered);
163 PARSE_NEXT (result->no_user_id);
164 PARSE_NEXT (result->imported);
165 PARSE_NEXT (result->imported_rsa);
166 PARSE_NEXT (result->unchanged);
167 PARSE_NEXT (result->new_user_ids);
168 PARSE_NEXT (result->new_sub_keys);
169 PARSE_NEXT (result->new_signatures);
170 PARSE_NEXT (result->new_revocations);
171 PARSE_NEXT (result->secret_read);
172 PARSE_NEXT (result->secret_imported);
173 PARSE_NEXT (result->secret_unchanged);
174 PARSE_NEXT (result->skipped_new_keys);
175 PARSE_NEXT (result->not_imported);
182 import_status_handler (void *priv, gpgme_status_code_t code, char *args)
184 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
189 err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL);
196 case GPGME_STATUS_IMPORT_OK:
197 case GPGME_STATUS_IMPORT_PROBLEM:
198 err = parse_import (args, opd->lastp,
199 code == GPGME_STATUS_IMPORT_OK ? 0 : 1);
203 opd->lastp = &(*opd->lastp)->next;
206 case GPGME_STATUS_IMPORT_RES:
207 err = parse_import_res (args, &opd->result);
218 _gpgme_op_import_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t keydata)
224 err = _gpgme_op_reset (ctx, synchronous);
228 err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook,
229 sizeof (*opd), release_op_data);
233 opd->lastp = &opd->result.imports;
236 return gpg_error (GPG_ERR_NO_DATA);
238 _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
240 return _gpgme_engine_op_import (ctx->engine, keydata);
245 gpgme_op_import_start (gpgme_ctx_t ctx, gpgme_data_t keydata)
247 return _gpgme_op_import_start (ctx, 0, keydata);
251 /* Import the key in KEYDATA into the keyring. */
253 gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata)
255 gpgme_error_t err = _gpgme_op_import_start (ctx, 1, keydata);
257 err = _gpgme_wait_one (ctx);
263 gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata, int *nr)
265 gpgme_error_t err = gpgme_op_import (ctx, keydata);
268 gpgme_import_result_t result = gpgme_op_import_result (ctx);
269 *nr = result->considered;