core, lib, modules: restructured source code tree
[sip-router] / src / core / ut.h
1 /*
2  * - various general purpose functions
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  */
19 /** Kamailio core :: various general purpose/helper functions.
20  * @file
21  * @ingroup core
22  */
23
24
25 #ifndef ut_h
26 #define ut_h
27
28 #include "comp_defs.h"
29
30 #include <sys/types.h>
31 #include <sys/select.h>
32 #include <sys/time.h>
33 #include <limits.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <ctype.h>
37 #include <string.h>
38 #include <strings.h>
39
40 #include "compiler_opt.h"
41 #include "config.h"
42 #include "dprint.h"
43 #include "str.h"
44 #include "mem/mem.h"
45 #include "mem/shm_mem.h"
46
47
48
49 /* zero-string wrapper */
50 #define ZSW(_c) ((_c)?(_c):"")
51
52 /* returns string beginning and length without insignificant chars */
53 #define trim_len( _len, _begin, _mystr ) \
54         do{     static char _c; \
55                 (_len)=(_mystr).len; \
56                 while ((_len) && ((_c=(_mystr).s[(_len)-1])==0 || _c=='\r' || \
57                                         _c=='\n' || _c==' ' || _c=='\t' )) \
58                         (_len)--; \
59                 (_begin)=(_mystr).s; \
60                 while ((_len) && ((_c=*(_begin))==' ' || _c=='\t')) { \
61                         (_len)--;\
62                         (_begin)++; \
63                 } \
64         }while(0)
65
66 #define trim_r( _mystr ) \
67         do{     static char _c; \
68                 while( ((_mystr).len) && ( ((_c=(_mystr).s[(_mystr).len-1]))==0 ||\
69                                                                         _c=='\r' || _c=='\n' ) \
70                                 ) \
71                         (_mystr).len--; \
72         }while(0)
73
74
75 #define  translate_pointer( _new_buf , _org_buf , _p) \
76         ( (_p)?(_new_buf + (_p-_org_buf)):(0) )
77
78 #define via_len(_via) \
79         ((_via)->bsize-((_via)->name.s-\
80                 ((_via)->hdr.s+(_via)->hdr.len)))
81
82
83
84 /* rounds to sizeof(type), but type must have a 2^k size (e.g. short, int,
85  * long, void*) */
86 #define ROUND2TYPE(s, type) \
87         (((s)+(sizeof(type)-1))&(~(sizeof(type)-1)))
88
89
90 /* rounds to sizeof(char*) - the first 4 byte multiple on 32 bit archs
91  * and the first 8 byte multiple on 64 bit archs */
92 #define ROUND_POINTER(s) ROUND2TYPE(s, char*)
93
94 /* rounds to sizeof(long) - the first 4 byte multiple on 32 bit archs
95  * and the first 8 byte multiple on 64 bit archs  (equiv. to ROUND_POINTER)*/
96 #define ROUND_LONG(s)  ROUND2TYPE(s, long)
97
98 /* rounds to sizeof(int) - the first t byte multiple on 32 and 64  bit archs */
99 #define ROUND_INT(s) ROUND2TYPE(s, int)
100
101 /* rounds to sizeof(short) - the first 2 byte multiple */
102 #define ROUND_SHORT(s) ROUND2TYPE(s, short)
103
104
105 /* params: v - either a variable name, structure member or a type
106  * returns an unsigned long containing the maximum possible value that will
107  * fit in v, if v is unsigned or converted to an unsigned version
108  * example: MAX_UVAR_VALUE(unsigned short); MAX_UVAR_VALUE(i);
109  *  MAX_UVAR_VALUE(((struct foo*)0)->bar) */
110 #define MAX_UVAR_VALUE(v) \
111         (((unsigned long)(-1))>>((sizeof(unsigned long)-sizeof(v))*8UL))
112
113
114 #define MIN_int(a, b) (((a)<(b))?(a):(b))
115 #define MAX_int(a, b) (((a)>(b))?(a):(b))
116
117 #define MIN_unsigned(a, b) (unsigned)(((unsigned)(a)<(unsigned)(b))?(a):(b))
118 #define MAX_unsigned(a, b) (unsigned)(((unsigned)(a)>(unsigned)(b))?(a):(b))
119
120 #if 0
121 #define MIN_int(a, b) ((b)+(((a)-(b))& -((a)<(b))))
122 #define MAX_int(a, b) ((a)-(((a)-(b))& -((b)>(a))))
123
124 /* depend on signed right shift result which depends on the compiler */
125 #define MIN_int(a, b) ((b)+(((a)-(b))&(((a)-(b))>>(sizeof(int)*8-1))))
126 #define MAX_int(a, b) ((a)-(((a)-(b))&(((a)-(b))>>(sizeof(int)*8-1))))
127 #endif
128
129
130 #define append_str(_dest,_src,_len)                             \
131         do{                                                                                     \
132                 memcpy( (_dest) , (_src) , (_len) );    \
133                 (_dest) += (_len) ;                                             \
134         }while(0);                                                                      \
135
136         
137 /*! append _c char to _dest string */
138 #define append_chr(_dest,_c) \
139         *((_dest)++) = _c;
140
141
142 #define is_in_str(p, in) (p < in->s + in->len && *p)
143
144
145 /* links a value to a msgid */
146 struct msgid_var{
147         union{
148                 char char_val;
149                 int int_val;
150                 long long_val;
151         }u;
152         unsigned int msgid;
153 };
154
155 /* return the value or 0 if the msg_id doesn't match */
156 #define get_msgid_val(var, id, type)\
157         ((type)((type)((var).msgid!=(id))-1)&((var).u.type##_val))
158
159 #define set_msgid_val(var, id, type, value)\
160         do{\
161                 (var).msgid=(id); \
162                 (var).u.type##_val=(value); \
163         }while(0)
164
165 /* char to hex conversion table */
166 static char fourbits2char[16] = { '0', '1', '2', '3', '4', '5',
167         '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
168
169
170 /* converts a str to an u. short, returns the u. short and sets *err on
171  * error and if err!=null
172   */
173 static inline unsigned short str2s(const char* s, unsigned int len, int *err)
174 {
175         unsigned short ret;
176         int i;
177         unsigned char *limit;
178         unsigned char* str;
179
180         /*init*/
181         str=(unsigned char*)s;
182         ret=i=0;
183         limit=str+len;
184
185         for(;str<limit ;str++){
186                 if ( (*str <= '9' ) && (*str >= '0') ){
187                                 ret=ret*10+*str-'0';
188                                 i++;
189                                 if (i>5) goto error_digits;
190                 }else{
191                                 /* error unknown char */
192                                 goto error_char;
193                 }
194         }
195         if (err) *err=0;
196         return ret;
197
198 error_digits:
199         if (err) *err=1;
200         return 0;
201 error_char:
202         if (err) *err=1;
203         return 0;
204 }
205
206
207
208 static inline int btostr( char *p,  unsigned char val)
209 {
210         unsigned int a,b,i =0;
211
212         if ( (a=val/100)!=0 )
213                 *(p+(i++)) = a+'0';         /*first digit*/
214         if ( (b=val%100/10)!=0 || a)
215                 *(p+(i++)) = b+'0';        /*second digit*/
216         *(p+(i++)) = '0'+val%10;              /*third digit*/
217
218         return i;
219 }
220
221
222 #define INT2STR_MAX_LEN  (19+1+1+1) /* 2^64~= 16*10^18 =>
223                                                                            19+1 digits + sign + \0 */
224
225 /* 
226  * returns a pointer to a static buffer containing l in asciiz (with base "base") & sets len 
227  * left padded with 0 to "size"
228  */
229 static inline char* int2str_base_0pad(unsigned int l, int* len, int base, 
230                                                                                         int size)
231 {
232         static char r[INT2STR_MAX_LEN];
233         int i, j;
234
235         if (base < 2) {
236                 BUG("base underflow\n");
237                 return NULL;
238         }
239         if (base > 36) {
240                 BUG("base overflow\n");
241                 return NULL;
242         }
243         i=INT2STR_MAX_LEN-2;
244         j=i-size;
245         r[INT2STR_MAX_LEN-1]=0; /* null terminate */
246         do{
247                 r[i]=l%base;
248                 if (r[i]<10)
249                         r[i]+='0';
250                 else
251                         r[i]+='a'-10;
252                 i--;
253                 l/=base;
254         }while((l || i>j) && (i>=0));
255         if (l && (i<0)){
256                 BUG("result buffer overflow\n");
257         }
258         if (len) *len=(INT2STR_MAX_LEN-2)-i;
259         return &r[i+1];
260 }
261
262 /* returns a pointer to a static buffer containing l in asciiz (with base "base") & sets len */
263 static inline char* int2str_base(unsigned int l, int* len, int base)
264 {
265         return int2str_base_0pad(l, len, base, 0);
266 }
267
268
269
270 /** unsigned long to str conversion using a provided buffer.
271  * Converts/prints an unsigned long to a string. The result buffer must be
272  * provided  and its length must be at least INT2STR_MAX_LEN.
273  * @param l - unsigned long to be converted
274  * @param r - pointer to result buffer
275  * @param r_size - result buffer size, must be at least INT2STR_MAX_LEN.
276  * @param *len - length of the written string, _without_ the terminating 0.
277  * @return  pointer _inside_ r, to the converted string (note: the string
278  *  is written from the end of the buffer and not from the start and hence
279  *  the returned pointer will most likely not be equal to r). In case of error
280  *  it returns 0 (the only error being insufficient provided buffer size).
281  */
282 static inline char* int2strbuf(unsigned long l, char *r, int r_size, int* len)
283 {
284         int i;
285
286         if(unlikely(r_size<INT2STR_MAX_LEN)) {
287                 if (len)
288                         *len = 0;
289                 return 0; /* => if someone misuses it => crash (feature no. 1) */
290         }
291         i=INT2STR_MAX_LEN-2;
292         r[INT2STR_MAX_LEN-1]=0; /* null terminate */
293         do{
294                 r[i]=l%10+'0';
295                 i--;
296                 l/=10;
297         }while(l && (i>=0));
298         if (l && (i<0)){
299                 LM_CRIT("overflow\n");
300         }
301         if (len) *len=(INT2STR_MAX_LEN-2)-i;
302         return &r[i+1];
303 }
304
305 extern char ut_buf_int2str[INT2STR_MAX_LEN];
306 /** interger(long) to string conversion.
307  * This version uses a static buffer (shared with sint2str()).
308  * WARNING: other function calls might overwrite the static buffer, so
309  * either always save the result immediately or use int2strbuf(...).
310  * @param l - unsigned long to be converted/printed.
311  * @param *len - will be filled with the final length (without the terminating
312  *   0).
313  * @return a pointer to a static buffer containing l in asciiz & sets len.
314  */
315 static inline char* int2str(unsigned long l, int* len)
316 {
317         return int2strbuf(l, ut_buf_int2str, INT2STR_MAX_LEN, len);
318 }
319
320
321
322 /** signed long to str conversion using a provided buffer.
323  * Converts a long to a signed string. The result buffer must be provided
324  * and its length must be at least INT2STR_MAX_LEN.
325  * @param l - long to be converted
326  * @param r - pointer to result buffer
327  * @param r_size - result buffer size, must be at least INT2STR_MAX_LEN.
328  * @param *len - length of the written string, _without_ the terminating 0.
329  * @return  pointer _inside_ r, to the converted string (note: the string
330  *  is written from the end of the buffer and not from the start and hence
331  *  the returned pointer will most likely not be equal to r). In case of error
332  *  it returns 0 (the only error being insufficient provided buffer size).
333  */
334 static inline char* sint2strbuf(long l, char* r, int r_size, int* len)
335 {
336         int sign;
337         char *p;
338         int p_len;
339
340         sign = 0;
341         if(l<0) {
342                 sign = 1;
343                 l = -l;
344         }
345         p = int2strbuf((unsigned long)l, r, r_size, &p_len);
346         if(sign && p_len<(r_size-1)) {
347                 *(--p) = '-';
348                 p_len++;;
349         }
350         if (likely(len))
351                 *len = p_len;
352         return p;
353 }
354
355
356 /** Signed INTeger-TO-STRing: converts a long to a string.
357  * This version uses a static buffer, shared with int2str().
358  * WARNING: other function calls might overwrite the static buffer, so
359  * either always save the result immediately or use sint2strbuf(...).
360  * @param l - long to be converted/printed.
361  * @param *len - will be filled with the final length (without the terminating
362  *   0).
363  * @return a pointer to a static buffer containing l in asciiz & sets len.
364  */
365 static inline char* sint2str(long l, int* len)
366 {
367         return sint2strbuf(l, ut_buf_int2str, INT2STR_MAX_LEN, len);
368 }
369
370
371
372 #define USHORT2SBUF_MAX_LEN  5 /* 65535*/
373 /* converts an unsigned short (16 bits) to asciiz
374  * returns bytes written or 0 on error
375  * the passed len must be at least USHORT2SBUF_MAX chars or error
376  * would be returned.
377  * (optimized for port conversion (4 or 5 digits most of the time)*/
378 static inline int ushort2sbuf(unsigned short u, char* buf, int len)
379 {
380         int offs;
381         unsigned char a, b, c, d;
382         
383         if (unlikely(len<USHORT2SBUF_MAX_LEN))
384                 return 0;
385         offs=0;
386         a=u/10000; u%=10000;
387         buf[offs]=a+'0'; offs+=(a!=0);
388         b=u/1000;  u%=1000;
389         buf[offs]=b+'0'; offs+=((offs|b)!=0);
390         c=u/100;   u%=100;
391         buf[offs]=c+'0'; offs+=((offs|c)!=0);
392         d=u/10;    u%=10;
393         buf[offs]=d+'0'; offs+=((offs|d)!=0);
394         buf[offs]=(unsigned char)u+'0';
395         return offs+1;
396 }
397
398
399
400 #define USHORT2STR_MAX_LEN  (USHORT2SBUF_MAX_LEN+1) /* 65535\0*/
401 /* converts an unsigned short (16 bits) to asciiz
402  * (optimized for port conversiob (4 or 5 digits most of the time)*/
403 static inline char* ushort2str(unsigned short u)
404 {
405         static char buf[USHORT2STR_MAX_LEN];
406         int len;
407
408         len=ushort2sbuf(u, buf, sizeof(buf)-1);
409         buf[len]=0;
410         return buf;
411 }
412
413
414
415 /* fast memchr version */
416 static inline char* q_memchr(char* p, int c, unsigned int size)
417 {
418         char* end;
419
420         end=p+size;
421         for(;p<end;p++){
422                 if (*p==(unsigned char)c) return p;
423         }
424         return 0;
425 }
426
427
428 /* fast reverse char search */
429
430 static inline char* q_memrchr(char* p, int c, unsigned int size)
431 {
432         char* end;
433
434         end=p+size-1;
435         for(;end>=p;end--) {
436                 if (*end==(unsigned char)c) return end;
437         }
438         return 0;
439 }
440
441 /* returns -1 on error, 1! on success (consistent with int2reverse_hex) */
442 inline static int reverse_hex2int( char *c, int len, unsigned int* res)
443 {
444         char *pc;
445         char mychar;
446
447         *res=0;
448         for (pc=c+len-1; len>0; pc--, len--) {
449                 *res <<= 4 ;
450                 mychar=*pc;
451                 if ( mychar >='0' && mychar <='9') *res+=mychar -'0';
452                 else if (mychar >='a' && mychar <='f') *res+=mychar -'a'+10;
453                 else if (mychar  >='A' && mychar <='F') *res+=mychar -'A'+10;
454                 else return -1;
455         }
456         return 1;
457 }
458
459 inline static int int2reverse_hex( char **c, int *size, unsigned int nr )
460 {
461         unsigned short digit;
462
463         if (*size && nr==0) {
464                 **c = '0';
465                 (*c)++;
466                 (*size)--;
467                 return 1;
468         }
469
470         while (*size && nr ) {
471                 digit = nr & 0xf ;
472                 **c= digit >= 10 ? digit + 'a' - 10 : digit + '0';
473                 nr >>= 4;
474                 (*c)++;
475                 (*size)--;
476         }
477         return nr ? -1 /* number not processed; too little space */ : 1;
478 }
479
480 /* double output length assumed ; does NOT zero-terminate */
481 inline static int string2hex( 
482         /* input */ unsigned char *str, int len,
483         /* output */ char *hex )
484 {
485         int orig_len;
486
487         if (len==0) {
488                 *hex='0';
489                 return 1;
490         }
491
492         orig_len=len;
493         while ( len ) {
494
495                 *hex=fourbits2char[(*str) >> 4];
496                 hex++;
497                 *hex=fourbits2char[(*str) & 0xf];
498                 hex++;
499                 len--;
500                 str++;
501
502         }
503         return orig_len-len;
504 }
505
506 /* portable sleep in microseconds (no interrupt handling now) */
507
508 inline static void sleep_us( unsigned int nusecs )
509 {
510         struct timeval tval;
511         tval.tv_sec =nusecs/1000000;
512         tval.tv_usec=nusecs%1000000;
513         select(0, NULL, NULL, NULL, &tval );
514 }
515
516
517 /* portable determination of max_path */
518 inline static int pathmax(void)
519 {
520 #ifdef PATH_MAX
521         static int pathmax=PATH_MAX;
522 #else
523         static int pathmax=0;
524 #endif
525         if (pathmax==0) { /* init */
526                 pathmax=pathconf("/", _PC_PATH_MAX);
527                 pathmax=(pathmax<=0)?PATH_MAX_GUESS:pathmax+1;
528         }
529         return pathmax;
530 }
531
532 inline static int hex2int(char hex_digit)
533 {
534         if (hex_digit>='0' && hex_digit<='9')
535                 return hex_digit-'0';
536         if (hex_digit>='a' && hex_digit<='f')
537                 return hex_digit-'a'+10;
538         if (hex_digit>='A' && hex_digit<='F')
539                 return hex_digit-'A'+10;
540         /* no valid hex digit ... */
541         LM_ERR("'%c' is no hex char\n", hex_digit );
542         return -1;
543 }
544
545 /* Un-escape URI user  -- it takes a pointer to original user
546    str, as well as the new, unescaped one, which MUST have
547    an allocated buffer linked to the 'str' structure ;
548    (the buffer can be allocated with the same length as
549    the original string -- the output string is always
550    shorter (if escaped characters occur) or same-long
551    as the original one).
552
553    only printable characters are permitted
554
555         <0 is returned on an unescaping error, length of the
556         unescaped string otherwise
557 */
558 inline static int un_escape(str *user, str *new_user ) 
559 {
560         int i, j, value;
561         int hi, lo;
562
563         if( new_user==0 || new_user->s==0) {
564                 LM_CRIT("invalid param\n");
565                 return -1;
566         }
567
568         new_user->len = 0;
569         j = 0;
570
571         for (i = 0; i < user->len; i++) {
572                 if (user->s[i] == '%') {
573                         if (i + 2 >= user->len) {
574                                 LM_ERR("escape sequence too short in '%.*s' @ %d\n",
575                                         user->len, user->s, i );
576                                 goto error;
577                         }
578                         hi=hex2int(user->s[i + 1]);
579                         if (hi<0) {
580                                 LM_ERR("non-hex high digit in an escape sequence in"
581                                         " '%.*s' @ %d\n",
582                                         user->len, user->s, i+1 );
583                                 goto error;
584                         }
585                         lo=hex2int(user->s[i + 2]);
586                         if (lo<0) {
587                                 LM_ERR("non-hex low digit in an escape sequence in "
588                                         "'%.*s' @ %d\n",
589                                         user->len, user->s, i+2 );
590                                 goto error;
591                         }
592                         value=(hi<<4)+lo;
593                         if (value < 32 || value > 126) {
594                                 LM_ERR("non-ASCII escaped character in '%.*s' @ %d\n",
595                                         user->len, user->s, i );
596                                 goto error;
597                         }
598                         new_user->s[j] = value;
599                         i+=2; /* consume the two hex digits, for cycle will move to the next char */
600                 } else {
601                         new_user->s[j] = user->s[i];
602                 }
603         j++; /* good -- we translated another character */
604         }
605         new_user->len = j;
606         return j;
607
608 error:
609         new_user->len = j;
610         return -1;
611
612
613
614 /*
615  * Convert a string to lower case
616  */
617 static inline void strlower(str* _s)
618 {
619         int i;
620
621         if (_s == NULL) return ;
622         if (_s->len < 0) return ;
623         if (_s->s == NULL) return ;
624
625         for(i = 0; i < _s->len; i++) {
626                 _s->s[i] = tolower(_s->s[i]);
627         }
628 }
629
630
631 /*
632  * Convert a str into integer
633  */
634 static inline int str2int(str* _s, unsigned int* _r)
635 {
636         int i;
637
638         if (_s == NULL) return -1;
639         if (_r == NULL) return -1;
640         if (_s->len < 0) return -1;
641         if (_s->s == NULL) return -1;
642
643         *_r = 0;
644         for(i = 0; i < _s->len; i++) {
645                 if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
646                         *_r *= 10;
647                         *_r += _s->s[i] - '0';
648                 } else {
649                         return -1;
650                 }
651         }
652
653         return 0;
654 }
655
656 /*
657  * Convert an str to signed integer
658  */
659 static inline int str2sint(str* _s, int* _r)
660 {
661         int i;
662         int sign;
663
664         if (_s == NULL) return -1;
665         if (_r == NULL) return -1;
666         if (_s->len < 0) return -1;
667         if (_s->s == NULL) return -1;
668
669         *_r = 0;
670         sign = 1;
671         i = 0;
672         if (_s->s[0] == '+') {
673                 i++;
674         } else if (_s->s[0] == '-') {
675                 sign = -1;
676                 i++;
677         }
678         for(; i < _s->len; i++) {
679                 if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
680                         *_r *= 10;
681                         *_r += _s->s[i] - '0';
682                 } else {
683                         return -1;
684                 }
685         }
686         *_r *= sign;
687
688         return 0;
689 }
690
691
692
693 #ifdef SHM_MEM
694 /**
695  * \brief Make a copy of a str structure using shm_malloc
696  * \param dst destination
697  * \param src source
698  * \return 0 on success, -1 on failure
699  */
700 static inline int shm_str_dup(str* dst, const str* src)
701 {
702         /* NULL checks */
703         if (dst == NULL || src == NULL) {
704                 LM_ERR("NULL src or dst\n");
705                 return -1;
706         }
707
708         /**
709          * fallback actions:
710          *      - dst->len=0
711          *      - dst->s is allocated sizeof(void*) size
712          *      - return 0 (i.e. success)
713          */
714
715         /* fallback checks */
716         if (src->len < 0 || src->s == NULL) {
717                 LM_WARN("shm_str_dup fallback; dup called for src->s == NULL or src->len < 0\n");
718                 dst->len = 0;
719         } else {
720                 dst->len = src->len;
721         }
722
723         dst->s = (char*)shm_malloc(dst->len);
724         if (dst->s == NULL) {
725                 SHM_MEM_ERROR;
726                 return -1;
727         }
728
729         /* avoid memcpy from NULL source - undefined behaviour */
730         if (src->s == NULL) {
731                 LM_WARN("shm_str_dup fallback; skip memcpy for src->s == NULL\n");
732                 return 0;
733         }
734
735         memcpy(dst->s, src->s, dst->len);
736
737         return 0;
738 }
739 #endif /* SHM_MEM */
740
741
742
743 /**
744  * \brief Make a copy of a str structure using pkg_malloc
745  * \param dst destination
746  * \param src source
747  * \return 0 on success, -1 on failure
748  */
749 static inline int pkg_str_dup(str* dst, const str* src)
750 {
751         /* NULL checks */
752         if (dst == NULL || src == NULL) {
753                 LM_ERR("NULL src or dst\n");
754                 return -1;
755         }
756
757         /**
758          * fallback actions:
759          *      - dst->len=0
760          *      - dst->s is allocated sizeof(void*) size
761          *      - return 0 (i.e. success)
762          */
763
764         /* fallback checks */
765         if (src->len < 0 || src->s == NULL) {
766                 LM_WARN("pkg_str_dup fallback; dup called for src->s == NULL or src->len < 0\n");
767                 dst->len = 0;
768         } else {
769                 dst->len = src->len;
770         }
771
772         dst->s = (char*)pkg_malloc(dst->len);
773         if (dst->s == NULL) {
774                 PKG_MEM_ERROR;
775                 return -1;
776         }
777
778         /* avoid memcpy from NULL source - undefined behaviour */
779         if (src->s == NULL) {
780                 LM_WARN("pkg_str_dup fallback; skip memcpy for src->s == NULL\n");
781                 return 0;
782         }
783
784         memcpy(dst->s, src->s, dst->len);
785
786         return 0;
787 }
788
789 /**
790  * \brief Compare two str's case sensitive
791  * \param str1 first str
792  * \param str2 second str
793  * \return 0 if both are equal, positive if str1 is greater, negative if str2 is greater, -2 on errors
794  */
795 static inline int str_strcmp(const str *str1, const str *str2)
796 {
797         if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
798         {
799                 LM_ERR("bad parameters\n");
800                 return -2;
801         }
802
803         if (str1->len < str2->len)
804                 return -1;
805         else if (str1->len > str2->len)
806                 return 1;
807         else
808                 return strncmp(str1->s, str2->s, str1->len);
809 }
810
811 /**
812  * \brief Compare two str's case insensitive
813  * \param str1 first str
814  * \param str2 second str
815  * \return 0 if both are equal, positive if str1 is greater, negative if str2 is greater, -2 on errors
816  */
817 static inline int str_strcasecmp(const str *str1, const str *str2)
818 {
819         if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
820         {
821                 LM_ERR("bad parameters\n");
822                 return -2;
823         }
824         if (str1->len < str2->len)
825                 return -1;
826         else if (str1->len > str2->len)
827                 return 1;
828         else
829                 return strncasecmp(str1->s, str2->s, str1->len);
830 }
831
832 #ifndef MIN
833 #define MIN(x, y)       ((x) < (y) ? (x) : (y))
834 #endif
835 #ifndef MAX
836 #define MAX(x, y)       ((x) > (y) ? (x) : (y))
837 #endif
838
839
840 /* INTeger-TO-Buffer-STRing : convers an unsigned long to a string 
841  * IMPORTANT: the provided buffer must be at least INT2STR_MAX_LEN size !! */
842 static inline char* int2bstr(unsigned long l, char *s, int* len)
843 {
844         int i;
845         i=INT2STR_MAX_LEN-2;
846         s[INT2STR_MAX_LEN-1]=0;
847         /* null terminate */
848         do{
849                 s[i]=l%10+'0';
850                 i--;
851                 l/=10;
852         }while(l && (i>=0));
853         if (l && (i<0)){
854                 LM_CRIT("overflow error\n");
855         }
856         if (len) *len=(INT2STR_MAX_LEN-2)-i;
857         return &s[i+1];
858 }
859
860
861 inline static int hexstr2int(char *c, int len, unsigned int *val)
862 {
863         char *pc;
864         int r;
865         char mychar;
866
867         r=0;
868         for (pc=c; pc<c+len; pc++) {
869                 r <<= 4 ;
870                 mychar=*pc;
871                 if ( mychar >='0' && mychar <='9') r+=mychar -'0';
872                 else if (mychar >='a' && mychar <='f') r+=mychar -'a'+10;
873                 else if (mychar  >='A' && mychar <='F') r+=mychar -'A'+10;
874                 else return -1;
875         }
876         *val = r;
877         return 0;
878 }
879
880
881
882 /*
883  * Convert a str (base 10 or 16) into integer
884  */
885 static inline int strno2int( str *val, unsigned int *mask )
886 {
887         /* hexa or decimal*/
888         if (val->len>2 && val->s[0]=='0' && val->s[1]=='x') {
889                 return hexstr2int( val->s+2, val->len-2, mask);
890         } else {
891                 return str2int( val, mask);
892         }
893 }
894
895 /* converts a username into uid:gid,
896  * returns -1 on error & 0 on success */
897 int user2uid(int* uid, int* gid, char* user);
898
899 /* converts a group name into a gid
900  * returns -1 on error, 0 on success */
901 int group2gid(int* gid, char* group);
902
903 /*
904  * Replacement of timegm (does not exists on all platforms
905  * Taken from 
906  * http://lists.samba.org/archive/samba-technical/2002-November/025737.html
907  */
908 time_t _timegm(struct tm* t);
909
910 /* Convert time_t value that is relative to local timezone to UTC */
911 time_t local2utc(time_t in);
912
913 /* Convert time_t value in UTC to to value relative to local time zone */
914 time_t utc2local(time_t in);
915
916 /*
917  * Return str as zero terminated string allocated
918  * using pkg_malloc
919  */
920 char* as_asciiz(str* s);
921
922
923 /* return system version (major.minor.minor2) as
924  *  (major<<16)|(minor)<<8|(minor2)
925  * (if some of them are missing, they are set to 0)
926  * if the parameters are not null they are set to the coresp. part */
927 unsigned int get_sys_version(int* major, int* minor, int* minor2);
928
929 /** Converts relative pathnames to absolute pathnames. This function returns
930  * the full pathname of a file in parameter. If the file pathname does not
931  * start with / then it will be converted into an absolute pathname. The
932  * function gets the absolute directory pathname from \c base and appends \c
933  * file to it. The first parameter can be NULL, in this case the function will
934  * use the location of the main SER configuration file as reference.
935  * @param base filename to be used as reference when \c file is relative. It
936  *             must be absolute. The location of the SER configuration file
937  *             will be used as reference if you set the value of this
938  *             parameter to NULL.
939  * @param file A pathname to be converted to absolute.
940  * @return A string containing absolute pathname, the string must be freed
941  * with free. NULL on error.
942  */
943 char* get_abs_pathname(str* base, str* file);
944
945 /**
946  * search for needle in text
947  */
948 char *str_search(str *text, str *needle);
949
950 /*
951  * ser_memmem() returns the location of the first occurrence of data
952  * pattern b2 of size len2 in memory block b1 of size len1 or
953  * NULL if none is found. Obtained from NetBSD.
954  */
955 void * ser_memmem(const void *b1, const void *b2, size_t len1, size_t len2);
956
957 /*
958  * ser_memrmem() returns the location of the last occurrence of data
959  * pattern b2 of size len2 in memory block b1 of size len1 or
960  * NULL if none is found.
961  */
962 void * ser_memrmem(const void *b1, const void *b2, size_t len1, size_t len2);
963
964 #endif