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

Reply via email to