annotate 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
rev   line source
paulo@0 1 /*
paulo@0 2 * $Id: gt_utils.c,v 1.10 2004/04/17 06:05:54 hipnod Exp $
paulo@0 3 *
paulo@0 4 * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net)
paulo@0 5 *
paulo@0 6 * This program is free software; you can redistribute it and/or modify it
paulo@0 7 * under the terms of the GNU General Public License as published by the
paulo@0 8 * Free Software Foundation; either version 2, or (at your option) any
paulo@0 9 * later version.
paulo@0 10 *
paulo@0 11 * This program is distributed in the hope that it will be useful, but
paulo@0 12 * WITHOUT ANY WARRANTY; without even the implied warranty of
paulo@0 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
paulo@0 14 * General Public License for more details.
paulo@0 15 */
paulo@0 16
paulo@0 17 #include "gt_gnutella.h"
paulo@0 18
paulo@0 19 #include "gt_utils.h"
paulo@0 20
paulo@0 21 #ifdef USE_ZLIB
paulo@0 22 #include <zlib.h>
paulo@0 23 #endif /* USE_ZLIB */
paulo@0 24
paulo@0 25 /*****************************************************************************/
paulo@0 26
paulo@0 27 int peer_addr (int fd, in_addr_t *r_ip, in_port_t *r_port)
paulo@0 28 {
paulo@0 29 struct sockaddr_in sin;
paulo@0 30 int len = sizeof (struct sockaddr_in);
paulo@0 31
paulo@0 32 if (getpeername (fd, (struct sockaddr *) &sin, &len) < 0)
paulo@0 33 return FALSE;
paulo@0 34
paulo@0 35 /* maybe port should be kept in network byte-order */
paulo@0 36 if (r_port)
paulo@0 37 *r_port = ntohs (sin.sin_port);
paulo@0 38
paulo@0 39 if (r_ip)
paulo@0 40 *r_ip = sin.sin_addr.s_addr;
paulo@0 41
paulo@0 42 return TRUE;
paulo@0 43 }
paulo@0 44
paulo@0 45 char *make_str (char *array, int len)
paulo@0 46 {
paulo@0 47 static int data_len = 0;
paulo@0 48 static char *data = 0;
paulo@0 49
paulo@0 50 if (len <= 0)
paulo@0 51 return "";
paulo@0 52
paulo@0 53 if (!data_len || data_len < len)
paulo@0 54 {
paulo@0 55 if (data)
paulo@0 56 free (data);
paulo@0 57
paulo@0 58 if (!(data = malloc (len + 1)))
paulo@0 59 return "(No memory for string)";
paulo@0 60 }
paulo@0 61
paulo@0 62 memcpy (data, array, len);
paulo@0 63
paulo@0 64 data[len] = 0;
paulo@0 65
paulo@0 66 if (len > data_len)
paulo@0 67 data_len = len;
paulo@0 68
paulo@0 69 return data;
paulo@0 70 }
paulo@0 71
paulo@0 72 void fprint_hex (FILE *f, char *buf, int len)
paulo@0 73 {
paulo@0 74 int i, j;
paulo@0 75 unsigned char *line;
paulo@0 76 unsigned char *end;
paulo@0 77
paulo@0 78 end = buf + len;
paulo@0 79
paulo@0 80 while ((line = buf) != end)
paulo@0 81 {
paulo@0 82 for (i = 0; i < 16; i++)
paulo@0 83 {
paulo@0 84 if (line + i == end)
paulo@0 85 break;
paulo@0 86
paulo@0 87 fprintf (f, "%02x ", line[i]);
paulo@0 88 }
paulo@0 89
paulo@0 90 for (j = i; j < 16; j++)
paulo@0 91 fprintf (f, " ");
paulo@0 92
paulo@0 93 fprintf (f, " ");
paulo@0 94
paulo@0 95 for (i = 0; i < 16; i++)
paulo@0 96 {
paulo@0 97 if (line + i == end)
paulo@0 98 break;
paulo@0 99
paulo@0 100 fprintf (f, "%c", isprint (line[i]) ? line[i] : '.');
paulo@0 101 }
paulo@0 102
paulo@0 103 buf += i;
paulo@0 104 fprintf (f, "\n");
paulo@0 105 }
paulo@0 106 }
paulo@0 107
paulo@0 108 /*****************************************************************************/
paulo@0 109 /* HTTP HEADER STORAGE */
paulo@0 110
paulo@0 111 #if 0
paulo@0 112 static unsigned long hash_lowercase (Dataset *d, void *key, size_t key_len)
paulo@0 113 {
paulo@0 114 char *str;
paulo@0 115 int i;
paulo@0 116 unsigned long hash;
paulo@0 117
paulo@0 118 for (hash = 0, i = 0; i < key_len; i++)
paulo@0 119 hash ^= tolower (str[i]);
paulo@0 120
paulo@0 121 return hash;
paulo@0 122 }
paulo@0 123
paulo@0 124 static int cmp_caseless (Dataset *d, DatasetNode *node, void *key,
paulo@0 125 size_t key_len)
paulo@0 126 {
paulo@0 127 return strncasecmp (node->key, key, MIN (node->key_len, key_len));
paulo@0 128 }
paulo@0 129
paulo@0 130 /* Like a Dataset, but stores case-insensitive strings for keys to
paulo@0 131 * string fields. */
paulo@0 132 Headers *headers_new ()
paulo@0 133 {
paulo@0 134 Dataset *dataset;
paulo@0 135
paulo@0 136 if (!(dataset = dataset_new (DATASET_DEFAULT)))
paulo@0 137 return NULL;
paulo@0 138
paulo@0 139 dataset->hash_func = hash_lowercase;
paulo@0 140
paulo@0 141 return hdrs;
paulo@0 142 }
paulo@0 143
paulo@0 144 char *header_lookup (Headers *hdrs, char *key)
paulo@0 145 {
paulo@0 146 char *value;
paulo@0 147
paulo@0 148 if (!hdrs || !key)
paulo@0 149 return NULL;
paulo@0 150
paulo@0 151 return dataset_lookupstr (dataset, key);
paulo@0 152 }
paulo@0 153
paulo@0 154 void header_insert (Headers **hdrs, char *key, char *value)
paulo@0 155 {
paulo@0 156 if (!d || !key)
paulo@0 157 return;
paulo@0 158
paulo@0 159 if (!(*hdrs) && !(*hdrs = headers_new ()))
paulo@0 160 return;
paulo@0 161
paulo@0 162 dataset_insertstr (hdrs->dataset, key, value);
paulo@0 163 }
paulo@0 164
paulo@0 165 void header_remove (Headers *hdrs, char *key)
paulo@0 166 {
paulo@0 167 if (!hdrs)
paulo@0 168 return NULL;
paulo@0 169
paulo@0 170 dataset_remove (hdrs->dataset, key, size);
paulo@0 171 }
paulo@0 172 #endif
paulo@0 173
paulo@0 174 /*****************************************************************************/
paulo@0 175 /* ZLIB WRAPPER ROUTINES */
paulo@0 176
paulo@0 177 static char *zlib_strerror (int error)
paulo@0 178 {
paulo@0 179 #ifndef USE_ZLIB
paulo@0 180 return NULL;
paulo@0 181 #else /* USE_ZLIB */
paulo@0 182 switch (error)
paulo@0 183 {
paulo@0 184 case Z_OK: return "OK";
paulo@0 185 case Z_STREAM_END: return "End of stream";
paulo@0 186 case Z_NEED_DICT: return "Decompressing dictionary needed";
paulo@0 187 case Z_STREAM_ERROR: return "Stream error";
paulo@0 188 case Z_ERRNO: return "Generic zlib error";
paulo@0 189 case Z_DATA_ERROR: return "Data error";
paulo@0 190 case Z_MEM_ERROR: return "Memory error";
paulo@0 191 case Z_BUF_ERROR: return "Buffer error";
paulo@0 192 case Z_VERSION_ERROR: return "Incompatible runtime zlib library";
paulo@0 193 default: break;
paulo@0 194 }
paulo@0 195
paulo@0 196 return "Invalid zlib error code";
paulo@0 197 #endif /* USE_ZLIB */
paulo@0 198 }
paulo@0 199
paulo@0 200 static void zstream_close (ZlibStream *stream)
paulo@0 201 {
paulo@0 202 #ifdef USE_ZLIB
paulo@0 203 switch (stream->type)
paulo@0 204 {
paulo@0 205 case ZSTREAM_INFLATE: inflateEnd (stream->streamptr); break;
paulo@0 206 case ZSTREAM_DEFLATE: deflateEnd (stream->streamptr); break;
paulo@0 207 default: break;
paulo@0 208 }
paulo@0 209
paulo@0 210 if (stream->streamptr)
paulo@0 211 free (stream->streamptr);
paulo@0 212
paulo@0 213 stream->type = ZSTREAM_NONE;
paulo@0 214 stream->streamptr = NULL;
paulo@0 215 #endif /* USE_ZLIB */
paulo@0 216 }
paulo@0 217
paulo@0 218 ZlibStream *zlib_stream_open (size_t max_size)
paulo@0 219 {
paulo@0 220 ZlibStream *stream;
paulo@0 221 char *data;
paulo@0 222
paulo@0 223 if (!(stream = malloc (sizeof (ZlibStream))))
paulo@0 224 return NULL;
paulo@0 225
paulo@0 226 if (!(data = malloc (max_size)))
paulo@0 227 {
paulo@0 228 free (stream);
paulo@0 229 return NULL;
paulo@0 230 }
paulo@0 231
paulo@0 232 memset (stream, 0, sizeof (ZlibStream));
paulo@0 233 memset (data, 0, max_size);
paulo@0 234
paulo@0 235 stream->start = data;
paulo@0 236 stream->end = data + max_size;
paulo@0 237 stream->data = data;
paulo@0 238 stream->pos = data;
paulo@0 239 stream->type = ZSTREAM_NONE;
paulo@0 240
paulo@0 241 return stream;
paulo@0 242 }
paulo@0 243
paulo@0 244 void zlib_stream_close (ZlibStream *stream)
paulo@0 245 {
paulo@0 246 if (!stream)
paulo@0 247 return;
paulo@0 248
paulo@0 249 if (stream->type != ZSTREAM_NONE)
paulo@0 250 zstream_close (stream);
paulo@0 251
paulo@0 252 if (stream->data)
paulo@0 253 free (stream->data);
paulo@0 254
paulo@0 255 free (stream);
paulo@0 256 }
paulo@0 257
paulo@0 258 int zlib_stream_write (ZlibStream *stream, char *data, size_t size)
paulo@0 259 {
paulo@0 260 if (!stream)
paulo@0 261 return 0;
paulo@0 262
paulo@0 263 /* check for overflow */
paulo@0 264 if (stream->pos + (size-1) > stream->end)
paulo@0 265 return 0;
paulo@0 266
paulo@0 267 memcpy (stream->pos, data, size);
paulo@0 268
paulo@0 269 stream->pos += size;
paulo@0 270
paulo@0 271 return size;
paulo@0 272 }
paulo@0 273
paulo@0 274 int zlib_stream_read (ZlibStream *stream, char **r_data)
paulo@0 275 {
paulo@0 276 size_t size;
paulo@0 277
paulo@0 278 if (stream->start == stream->pos)
paulo@0 279 return 0;
paulo@0 280
paulo@0 281 *r_data = stream->start;
paulo@0 282
paulo@0 283 size = stream->pos - stream->start;
paulo@0 284
paulo@0 285 stream->start = stream->pos;
paulo@0 286
paulo@0 287 return size;
paulo@0 288 }
paulo@0 289
paulo@0 290 int zlib_stream_inflate (ZlibStream *stream, char *zdata, size_t size)
paulo@0 291 {
paulo@0 292 #ifndef USE_ZLIB
paulo@0 293 return FALSE;
paulo@0 294 #else /* USE_ZLIB */
paulo@0 295 z_streamp inz;
paulo@0 296 int ret;
paulo@0 297 size_t free_size;
paulo@0 298
paulo@0 299 if (!stream)
paulo@0 300 return FALSE;
paulo@0 301
paulo@0 302 if (!stream->streamptr)
paulo@0 303 {
paulo@0 304 assert (stream->type == ZSTREAM_NONE);
paulo@0 305
paulo@0 306 if (!(inz = malloc (sizeof (*inz))))
paulo@0 307 return FALSE;
paulo@0 308
paulo@0 309 inz->zalloc = NULL;
paulo@0 310 inz->zfree = NULL;
paulo@0 311 inz->opaque = NULL;
paulo@0 312
paulo@0 313 if ((ret = inflateInit (inz)) != Z_OK)
paulo@0 314 {
paulo@0 315 GT->DBGFN (GT, "inflateInit error %s", zlib_strerror (ret));
paulo@0 316 free (inz);
paulo@0 317 return FALSE;
paulo@0 318 }
paulo@0 319
paulo@0 320 stream->type = ZSTREAM_INFLATE;
paulo@0 321 stream->streamptr = inz;
paulo@0 322 }
paulo@0 323
paulo@0 324 inz = stream->streamptr;
paulo@0 325
paulo@0 326 /* Argh, I think this is right, but I'm not sure about the +1 */
paulo@0 327 free_size = stream->end - stream->pos + 1;
paulo@0 328
paulo@0 329 inz->next_in = zdata;
paulo@0 330 inz->avail_in = size;
paulo@0 331 inz->next_out = stream->pos;
paulo@0 332 inz->avail_out = free_size;
paulo@0 333
paulo@0 334 GT->DBGFN (GT, "next_out: %p avail_out: %u", inz->next_out, inz->avail_out);
paulo@0 335
paulo@0 336 if ((ret = inflate (inz, Z_NO_FLUSH)) != Z_OK)
paulo@0 337 {
paulo@0 338 GT->DBGFN (GT, "decompression error: %s", zlib_strerror (ret));
paulo@0 339 return FALSE;
paulo@0 340 }
paulo@0 341
paulo@0 342 GT->DBGFN (GT, "inz->avail_in = %u, inz->avail_out = %u", inz->avail_in,
paulo@0 343 inz->avail_out);
paulo@0 344
paulo@0 345 stream->pos += free_size - inz->avail_out;
paulo@0 346
paulo@0 347 if (ret == Z_STREAM_END)
paulo@0 348 zstream_close (stream);
paulo@0 349
paulo@0 350 return TRUE;
paulo@0 351 #endif /* USE_ZLIB */
paulo@0 352 }