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