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 */
str2s(const char * s,unsigned int len,int * err)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
btostr(char * p,unsigned char val)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 */
int2str_base_0pad(unsigned int l,int * len,int base,int size)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 */
int2str_base(unsigned int l,int * len,int base)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 */
int2strbuf(unsigned long l,char * r,int r_size,int * len)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 */
int2str(unsigned long l,int * len)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 */
sint2strbuf(long l,char * r,int r_size,int * len)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 */
sint2str(long l,int * len)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)*/
ushort2sbuf(unsigned short u,char * buf,int len)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)*/
ushort2str(unsigned short u)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 */
q_memchr(char * p,int c,unsigned int size)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
q_memrchr(char * p,int c,unsigned int size)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) */
reverse_hex2int(char * c,int len,unsigned int * res)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
int2reverse_hex(char ** c,int * size,unsigned int nr)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 */
string2hex(unsigned char * str,int len,char * hex)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
sleep_us(unsigned int nusecs)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 */
pathmax(void)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
hex2int(char hex_digit)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 */
un_escape(str * user,str * new_user)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 */
strlower(str * _s)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 */
str2int(str * _s,unsigned int * _r)634 static inline int str2int(str* _s, unsigned int* _r)
635 {
636 int i;
637
638 if (_r == NULL) return -1;
639 *_r = 0;
640 if (_s == NULL) return -1;
641 if (_s->len < 0) return -1;
642 if (_s->s == NULL) return -1;
643
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 */
str2sint(str * _s,int * _r)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 * Convert a str into integer
694 */
strz2int(char * _s,unsigned int * _r)695 static inline int strz2int(char* _s, unsigned int* _r)
696 {
697 int i;
698
699 if (_r == NULL) return -1;
700 *_r = 0;
701 if (_s == NULL) return -1;
702
703 for(i = 0; _s[i] != '\0'; i++) {
704 if ((_s[i] >= '0') && (_s[i] <= '9')) {
705 *_r *= 10;
706 *_r += _s[i] - '0';
707 } else {
708 return -1;
709 }
710 }
711
712 return 0;
713 }
714
715 /*
716 * Convert an str to signed integer
717 */
strz2sint(char * _s,int * _r)718 static inline int strz2sint(char* _s, int* _r)
719 {
720 int i;
721 int sign;
722
723 if (_r == NULL) return -1;
724 *_r = 0;
725 if (_s == NULL) return -1;
726
727 sign = 1;
728 i = 0;
729 if (_s[0] == '+') {
730 i++;
731 } else if (_s[0] == '-') {
732 sign = -1;
733 i++;
734 }
735 for(; _s[i] != '\0'; i++) {
736 if ((_s[i] >= '0') && (_s[i] <= '9')) {
737 *_r *= 10;
738 *_r += _s[i] - '0';
739 } else {
740 return -1;
741 }
742 }
743 *_r *= sign;
744
745 return 0;
746 }
747
748 /**
749 * duplicate str structure and content in a single shm block
750 */
shm_str_dup_block(const str * src)751 static inline str* shm_str_dup_block(const str* src)
752 {
753 str *dst;
754
755 if(src==NULL) {
756 return NULL;
757 }
758 dst = (str*)shm_malloc(sizeof(str) + src->len + 1);
759 if (dst == NULL) {
760 SHM_MEM_ERROR;
761 return NULL;
762 }
763 memset(dst, 0, sizeof(str) + src->len + 1);
764
765 dst->s = (char*)dst + sizeof(str);
766 dst->len = src->len;
767 memcpy(dst->s, src->s, src->len);
768
769 return dst;
770 }
771
772 /**
773 * \brief Make a copy of a str structure to a str using shm_malloc
774 * The copy will be zero-terminated
775 * \param dst destination
776 * \param src source
777 * \return 0 on success, -1 on failure
778 */
shm_str_dup(str * dst,const str * src)779 static inline int shm_str_dup(str* dst, const str* src)
780 {
781 /* NULL checks */
782 if (dst == NULL || src == NULL) {
783 LM_ERR("NULL src or dst\n");
784 return -1;
785 }
786
787 /**
788 * fallback actions:
789 * - dst->len=0
790 * - dst->s is allocated sizeof(void*) size
791 * - return 0 (i.e. success)
792 */
793
794 /* fallback checks */
795 if (src->len < 0 || src->s == NULL) {
796 LM_WARN("shm_str_dup fallback; dup called for src->s == NULL or src->len < 0\n");
797 dst->len = 0;
798 } else {
799 dst->len = src->len;
800 }
801
802 dst->s = (char*)shm_malloc(dst->len+1);
803 if (dst->s == NULL) {
804 SHM_MEM_ERROR;
805 return -1;
806 }
807
808 /* avoid memcpy from NULL source - undefined behaviour */
809 if (src->s == NULL) {
810 LM_WARN("shm_str_dup fallback; skip memcpy for src->s == NULL\n");
811 return 0;
812 }
813
814 memcpy(dst->s, src->s, dst->len);
815 dst->s[dst->len] = 0;
816
817 return 0;
818 }
819
820 /**
821 * \brief Make a copy of a char pointer to a char pointer using shm_malloc
822 * \param src source
823 * \return a pointer to the new allocated char on success, 0 on failure
824 */
shm_char_dup(const char * src)825 static inline char* shm_char_dup(const char *src)
826 {
827 char *rval;
828 int len;
829
830 if (!src) {
831 LM_ERR("NULL src or dst\n");
832 return NULL;
833 }
834
835 len = strlen(src) + 1;
836 rval = (char*)shm_malloc(len);
837 if (!rval) {
838 SHM_MEM_ERROR;
839 return NULL;
840 }
841
842 memcpy(rval, src, len);
843
844 return rval;
845 }
846
847
848 /**
849 * \brief Make a copy from str structure to a char pointer using shm_malloc
850 * \param src source
851 * \return a pointer to the new allocated char on success, 0 on failure
852 */
shm_str2char_dup(str * src)853 static inline char* shm_str2char_dup(str *src)
854 {
855 char *res;
856
857 if (!src || !src->s) {
858 LM_ERR("NULL src\n");
859 return NULL;
860 }
861
862 if (!(res = (char *) shm_malloc(src->len + 1))) {
863 SHM_MEM_ERROR;
864 return NULL;
865 }
866
867 strncpy(res, src->s, src->len);
868 res[src->len] = 0;
869
870 return res;
871 }
872
873
874 /**
875 * \brief Make a copy of a str structure using pkg_malloc
876 * The copy will be zero-terminated
877 * \param dst destination
878 * \param src source
879 * \return 0 on success, -1 on failure
880 */
pkg_str_dup(str * dst,const str * src)881 static inline int pkg_str_dup(str* dst, const str* src)
882 {
883 /* NULL checks */
884 if (dst == NULL || src == NULL) {
885 LM_ERR("NULL src or dst\n");
886 return -1;
887 }
888
889 /**
890 * fallback actions:
891 * - dst->len=0
892 * - dst->s is allocated sizeof(void*) size
893 * - return 0 (i.e. success)
894 */
895
896 /* fallback checks */
897 if (src->len < 0 || src->s == NULL) {
898 LM_WARN("pkg_str_dup fallback; dup called for src->s == NULL or src->len < 0\n");
899 dst->len = 0;
900 } else {
901 dst->len = src->len;
902 }
903
904 dst->s = (char*)pkg_malloc(dst->len+1);
905 if (dst->s == NULL) {
906 PKG_MEM_ERROR;
907 return -1;
908 }
909
910 /* avoid memcpy from NULL source - undefined behaviour */
911 if (src->s == NULL) {
912 LM_WARN("pkg_str_dup fallback; skip memcpy for src->s == NULL\n");
913 return 0;
914 }
915
916 memcpy(dst->s, src->s, dst->len);
917 dst->s[dst->len] = 0;
918
919 return 0;
920 }
921
922 /**
923 * \brief Compare two str's case sensitive
924 * \param str1 first str
925 * \param str2 second str
926 * \return 0 if both are equal, positive if str1 is greater, negative if str2 is greater, -2 on errors
927 */
str_strcmp(const str * str1,const str * str2)928 static inline int str_strcmp(const str *str1, const str *str2)
929 {
930 if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
931 {
932 LM_ERR("bad parameters\n");
933 return -2;
934 }
935
936 if (str1->len < str2->len)
937 return -1;
938 else if (str1->len > str2->len)
939 return 1;
940 else
941 return strncmp(str1->s, str2->s, str1->len);
942 }
943
944 /**
945 * \brief Compare two str's case insensitive
946 * \param str1 first str
947 * \param str2 second str
948 * \return 0 if both are equal, positive if str1 is greater, negative if str2 is greater, -2 on errors
949 */
str_strcasecmp(const str * str1,const str * str2)950 static inline int str_strcasecmp(const str *str1, const str *str2)
951 {
952 if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
953 {
954 LM_ERR("bad parameters\n");
955 return -2;
956 }
957 if (str1->len < str2->len)
958 return -1;
959 else if (str1->len > str2->len)
960 return 1;
961 else
962 return strncasecmp(str1->s, str2->s, str1->len);
963 }
964
965 #ifndef MIN
966 #define MIN(x, y) ((x) < (y) ? (x) : (y))
967 #endif
968 #ifndef MAX
969 #define MAX(x, y) ((x) > (y) ? (x) : (y))
970 #endif
971
972
973 /* INTeger-TO-Buffer-STRing : convers an unsigned long to a string
974 * IMPORTANT: the provided buffer must be at least INT2STR_MAX_LEN size !! */
int2bstr(unsigned long l,char * s,int * len)975 static inline char* int2bstr(unsigned long l, char *s, int* len)
976 {
977 int i;
978 i=INT2STR_MAX_LEN-2;
979 s[INT2STR_MAX_LEN-1]=0;
980 /* null terminate */
981 do{
982 s[i]=l%10+'0';
983 i--;
984 l/=10;
985 }while(l && (i>=0));
986 if (l && (i<0)){
987 LM_CRIT("overflow error\n");
988 }
989 if (len) *len=(INT2STR_MAX_LEN-2)-i;
990 return &s[i+1];
991 }
992
993
hexstr2int(char * c,int len,unsigned int * val)994 inline static int hexstr2int(char *c, int len, unsigned int *val)
995 {
996 char *pc;
997 int r;
998 char mychar;
999
1000 r=0;
1001 for (pc=c; pc<c+len; pc++) {
1002 r <<= 4 ;
1003 mychar=*pc;
1004 if ( mychar >='0' && mychar <='9') r+=mychar -'0';
1005 else if (mychar >='a' && mychar <='f') r+=mychar -'a'+10;
1006 else if (mychar >='A' && mychar <='F') r+=mychar -'A'+10;
1007 else return -1;
1008 }
1009 *val = r;
1010 return 0;
1011 }
1012
1013
1014
1015 /*
1016 * Convert a str (base 10 or 16) into integer
1017 */
strno2int(str * val,unsigned int * mask)1018 static inline int strno2int( str *val, unsigned int *mask )
1019 {
1020 /* hexa or decimal*/
1021 if (val->len>2 && val->s[0]=='0' && val->s[1]=='x') {
1022 return hexstr2int( val->s+2, val->len-2, mask);
1023 } else {
1024 return str2int( val, mask);
1025 }
1026 }
1027
1028 /* converts a username into uid:gid,
1029 * returns -1 on error & 0 on success */
1030 int user2uid(int* uid, int* gid, char* user);
1031
1032 /* converts a group name into a gid
1033 * returns -1 on error, 0 on success */
1034 int group2gid(int* gid, char* group);
1035
1036 /*
1037 * Replacement of timegm (does not exists on all platforms
1038 * Taken from
1039 * http://lists.samba.org/archive/samba-technical/2002-November/025737.html
1040 */
1041 time_t _timegm(struct tm* t);
1042
1043 /* Convert time_t value that is relative to local timezone to UTC */
1044 time_t local2utc(time_t in);
1045
1046 /* Convert time_t value in UTC to to value relative to local time zone */
1047 time_t utc2local(time_t in);
1048
1049 /*
1050 * Return str as zero terminated string allocated
1051 * using pkg_malloc
1052 */
1053 char* as_asciiz(str* s);
1054
1055
1056 /* return system version (major.minor.minor2) as
1057 * (major<<16)|(minor)<<8|(minor2)
1058 * (if some of them are missing, they are set to 0)
1059 * if the parameters are not null they are set to the coresp. part */
1060 unsigned int get_sys_version(int* major, int* minor, int* minor2);
1061
1062 /** Converts relative pathnames to absolute pathnames. This function returns
1063 * the full pathname of a file in parameter. If the file pathname does not
1064 * start with / then it will be converted into an absolute pathname. The
1065 * function gets the absolute directory pathname from \c base and appends \c
1066 * file to it. The first parameter can be NULL, in this case the function will
1067 * use the location of the main SER configuration file as reference.
1068 * @param base filename to be used as reference when \c file is relative. It
1069 * must be absolute. The location of the SER configuration file
1070 * will be used as reference if you set the value of this
1071 * parameter to NULL.
1072 * @param file A pathname to be converted to absolute.
1073 * @return A string containing absolute pathname, the string must be freed
1074 * with free. NULL on error.
1075 */
1076 char* get_abs_pathname(str* base, str* file);
1077
1078 /**
1079 * search for needle in text
1080 */
1081 char *str_search(str *text, str *needle);
1082
1083 /*
1084 * ser_memmem() returns the location of the first occurrence of data
1085 * pattern b2 of size len2 in memory block b1 of size len1 or
1086 * NULL if none is found. Obtained from NetBSD.
1087 */
1088 void * ser_memmem(const void *b1, const void *b2, size_t len1, size_t len2);
1089
1090 /*
1091 * ser_memrmem() returns the location of the last occurrence of data
1092 * pattern b2 of size len2 in memory block b1 of size len1 or
1093 * NULL if none is found.
1094 */
1095 void * ser_memrmem(const void *b1, const void *b2, size_t len1, size_t len2);
1096
1097 #endif
1098