X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/key-data.c?ds=sidebyside diff --git a/key-data.c b/key-data.c deleted file mode 100644 index 69795fe6..00000000 --- a/key-data.c +++ /dev/null @@ -1,469 +0,0 @@ -/* -*-c-*- - * - * $Id$ - * - * Encoding and decoding of key data - * - * (c) 1999 Straylight/Edgeware - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of Catacomb. - * - * Catacomb is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Catacomb is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with Catacomb; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "key-data.h" -#include "mp.h" -#include "mptext.h" - -/*----- Reference counting stuff ------------------------------------------*/ - -/* --- @key_incref@ --- * - * - * Arguments: @key_data *k@ = pointer to key data - * - * Returns: --- - * - * Use: Increments the refcount on a key data block. - */ - -void key_incref(key_data *k) { KEY_INCREF(k); } - -/* --- @key_destroy@ --- * - * - * Arguments: @key_data *k@ = pointer to key data to destroy - * - * Returns: --- - * - * Use: Destroys a block of key data, regardless of reference count. - * Don't use this unless you know what you're doing. - */ - -void key_destroy(key_data *k) -{ - switch (k->e & KF_ENCMASK) { - case KENC_BINARY: - case KENC_ENCRYPT: - if (k->u.k.k) { - if (k->e & KF_BURN) - memset(k->u.k.k, 0, k->u.k.sz); - sub_free(k->u.k.k, k->u.k.sz); - } - break; - case KENC_MP: - mp_drop(k->u.m); - break; - case KENC_STRING: - xfree(k->u.p); - break; - case KENC_EC: - EC_DESTROY(&k->u.e); - break; - case KENC_STRUCT: { - key_data *kd; - key_subkeyiter i; - - for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, 0, &kd); ) - KEY_DROP(kd); - sym_destroy(&k->u.s); - } break; - default: - abort(); - } - DESTROY(k); -} - -/* --- @key_drop@ --- * - * - * Arguments: @key_data *k@ = pointer to key data to destroy - * - * Returns: --- - * - * Use: Drops a reference to key data, destroying it if necessary. - */ - -void key_drop(key_data *k) { KEY_DROP(k); } - -/* --- @key_split@ --- * - * - * Arguments: @key_data **kk@ = address of pointer to key data block - * - * Returns: --- - * - * Use: Replaces @*kk@ with a pointer to the same key data, but with - * just one reference. - */ - -void key_split(key_data **kk) -{ - key_data *k = *kk; - - if (k->ref == 1) - return; - switch (k->e & KF_ENCMASK) { - case KENC_BINARY: - *kk = key_newbinary(k->e, k->u.k.k, k->u.k.sz); - break; - case KENC_ENCRYPT: - *kk = key_newencrypted(k->e, k->u.k.k, k->u.k.sz); - break; - case KENC_MP: - *kk = key_newmp(k->e, k->u.m); - break; - case KENC_STRING: - *kk = key_newstring(k->e, k->u.p); - break; - case KENC_EC: - *kk = key_newec(k->e, &k->u.e); - break; - case KENC_STRUCT: { - key_subkeyiter i; - const char *tag; - key_data *kd; - - *kk = key_newstruct(); - for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) - key_structset(*kk, tag, kd); - } break; - default: - abort(); - } -} - -/*----- Setting new values ------------------------------------------------*/ - -/* --- @key_newraw@ --- * - * - * Arguments: @unsigned e@ = encoding type to set - * - * Returns: New key block, not filled in. - */ - -key_data *key_newraw(unsigned e) -{ - key_data *k = CREATE(key_data); - k->e = e; - k->ref = 1; - return (k); -} - -/* --- @key_newbinary@ --- * - * - * Arguments: @unsigned e@ = other encoding flags - * @const void *p@ = pointer to key data - * @size_t sz@ = size of the key data - * - * Returns: New key data object. - */ - -key_data *key_newbinary(unsigned e, const void *p, size_t sz) -{ - key_data *k = key_newraw(KENC_BINARY | e); - k->u.k.k = sub_alloc(sz); - memcpy(k->u.k.k, p, sz); - k->u.k.sz = sz; - return (k); -} - -/* --- @key_newencrypted@ --- * - * - * Arguments: @unsigned e@ = other encoding flags - * @const void *p@ = pointer to key data - * @size_t sz@ = size of the key data - * - * Returns: New key data object. - */ - -key_data *key_newencrypted(unsigned e, const void *p, size_t sz) -{ - key_data *k = key_newraw(KENC_ENCRYPT | e); - k->u.k.k = sub_alloc(sz); - memcpy(k->u.k.k, p, sz); - k->u.k.sz = sz; - return (k); -} - -/* --- @key_newmp@ --- * - * - * Arguments: @unsigned e@ = other encoding flags - * @mp *m@ = pointer to the value to set - * - * Returns: New key data object. - */ - -key_data *key_newmp(unsigned e, mp *m) -{ - key_data *k = key_newraw(KENC_MP | e); - k->u.m = MP_COPY(m); - return (k); -} - -/* --- @key_newstring@ --- * - * - * Arguments: @unsigned e@ = other encoding flags - * @const char *p@ = pointer to the value to set - * - * Returns: New key data object. - */ - -key_data *key_newstring(unsigned e, const char *p) -{ - key_data *k = key_newraw(KENC_STRING | e); - k->u.p = xstrdup(p); - return (k); -} - -/* --- @key_newec@ --- * - * - * Arguments: @unsigned e@ = other encoding flags - * @const ec *pt@ = pointer to the value to set - * - * Returns: New key data object. - */ - -key_data *key_newec(unsigned e, const ec *pt) -{ - key_data *k = key_newraw(KENC_EC | e); - EC_CREATE(&k->u.e); - EC_COPY(&k->u.e, pt); - return (k); -} - -/* --- @key_newstruct@ --- * - * - * Arguments: --- - * - * Returns: New key data object. - */ - -key_data *key_newstruct(void) -{ - key_data *k = key_newraw(KENC_STRUCT); - sym_create(&k->u.s); - return (k); -} - -/* --- @key_structfind@ --- * - * - * Arguments: @key_data *k@ = pointer to key data block - * @const char *tag@ = pointer to tag string - * - * Returns: Pointer to key data block, or null. - * - * Use: Looks up the tag in a structured key. - */ - -key_data *key_structfind(key_data *k, const char *tag) -{ - key_struct *ks; - assert(((void)"Key is not structured", - (k->e & KF_ENCMASK) == KENC_STRUCT)); - ks = sym_find(&k->u.s, tag, -1, 0, 0); - if (!ks) - return (0); - return (ks->k); -} - -/* --- @key_mksubkeyiter@ --- * - * - * Arguments: @key_subkeyiter *i@ = pointer to iterator block - * @key_data *k@ = pointer to key data block - * - * Returns: --- - * - * Use: Initializes a subkey iterator. - */ - -void key_mksubkeyiter(key_subkeyiter *i, key_data *k) -{ - assert(((void)"Key is not structured", - (k->e & KF_ENCMASK) == KENC_STRUCT)); - sym_mkiter(&i->i, &k->u.s); -} - -/* --- @key_nextsubkey@ --- * - * - * Arguments: @key_structiter *i@ = pointer to iterator block - * @const char **tag@ = where to put the tag pointer, or null - * @key_data **kd@ = where to put the key data pointer, or null - * - * Returns: Nonzero if there was another item, zero if we hit the - * end-stop. - * - * Use: Collects the next subkey of a structured key. - */ - -int key_nextsubkey(key_subkeyiter *i, const char **tag, key_data **kd) -{ - key_struct *ks; - - if ((ks = sym_next(&i->i)) == 0) - return (0); - if (tag) *tag = SYM_NAME(ks); - if (kd) *kd = ks->k; - return (1); -} - -/* --- @key_structset@, @key_structsteal@ --- * - * - * Arguments: @key_data *k@ = pointer to key data block - * @const char *tag@ = pointer to tag string - * @key_data *kd@ = new key data to store - * - * Returns: --- - * - * Use: Creates a new subkey. Stealing doesn't affect @kd@'s - * refcount. If @kd@ is null, the subkey is deleted. - */ - -static void structset(key_data *k, int stealp, - const char *tag, key_data *kd) -{ - key_struct *ks; - unsigned f; - - assert(((void)"Key is not structured", k->e == KENC_STRUCT)); - assert(((void)"Key has multiple references", k->ref == 1)); - if (!kd) { - ks = sym_find(&k->u.s, tag, -1, 0, 0); - if (ks) sym_remove(&k->u.s, ks); - } else { - ks = sym_find(&k->u.s, tag, -1, sizeof(*ks), &f); - if (f) - key_drop(ks->k); - if (!stealp) KEY_INCREF(kd); - ks->k = kd; - } -} - -void key_structset(key_data *k, const char *tag, key_data *kd) - { structset(k, 0, tag, kd); } -void key_structsteal(key_data *k, const char *tag, key_data *kd) - { structset(k, 1, tag, kd); } - -/*----- Miscellaneous operations ------------------------------------------*/ - -/* --- @key_do@ --- * - * - * Arguments: @key_data *k@ = pointer to key data block - * @const key_filter *kf@ = pointer to filter block - * @dstr *d@ = pointer to base string - * @int (*func)(key_data *kd, dstr *d, void *p@ = function - * @void *p@ = argument to function - * - * Returns: Nonzero return code from function, or zero. - * - * Use: Runs a function over all the leaves of a key. - */ - -int key_do(key_data *k, const key_filter *kf, dstr *d, - int (*func)(key_data */*kd*/, dstr */*d*/, void */*p*/), - void *p) -{ - if (!KEY_MATCH(k, kf)) - return (0); - if ((k->e & KF_ENCMASK) != KENC_STRUCT) - return (func(k, d, p)); - else { - key_subkeyiter i; - const char *tag; - size_t n = 0; - int rc; - - if (d) - n = d->len; - for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &k); ) { - if (d) { - d->len = n; - dstr_putf(d, ".%s", tag); - } - if ((rc = key_do(k, kf, d, func, p)) != 0) - return (rc); - } - return (0); - } -} - -/* --- @key_copydata@ --- * - * - * Arguments: @key_data *k@ = key data to copy - * @const key_filter *kf@ = pointer to filter block - * - * Returns: Pointer to a copy of the data, or null if the root subkey - * didn't match the filter. - * - * Use: Copies a chunk of key data. Subkeys, whether they're - * structured or leaves, which don't match the filter aren't - * copied. The copy may or may not have structure in common - * with the original. - */ - -static int structmatchp(key_data *k, const key_filter *kf) -{ - key_subkeyiter i; - - if (!KEY_MATCH(k, kf)) return (0); - else if ((k->e & KF_ENCMASK) == KENC_STRUCT) return (1); - else { - for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, 0, &k); ) - if (!structmatchp(k, kf)) return (0); - return (1); - } -} - -key_data *key_copydata(key_data *k, const key_filter *kf) -{ - key_subkeyiter i; - const char *tag; - key_data *kd, *kkd; - - /* --- Trivial cases --- */ - - if (!KEY_MATCH(k, kf)) - return (0); - else if (structmatchp(k, kf)) { - key_incref(k); - return (k); - } - - /* --- Copy a structured key recursively --- */ - - kkd = key_newstruct(); - for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) { - if ((kd = key_copydata(kd, kf)) != 0) - key_structsteal(kkd, tag, kd); - } - - /* --- Done --- */ - - return (kkd); -} - -/*----- That's all, folks -------------------------------------------------*/