]> git.ipfire.org Git - people/ms/strongswan.git/blame - src/libstrongswan/utils/utils.h
utils: Return plain drive letter as base/pathname for drive letters on Windows
[people/ms/strongswan.git] / src / libstrongswan / utils / utils.h
CommitLineData
552cc11b 1/*
766141bc 2 * Copyright (C) 2008-2014 Tobias Brunner
552cc11b
MW
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
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 MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
552cc11b
MW
15 */
16
17/**
bca34c37
TB
18 * @defgroup utils_i utils
19 * @{ @ingroup utils
552cc11b
MW
20 */
21
22#ifndef UTILS_H_
23#define UTILS_H_
24
25#include <sys/types.h>
26#include <stdlib.h>
27#include <stddef.h>
3f310c0d 28#include <sys/time.h>
0be12e35 29#include <string.h>
552cc11b 30
922ee2c5
MW
31#ifdef WIN32
32# include "windows.h"
33#else
34# define _GNU_SOURCE
35# include <arpa/inet.h>
36# include <sys/socket.h>
37# include <netdb.h>
38# include <netinet/in.h>
266ee0a1 39# include <sched.h>
922ee2c5
MW
40#endif
41
eab241fb
AS
42/**
43 * strongSwan program return codes
44 */
45#define SS_RC_LIBSTRONGSWAN_INTEGRITY 64
46#define SS_RC_DAEMON_INTEGRITY 65
3646c8a1 47#define SS_RC_INITIALIZATION_FAILED 66
eab241fb 48
5d8306de
AS
49#define SS_RC_FIRST SS_RC_LIBSTRONGSWAN_INTEGRITY
50#define SS_RC_LAST SS_RC_INITIALIZATION_FAILED
51
552cc11b
MW
52/**
53 * Number of bits in a byte
54 */
55#define BITS_PER_BYTE 8
56
57/**
58 * Default length for various auxiliary text buffers
59 */
60#define BUF_LEN 512
61
62/**
a2a28d90 63 * General purpose boolean type.
552cc11b 64 */
a2a28d90
TB
65#ifdef HAVE_STDBOOL_H
66# include <stdbool.h>
67#else
68# ifndef HAVE__BOOL
69# define _Bool signed char
70# endif /* HAVE__BOOL */
71# define bool _Bool
72# define false 0
73# define true 1
74# define __bool_true_false_are_defined 1
75#endif /* HAVE_STDBOOL_H */
76#ifndef FALSE
77# define FALSE false
78#endif /* FALSE */
79#ifndef TRUE
80# define TRUE true
81#endif /* TRUE */
82
9ee8b3b4
MW
83#include "enum.h"
84#include "utils/strerror.h"
85
a43f1e56
MW
86/**
87 * Directory separator character in paths on this platform
88 */
89#ifdef WIN32
90# define DIRECTORY_SEPARATOR "\\"
91#else
92# define DIRECTORY_SEPARATOR "/"
93#endif
94
87a79e6a
MW
95/**
96 * Initialize utility functions
97 */
98void utils_init();
99
100/**
101 * Deinitialize utility functions
102 */
103void utils_deinit();
104
a2a28d90
TB
105/**
106 * Helper function that compares two strings for equality
107 */
108static inline bool streq(const char *x, const char *y)
109{
110 return strcmp(x, y) == 0;
111}
552cc11b
MW
112
113/**
985dcab1 114 * Helper function that compares two strings for equality, length limited
552cc11b 115 */
985dcab1
TB
116static inline bool strneq(const char *x, const char *y, size_t len)
117{
118 return strncmp(x, y, len) == 0;
119}
552cc11b 120
f460facd
TB
121/**
122 * Helper function that checks if a string starts with a given prefix
123 */
124static inline bool strpfx(const char *x, const char *prefix)
125{
126 return strneq(x, prefix, strlen(prefix));
127}
128
63176bbc 129/**
a2a28d90 130 * Helper function that compares two strings for equality ignoring case
63176bbc 131 */
a2a28d90
TB
132static inline bool strcaseeq(const char *x, const char *y)
133{
134 return strcasecmp(x, y) == 0;
135}
63176bbc 136
7a3e0a63 137/**
985dcab1 138 * Helper function that compares two strings for equality ignoring case, length limited
7a3e0a63 139 */
985dcab1
TB
140static inline bool strncaseeq(const char *x, const char *y, size_t len)
141{
142 return strncasecmp(x, y, len) == 0;
143}
7a3e0a63 144
32a145fd
TB
145/**
146 * Helper function that checks if a string starts with a given prefix
147 */
148static inline bool strcasepfx(const char *x, const char *prefix)
149{
150 return strncaseeq(x, prefix, strlen(prefix));
151}
152
1038d9fe
MW
153/**
154 * NULL-safe strdup variant
155 */
753ca22f
TB
156static inline char *strdupnull(const char *s)
157{
158 return s ? strdup(s) : NULL;
159}
1038d9fe 160
552cc11b 161/**
985dcab1 162 * Helper function that compares two binary blobs for equality
552cc11b 163 */
985dcab1
TB
164static inline bool memeq(const void *x, const void *y, size_t len)
165{
166 return memcmp(x, y, len) == 0;
167}
552cc11b
MW
168
169/**
170 * Macro gives back larger of two values.
171 */
e822fc57
TB
172#define max(x,y) ({ \
173 typeof(x) _x = (x); \
174 typeof(y) _y = (y); \
175 _x > _y ? _x : _y; })
176
552cc11b
MW
177
178/**
179 * Macro gives back smaller of two values.
180 */
e822fc57
TB
181#define min(x,y) ({ \
182 typeof(x) _x = (x); \
183 typeof(y) _y = (y); \
184 _x < _y ? _x : _y; })
552cc11b
MW
185
186/**
187 * Call destructor of an object, if object != NULL
188 */
189#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
190
191/**
192 * Call offset destructor of an object, if object != NULL
193 */
194#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
195
196/**
197 * Call function destructor of an object, if object != NULL
198 */
199#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
200
201/**
202 * Debug macro to follow control flow
203 */
204#define POS printf("%s, line %d\n", __FILE__, __LINE__)
205
74eed73a
MW
206/**
207 * Object allocation/initialization macro, using designated initializer.
208 */
2e1f4a46
MW
209#define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \
210 *(this) = (typeof(*(this))){ __VA_ARGS__ }; }
74eed73a 211
1a1ff9d1
MW
212/**
213 * Method declaration/definition macro, providing private and public interface.
214 *
215 * Defines a method name with this as first parameter and a return value ret,
216 * and an alias for this method with a _ prefix, having the this argument
217 * safely casted to the public interface iface.
218 * _name is provided a function pointer, but will get optimized out by GCC.
219 */
220#define METHOD(iface, name, ret, this, ...) \
23d2bf84
MW
221 static ret name(union {iface *_public; this;} \
222 __attribute__((transparent_union)), ##__VA_ARGS__); \
d185b6ac 223 static typeof(name) *_##name = (typeof(name)*)name; \
23d2bf84
MW
224 static ret name(this, ##__VA_ARGS__)
225
226/**
227 * Same as METHOD(), but is defined for two public interfaces.
228 */
229#define METHOD2(iface1, iface2, name, ret, this, ...) \
230 static ret name(union {iface1 *_public1; iface2 *_public2; this;} \
231 __attribute__((transparent_union)), ##__VA_ARGS__); \
d185b6ac 232 static typeof(name) *_##name = (typeof(name)*)name; \
1a1ff9d1
MW
233 static ret name(this, ##__VA_ARGS__)
234
9e932513
MW
235/**
236 * Callback declaration/definition macro, allowing casted first parameter.
237 *
238 * This is very similar to METHOD, but instead of casting the first parameter
239 * to a public interface, it uses a void*. This allows type safe definition
240 * of a callback function, while using the real type for the first parameter.
241 */
242#define CALLBACK(name, ret, param1, ...) \
243 static ret _cb_##name(union {void *_generic; param1;} \
244 __attribute__((transparent_union)), ##__VA_ARGS__); \
245 static typeof(_cb_##name) *name = (typeof(_cb_##name)*)_cb_##name; \
246 static ret _cb_##name(param1, ##__VA_ARGS__)
247
7ba89ccd
MW
248/**
249 * Architecture independent bitfield definition helpers (at least with GCC).
250 *
251 * Defines a bitfield with a type t and a fixed size of bitfield members, e.g.:
252 * BITFIELD2(u_int8_t,
253 * low: 4,
254 * high: 4,
255 * ) flags;
256 * The member defined first placed at bit 0.
257 */
258#if BYTE_ORDER == LITTLE_ENDIAN
259#define BITFIELD2(t, a, b,...) struct { t a; t b; __VA_ARGS__}
260#define BITFIELD3(t, a, b, c,...) struct { t a; t b; t c; __VA_ARGS__}
261#define BITFIELD4(t, a, b, c, d,...) struct { t a; t b; t c; t d; __VA_ARGS__}
262#define BITFIELD5(t, a, b, c, d, e,...) struct { t a; t b; t c; t d; t e; __VA_ARGS__}
263#elif BYTE_ORDER == BIG_ENDIAN
264#define BITFIELD2(t, a, b,...) struct { t b; t a; __VA_ARGS__}
265#define BITFIELD3(t, a, b, c,...) struct { t c; t b; t a; __VA_ARGS__}
266#define BITFIELD4(t, a, b, c, d,...) struct { t d; t c; t b; t a; __VA_ARGS__}
267#define BITFIELD5(t, a, b, c, d, e,...) struct { t e; t d; t c; t b; t a; __VA_ARGS__}
268#endif
269
552cc11b
MW
270/**
271 * Macro to allocate a sized type.
272 */
273#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
274
fca4d3ee
MW
275/**
276 * Get the number of elements in an array
277 */
278#define countof(array) (sizeof(array)/sizeof(array[0]))
279
479f2950
MW
280/**
281 * Ignore result of functions tagged with warn_unused_result attributes
282 */
d0230850 283#define ignore_result(call) { if(call){}; }
479f2950 284
552cc11b
MW
285/**
286 * Assign a function as a class method
287 */
288#define ASSIGN(method, function) (method = (typeof(method))function)
289
290/**
291 * time_t not defined
292 */
293#define UNDEFINED_TIME 0
294
9f0327e6
AS
295/**
296 * Maximum time since epoch causing wrap-around on Jan 19 03:14:07 UTC 2038
297 */
298#define TIME_32_BIT_SIGNED_MAX 0x7fffffff
299
cc396286
TB
300/**
301 * define some missing fixed width int types on OpenSolaris.
302 * TODO: since the uintXX_t types are defined by the C99 standard we should
303 * probably use those anyway
304 */
922ee2c5 305#if defined __sun || defined WIN32
cc396286
TB
306 #include <stdint.h>
307 typedef uint8_t u_int8_t;
308 typedef uint16_t u_int16_t;
309 typedef uint32_t u_int32_t;
310 typedef uint64_t u_int64_t;
311#endif
312
552cc11b
MW
313typedef enum status_t status_t;
314
315/**
316 * Return values of function calls.
317 */
318enum status_t {
319 /**
320 * Call succeeded.
321 */
322 SUCCESS,
7daf5226 323
552cc11b
MW
324 /**
325 * Call failed.
326 */
327 FAILED,
7daf5226 328
552cc11b
MW
329 /**
330 * Out of resources.
331 */
332 OUT_OF_RES,
7daf5226 333
552cc11b
MW
334 /**
335 * The suggested operation is already done
336 */
337 ALREADY_DONE,
7daf5226 338
552cc11b
MW
339 /**
340 * Not supported.
341 */
342 NOT_SUPPORTED,
7daf5226 343
552cc11b
MW
344 /**
345 * One of the arguments is invalid.
346 */
347 INVALID_ARG,
7daf5226 348
552cc11b
MW
349 /**
350 * Something could not be found.
351 */
352 NOT_FOUND,
7daf5226 353
552cc11b
MW
354 /**
355 * Error while parsing.
356 */
357 PARSE_ERROR,
7daf5226 358
552cc11b
MW
359 /**
360 * Error while verifying.
361 */
362 VERIFY_ERROR,
7daf5226 363
552cc11b
MW
364 /**
365 * Object in invalid state.
366 */
367 INVALID_STATE,
7daf5226 368
552cc11b
MW
369 /**
370 * Destroy object which called method belongs to.
371 */
372 DESTROY_ME,
7daf5226 373
552cc11b
MW
374 /**
375 * Another call to the method is required.
376 */
377 NEED_MORE,
378};
379
380/**
381 * enum_names for type status_t.
382 */
383extern enum_name_t *status_names;
384
4d174272
MW
385typedef enum tty_escape_t tty_escape_t;
386
387/**
388 * Excape codes for tty colors
389 */
390enum tty_escape_t {
391 /** text properties */
392 TTY_RESET,
393 TTY_BOLD,
394 TTY_UNDERLINE,
395 TTY_BLINKING,
396
397 /** foreground colors */
398 TTY_FG_BLACK,
399 TTY_FG_RED,
400 TTY_FG_GREEN,
401 TTY_FG_YELLOW,
402 TTY_FG_BLUE,
403 TTY_FG_MAGENTA,
404 TTY_FG_CYAN,
405 TTY_FG_WHITE,
406 TTY_FG_DEF,
407
408 /** background colors */
409 TTY_BG_BLACK,
410 TTY_BG_RED,
411 TTY_BG_GREEN,
412 TTY_BG_YELLOW,
413 TTY_BG_BLUE,
414 TTY_BG_MAGENTA,
415 TTY_BG_CYAN,
416 TTY_BG_WHITE,
417 TTY_BG_DEF,
418};
419
420/**
421 * Get the escape string for a given TTY color, empty string on non-tty fd
422 */
423char* tty_escape_get(int fd, tty_escape_t escape);
424
552cc11b
MW
425/**
426 * deprecated pluto style return value:
427 * error message, NULL for success
428 */
429typedef const char *err_t;
430
431/**
432 * Handle struct timeval like an own type.
433 */
434typedef struct timeval timeval_t;
435
436/**
437 * Handle struct timespec like an own type.
438 */
439typedef struct timespec timespec_t;
440
441/**
442 * Handle struct chunk_t like an own type.
443 */
444typedef struct sockaddr sockaddr_t;
445
552cc11b
MW
446/**
447 * Same as memcpy, but XORs src into dst instead of copy
448 */
449void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
450
ed678b52
MW
451/**
452 * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
453 */
454void memwipe_noinline(void *ptr, size_t n);
455
456/**
457 * Safely overwrite n bytes of memory at ptr with zero, inlining variant.
458 */
459static inline void memwipe_inline(void *ptr, size_t n)
460{
461 volatile char *c = (volatile char*)ptr;
d45b242b 462 size_t m, i;
ed678b52
MW
463
464 /* byte wise until long aligned */
d45b242b 465 for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
ed678b52
MW
466 {
467 c[i] = 0;
468 }
d45b242b
MW
469 /* word wise */
470 if (n >= sizeof(long))
ed678b52 471 {
d45b242b
MW
472 for (m = n - sizeof(long); i <= m; i += sizeof(long))
473 {
474 *(volatile long*)&c[i] = 0;
475 }
ed678b52
MW
476 }
477 /* byte wise of the rest */
478 for (; i < n; i++)
479 {
480 c[i] = 0;
481 }
482}
483
484/**
485 * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
486 */
487static inline void memwipe(void *ptr, size_t n)
488{
c480b5f4
TB
489 if (!ptr)
490 {
491 return;
492 }
ed678b52
MW
493 if (__builtin_constant_p(n))
494 {
495 memwipe_inline(ptr, n);
496 }
497 else
498 {
499 memwipe_noinline(ptr, n);
500 }
501}
502
81736d7d
TB
503/**
504 * A variant of strstr with the characteristics of memchr, where haystack is not
505 * a null-terminated string but simply a memory area of length n.
506 */
507void *memstr(const void *haystack, const char *needle, size_t n);
508
2ed241ae
TB
509/**
510 * Replacement for memrchr(3) if it is not provided by the C library.
511 *
512 * @param s start of the memory area to search
513 * @param c character to search
514 * @param n length of memory area to search
515 * @return pointer to the found character or NULL
516 */
517void *utils_memrchr(const void *s, int c, size_t n);
518
519#ifndef HAVE_MEMRCHR
520#define memrchr(s,c,n) utils_memrchr(s,c,n)
521#endif
522
d543d9ca
TB
523/**
524 * Translates the characters in the given string, searching for characters
525 * in 'from' and mapping them to characters in 'to'.
526 * The two characters sets 'from' and 'to' must contain the same number of
527 * characters.
528 */
529char *translate(char *str, const char *from, const char *to);
530
ccb6758e 531/**
4ab38d98 532 * Replaces all occurrences of search in the given string with replace.
ccb6758e
TB
533 *
534 * Allocates memory only if anything is replaced in the string. The original
535 * string is also returned if any of the arguments are invalid (e.g. if search
536 * is empty or any of them are NULL).
537 *
538 * @param str original string
539 * @param search string to search for and replace
4ab38d98 540 * @param replace string to replace found occurrences with
ccb6758e
TB
541 * @return allocated string, if anything got replaced, str otherwise
542 */
543char *strreplace(const char *str, const char *search, const char *replace);
544
766141bc
TB
545/**
546 * Like dirname(3) returns the directory part of the given null-terminated
547 * pathname, up to but not including the final '/' (or '.' if no '/' is found).
548 * Trailing '/' are not counted as part of the pathname.
549 *
550 * The difference is that it does this in a thread-safe manner (i.e. it does not
551 * use static buffers) and does not modify the original path.
552 *
553 * @param path original pathname
554 * @return allocated directory component
555 */
556char *path_dirname(const char *path);
557
558/**
559 * Like basename(3) returns the filename part of the given null-terminated path,
560 * i.e. the part following the final '/' (or '.' if path is empty or NULL).
561 * Trailing '/' are not counted as part of the pathname.
562 *
563 * The difference is that it does this in a thread-safe manner (i.e. it does not
564 * use static buffers) and does not modify the original path.
565 *
566 * @param path original pathname
567 * @return allocated filename component
568 */
569char *path_basename(const char *path);
570
6c20579a 571/**
7daf5226 572 * Creates a directory and all required parent directories.
6c20579a 573 *
3f310c0d 574 * @param path path to the new directory
7daf5226 575 * @param mode permissions of the new directory/directories
6c20579a
TB
576 * @return TRUE on success
577 */
578bool mkdir_p(const char *path, mode_t mode);
579
9a8fdc15
TB
580#ifndef HAVE_CLOSEFROM
581/**
582 * Close open file descriptors greater than or equal to lowfd.
583 *
4ab38d98 584 * @param lowfd start closing file descriptors from here
9a8fdc15
TB
585 */
586void closefrom(int lowfd);
587#endif
588
3f310c0d
MW
589/**
590 * Get a timestamp from a monotonic time source.
591 *
592 * While the time()/gettimeofday() functions are affected by leap seconds
593 * and system time changes, this function returns ever increasing monotonic
594 * time stamps.
595 *
596 * @param tv timeval struct receiving monotonic timestamps, or NULL
597 * @return monotonic timestamp in seconds
598 */
599time_t time_monotonic(timeval_t *tv);
600
eecd41e3
TB
601/**
602 * Add the given number of milliseconds to the given timeval struct
603 *
604 * @param tv timeval struct to modify
605 * @param ms number of milliseconds
606 */
607static inline void timeval_add_ms(timeval_t *tv, u_int ms)
608{
609 tv->tv_usec += ms * 1000;
819c02db 610 while (tv->tv_usec >= 1000000 /* 1s */)
eecd41e3
TB
611 {
612 tv->tv_usec -= 1000000;
613 tv->tv_sec++;
614 }
615}
616
081ae2eb
MW
617/**
618 * returns null
619 */
620void *return_null();
621
233b853d
MW
622/**
623 * No-Operation function
624 */
625void nop();
626
da17b016
MW
627/**
628 * returns TRUE
629 */
630bool return_true();
631
632/**
633 * returns FALSE
634 */
635bool return_false();
636
502edf42
MW
637/**
638 * returns FAILED
639 */
640status_t return_failed();
641
4755ab50
MW
642/**
643 * returns SUCCESS
644 */
645status_t return_success();
646
0be12e35
MW
647/**
648 * Write a 16-bit host order value in network order to an unaligned address.
649 *
650 * @param host host order 16-bit value
651 * @param network unaligned address to write network order value to
652 */
653static inline void htoun16(void *network, u_int16_t host)
654{
dbee988e
MW
655 char *unaligned = (char*)network;
656
0be12e35 657 host = htons(host);
dbee988e 658 memcpy(unaligned, &host, sizeof(host));
0be12e35
MW
659}
660
661/**
662 * Write a 32-bit host order value in network order to an unaligned address.
663 *
664 * @param host host order 32-bit value
665 * @param network unaligned address to write network order value to
666 */
667static inline void htoun32(void *network, u_int32_t host)
668{
dbee988e
MW
669 char *unaligned = (char*)network;
670
0be12e35 671 host = htonl(host);
dbee988e 672 memcpy((char*)unaligned, &host, sizeof(host));
0be12e35
MW
673}
674
fbeb9454
AS
675/**
676 * Write a 64-bit host order value in network order to an unaligned address.
677 *
a91462df 678 * @param host host order 64-bit value
fbeb9454
AS
679 * @param network unaligned address to write network order value to
680 */
681static inline void htoun64(void *network, u_int64_t host)
682{
683 char *unaligned = (char*)network;
f4e25e60
MW
684
685#ifdef be64toh
686 host = htobe64(host);
687 memcpy((char*)unaligned, &host, sizeof(host));
688#else
fbeb9454
AS
689 u_int32_t high_part, low_part;
690
691 high_part = host >> 32;
692 high_part = htonl(high_part);
693 low_part = host & 0xFFFFFFFFLL;
694 low_part = htonl(low_part);
695
696 memcpy(unaligned, &high_part, sizeof(high_part));
697 unaligned += sizeof(high_part);
698 memcpy(unaligned, &low_part, sizeof(low_part));
f4e25e60 699#endif
fbeb9454
AS
700}
701
0be12e35
MW
702/**
703 * Read a 16-bit value in network order from an unaligned address to host order.
704 *
705 * @param network unaligned address to read network order value from
706 * @return host order value
707 */
708static inline u_int16_t untoh16(void *network)
709{
dbee988e 710 char *unaligned = (char*)network;
0be12e35
MW
711 u_int16_t tmp;
712
dbee988e 713 memcpy(&tmp, unaligned, sizeof(tmp));
0be12e35
MW
714 return ntohs(tmp);
715}
716
717/**
718 * Read a 32-bit value in network order from an unaligned address to host order.
719 *
720 * @param network unaligned address to read network order value from
721 * @return host order value
722 */
723static inline u_int32_t untoh32(void *network)
724{
dbee988e 725 char *unaligned = (char*)network;
0be12e35
MW
726 u_int32_t tmp;
727
dbee988e 728 memcpy(&tmp, unaligned, sizeof(tmp));
f8f4f31a 729 return ntohl(tmp);
0be12e35
MW
730}
731
fbeb9454
AS
732/**
733 * Read a 64-bit value in network order from an unaligned address to host order.
734 *
735 * @param network unaligned address to read network order value from
736 * @return host order value
737 */
738static inline u_int64_t untoh64(void *network)
739{
740 char *unaligned = (char*)network;
f4e25e60
MW
741
742#ifdef be64toh
743 u_int64_t tmp;
744
745 memcpy(&tmp, unaligned, sizeof(tmp));
746 return be64toh(tmp);
747#else
fbeb9454
AS
748 u_int32_t high_part, low_part;
749
750 memcpy(&high_part, unaligned, sizeof(high_part));
751 unaligned += sizeof(high_part);
752 memcpy(&low_part, unaligned, sizeof(low_part));
753
754 high_part = ntohl(high_part);
755 low_part = ntohl(low_part);
756
757 return (((u_int64_t)high_part) << 32) + low_part;
f4e25e60 758#endif
fbeb9454
AS
759}
760
84044f9c 761/**
812ae898 762 * Get the padding required to make size a multiple of alignment
84044f9c 763 */
812ae898 764static inline size_t pad_len(size_t size, size_t alignment)
84044f9c 765{
812ae898 766 size_t remainder;
84044f9c 767
812ae898
TB
768 remainder = size % alignment;
769 return remainder ? alignment - remainder : 0;
770}
771
772/**
773 * Round up size to be multiple of alignment
774 */
775static inline size_t round_up(size_t size, size_t alignment)
776{
777 return size + pad_len(size, alignment);
84044f9c
MW
778}
779
780/**
812ae898 781 * Round down size to be a multiple of alignment
84044f9c 782 */
812ae898 783static inline size_t round_down(size_t size, size_t alignment)
84044f9c 784{
812ae898 785 return size - (size % alignment);
84044f9c
MW
786}
787
552cc11b
MW
788/**
789 * Special type to count references
790 */
4d04e2c6 791typedef u_int refcount_t;
efd0fe21 792
a0c2370e
TB
793/* use __atomic* built-ins with GCC 4.7 and newer */
794#ifdef __GNUC__
795# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6))
796# define HAVE_GCC_ATOMIC_OPERATIONS
797# endif
798#endif
799
efd0fe21
MW
800#ifdef HAVE_GCC_ATOMIC_OPERATIONS
801
0f603d42
TB
802#define ref_get(ref) __atomic_add_fetch(ref, 1, __ATOMIC_RELAXED)
803/* The relaxed memory model works fine for increments as these (usually) don't
804 * change the state of refcounted objects. But here we have to ensure that we
805 * free the right stuff if ref counted objects are mutable. So we have to sync
806 * with other threads that call ref_put(). It would be sufficient to use
807 * __ATOMIC_RELEASE here and then call __atomic_thread_fence() with
808 * __ATOMIC_ACQUIRE if we reach 0, but since we don't have control over the use
809 * of ref_put() we have to make sure. */
810#define ref_put(ref) (!__atomic_sub_fetch(ref, 1, __ATOMIC_ACQ_REL))
811#define ref_cur(ref) __atomic_load_n(ref, __ATOMIC_RELAXED)
812
813#define _cas_impl(ptr, oldval, newval) ({ typeof(oldval) _old = oldval; \
814 __atomic_compare_exchange_n(ptr, &_old, newval, FALSE, \
815 __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); })
816#define cas_bool(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
817#define cas_ptr(ptr, oldval, newval) _cas_impl(ptr, oldval, newval)
818
819#elif defined(HAVE_GCC_SYNC_OPERATIONS)
820
3160b92a 821#define ref_get(ref) __sync_add_and_fetch(ref, 1)
efd0fe21 822#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
efedd0d2 823#define ref_cur(ref) __sync_fetch_and_add(ref, 0)
efd0fe21 824
5317dd68
TB
825#define cas_bool(ptr, oldval, newval) \
826 (__sync_bool_compare_and_swap(ptr, oldval, newval))
827#define cas_ptr(ptr, oldval, newval) \
828 (__sync_bool_compare_and_swap(ptr, oldval, newval))
829
0f603d42 830#else /* !HAVE_GCC_ATOMIC_OPERATIONS && !HAVE_GCC_SYNC_OPERATIONS */
efd0fe21 831
552cc11b
MW
832/**
833 * Get a new reference.
834 *
efedd0d2 835 * Increments the reference counter atomically.
552cc11b
MW
836 *
837 * @param ref pointer to ref counter
3160b92a 838 * @return new value of ref
552cc11b 839 */
3160b92a 840refcount_t ref_get(refcount_t *ref);
552cc11b
MW
841
842/**
843 * Put back a unused reference.
844 *
efedd0d2 845 * Decrements the reference counter atomically and
552cc11b
MW
846 * says if more references available.
847 *
848 * @param ref pointer to ref counter
849 * @return TRUE if no more references counted
850 */
851bool ref_put(refcount_t *ref);
852
efedd0d2
TB
853/**
854 * Get the current value of the reference counter.
855 *
856 * @param ref pointer to ref counter
857 * @return current value of ref
858 */
859refcount_t ref_cur(refcount_t *ref);
860
5317dd68
TB
861/**
862 * Atomically replace value of ptr with newval if it currently equals oldval.
863 *
864 * @param ptr pointer to variable
865 * @param oldval old value of the variable
866 * @param newval new value set if possible
867 * @return TRUE if value equaled oldval and newval was written
868 */
869bool cas_bool(bool *ptr, bool oldval, bool newval);
870
871/**
872 * Atomically replace value of ptr with newval if it currently equals oldval.
873 *
874 * @param ptr pointer to variable
875 * @param oldval old value of the variable
876 * @param newval new value set if possible
877 * @return TRUE if value equaled oldval and newval was written
878 */
879bool cas_ptr(void **ptr, void *oldval, void *newval);
880
efd0fe21
MW
881#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
882
2077d996
MW
883#ifndef HAVE_FMEMOPEN
884# ifdef HAVE_FUNOPEN
9df621d2
MW
885# define HAVE_FMEMOPEN
886# define HAVE_FMEMOPEN_FALLBACK
5ac29360 887# include <stdio.h>
2077d996
MW
888/**
889 * fmemopen(3) fallback using BSD funopen.
890 *
891 * We could also provide one using fopencookie(), but should we have it we
892 * most likely have fmemopen().
893 *
894 * fseek() is currently not supported.
895 */
896FILE *fmemopen(void *buf, size_t size, const char *mode);
897# endif /* FUNOPEN */
898#endif /* FMEMOPEN */
899
552cc11b 900/**
d25ce370 901 * printf hook for time_t.
552cc11b 902 *
7daf5226 903 * Arguments are:
323f9f99 904 * time_t* time, bool utc
552cc11b 905 */
1b40b74d 906int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
d25ce370 907 const void *const *args);
552cc11b
MW
908
909/**
d25ce370 910 * printf hook for time_t deltas.
552cc11b 911 *
7daf5226 912 * Arguments are:
323f9f99 913 * time_t* begin, time_t* end
552cc11b 914 */
1b40b74d 915int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
d25ce370 916 const void *const *args);
552cc11b
MW
917
918/**
d25ce370 919 * printf hook for memory areas.
552cc11b 920 *
7daf5226 921 * Arguments are:
817ab8a8 922 * u_char *ptr, u_int len
552cc11b 923 */
1b40b74d 924int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
d25ce370 925 const void *const *args);
552cc11b 926
1490ff4d 927#endif /** UTILS_H_ @}*/