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