Module Name: src Committed By: agc Date: Mon Jul 26 06:37:35 UTC 2010
Modified Files: src/crypto/external/bsd/netpgp/dist/src/lib: keyring.h packet-print.c Added Files: src/crypto/external/bsd/netpgp/dist/src/lib: mj.c mj.h Log Message: add a minimalist JSON implementation, and add a new function to access the data, and serialise it using JSON. To generate a diff of this commit: cvs rdiff -u -r1.27 -r1.28 \ src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h cvs rdiff -u -r0 -r1.1 src/crypto/external/bsd/netpgp/dist/src/lib/mj.c \ src/crypto/external/bsd/netpgp/dist/src/lib/mj.h cvs rdiff -u -r1.33 -r1.34 \ src/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h diff -u src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.27 src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.28 --- src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h:1.27 Fri Jun 25 03:37:27 2010 +++ src/crypto/external/bsd/netpgp/dist/src/lib/keyring.h Mon Jul 26 06:37:35 2010 @@ -55,6 +55,7 @@ #include "packet.h" #include "packet-parse.h" +#include "mj.h" enum { MAX_ID_LENGTH = 128, @@ -118,6 +119,9 @@ int __ops_sprint_keydata(__ops_io_t *, const __ops_keyring_t *, const __ops_key_t *, char **, const char *, const __ops_pubkey_t *, const int); +int __ops_sprint_mj(__ops_io_t *, const __ops_keyring_t *, + const __ops_key_t *, char **, const char *, + const __ops_pubkey_t *, const int); int __ops_hkp_sprint_keydata(__ops_io_t *, const __ops_keyring_t *, const __ops_key_t *, char **, const __ops_pubkey_t *, const int); Index: src/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c diff -u src/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c:1.33 src/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c:1.34 --- src/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c:1.33 Fri Jul 9 05:35:34 2010 +++ src/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c Mon Jul 26 06:37:35 2010 @@ -58,7 +58,7 @@ #if defined(__NetBSD__) __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); -__RCSID("$NetBSD: packet-print.c,v 1.33 2010/07/09 05:35:34 agc Exp $"); +__RCSID("$NetBSD: packet-print.c,v 1.34 2010/07/26 06:37:35 agc Exp $"); #endif #include <string.h> @@ -77,6 +77,7 @@ #include "netpgpsdk.h" #include "packet.h" #include "netpgpdigest.h" +#include "mj.h" /* static functions */ @@ -361,7 +362,7 @@ /* print the sub key binding signature info */ static int -psubkeybinding(char *buf, size_t size, __ops_subsig_t *subsig, const __ops_pubkey_t *pubkey, char *expired) +psubkeybinding(char *buf, size_t size, __ops_subsig_t *subsig, const __ops_pubkey_t *pubkey, const char *expired) { char keyid[512]; char t[32]; @@ -473,6 +474,110 @@ } int +__ops_sprint_mj(__ops_io_t *io, const __ops_keyring_t *keyring, + const __ops_key_t *key, char **buf, const char *header, + const __ops_pubkey_t *pubkey, const int psigs) +{ + const __ops_key_t *trustkey; + unsigned from; + unsigned i; + unsigned j; + time_t now; + mj_t expired_obj; + mj_t uids_array; + mj_t sig_array; + mj_t sig_obj; + mj_t key_obj; + char uidbuf[KB(64)]; + char keyid[OPS_KEY_ID_SIZE * 3]; + char fp[(OPS_FINGERPRINT_SIZE * 3) + 1]; + int r; + + if (key == NULL || key->revoked) { + return -1; + } + (void) memset(uidbuf, 0x0, sizeof(uidbuf)); + (void) memset(&key_obj, 0x0, sizeof(key_obj)); + mj_create(&key_obj, "object"); + mj_append_field(&key_obj, "header", "string", header); + mj_append_field(&key_obj, "key bits", "integer", (int64_t) numkeybits(pubkey)); + mj_append_field(&key_obj, "pka", "string", __ops_show_pka(pubkey->alg)); + mj_append_field(&key_obj, "key id", "string", strhexdump(keyid, key->key_id, OPS_KEY_ID_SIZE, "")); + mj_append(&key_obj, "fingerprint", "string", + strhexdump(fp, key->fingerprint.fingerprint, key->fingerprint.length, " ")); + now = time(NULL); + mj_append_field(&key_obj, "birthtime", "integer", pubkey->birthtime); + mj_append_field(&key_obj, "duration", "integer", pubkey->duration); + if (pubkey->duration > 0) { + (void) memset(&expired_obj, 0x0, sizeof(expired_obj)); + mj_append_field(&expired_obj, "expiry status", "string", + (pubkey->birthtime + pubkey->duration < now) ? "[EXPIRED]" : "[EXPIRES]"); + mj_append_field(&expired_obj, "expiry", "integer", + (int64_t)(pubkey->birthtime + pubkey->duration)); + mj_append_field(&key_obj, "expiration", "object", &expired_obj); + } + (void) memset(&uids_array, 0x0, sizeof(uids_array)); + mj_create(&uids_array, "array"); + for (i = 0; i < key->uidc; i++) { + if ((r = isrevoked(key, i)) >= 0 && + key->revokes[r].code == OPS_REVOCATION_COMPROMISED) { + continue; + } + mj_append(&uids_array, "string", key->uids[i]); + mj_append(&uids_array, "integer", r); + (void) memset(&sig_array, 0x0, sizeof(sig_array)); + mj_create(&sig_array, "array"); + for (j = 0 ; j < key->subsigc ; j++) { + (void) memset(&sig_obj, 0x0, sizeof(sig_obj)); + mj_create(&sig_obj, "object"); + if (psigs) { + if (key->subsigs[j].uid != i) { + continue; + } + } else { + if (!(key->subsigs[j].sig.info.version == 4 && + key->subsigs[j].sig.info.type == OPS_SIG_SUBKEY && + i == key->uidc - 1)) { + continue; + } + } + mj_append_field(&sig_obj, "pgp version", "integer", (int64_t)key->subsigs[j].sig.info.version); + if (key->subsigs[j].sig.info.version == 4 && + key->subsigs[j].sig.info.type == OPS_SIG_SUBKEY) { + mj_append_field(&sig_obj, "header", "string", "sub"); + mj_append_field(&sig_obj, "key size", "integer", (int64_t)numkeybits(pubkey)); + mj_append_field(&sig_obj, "pka", "string", + (const char *)__ops_show_pka(key->subsigs[j].sig.info.key_alg)); + mj_append_field(&sig_obj, "signer", "string", + strhexdump(keyid, key->subsigs[j].sig.info.signer_id, OPS_KEY_ID_SIZE, "")); + mj_append_field(&sig_obj, "signtime", "integer", + (int64_t)key->subsigs[j].sig.info.birthtime); + } else { + mj_append_field(&sig_obj, "signer", "string", + strhexdump(keyid, key->subsigs[j].sig.info.signer_id, OPS_KEY_ID_SIZE, "")); + mj_append_field(&sig_obj, "signtime", "integer", + (int64_t)(key->subsigs[j].sig.info.birthtime)); + from = 0; + trustkey = __ops_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from); + mj_append_field(&sig_obj, "trustkey", "string", + (trustkey) ? (char *)trustkey->uids[trustkey->uid0] : "[unknown]"); + } + mj_append(&sig_array, "object", &sig_obj); + mj_delete(&sig_obj); + } + if (mj_arraycount(&sig_array) > 0) { + mj_append(&uids_array, "array", &sig_array); + } + mj_delete(&sig_array); + } + mj_append_field(&key_obj, "uids", "array", &uids_array); + mj_delete(&uids_array); + mj_asprint(buf, &key_obj); + mj_delete(&key_obj); + return 1; +} + +int __ops_hkp_sprint_keydata(__ops_io_t *io, const __ops_keyring_t *keyring, const __ops_key_t *key, char **buf, const __ops_pubkey_t *pubkey, const int psigs) Added files: Index: src/crypto/external/bsd/netpgp/dist/src/lib/mj.c diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/lib/mj.c:1.1 --- /dev/null Mon Jul 26 06:37:35 2010 +++ src/crypto/external/bsd/netpgp/dist/src/lib/mj.c Mon Jul 26 06:37:35 2010 @@ -0,0 +1,478 @@ +/* + Copyright (c) 2010 Alistair Crooks (a...@pkgsrc.org) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include <sys/types.h> + +#include <inttypes.h> +#include <regex.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "mj.h" +#include "defs.h" + +/* save 'n' chars of 's' in malloc'd memory */ +static char * +strnsave(const char fore, const char *s, int n, unsigned esc) +{ + char *newc; + char *cp; + int i; + + if (n < 0) { + n = strlen(s); + } + NEWARRAY(char, cp, 2 + (n * 2) + 1, "strnsave", return NULL); + if (esc) { + newc = cp; + if (fore) { + *newc++ = fore; + } + for (i = 0 ; i < n ; i++) { + if (*s == '\\') { + *newc++ = *s++; + } else if (i > 1 && i < n - 1 && *s == '"') { + *newc++ = '\\'; + } + *newc++ = *s++; + } + if (fore) { + *newc++ = fore; + } + *newc = 0x0; + } else { + (void) memcpy(cp, s, (unsigned)n); + cp[n] = 0x0; + } + return cp; +} + +/* look in an object for the item */ +static int +findentry(mj_t *atom, const char *name) +{ + unsigned i; + + for (i = 0 ; i < atom->c ; i += 2) { + if (strcmp(name, atom->value.v[i].value.s) == 0) { + return i; + } + } + return -1; +} + +/* create a real number */ +static void +create_number(mj_t *atom, double d) +{ + char number[128]; + + atom->type = MJ_NUMBER; + atom->c = snprintf(number, sizeof(number), "%g", d); + atom->value.s = strnsave(0x0, number, (int)atom->c, 0); +} + +/* create an integer */ +static void +create_integer(mj_t *atom, int64_t i) +{ + char number[128]; + + atom->type = MJ_NUMBER; + atom->c = snprintf(number, sizeof(number), "%" PRIi64, i); + atom->value.s = strnsave(0x0, number, (int)atom->c, 0); +} + +/* create a string */ +static void +create_string(mj_t *atom, char *s) +{ + atom->type = MJ_STRING; + atom->value.s = strnsave('"', s, -1, 1); + atom->c = strlen(atom->value.s); +} + +#define MJ_OPEN_BRACKET (MJ_OBJECT + 1) /* 8 */ +#define MJ_CLOSE_BRACKET (MJ_OPEN_BRACKET + 1) /* 9 */ +#define MJ_OPEN_BRACE (MJ_CLOSE_BRACKET + 1) /* 10 */ +#define MJ_CLOSE_BRACE (MJ_OPEN_BRACE + 1) /* 11 */ +#define MJ_COLON (MJ_CLOSE_BRACE + 1) /* 12 */ +#define MJ_COMMA (MJ_COLON + 1) /* 13 */ + +/* return the token type, and start and finish locations in string */ +static int +gettok(const char *s, int *from, int *to, int *tok) +{ + static regex_t tokregex; + regmatch_t matches[15]; + static int compiled; + + if (!compiled) { + compiled = 1; + (void) regcomp(&tokregex, + "[ \t\r\n]*(([+-]?[0-9]{1,21}(\\.[0-9]*)?([eE][-+][0-9]+)?)|" + "(\"([^\"\\]|\\.)*\")|(null)|(false)|(true)|([][{}:,]))", + REG_EXTENDED); + } + if (regexec(&tokregex, &s[*from = *to], 15, matches, 0) != 0) { + return *tok = -1; + } + *to = *from + (int)(matches[1].rm_eo); + *tok = (matches[2].rm_so >= 0) ? MJ_NUMBER : + (matches[5].rm_so >= 0) ? MJ_STRING : + (matches[7].rm_so >= 0) ? MJ_NULL : + (matches[8].rm_so >= 0) ? MJ_FALSE : + (matches[9].rm_so >= 0) ? MJ_TRUE : + (matches[10].rm_so < 0) ? -1 : + (s[*from + (int)(matches[10].rm_so)] == '[') ? MJ_OPEN_BRACKET : + (s[*from + (int)(matches[10].rm_so)] == ']') ? MJ_CLOSE_BRACKET : + (s[*from + (int)(matches[10].rm_so)] == '{') ? MJ_OPEN_BRACE : + (s[*from + (int)(matches[10].rm_so)] == '}') ? MJ_CLOSE_BRACE : + (s[*from + (int)(matches[10].rm_so)] == ':') ? MJ_COLON : + MJ_COMMA; + *from += (int)(matches[1].rm_so); + return *tok; +} + +/***************************************************************************/ + +/* return the number of entries in the array */ +int +mj_arraycount(mj_t *atom) +{ + return atom->c; +} + +/* create a new JSON node */ +int +mj_create(mj_t *atom, const char *type, ...) +{ + va_list args; + + if (strcmp(type, "false") == 0) { + atom->type = MJ_FALSE; + atom->c = 0; + } else if (strcmp(type, "true") == 0) { + atom->type = MJ_TRUE; + atom->c = 1; + } else if (strcmp(type, "null") == 0) { + atom->type = MJ_NULL; + } else if (strcmp(type, "number") == 0) { + va_start(args, type); + create_number(atom, (double)va_arg(args, double)); + va_end(args); + } else if (strcmp(type, "integer") == 0) { + va_start(args, type); + create_integer(atom, (int64_t)va_arg(args, int64_t)); + va_end(args); + } else if (strcmp(type, "string") == 0) { + va_start(args, type); + create_string(atom, (char *)va_arg(args, char *)); + va_end(args); + } else if (strcmp(type, "array") == 0) { + atom->type = MJ_ARRAY; + } else if (strcmp(type, "object") == 0) { + atom->type = MJ_OBJECT; + } else { + (void) fprintf(stderr, "weird type '%s'\n", type); + return 0; + } + return 1; +} + +/* put a JSON tree into a text string */ +int +mj_snprint(char *buf, size_t size, mj_t *atom) +{ + unsigned i; + int cc; + + switch(atom->type) { + case MJ_NULL: + return snprintf(buf, size, "null"); + case MJ_FALSE: + return snprintf(buf, size, "false"); + case MJ_TRUE: + return snprintf(buf, size, "true"); + case MJ_NUMBER: + case MJ_STRING: + return snprintf(buf, size, "%s", atom->value.s); + case MJ_ARRAY: + cc = snprintf(buf, size, "[ "); + for (i = 0 ; i < atom->c ; i++) { + cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i]); + if (i < atom->c - 1) { + cc += snprintf(&buf[cc], size - cc, ", "); + } + } + return cc + snprintf(&buf[cc], size - cc, "]\n"); + case MJ_OBJECT: + cc = snprintf(buf, size, "{ "); + for (i = 0 ; i < atom->c ; i += 2) { + cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i]); + cc += snprintf(&buf[cc], size - cc, ":"); + cc += mj_snprint(&buf[cc], size - cc, &atom->value.v[i + 1]); + if (i + 1 < atom->c - 1) { + cc += snprintf(&buf[cc], size - cc, ", "); + } + } + return cc + snprintf(&buf[cc], size - cc, "}\n"); + default: + (void) fprintf(stderr, "mj_snprint: weird type %d\n", atom->type); + return 0; + } +} + +/* allocate and print the atom */ +int +mj_asprint(char **buf, mj_t *atom) +{ + int size; + + size = mj_string_size(atom); + if ((*buf = calloc(1, (unsigned)(size + 1))) == NULL) { + return -1; + } + (void) mj_snprint(*buf, (unsigned)(size + 1), atom); + return size + 1; +} + +/* read into a JSON tree from a string */ +int +mj_parse(mj_t *atom, const char *s, int *from, int *to, int *tok) +{ + int i; + + while (gettok(s, from, to, tok) >= 0) { + switch(atom->type = *tok) { + case MJ_STRING: + case MJ_NUMBER: + atom->value.s = strnsave(0x0, &s[*from], *to - *from, 1); + atom->c = strlen(atom->value.s); + return gettok(s, from, to, tok); + case MJ_NULL: + case MJ_FALSE: + case MJ_TRUE: + atom->c = (unsigned)to; + return gettok(s, from, to, tok); + case MJ_OPEN_BRACKET: + mj_create(atom, "array"); + ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); + while (mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACKET) { + if (*tok != MJ_COMMA) { + (void) fprintf(stderr, "1. expected comma (got %d) at '%s'\n", *tok, &s[*from]); + break; + } + ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); + } + return gettok(s, from, to, tok); + case MJ_OPEN_BRACE: + mj_create(atom, "object"); + ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); + for (i = 0 ; mj_parse(&atom->value.v[atom->c++], s, from, to, tok) >= 0 && *tok != MJ_CLOSE_BRACE ; i++) { + if (((i % 2) == 0 && *tok != MJ_COLON) || ((i % 2) == 1 && *tok != MJ_COMMA)) { + (void) fprintf(stderr, "2. expected comma (got %d) at '%s'\n", *tok, &s[*from]); + break; + } + ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_parse()", return 0); + } + return gettok(s, from, to, tok); + default: + return *tok; + } + } + return *tok; +} + +/* return the item which corresponds to the name in the array */ +mj_t * +mj_object_find(mj_t *atom, const char *name) +{ + int i; + + return ((i = findentry(atom, name)) >= 0) ? &atom->value.v[i + 1] : NULL; +} + +/* find an atom in a composite mj JSON node */ +mj_t * +mj_get_atom(mj_t *atom, ...) +{ + unsigned i; + va_list args; + char *name; + + switch(atom->type) { + case MJ_ARRAY: + va_start(args, atom); + i = va_arg(args, int); + va_end(args); + return (i < atom->c) ? &atom->value.v[i] : NULL; + case MJ_OBJECT: + va_start(args, atom); + name = va_arg(args, char *); + va_end(args); + return mj_object_find(atom, name); + default: + return NULL; + } +} + +/* perform a deep copy on an mj JSON atom */ +int +mj_deepcopy(mj_t *dst, mj_t *src) +{ + unsigned i; + + switch(src->type) { + case MJ_FALSE: + case MJ_TRUE: + case MJ_NULL: + (void) memcpy(dst, src, sizeof(*dst)); + return 1; + case MJ_STRING: + case MJ_NUMBER: + (void) memcpy(dst, src, sizeof(*dst)); + dst->value.s = strnsave(0x0, src->value.s, -1, 0); + return 1; + case MJ_ARRAY: + case MJ_OBJECT: + (void) memcpy(dst, src, sizeof(*dst)); + NEWARRAY(mj_t, dst->value.v, dst->size, "mj_deepcopy()", return 0); + for (i = 0 ; i < src->c ; i++) { + if (!mj_deepcopy(&dst->value.v[i], &src->value.v[i])) { + return 0; + } + } + return 1; + default: + (void) fprintf(stderr, "weird type '%d'\n", src->type); + return 0; + } +} + +/* do a deep delete on the object */ +void +mj_delete(mj_t *atom) +{ + unsigned i; + + switch(atom->type) { + case MJ_STRING: + case MJ_NUMBER: + free(atom->value.s); + break; + case MJ_ARRAY: + case MJ_OBJECT: + for (i = 0 ; i < atom->c ; i++) { + mj_delete(&atom->value.v[i]); + } + break; + default: + break; + } +} + +/* return the string size needed for the textual output of the JSON node */ +int +mj_string_size(mj_t *atom) +{ + unsigned i; + int cc; + + switch(atom->type) { + case MJ_NULL: + case MJ_TRUE: + return 4; + case MJ_FALSE: + return 5; + case MJ_NUMBER: + case MJ_STRING: + return atom->c; + case MJ_ARRAY: + for (cc = 2, i = 0 ; i < atom->c ; i++) { + cc += mj_string_size(&atom->value.v[i]); + if (i < atom->c - 1) { + cc += 2; + } + } + return cc + 1 + 1; + case MJ_OBJECT: + for (cc = 2, i = 0 ; i < atom->c ; i += 2) { + cc += mj_string_size(&atom->value.v[i]) + 1 + mj_string_size(&atom->value.v[i + 1]); + if (i + 1 < atom->c - 1) { + cc += 2; + } + } + return cc + 1 + 1; + default: + (void) fprintf(stderr, "mj_string_size: weird type %d\n", atom->type); + return 0; + } +} + +/* create a new atom, and append it to the array or object */ +int +mj_append(mj_t *atom, const char *type, ...) +{ + va_list args; + + if (atom->type != MJ_ARRAY && atom->type != MJ_OBJECT) { + return 0; + } + ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append()", return 0); + va_start(args, type); + if (strcmp(type, "string") == 0) { + create_string(&atom->value.v[atom->c++], (char *)va_arg(args, char *)); + } else if (strcmp(type, "integer") == 0) { + create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t)); + } else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) { + mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *)); + } + va_end(args); + return 1; +} + +/* append a field to an object */ +int +mj_append_field(mj_t *atom, const char *name, const char *type, ...) +{ + va_list args; + + if (atom->type != MJ_OBJECT) { + return 0; + } + mj_append(atom, "string", name); + ALLOC(mj_t, atom->value.v, atom->size, atom->c, 10, 10, "mj_append_field()", return 0); + va_start(args, type); + if (strcmp(type, "string") == 0) { + create_string(&atom->value.v[atom->c++], (char *)va_arg(args, char *)); + } else if (strcmp(type, "integer") == 0) { + create_integer(&atom->value.v[atom->c++], (int64_t)va_arg(args, int64_t)); + } else if (strcmp(type, "object") == 0 || strcmp(type, "array") == 0) { + mj_deepcopy(&atom->value.v[atom->c++], (mj_t *)va_arg(args, mj_t *)); + } + va_end(args); + return 1; +} Index: src/crypto/external/bsd/netpgp/dist/src/lib/mj.h diff -u /dev/null src/crypto/external/bsd/netpgp/dist/src/lib/mj.h:1.1 --- /dev/null Mon Jul 26 06:37:35 2010 +++ src/crypto/external/bsd/netpgp/dist/src/lib/mj.h Mon Jul 26 06:37:35 2010 @@ -0,0 +1,64 @@ +/* + Copyright (c) 2010 Alistair Crooks (a...@pkgsrc.org) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +#ifndef MJ_H_ +#define MJ_H_ 20100718 + +enum { + MJ_NULL = 1, + MJ_FALSE = 2, + MJ_TRUE = 3, + MJ_NUMBER = 4, + MJ_STRING = 5, + MJ_ARRAY = 6, + MJ_OBJECT = 7 +}; + +/* a minimalist JSON node */ +typedef struct mj_t { + unsigned type; /* type of JSON node */ + unsigned c; /* # of chars */ + unsigned size; /* size of array */ + union { + struct mj_t *v; /* sub-objects */ + char *s; /* string value */ + } value; +} mj_t; + +/* creation and deletion */ +int mj_create(mj_t *, const char *, ...); +int mj_parse(mj_t *, const char *, int *, int *, int *); +int mj_append(mj_t *, const char *, ...); +int mj_append_field(mj_t *, const char *, const char *, ...); +int mj_deepcopy(mj_t *, mj_t *); +void mj_delete(mj_t *); + +/* JSON object access */ +int mj_arraycount(mj_t *); +mj_t *mj_object_find(mj_t *, const char *); +mj_t *mj_get_atom(mj_t *, ...); + +/* textual output */ +int mj_snprint(char *, size_t, mj_t *); +int mj_asprint(char **, mj_t *); +int mj_string_size(mj_t *); + +#endif