Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
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 } |