Home | History | Annotate | Line # | Download | only in cgdconfig
utils.c revision 1.18.2.1
      1  1.18.2.1  wrstuden /* $NetBSD: utils.c,v 1.18.2.1 2008/06/23 04:29:57 wrstuden Exp $ */
      2       1.1     elric 
      3       1.1     elric /*-
      4       1.2     elric  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
      5       1.1     elric  * All rights reserved.
      6       1.1     elric  *
      7       1.1     elric  * This code is derived from software contributed to The NetBSD Foundation
      8       1.1     elric  * by Roland C. Dowdeswell.
      9       1.1     elric  *
     10       1.1     elric  * Redistribution and use in source and binary forms, with or without
     11       1.1     elric  * modification, are permitted provided that the following conditions
     12       1.1     elric  * are met:
     13       1.1     elric  * 1. Redistributions of source code must retain the above copyright
     14       1.1     elric  *    notice, this list of conditions and the following disclaimer.
     15       1.1     elric  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1     elric  *    notice, this list of conditions and the following disclaimer in the
     17       1.1     elric  *    documentation and/or other materials provided with the distribution.
     18       1.1     elric  *
     19       1.1     elric  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20       1.1     elric  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21       1.1     elric  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22       1.1     elric  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23       1.1     elric  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24       1.1     elric  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25       1.1     elric  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26       1.1     elric  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27       1.1     elric  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28       1.1     elric  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29       1.1     elric  * POSSIBILITY OF SUCH DAMAGE.
     30       1.1     elric  */
     31       1.1     elric 
     32       1.1     elric #include <sys/cdefs.h>
     33       1.1     elric #ifndef lint
     34  1.18.2.1  wrstuden __RCSID("$NetBSD: utils.c,v 1.18.2.1 2008/06/23 04:29:57 wrstuden Exp $");
     35       1.1     elric #endif
     36       1.1     elric 
     37       1.2     elric #include <sys/param.h>
     38       1.2     elric 
     39       1.2     elric #include <stdlib.h>
     40       1.1     elric #include <string.h>
     41       1.6  christos #include <err.h>
     42      1.15  christos #include <util.h>
     43       1.1     elric 
     44       1.2     elric /* include the resolver gunk in order that we can use b64 routines */
     45       1.2     elric #include <netinet/in.h>
     46       1.2     elric #include <arpa/nameser.h>
     47       1.2     elric #include <resolv.h>
     48       1.2     elric 
     49       1.1     elric #include "utils.h"
     50       1.1     elric 
     51       1.6  christos 
     52       1.1     elric /* just strsep(3), but skips empty fields. */
     53       1.1     elric 
     54       1.1     elric static char *
     55       1.1     elric strsep_getnext(char **stringp, const char *delim)
     56       1.1     elric {
     57       1.1     elric 	char	*ret;
     58       1.1     elric 
     59       1.1     elric 	ret = strsep(stringp, delim);
     60       1.1     elric 	while (ret && index(delim, *ret))
     61       1.1     elric 		ret = strsep(stringp, delim);
     62       1.1     elric 	return ret;
     63       1.1     elric }
     64       1.1     elric 
     65       1.1     elric /*
     66       1.1     elric  * this function returns a dynamically sized char ** of the words
     67       1.1     elric  * in the line.  the caller is responsible for both free(3)ing
     68       1.1     elric  * each word and the superstructure by calling words_free().
     69       1.1     elric  */
     70       1.1     elric char **
     71       1.1     elric words(const char *line, int *num)
     72       1.1     elric {
     73       1.1     elric 	int	  i = 0;
     74       1.1     elric 	int	  nwords = 0;
     75       1.1     elric 	char	 *cur;
     76       1.1     elric 	char	**ret;
     77       1.9  christos 	const char	 *tmp;
     78       1.9  christos 	char	 *tmp1, *tmpf;
     79       1.1     elric 
     80       1.1     elric 	*num = 0;
     81       1.9  christos 	tmp = line;
     82       1.1     elric 	if (tmp[0] == '\0')
     83       1.1     elric 		return NULL;
     84       1.1     elric 	while (tmp[0]) {
     85       1.1     elric 		if ((tmp[1] == ' ' || tmp[1] == '\t' || tmp[1] == '\0') &&
     86       1.1     elric 		    (tmp[0] != ' ' && tmp[0] != '\t'))
     87       1.1     elric 			nwords++;
     88       1.1     elric 		tmp++;
     89       1.1     elric 	}
     90       1.6  christos 	ret = emalloc((nwords+1) * sizeof(char *));
     91       1.9  christos 	tmp1 = tmpf = estrdup(line);
     92       1.9  christos 	while ((cur = strsep_getnext(&tmpf, " \t")) != NULL)
     93       1.6  christos 		ret[i++] = estrdup(cur);
     94       1.1     elric 	ret[i] = NULL;
     95       1.1     elric 	free(tmp1);
     96       1.1     elric 	*num = nwords;
     97       1.1     elric 	return ret;
     98       1.1     elric }
     99       1.1     elric 
    100       1.1     elric void
    101       1.1     elric words_free(char **w, int num)
    102       1.1     elric {
    103       1.1     elric 	int	i;
    104       1.1     elric 
    105       1.1     elric 	for (i=0; i < num; i++)
    106       1.1     elric 		free(w[i]);
    107       1.1     elric }
    108       1.1     elric 
    109       1.1     elric /*
    110       1.1     elric  * this is a simple xor that has the same calling conventions as
    111       1.1     elric  * memcpy(3).
    112       1.1     elric  */
    113       1.1     elric 
    114       1.1     elric void
    115       1.1     elric memxor(void *res, const void *src, size_t len)
    116       1.1     elric {
    117       1.1     elric 	char *r;
    118       1.1     elric 	const char *s;
    119      1.16    cbiere 	size_t i;
    120       1.1     elric 
    121       1.1     elric 	r = res;
    122       1.1     elric 	s = src;
    123      1.16    cbiere 	for (i = 0; i < len; i++)
    124       1.1     elric 		r[i] ^= s[i];
    125       1.2     elric }
    126       1.2     elric 
    127       1.2     elric /*
    128       1.2     elric  * well, a very simple set of string functions...
    129       1.2     elric  *
    130       1.2     elric  * The goal here is basically to manage length encoded strings,
    131       1.2     elric  * but just for safety we nul terminate them anyway.
    132       1.2     elric  */
    133       1.2     elric 
    134       1.2     elric /* for now we use a very simple encoding */
    135       1.2     elric 
    136       1.2     elric struct string {
    137       1.2     elric 	char	*text;
    138      1.17  christos 	size_t	 length;
    139       1.2     elric };
    140       1.2     elric 
    141       1.2     elric string_t *
    142  1.18.2.1  wrstuden string_zero()
    143  1.18.2.1  wrstuden {
    144  1.18.2.1  wrstuden 	string_t *out;
    145  1.18.2.1  wrstuden 
    146  1.18.2.1  wrstuden 	out = emalloc(sizeof(*out));
    147  1.18.2.1  wrstuden 	out->length = 0;
    148  1.18.2.1  wrstuden 	out->text = NULL;
    149  1.18.2.1  wrstuden 	return out;
    150  1.18.2.1  wrstuden }
    151  1.18.2.1  wrstuden 
    152  1.18.2.1  wrstuden string_t *
    153      1.17  christos string_new(const char *intext, size_t inlength)
    154       1.2     elric {
    155       1.2     elric 	string_t *out;
    156       1.2     elric 
    157       1.6  christos 	out = emalloc(sizeof(*out));
    158       1.2     elric 	out->length = inlength;
    159       1.6  christos 	out->text = emalloc(out->length + 1);
    160      1.17  christos 	(void)memcpy(out->text, intext, out->length);
    161       1.2     elric 	out->text[out->length] = '\0';
    162       1.2     elric 	return out;
    163       1.2     elric }
    164       1.2     elric 
    165       1.2     elric string_t *
    166       1.2     elric string_dup(const string_t *in)
    167       1.2     elric {
    168       1.2     elric 
    169       1.2     elric 	return string_new(in->text, in->length);
    170       1.2     elric }
    171       1.2     elric 
    172       1.2     elric void
    173       1.2     elric string_free(string_t *s)
    174       1.2     elric {
    175       1.2     elric 
    176       1.2     elric 	if (!s)
    177       1.2     elric 		return;
    178       1.6  christos 	free(s->text);
    179       1.2     elric 	free(s);
    180       1.2     elric }
    181       1.2     elric 
    182       1.2     elric void
    183       1.2     elric string_assign(string_t **lhs, string_t *rhs)
    184       1.2     elric {
    185       1.2     elric 
    186       1.2     elric 	string_free(*lhs);
    187       1.2     elric 	*lhs = rhs;
    188       1.2     elric }
    189       1.2     elric 
    190       1.2     elric string_t *
    191       1.2     elric string_add(const string_t *a1, const string_t *a2)
    192       1.2     elric {
    193       1.2     elric 	string_t *sum;
    194       1.2     elric 
    195       1.6  christos 	sum = emalloc(sizeof(*sum));
    196       1.2     elric 	sum->length = a1->length + a2->length;
    197       1.6  christos 	sum->text = emalloc(sum->length + 1);
    198      1.17  christos 	(void)memcpy(sum->text, a1->text, a1->length);
    199      1.17  christos 	(void)memcpy(sum->text + a1->length, a2->text, a2->length);
    200       1.2     elric 	sum->text[sum->length] = '\0';
    201       1.2     elric 	return sum;
    202       1.2     elric }
    203       1.2     elric 
    204       1.2     elric string_t *
    205       1.2     elric string_add_d(string_t *a1, string_t *a2)
    206       1.2     elric {
    207       1.2     elric 	string_t *sum;
    208       1.2     elric 
    209       1.2     elric 	sum = string_add(a1, a2);
    210       1.2     elric 	string_free(a1);
    211       1.2     elric 	string_free(a2);
    212       1.2     elric 	return sum;
    213       1.2     elric }
    214       1.2     elric 
    215       1.2     elric string_t *
    216       1.2     elric string_fromcharstar(const char *in)
    217       1.2     elric {
    218       1.2     elric 
    219       1.2     elric 	return string_new(in, strlen(in));
    220       1.2     elric }
    221       1.2     elric 
    222       1.2     elric const char *
    223       1.2     elric string_tocharstar(const string_t *in)
    224       1.2     elric {
    225       1.2     elric 
    226       1.2     elric 	return in->text;
    227       1.2     elric }
    228       1.2     elric 
    229       1.2     elric string_t *
    230       1.2     elric string_fromint(int in)
    231       1.2     elric {
    232       1.2     elric 	string_t *ret;
    233       1.2     elric 
    234       1.6  christos 	ret = emalloc(sizeof(*ret));
    235       1.2     elric 	ret->length = asprintf(&ret->text, "%d", in);
    236      1.17  christos 	if (ret->text == NULL)
    237       1.6  christos 		err(1, NULL);
    238       1.2     elric 	return ret;
    239       1.2     elric }
    240       1.2     elric 
    241       1.2     elric void
    242       1.2     elric string_fprint(FILE *f, const string_t *s)
    243       1.2     elric {
    244      1.17  christos 	(void)fwrite(s->text, s->length, 1, f);
    245       1.2     elric }
    246       1.2     elric 
    247       1.2     elric struct bits {
    248      1.17  christos 	size_t	 length;
    249       1.2     elric 	char	*text;
    250       1.2     elric };
    251       1.2     elric 
    252       1.2     elric bits_t *
    253      1.17  christos bits_new(const void *buf, size_t len)
    254       1.2     elric {
    255       1.2     elric 	bits_t	*b;
    256       1.2     elric 
    257       1.7     elric 	b = emalloc(sizeof(*b));
    258       1.2     elric 	b->length = len;
    259       1.6  christos 	b->text = emalloc(BITS2BYTES(b->length));
    260      1.17  christos 	(void)memcpy(b->text, buf, BITS2BYTES(b->length));
    261       1.2     elric 	return b;
    262       1.2     elric }
    263       1.2     elric 
    264       1.2     elric bits_t *
    265       1.2     elric bits_dup(const bits_t *in)
    266       1.2     elric {
    267       1.2     elric 
    268       1.2     elric 	return bits_new(in->text, in->length);
    269       1.2     elric }
    270       1.2     elric 
    271       1.2     elric void
    272       1.2     elric bits_free(bits_t *b)
    273       1.2     elric {
    274       1.2     elric 
    275       1.2     elric 	if (!b)
    276       1.2     elric 		return;
    277       1.6  christos 	free(b->text);
    278       1.2     elric 	free(b);
    279       1.2     elric }
    280       1.2     elric 
    281       1.2     elric void
    282       1.2     elric bits_assign(bits_t **lhs, bits_t *rhs)
    283       1.2     elric {
    284       1.2     elric 
    285       1.2     elric 	bits_free(*lhs);
    286       1.2     elric 	*lhs = rhs;
    287       1.2     elric }
    288       1.2     elric 
    289       1.2     elric const void *
    290       1.2     elric bits_getbuf(bits_t *in)
    291       1.2     elric {
    292       1.2     elric 
    293       1.2     elric 	return in->text;
    294       1.2     elric }
    295       1.2     elric 
    296      1.17  christos size_t
    297       1.2     elric bits_len(bits_t *in)
    298       1.2     elric {
    299       1.2     elric 
    300       1.2     elric 	return in->length;
    301       1.3        cb }
    302       1.3        cb 
    303       1.3        cb int
    304       1.3        cb bits_match(const bits_t *b1, const bits_t *b2)
    305       1.3        cb {
    306       1.3        cb 	int i;
    307       1.3        cb 
    308       1.3        cb 	if (b1->length != b2->length)
    309       1.3        cb 		return 0;
    310       1.3        cb 
    311       1.3        cb 	for (i = 0; i < BITS2BYTES(b1->length); i++)
    312       1.3        cb 		if (b1->text[i] != b2->text[i])
    313       1.3        cb 			return 0;
    314       1.3        cb 
    315       1.3        cb 	return 1;
    316       1.2     elric }
    317       1.2     elric 
    318       1.2     elric bits_t *
    319       1.2     elric bits_xor(const bits_t *x1, const bits_t *x2)
    320       1.2     elric {
    321       1.2     elric 	bits_t	*b;
    322       1.2     elric 	int	 i;
    323       1.2     elric 
    324       1.6  christos 	b = emalloc(sizeof(*b));
    325       1.2     elric 	b->length = MAX(x1->length, x2->length);
    326       1.6  christos 	b->text = ecalloc(1, BITS2BYTES(b->length));
    327       1.2     elric 	for (i=0; i < BITS2BYTES(MIN(x1->length, x2->length)); i++)
    328       1.2     elric 		b->text[i] = x1->text[i] ^ x2->text[i];
    329       1.2     elric 	return b;
    330       1.2     elric }
    331       1.2     elric 
    332       1.2     elric bits_t *
    333       1.2     elric bits_xor_d(bits_t *x1, bits_t *x2)
    334       1.2     elric {
    335       1.2     elric 	bits_t	*ret;
    336       1.2     elric 
    337       1.2     elric 	ret = bits_xor(x1, x2);
    338       1.2     elric 	bits_free(x1);
    339       1.2     elric 	bits_free(x2);
    340       1.2     elric 	return ret;
    341       1.2     elric }
    342       1.2     elric 
    343       1.2     elric /*
    344       1.2     elric  * bits_decode() reads an encoded base64 stream.  We interpret
    345       1.2     elric  * the first 32 bits as an unsigned integer in network byte order
    346       1.2     elric  * specifying the number of bits in the stream to give a little
    347       1.2     elric  * resilience.
    348       1.2     elric  */
    349       1.2     elric 
    350       1.2     elric bits_t *
    351       1.2     elric bits_decode(const string_t *in)
    352       1.2     elric {
    353       1.2     elric 	bits_t	*ret;
    354      1.17  christos 	size_t	 len;
    355      1.17  christos 	size_t	 nbits;
    356      1.17  christos 	u_int32_t	*tmp;
    357       1.2     elric 
    358       1.2     elric 	len = in->length;
    359       1.6  christos 	tmp = emalloc(len);
    360       1.2     elric 
    361      1.17  christos 	len = __b64_pton(in->text, (void *)tmp, len);
    362       1.2     elric 
    363      1.17  christos 	if (len == (size_t)-1) {
    364      1.17  christos 		warnx("bits_decode: mangled base64 stream");
    365      1.17  christos 		warnx("  %s", in->text);
    366      1.12  christos 		free(tmp);
    367       1.2     elric 		return NULL;
    368       1.2     elric 	}
    369       1.2     elric 
    370      1.17  christos 	nbits = ntohl(*tmp);
    371      1.17  christos 	if (nbits > (len - sizeof(*tmp)) * NBBY) {
    372      1.17  christos 		warnx("bits_decode: encoded bits claim to be "
    373      1.17  christos 		    "longer than they are (nbits=%zu, stream len=%zu bytes)",
    374      1.17  christos 		    nbits, len);
    375      1.12  christos 		free(tmp);
    376       1.2     elric 		return NULL;
    377       1.2     elric 	}
    378       1.2     elric 
    379      1.17  christos 	ret = bits_new(tmp + 1, nbits);
    380       1.2     elric 	free(tmp);
    381       1.2     elric 	return ret;
    382       1.2     elric }
    383       1.2     elric 
    384       1.2     elric bits_t *
    385       1.2     elric bits_decode_d(string_t *in)
    386       1.2     elric {
    387       1.2     elric 	bits_t *ret;
    388       1.2     elric 
    389       1.2     elric 	ret = bits_decode(in);
    390       1.2     elric 	string_free(in);
    391       1.2     elric 	return ret;
    392       1.2     elric }
    393       1.2     elric 
    394       1.2     elric string_t *
    395       1.2     elric bits_encode(const bits_t *in)
    396       1.2     elric {
    397       1.2     elric 	string_t *ret;
    398      1.17  christos 	size_t	 len;
    399       1.2     elric 	char	*out;
    400      1.17  christos 	u_int32_t *tmp;
    401       1.2     elric 
    402       1.2     elric 	if (!in)
    403       1.2     elric 		return NULL;
    404       1.2     elric 
    405       1.2     elric 	/* compute the total size of the input stream */
    406      1.17  christos 	len = BITS2BYTES(in->length) + sizeof(*tmp);
    407       1.2     elric 
    408       1.6  christos 	tmp = emalloc(len);
    409       1.6  christos 	out = emalloc(len * 2);
    410       1.2     elric 	/* stuff the length up front */
    411      1.17  christos 	*tmp = htonl(in->length);
    412      1.17  christos 	(void)memcpy(tmp + 1, in->text, len - sizeof(*tmp));
    413       1.2     elric 
    414      1.17  christos 	if ((len = __b64_ntop((void *)tmp, len, out, len * 2)) == (size_t)-1) {
    415      1.13  christos 		free(out);
    416      1.10  christos 		free(tmp);
    417      1.10  christos 		return NULL;
    418      1.10  christos 	}
    419       1.2     elric 	ret = string_new(out, len);
    420       1.2     elric 	free(tmp);
    421       1.2     elric 	free(out);
    422       1.2     elric 	return ret;
    423       1.2     elric }
    424       1.2     elric 
    425       1.2     elric string_t *
    426       1.2     elric bits_encode_d(bits_t *in)
    427       1.2     elric {
    428       1.2     elric 	string_t *ret;
    429       1.2     elric 
    430       1.2     elric 	ret = bits_encode(in);
    431       1.2     elric 	bits_free(in);
    432       1.2     elric 	return ret;
    433       1.2     elric }
    434       1.2     elric 
    435       1.2     elric bits_t *
    436      1.17  christos bits_fget(FILE *f, size_t len)
    437       1.2     elric {
    438       1.2     elric 	bits_t	*bits;
    439       1.2     elric 	int	 ret;
    440       1.2     elric 
    441       1.6  christos 	bits = emalloc(sizeof(*bits));
    442       1.2     elric 	bits->length = len;
    443       1.6  christos 	bits->text = emalloc(BITS2BYTES(bits->length));
    444       1.2     elric 	ret = fread(bits->text, BITS2BYTES(bits->length), 1, f);
    445       1.2     elric 	if (ret != 1) {
    446       1.2     elric 		bits_free(bits);
    447       1.2     elric 		return NULL;
    448       1.2     elric 	}
    449       1.2     elric 	return bits;
    450       1.2     elric }
    451       1.2     elric 
    452       1.2     elric bits_t *
    453      1.17  christos bits_cget(const char *fn, size_t len)
    454       1.2     elric {
    455       1.2     elric 	bits_t	*bits;
    456       1.2     elric 	FILE	*f;
    457       1.2     elric 
    458       1.2     elric 	f = fopen(fn, "r");
    459       1.8     lukem 	if (!f)
    460       1.2     elric 		return NULL;
    461       1.2     elric 
    462       1.2     elric 	bits = bits_fget(f, len);
    463      1.17  christos 	(void)fclose(f);
    464       1.2     elric 	return bits;
    465       1.2     elric }
    466       1.2     elric 
    467       1.2     elric bits_t *
    468      1.17  christos bits_getrandombits(size_t len, int hard)
    469       1.2     elric {
    470       1.2     elric 
    471       1.5        tv 	return bits_cget((hard ? "/dev/random" : "/dev/urandom"), len);
    472       1.2     elric }
    473       1.2     elric 
    474       1.2     elric void
    475       1.2     elric bits_fprint(FILE *f, const bits_t *bits)
    476       1.2     elric {
    477       1.2     elric 	string_t *s;
    478       1.2     elric 
    479       1.2     elric 	s = bits_encode(bits);
    480       1.2     elric 	string_fprint(f, s);
    481       1.2     elric 	free(s);
    482       1.2     elric }
    483