diff options
Diffstat (limited to 'src/include/gnunet_common.h')
-rw-r--r-- | src/include/gnunet_common.h | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h new file mode 100644 index 000000000..61b572eb8 --- /dev/null +++ b/src/include/gnunet_common.h | |||
@@ -0,0 +1,469 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2006 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file include/gnunet_common.h | ||
23 | * @brief commonly used definitions; globals in this file | ||
24 | * are exempt from the rule that the module name ("common") | ||
25 | * must be part of the symbol name. | ||
26 | * | ||
27 | * @author Christian Grothoff | ||
28 | * @author Nils Durner | ||
29 | */ | ||
30 | #ifndef GNUNET_COMMON_H | ||
31 | #define GNUNET_COMMON_H | ||
32 | |||
33 | /** | ||
34 | * Version of the API (for entire gnunetutil.so library). | ||
35 | */ | ||
36 | #define GNUNET_UTIL_VERSION 0x00000000 | ||
37 | |||
38 | /** | ||
39 | * Name used for "services" that are actually command-line | ||
40 | * programs invoked by the end user. | ||
41 | */ | ||
42 | #define GNUNET_CLIENT_SERVICE_NAME "client" | ||
43 | |||
44 | /** | ||
45 | * Named constants for return values. The following | ||
46 | * invariants hold: "GNUNET_NO == 0" (to allow "if (GNUNET_NO)") | ||
47 | * "GNUNET_OK != GNUNET_SYSERR", "GNUNET_OK != GNUNET_NO", "GNUNET_NO != GNUNET_SYSERR" | ||
48 | * and finally "GNUNET_YES != GNUNET_NO". | ||
49 | */ | ||
50 | #define GNUNET_OK 1 | ||
51 | #define GNUNET_SYSERR -1 | ||
52 | #define GNUNET_YES 1 | ||
53 | #define GNUNET_NO 0 | ||
54 | |||
55 | #define GNUNET_MIN(a,b) (((a) < (b)) ? (a) : (b)) | ||
56 | |||
57 | #define GNUNET_MAX(a,b) (((a) > (b)) ? (a) : (b)) | ||
58 | |||
59 | /** | ||
60 | * gcc-ism to get packed structs. | ||
61 | */ | ||
62 | #define GNUNET_PACKED __attribute__((packed)) | ||
63 | |||
64 | |||
65 | /* ************************ super-general types *********************** */ | ||
66 | |||
67 | /** | ||
68 | * Header for all communications. | ||
69 | */ | ||
70 | struct GNUNET_MessageHeader | ||
71 | { | ||
72 | |||
73 | /** | ||
74 | * The length of the struct (in bytes, including the length field itself) | ||
75 | */ | ||
76 | uint16_t size GNUNET_PACKED; | ||
77 | |||
78 | /** | ||
79 | * The type of the message (XX_CS_PROTO_XXXX) | ||
80 | */ | ||
81 | uint16_t type GNUNET_PACKED; | ||
82 | |||
83 | }; | ||
84 | |||
85 | |||
86 | /** | ||
87 | * @brief 512-bit hashcode | ||
88 | */ | ||
89 | typedef struct | ||
90 | { | ||
91 | uint32_t bits[512 / 8 / sizeof (uint32_t)]; /* = 16 */ | ||
92 | } | ||
93 | GNUNET_HashCode; | ||
94 | |||
95 | |||
96 | /** | ||
97 | * The identity of the host (basically the SHA-512 hashcode of | ||
98 | * it's public key). | ||
99 | */ | ||
100 | struct GNUNET_PeerIdentity | ||
101 | { | ||
102 | GNUNET_HashCode hashPubKey GNUNET_PACKED; | ||
103 | }; | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Function called with a filename. | ||
108 | * | ||
109 | * @param filename complete filename (absolute path) | ||
110 | * @param cls closure | ||
111 | * @return GNUNET_OK to continue to iterate, | ||
112 | * GNUNET_SYSERR to abort iteration with error! | ||
113 | */ | ||
114 | typedef int (*GNUNET_FileNameCallback) (void *cls, const char *filename); | ||
115 | |||
116 | |||
117 | /* ****************************** logging ***************************** */ | ||
118 | |||
119 | /** | ||
120 | * Types of errors. | ||
121 | */ | ||
122 | enum GNUNET_ErrorType | ||
123 | { | ||
124 | GNUNET_ERROR_TYPE_ERROR = 1, | ||
125 | GNUNET_ERROR_TYPE_WARNING = 2, | ||
126 | GNUNET_ERROR_TYPE_INFO = 4, | ||
127 | GNUNET_ERROR_TYPE_DEBUG = 8, | ||
128 | GNUNET_ERROR_TYPE_INVALID = 16, | ||
129 | GNUNET_ERROR_TYPE_BULK = 32 | ||
130 | }; | ||
131 | |||
132 | /** | ||
133 | * User-defined handler for log messages. | ||
134 | * | ||
135 | * @param cls closure | ||
136 | * @param kind severeity | ||
137 | * @param component what component is issuing the message? | ||
138 | * @param date when was the message logged? | ||
139 | * @param message what is the message | ||
140 | */ | ||
141 | typedef void (*GNUNET_Logger) (void *cls, | ||
142 | enum GNUNET_ErrorType kind, | ||
143 | const char *component, | ||
144 | const char *date, const char *message); | ||
145 | |||
146 | /** | ||
147 | * Main log function. | ||
148 | * | ||
149 | * @param kind how serious is the error? | ||
150 | * @param message what is the message (format string) | ||
151 | * @param ... arguments for format string | ||
152 | */ | ||
153 | void GNUNET_log (enum GNUNET_ErrorType kind, const char *message, ...); | ||
154 | |||
155 | |||
156 | |||
157 | /** | ||
158 | * Log function that specifies an alternative component. | ||
159 | * This function should be used by plugins. | ||
160 | * | ||
161 | * @param kind how serious is the error? | ||
162 | * @param comp component responsible for generating the message | ||
163 | * @param message what is the message (format string) | ||
164 | * @param ... arguments for format string | ||
165 | */ | ||
166 | void | ||
167 | GNUNET_log_from (enum GNUNET_ErrorType kind, | ||
168 | const char *comp, const char *message, ...); | ||
169 | |||
170 | |||
171 | /** | ||
172 | * Ignore the next n calls to the log function. | ||
173 | * | ||
174 | * @param n number of log calls to ignore, use 0 to | ||
175 | * assert that the log skip counter is currently zero. | ||
176 | */ | ||
177 | void GNUNET_log_skip (unsigned int n); | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Setup logging. | ||
182 | * | ||
183 | * @param component default component to use | ||
184 | * @param loglevel what types of messages should be logged | ||
185 | * @param logfile change logging to logfile (use NULL to keep stderr) | ||
186 | * @return GNUNET_OK on success, GNUNET_SYSERR if logfile could not be opened | ||
187 | */ | ||
188 | int | ||
189 | GNUNET_log_setup (const char *component, | ||
190 | const char *loglevel, const char *logfile); | ||
191 | |||
192 | /** | ||
193 | * Add a custom logger. | ||
194 | * | ||
195 | * @param logger log function | ||
196 | * @param logger_cls closure for logger | ||
197 | */ | ||
198 | void GNUNET_logger_add (GNUNET_Logger logger, void *logger_cls); | ||
199 | |||
200 | /** | ||
201 | * Remove a custom logger. | ||
202 | * | ||
203 | * @param logger log function | ||
204 | * @param logger_cls closure for logger | ||
205 | */ | ||
206 | void GNUNET_logger_remove (GNUNET_Logger logger, void *logger_cls); | ||
207 | |||
208 | |||
209 | /** | ||
210 | * Convert a peer identity to a string (for printing debug messages). | ||
211 | * This is one of the very few calls in the entire API that is | ||
212 | * NOT reentrant! | ||
213 | * | ||
214 | * @param pid the peer identity | ||
215 | * @return string form of the pid; will be overwritten by next | ||
216 | * call to GNUNET_i2s. | ||
217 | */ | ||
218 | const char *GNUNET_i2s (const struct GNUNET_PeerIdentity *pid); | ||
219 | |||
220 | /** | ||
221 | * Convert error type to string. | ||
222 | * | ||
223 | * @param kind type to convert | ||
224 | * @return string corresponding to the type | ||
225 | */ | ||
226 | const char *GNUNET_error_type_to_string (enum GNUNET_ErrorType kind); | ||
227 | |||
228 | /** | ||
229 | * Use this for fatal errors that cannot be handled | ||
230 | */ | ||
231 | #define GNUNET_assert(cond) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Assertion failed at %s:%d.\n"), __FILE__, __LINE__); abort(); } } while(0) | ||
232 | |||
233 | /** | ||
234 | * Use this for fatal errors that cannot be handled | ||
235 | */ | ||
236 | #define GNUNET_assert_at(cond, f, l) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Assertion failed at %s:%d.\n"), f, l); abort(); } } while(0) | ||
237 | |||
238 | /** | ||
239 | * Use this for internal assertion violations that are | ||
240 | * not fatal (can be handled) but should not occur. | ||
241 | */ | ||
242 | #define GNUNET_break(cond) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Assertion failed at %s:%d.\n"), __FILE__, __LINE__); } } while(0) | ||
243 | |||
244 | /** | ||
245 | * Use this for assertion violations caused by other | ||
246 | * peers (i.e. protocol violations). We do not want to | ||
247 | * confuse end-users (say, some other peer runs an | ||
248 | * older, broken or incompatible GNUnet version), but | ||
249 | * we still want to see these problems during | ||
250 | * development and testing. "OP == other peer". | ||
251 | */ | ||
252 | #define GNUNET_break_op(cond) do { if (! (cond)) { GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("External protocol violation detected at %s:%d.\n"), __FILE__, __LINE__); } } while(0) | ||
253 | |||
254 | /** | ||
255 | * Log an error message at log-level 'level' that indicates | ||
256 | * a failure of the command 'cmd' with the message given | ||
257 | * by strerror(errno). | ||
258 | */ | ||
259 | #define GNUNET_log_strerror(level, cmd) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, STRERROR(errno)); } while(0) | ||
260 | |||
261 | /** | ||
262 | * Log an error message at log-level 'level' that indicates | ||
263 | * a failure of the command 'cmd' with the message given | ||
264 | * by strerror(errno). | ||
265 | */ | ||
266 | #define GNUNET_log_strerror_file(level, cmd, filename) do { GNUNET_log(level, _("`%s' failed on file `%s' at %s:%d with error: %s\n"), cmd, filename,__FILE__, __LINE__, STRERROR(errno)); } while(0) | ||
267 | |||
268 | /* ************************* endianess conversion ****************** */ | ||
269 | |||
270 | /** | ||
271 | * Convert a long-long to host-byte-order. | ||
272 | * @param n the value in network byte order | ||
273 | * @return the same value in host byte order | ||
274 | */ | ||
275 | unsigned long long GNUNET_ntohll (unsigned long long n); | ||
276 | |||
277 | /** | ||
278 | * Convert a long long to network-byte-order. | ||
279 | * @param n the value in host byte order | ||
280 | * @return the same value in network byte order | ||
281 | */ | ||
282 | unsigned long long GNUNET_htonll (unsigned long long n); | ||
283 | |||
284 | |||
285 | /* ************************* allocation functions ****************** */ | ||
286 | |||
287 | /** | ||
288 | * Maximum allocation with GNUNET_malloc macro. | ||
289 | */ | ||
290 | #define GNUNET_MAX_GNUNET_MALLOC_CHECKED (1024 * 1024 * 40) | ||
291 | |||
292 | /** | ||
293 | * Wrapper around malloc. Allocates size bytes of memory. | ||
294 | * The memory will be zero'ed out. | ||
295 | * | ||
296 | * @param size the number of bytes to allocate, must be | ||
297 | * smaller than 40 MB. | ||
298 | * @return pointer to size bytes of memory | ||
299 | */ | ||
300 | #define GNUNET_malloc(size) GNUNET_xmalloc_(size, __FILE__, __LINE__) | ||
301 | |||
302 | /** | ||
303 | * Wrapper around malloc. Allocates size bytes of memory. | ||
304 | * The memory will be zero'ed out. | ||
305 | * | ||
306 | * @param size the number of bytes to allocate | ||
307 | * @return pointer to size bytes of memory | ||
308 | */ | ||
309 | #define GNUNET_malloc_large(size) GNUNET_xmalloc_unchecked_(size, __FILE__, __LINE__) | ||
310 | |||
311 | /** | ||
312 | * Wrapper around realloc. Rellocates size bytes of memory. | ||
313 | * | ||
314 | * @param ptr the pointer to reallocate | ||
315 | * @param size the number of bytes to reallocate | ||
316 | * @return pointer to size bytes of memory | ||
317 | */ | ||
318 | #define GNUNET_realloc(ptr, size) GNUNET_xrealloc_(ptr, size, __FILE__, __LINE__) | ||
319 | |||
320 | /** | ||
321 | * Wrapper around free. Frees the memory referred to by ptr. | ||
322 | * Note that is is generally better to free memory that was | ||
323 | * allocated with GNUNET_array_grow using GNUNET_array_grow(mem, size, 0) instead of GNUNET_free. | ||
324 | * | ||
325 | * @param ptr location where to free the memory. ptr must have | ||
326 | * been returned by GNUNET_strdup, GNUNET_malloc or GNUNET_array_grow earlier. | ||
327 | */ | ||
328 | #define GNUNET_free(ptr) GNUNET_xfree_(ptr, __FILE__, __LINE__) | ||
329 | |||
330 | /** | ||
331 | * Free the memory pointed to by ptr if ptr is not NULL. | ||
332 | * Equivalent to if (ptr!=null)GNUNET_free(ptr). | ||
333 | * | ||
334 | * @param ptr the location in memory to free | ||
335 | */ | ||
336 | #define GNUNET_free_non_null(ptr) do { void * __x__ = ptr; if (__x__ != NULL) { GNUNET_free(__x__); } } while(0) | ||
337 | |||
338 | /** | ||
339 | * Wrapper around GNUNET_strdup. Makes a copy of the zero-terminated string | ||
340 | * pointed to by a. | ||
341 | * | ||
342 | * @param a pointer to a zero-terminated string | ||
343 | * @return a copy of the string including zero-termination | ||
344 | */ | ||
345 | #define GNUNET_strdup(a) GNUNET_xstrdup_(a,__FILE__,__LINE__) | ||
346 | |||
347 | /** | ||
348 | * Grow a well-typed (!) array. This is a convenience | ||
349 | * method to grow a vector <tt>arr</tt> of size <tt>size</tt> | ||
350 | * to the new (target) size <tt>tsize</tt>. | ||
351 | * <p> | ||
352 | * | ||
353 | * Example (simple, well-typed stack): | ||
354 | * | ||
355 | * <pre> | ||
356 | * static struct foo * myVector = NULL; | ||
357 | * static int myVecLen = 0; | ||
358 | * | ||
359 | * static void push(struct foo * elem) { | ||
360 | * GNUNET_array_grow(myVector, myVecLen, myVecLen+1); | ||
361 | * memcpy(&myVector[myVecLen-1], elem, sizeof(struct foo)); | ||
362 | * } | ||
363 | * | ||
364 | * static void pop(struct foo * elem) { | ||
365 | * if (myVecLen == 0) die(); | ||
366 | * memcpy(elem, myVector[myVecLen-1], sizeof(struct foo)); | ||
367 | * GNUNET_array_grow(myVector, myVecLen, myVecLen-1); | ||
368 | * } | ||
369 | * </pre> | ||
370 | * | ||
371 | * @param arr base-pointer of the vector, may be NULL if size is 0; | ||
372 | * will be updated to reflect the new address. The TYPE of | ||
373 | * arr is important since size is the number of elements and | ||
374 | * not the size in bytes | ||
375 | * @param size the number of elements in the existing vector (number | ||
376 | * of elements to copy over) | ||
377 | * @param tsize the target size for the resulting vector, use 0 to | ||
378 | * free the vector (then, arr will be NULL afterwards). | ||
379 | */ | ||
380 | #define GNUNET_array_grow(arr,size,tsize) GNUNET_xgrow_((void**)&arr, sizeof(arr[0]), &size, tsize, __FILE__, __LINE__) | ||
381 | |||
382 | /** | ||
383 | * Append an element to a list (growing the | ||
384 | * list by one). | ||
385 | */ | ||
386 | #define GNUNET_array_append(arr,size,element) do { GNUNET_array_grow(arr,size,size+1); arr[size-1] = element; } while(0) | ||
387 | |||
388 | /** | ||
389 | * Like snprintf, just aborts if the buffer is of insufficient size. | ||
390 | */ | ||
391 | int GNUNET_snprintf (char *buf, size_t size, const char *format, ...); | ||
392 | |||
393 | /** | ||
394 | * Like asprintf, just portable. | ||
395 | */ | ||
396 | int GNUNET_asprintf (char **buf, const char *format, ...); | ||
397 | |||
398 | |||
399 | /* ************** internal implementations, use macros above! ************** */ | ||
400 | |||
401 | /** | ||
402 | * Allocate memory. Checks the return value, aborts if no more | ||
403 | * memory is available. Don't use GNUNET_xmalloc_ directly. Use the | ||
404 | * GNUNET_malloc macro. | ||
405 | * The memory will be zero'ed out. | ||
406 | */ | ||
407 | void *GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber); | ||
408 | |||
409 | /** | ||
410 | * Allocate memory. This function does not check if the | ||
411 | * allocation request is within reasonable bounds, allowing | ||
412 | * allocations larger than 40 MB. If you don't expect the | ||
413 | * possibility of very large allocations, use GNUNET_malloc instead. | ||
414 | * The memory will be zero'ed out. | ||
415 | */ | ||
416 | void *GNUNET_xmalloc_unchecked_ (size_t size, | ||
417 | const char *filename, int linenumber); | ||
418 | |||
419 | /** | ||
420 | * Reallocate memory. Checks the return value, aborts if no more | ||
421 | * memory is available. | ||
422 | */ | ||
423 | void *GNUNET_xrealloc_ (void *ptr, | ||
424 | const size_t n, const char *filename, int linenumber); | ||
425 | |||
426 | /** | ||
427 | * Free memory. Merely a wrapper for the case that we | ||
428 | * want to keep track of allocations. Don't use GNUNET_xfree_ | ||
429 | * directly. Use the GNUNET_free macro. | ||
430 | */ | ||
431 | void GNUNET_xfree_ (void *ptr, const char *filename, int linenumber); | ||
432 | |||
433 | |||
434 | /** | ||
435 | * Dup a string. Don't call GNUNET_xstrdup_ directly. Use the GNUNET_strdup macro. | ||
436 | */ | ||
437 | char *GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber); | ||
438 | |||
439 | /** | ||
440 | * Grow an array, the new elements are zeroed out. | ||
441 | * Grows old by (*oldCount-newCount)*elementSize | ||
442 | * bytes and sets *oldCount to newCount. | ||
443 | * | ||
444 | * Don't call GNUNET_xgrow_ directly. Use the GNUNET_array_grow macro. | ||
445 | * | ||
446 | * @param old address of the pointer to the array | ||
447 | * *old may be NULL | ||
448 | * @param elementSize the size of the elements of the array | ||
449 | * @param oldCount address of the number of elements in the *old array | ||
450 | * @param newCount number of elements in the new array, may be 0 (then *old will be NULL afterwards) | ||
451 | */ | ||
452 | void GNUNET_xgrow_ (void **old, | ||
453 | size_t elementSize, | ||
454 | unsigned int *oldCount, | ||
455 | unsigned int newCount, | ||
456 | const char *filename, int linenumber); | ||
457 | |||
458 | |||
459 | |||
460 | |||
461 | #if __STDC_VERSION__ < 199901L | ||
462 | # if __GNUC__ >= 2 | ||
463 | # define __func__ __FUNCTION__ | ||
464 | # else | ||
465 | # define __func__ "<unknown>" | ||
466 | # endif | ||
467 | #endif | ||
468 | |||
469 | #endif /*GNUNET_COMMON_H_ */ | ||