diff src/gt_utils.c @ 0:d39e1d0d75b6

initial add
author paulo@hit-nxdomain.opendns.com
date Sat, 20 Feb 2010 21:18:28 -0800
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/gt_utils.c	Sat Feb 20 21:18:28 2010 -0800
     1.3 @@ -0,0 +1,352 @@
     1.4 +/*
     1.5 + * $Id: gt_utils.c,v 1.10 2004/04/17 06:05:54 hipnod Exp $
     1.6 + *
     1.7 + * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net)
     1.8 + *
     1.9 + * This program is free software; you can redistribute it and/or modify it
    1.10 + * under the terms of the GNU General Public License as published by the
    1.11 + * Free Software Foundation; either version 2, or (at your option) any
    1.12 + * later version.
    1.13 + *
    1.14 + * This program is distributed in the hope that it will be useful, but
    1.15 + * WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.17 + * General Public License for more details.
    1.18 + */
    1.19 +
    1.20 +#include "gt_gnutella.h"
    1.21 +
    1.22 +#include "gt_utils.h"
    1.23 +
    1.24 +#ifdef USE_ZLIB
    1.25 +#include <zlib.h>
    1.26 +#endif /* USE_ZLIB */
    1.27 +
    1.28 +/*****************************************************************************/
    1.29 +
    1.30 +int peer_addr (int fd, in_addr_t *r_ip, in_port_t *r_port)
    1.31 +{
    1.32 +	struct sockaddr_in sin;
    1.33 +	int                len = sizeof (struct sockaddr_in);
    1.34 +
    1.35 +	if (getpeername (fd, (struct sockaddr *) &sin, &len) < 0)
    1.36 +		return FALSE;
    1.37 +
    1.38 +	/* maybe port should be kept in network byte-order */
    1.39 +	if (r_port)
    1.40 +		*r_port = ntohs (sin.sin_port);
    1.41 +
    1.42 +	if (r_ip)
    1.43 +		*r_ip   = sin.sin_addr.s_addr;
    1.44 +
    1.45 +	return TRUE;
    1.46 +}
    1.47 +
    1.48 +char *make_str (char *array, int len)
    1.49 +{
    1.50 +	static int   data_len = 0;
    1.51 +	static char *data     = 0;
    1.52 +
    1.53 +	if (len <= 0)
    1.54 +		return "";
    1.55 +
    1.56 +	if (!data_len || data_len < len)
    1.57 +	{
    1.58 +		if (data)
    1.59 +			free (data);
    1.60 +
    1.61 +		if (!(data = malloc (len + 1)))
    1.62 +			return "(No memory for string)";
    1.63 +	}
    1.64 +
    1.65 +	memcpy (data, array, len);
    1.66 +
    1.67 +	data[len] = 0;
    1.68 +
    1.69 +	if (len > data_len)
    1.70 +		data_len = len;
    1.71 +
    1.72 +	return data;
    1.73 +}
    1.74 +
    1.75 +void fprint_hex (FILE *f, char *buf, int len)
    1.76 +{
    1.77 +	int i, j;
    1.78 +	unsigned char *line;
    1.79 +	unsigned char *end;
    1.80 +
    1.81 +	end = buf + len;
    1.82 +
    1.83 +	while ((line = buf) != end)
    1.84 +	{
    1.85 +		for (i = 0; i < 16; i++)
    1.86 +		{
    1.87 +			if (line + i == end)
    1.88 +				break;
    1.89 +
    1.90 +			fprintf (f, "%02x ", line[i]);
    1.91 +		}
    1.92 +
    1.93 +		for (j = i; j < 16; j++)
    1.94 +			fprintf (f, "   ");
    1.95 +
    1.96 +		fprintf (f, " ");
    1.97 +
    1.98 +		for (i = 0; i < 16; i++)
    1.99 +		{
   1.100 +			if (line + i == end)
   1.101 +				break;
   1.102 +
   1.103 +			fprintf (f, "%c", isprint (line[i]) ? line[i] : '.');
   1.104 +		}
   1.105 +
   1.106 +		buf += i;
   1.107 +		fprintf (f, "\n");
   1.108 +	}
   1.109 +}
   1.110 +
   1.111 +/*****************************************************************************/
   1.112 +/* HTTP HEADER STORAGE */
   1.113 +
   1.114 +#if 0
   1.115 +static unsigned long hash_lowercase (Dataset *d, void *key, size_t key_len)
   1.116 +{
   1.117 +	char *str;
   1.118 +	int i;
   1.119 +	unsigned long hash;
   1.120 +
   1.121 +	for (hash = 0, i = 0; i < key_len; i++)
   1.122 +		hash ^= tolower (str[i]);
   1.123 +
   1.124 +	return hash;
   1.125 +}
   1.126 +
   1.127 +static int cmp_caseless (Dataset *d, DatasetNode *node, void *key,
   1.128 +                          size_t key_len)
   1.129 +{
   1.130 +	return strncasecmp (node->key, key, MIN (node->key_len, key_len));
   1.131 +}
   1.132 +
   1.133 +/* Like a Dataset, but stores case-insensitive strings for keys to
   1.134 + * string fields. */
   1.135 +Headers *headers_new ()
   1.136 +{
   1.137 +	Dataset *dataset;
   1.138 +
   1.139 +	if (!(dataset = dataset_new (DATASET_DEFAULT)))
   1.140 +		return NULL;
   1.141 +
   1.142 +	dataset->hash_func = hash_lowercase;
   1.143 +
   1.144 +	return hdrs;
   1.145 +}
   1.146 +
   1.147 +char *header_lookup (Headers *hdrs, char *key)
   1.148 +{
   1.149 +	char *value;
   1.150 +
   1.151 +	if (!hdrs || !key)
   1.152 +		return NULL;
   1.153 +
   1.154 +	return dataset_lookupstr (dataset, key);
   1.155 +}
   1.156 +
   1.157 +void header_insert (Headers **hdrs, char *key, char *value)
   1.158 +{
   1.159 +	if (!d || !key)
   1.160 +		return;
   1.161 +
   1.162 +	if (!(*hdrs) && !(*hdrs = headers_new ()))
   1.163 +		return;
   1.164 +
   1.165 +	dataset_insertstr (hdrs->dataset, key, value);
   1.166 +}
   1.167 +
   1.168 +void header_remove (Headers *hdrs, char *key)
   1.169 +{
   1.170 +	if (!hdrs)
   1.171 +		return NULL;
   1.172 +
   1.173 +	dataset_remove (hdrs->dataset, key, size);
   1.174 +}
   1.175 +#endif
   1.176 +
   1.177 +/*****************************************************************************/
   1.178 +/* ZLIB WRAPPER ROUTINES */
   1.179 +
   1.180 +static char *zlib_strerror (int error)
   1.181 +{
   1.182 +#ifndef USE_ZLIB
   1.183 +	return NULL;
   1.184 +#else /* USE_ZLIB */
   1.185 +	switch (error)
   1.186 +	{
   1.187 +	 case Z_OK:             return "OK";
   1.188 +	 case Z_STREAM_END:     return "End of stream";
   1.189 +	 case Z_NEED_DICT:      return "Decompressing dictionary needed";
   1.190 +	 case Z_STREAM_ERROR:   return "Stream error";
   1.191 +	 case Z_ERRNO:          return "Generic zlib error";
   1.192 +	 case Z_DATA_ERROR:     return "Data error";
   1.193 +	 case Z_MEM_ERROR:      return "Memory error";
   1.194 +	 case Z_BUF_ERROR:      return "Buffer error";
   1.195 +	 case Z_VERSION_ERROR:  return "Incompatible runtime zlib library";
   1.196 +	 default:               break;
   1.197 +	}
   1.198 +
   1.199 +	return "Invalid zlib error code";
   1.200 +#endif /* USE_ZLIB */
   1.201 +}
   1.202 +
   1.203 +static void zstream_close (ZlibStream *stream)
   1.204 +{
   1.205 +#ifdef USE_ZLIB
   1.206 +	switch (stream->type)
   1.207 +	{
   1.208 +	 case ZSTREAM_INFLATE: inflateEnd (stream->streamptr);    break;
   1.209 +	 case ZSTREAM_DEFLATE: deflateEnd (stream->streamptr);    break;
   1.210 +	 default:                                                 break;
   1.211 +	}
   1.212 +
   1.213 +	if (stream->streamptr)
   1.214 +		free (stream->streamptr);
   1.215 +
   1.216 +	stream->type      = ZSTREAM_NONE;
   1.217 +	stream->streamptr = NULL;
   1.218 +#endif /* USE_ZLIB */
   1.219 +}
   1.220 +
   1.221 +ZlibStream *zlib_stream_open (size_t max_size)
   1.222 +{
   1.223 +	ZlibStream *stream;
   1.224 +	char       *data;
   1.225 +
   1.226 +	if (!(stream = malloc (sizeof (ZlibStream))))
   1.227 +		return NULL;
   1.228 +
   1.229 +	if (!(data = malloc (max_size)))
   1.230 +	{
   1.231 +		free (stream);
   1.232 +		return NULL;
   1.233 +	}
   1.234 +
   1.235 +	memset (stream, 0, sizeof (ZlibStream));
   1.236 +	memset (data, 0, max_size);
   1.237 +
   1.238 +	stream->start = data;
   1.239 +	stream->end   = data + max_size;
   1.240 +	stream->data  = data;
   1.241 +	stream->pos   = data;
   1.242 +	stream->type  = ZSTREAM_NONE;
   1.243 +
   1.244 +	return stream;
   1.245 +}
   1.246 +
   1.247 +void zlib_stream_close (ZlibStream *stream)
   1.248 +{
   1.249 +	if (!stream)
   1.250 +		return;
   1.251 +
   1.252 +	if (stream->type != ZSTREAM_NONE)
   1.253 +		zstream_close (stream);
   1.254 +
   1.255 +	if (stream->data)
   1.256 +		free (stream->data);
   1.257 +
   1.258 +	free (stream);
   1.259 +}
   1.260 +
   1.261 +int zlib_stream_write (ZlibStream *stream, char *data, size_t size)
   1.262 +{
   1.263 +	if (!stream)
   1.264 +		return 0;
   1.265 +
   1.266 +	/* check for overflow */
   1.267 +	if (stream->pos + (size-1) > stream->end)
   1.268 +		return 0;
   1.269 +
   1.270 +	memcpy (stream->pos, data, size);
   1.271 +
   1.272 +	stream->pos += size;
   1.273 +
   1.274 +	return size;
   1.275 +}
   1.276 +
   1.277 +int zlib_stream_read (ZlibStream *stream, char **r_data)
   1.278 +{
   1.279 +	size_t size;
   1.280 +
   1.281 +	if (stream->start == stream->pos)
   1.282 +		return 0;
   1.283 +
   1.284 +	*r_data = stream->start;
   1.285 +
   1.286 +	size = stream->pos - stream->start;
   1.287 +
   1.288 +	stream->start = stream->pos;
   1.289 +
   1.290 +	return size;
   1.291 +}
   1.292 +
   1.293 +int zlib_stream_inflate (ZlibStream *stream, char *zdata, size_t size)
   1.294 +{
   1.295 +#ifndef USE_ZLIB
   1.296 +	return FALSE;
   1.297 +#else /* USE_ZLIB */
   1.298 +	z_streamp inz;
   1.299 +	int ret;
   1.300 +	size_t free_size;
   1.301 +
   1.302 +	if (!stream)
   1.303 +		return FALSE;
   1.304 +
   1.305 +	if (!stream->streamptr)
   1.306 +	{
   1.307 +		assert (stream->type == ZSTREAM_NONE);
   1.308 +
   1.309 +		if (!(inz = malloc (sizeof (*inz))))
   1.310 +			return FALSE;
   1.311 +
   1.312 +		inz->zalloc = NULL;
   1.313 +		inz->zfree  = NULL;
   1.314 +		inz->opaque = NULL;
   1.315 +
   1.316 +		if ((ret = inflateInit (inz)) != Z_OK)
   1.317 +		{
   1.318 +			GT->DBGFN (GT, "inflateInit error %s", zlib_strerror (ret));
   1.319 +			free (inz);
   1.320 +			return FALSE;
   1.321 +		}
   1.322 +
   1.323 +		stream->type      = ZSTREAM_INFLATE;
   1.324 +		stream->streamptr = inz;
   1.325 +	}
   1.326 +
   1.327 +	inz = stream->streamptr;
   1.328 +
   1.329 +	/* Argh, I think this is right, but I'm not sure about the +1 */
   1.330 +	free_size = stream->end - stream->pos + 1;
   1.331 +
   1.332 +	inz->next_in   = zdata;
   1.333 +	inz->avail_in  = size;
   1.334 +	inz->next_out  = stream->pos;
   1.335 +	inz->avail_out = free_size;
   1.336 +
   1.337 +	GT->DBGFN (GT, "next_out: %p avail_out: %u", inz->next_out, inz->avail_out);
   1.338 +
   1.339 +	if ((ret = inflate (inz, Z_NO_FLUSH)) != Z_OK)
   1.340 +	{
   1.341 +		GT->DBGFN (GT, "decompression error: %s", zlib_strerror (ret));
   1.342 +		return FALSE;
   1.343 +	}
   1.344 +
   1.345 +	GT->DBGFN (GT, "inz->avail_in = %u, inz->avail_out = %u", inz->avail_in, 
   1.346 +	           inz->avail_out);
   1.347 +
   1.348 +	stream->pos += free_size - inz->avail_out;
   1.349 +
   1.350 +	if (ret == Z_STREAM_END)
   1.351 +		zstream_close (stream);
   1.352 +
   1.353 +	return TRUE;
   1.354 +#endif /* USE_ZLIB */
   1.355 +}