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