4 * - various general purpose functions
6 * Copyright (C) 2001-2003 FhG Fokus
8 * This file is part of ser, a free SIP server.
10 * ser is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version
15 * For a license to use the ser software under conditions
16 * other than those described here, or to purchase support for this
17 * software, please contact iptel.org by e-mail at the following addresses:
20 * ser is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 * 2003-01-18 un_escape function introduced for convenience of code needing
32 * the complex&slow feature of unescaping
33 * 2003-01-28 scratchpad removed (jiri)
34 * 2003-01-29 pathmax added (jiri)
35 * 2003-02-13 strlower added (janakj)
36 * 2003-02-28 scratchpad compatibility abandoned (jiri)
37 * 2003-03-30 str2int and str2float added (janakj)
38 * 2003-04-26 ZSW (jiri)
39 * 2004-03-08 updated int2str (64 bits, INT2STR_MAX_LEN used) (andrei)
40 * 2005-11-29 reverse_hex2int/int2reverse_hex switched to unsigned int (andrei)
41 * 2005-12-09 added msgid_var (andrei)
42 * 2007-05-14 added get_sys_ver() (andrei)
43 * 2007-06-05 added MAX_UVAR_VALUE(), MAX_int(a,b) MIN_int(a,b) (andrei)
44 * 2008-05-21 added ushort2sbuf(), ushort2str() (andrei)
45 * 2009-03-16 added sint2strbuf() and incremented INST2STR_MAX_LEN to account
48 /** various helper functions.
56 #include "comp_defs.h"
58 #include <sys/types.h>
59 #include <sys/select.h>
68 #include "compiler_opt.h"
73 #include "mem/shm_mem.h"
77 /* zero-string wrapper */
78 #define ZSW(_c) ((_c)?(_c):"")
80 /* returns string beginning and length without insignificant chars */
81 #define trim_len( _len, _begin, _mystr ) \
83 (_len)=(_mystr).len; \
84 while ((_len) && ((_c=(_mystr).s[(_len)-1])==0 || _c=='\r' || \
85 _c=='\n' || _c==' ' || _c=='\t' )) \
87 (_begin)=(_mystr).s; \
88 while ((_len) && ((_c=*(_begin))==' ' || _c=='\t')) { \
94 #define trim_r( _mystr ) \
96 while( ((_mystr).len) && ( ((_c=(_mystr).s[(_mystr).len-1]))==0 ||\
97 _c=='\r' || _c=='\n' ) \
103 #define translate_pointer( _new_buf , _org_buf , _p) \
104 ( (_p)?(_new_buf + (_p-_org_buf)):(0) )
106 #define via_len(_via) \
107 ((_via)->bsize-((_via)->name.s-\
108 ((_via)->hdr.s+(_via)->hdr.len)))
112 /* rounds to sizeof(type), but type must have a 2^k size (e.g. short, int,
114 #define ROUND2TYPE(s, type) \
115 (((s)+(sizeof(type)-1))&(~(sizeof(type)-1)))
118 /* rounds to sizeof(char*) - the first 4 byte multiple on 32 bit archs
119 * and the first 8 byte multiple on 64 bit archs */
120 #define ROUND_POINTER(s) ROUND2TYPE(s, char*)
122 /* rounds to sizeof(long) - the first 4 byte multiple on 32 bit archs
123 * and the first 8 byte multiple on 64 bit archs (equiv. to ROUND_POINTER)*/
124 #define ROUND_LONG(s) ROUND2TYPE(s, long)
126 /* rounds to sizeof(int) - the first t byte multiple on 32 and 64 bit archs */
127 #define ROUND_INT(s) ROUND2TYPE(s, int)
129 /* rounds to sizeof(short) - the first 2 byte multiple */
130 #define ROUND_SHORT(s) ROUND2TYPE(s, short)
133 /* params: v - either a variable name, structure member or a type
134 * returns an unsigned long containing the maximum possible value that will
135 * fit in v, if v is unsigned or converted to an unsigned version
136 * example: MAX_UVAR_VALUE(unsigned short); MAX_UVAR_VALUE(i);
137 * MAX_UVAR_VALUE(((struct foo*)0)->bar) */
138 #define MAX_UVAR_VALUE(v) \
139 (((unsigned long)(-1))>>((sizeof(unsigned long)-sizeof(v))*8UL))
142 #define MIN_int(a, b) (((a)<(b))?(a):(b))
143 #define MAX_int(a, b) (((a)>(b))?(a):(b))
145 #define MIN_unsigned(a, b) (unsigned)(((unsigned)(a)<(unsigned)(b))?(a):(b))
146 #define MAX_unsigned(a, b) (unsigned)(((unsigned)(a)>(unsigned)(b))?(a):(b))
149 #define MIN_int(a, b) ((b)+(((a)-(b))& -((a)<(b))))
150 #define MAX_int(a, b) ((a)-(((a)-(b))& -((b)>(a))))
152 /* depend on signed right shift result which depends on the compiler */
153 #define MIN_int(a, b) ((b)+(((a)-(b))&(((a)-(b))>>(sizeof(int)*8-1))))
154 #define MAX_int(a, b) ((a)-(((a)-(b))&(((a)-(b))>>(sizeof(int)*8-1))))
158 #define append_str(_dest,_src,_len) \
160 memcpy( (_dest) , (_src) , (_len) ); \
161 (_dest) += (_len) ; \
165 /*! append _c char to _dest string */
166 #define append_chr(_dest,_c) \
170 /* links a value to a msgid */
180 /* return the value or 0 if the msg_id doesn't match */
181 #define get_msgid_val(var, id, type)\
182 ((type)((type)((var).msgid!=(id))-1)&((var).u.type##_val))
184 #define set_msgid_val(var, id, type, value)\
187 (var).u.type##_val=(value); \
190 /* char to hex conversion table */
191 static char fourbits2char[16] = { '0', '1', '2', '3', '4', '5',
192 '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
195 /* converts a str to an u. short, returns the u. short and sets *err on
196 * error and if err!=null
198 static inline unsigned short str2s(const char* s, unsigned int len,
203 unsigned char *limit;
208 str=(unsigned char*)s;
213 for(;str<limit ;str++){
214 if ( (*str <= '9' ) && (*str >= '0') ){
217 if (i>5) goto error_digits;
219 /* error unknown char */
227 /*DBG("str2s: ERROR: too many letters in [%.*s]\n", (int)len, init); */
231 /*DBG("str2s: ERROR: unexpected char %c in %.*s\n", *str, (int)len, init);
239 static inline int btostr( char *p, unsigned char val)
241 unsigned int a,b,i =0;
243 if ( (a=val/100)!=0 )
244 *(p+(i++)) = a+'0'; /*first digit*/
245 if ( (b=val%100/10)!=0 || a)
246 *(p+(i++)) = b+'0'; /*second digit*/
247 *(p+(i++)) = '0'+val%10; /*third digit*/
253 #define INT2STR_MAX_LEN (19+1+1+1) /* 2^64~= 16*10^18 =>
254 19+1 digits + sign + \0 */
257 * returns a pointer to a static buffer containing l in asciiz (with base "base") & sets len
258 * left padded with 0 to "size"
260 static inline char* int2str_base_0pad(unsigned int l, int* len, int base,
263 static char r[INT2STR_MAX_LEN];
267 BUG("base underflow\n");
271 BUG("base overflow\n");
276 r[INT2STR_MAX_LEN-1]=0; /* null terminate */
285 }while((l || i>j) && (i>=0));
287 BUG("result buffer overflow\n");
289 if (len) *len=(INT2STR_MAX_LEN-2)-i;
293 /* returns a pointer to a static buffer containing l in asciiz (with base "base") & sets len */
294 static inline char* int2str_base(unsigned int l, int* len, int base)
296 return int2str_base_0pad(l, len, base, 0);
301 /** unsigned long to str conversion using a provided buffer.
302 * Converts/prints an unsigned long to a string. The result buffer must be
303 * provided and its length must be at least INT2STR_MAX_LEN.
304 * @param l - unsigned long to be converted
305 * @param r - pointer to result buffer
306 * @param r_size - result buffer size, must be at least INT2STR_MAX_LEN.
307 * @param *len - length of the written string, _without_ the terminating 0.
308 * @return pointer _inside_ r, to the converted string (note: the string
309 * is written from the end of the buffer and not from the start and hence
310 * the returned pointer will most likely not be equal to r). In case of error
311 * it returns 0 (the only error being insufficient provided buffer size).
313 static inline char* int2strbuf(unsigned long l, char *r, int r_size, int* len)
317 if(unlikely(r_size<INT2STR_MAX_LEN)) {
320 return 0; /* => if someone misuses it => crash (feature no. 1) */
323 r[INT2STR_MAX_LEN-1]=0; /* null terminate */
330 LOG(L_CRIT, "BUG: int2str: overflow\n");
332 if (len) *len=(INT2STR_MAX_LEN-2)-i;
336 extern char ut_buf_int2str[INT2STR_MAX_LEN];
337 /** interger(long) to string conversion.
338 * This version uses a static buffer (shared with sint2str()).
339 * WARNING: other function calls might overwrite the static buffer, so
340 * either always save the result immediately or use int2strbuf(...).
341 * @param l - unsigned long to be converted/printed.
342 * @param *len - will be filled with the final length (without the terminating
344 * @return a pointer to a static buffer containing l in asciiz & sets len.
346 static inline char* int2str(unsigned long l, int* len)
348 return int2strbuf(l, ut_buf_int2str, INT2STR_MAX_LEN, len);
353 /** signed long to str conversion using a provided buffer.
354 * Converts a long to a signed string. The result buffer must be provided
355 * and its length must be at least INT2STR_MAX_LEN.
356 * @param l - long to be converted
357 * @param r - pointer to result buffer
358 * @param r_size - result buffer size, must be at least INT2STR_MAX_LEN.
359 * @param *len - length of the written string, _without_ the terminating 0.
360 * @return pointer _inside_ r, to the converted string (note: the string
361 * is written from the end of the buffer and not from the start and hence
362 * the returned pointer will most likely not be equal to r). In case of error
363 * it returns 0 (the only error being insufficient provided buffer size).
365 static inline char* sint2strbuf(long l, char* r, int r_size, int* len)
376 p = int2strbuf((unsigned long)l, r, r_size, &p_len);
377 if(sign && *len<(r_size-1)) {
387 /** Signed INTeger-TO-STRing: converts a long to a string.
388 * This version uses a static buffer, shared with int2str().
389 * WARNING: other function calls might overwrite the static buffer, so
390 * either always save the result immediately or use sint2strbuf(...).
391 * @param l - long to be converted/printed.
392 * @param *len - will be filled with the final length (without the terminating
394 * @return a pointer to a static buffer containing l in asciiz & sets len.
396 static inline char* sint2str(long l, int* len)
398 return sint2strbuf(l, ut_buf_int2str, INT2STR_MAX_LEN, len);
403 #define USHORT2SBUF_MAX_LEN 5 /* 65535*/
404 /* converts an unsigned short (16 bits) to asciiz
405 * returns bytes written or 0 on error
406 * the passed len must be at least USHORT2SBUF_MAX chars or error
408 * (optimized for port conversion (4 or 5 digits most of the time)*/
409 static inline int ushort2sbuf(unsigned short u, char* buf, int len)
412 unsigned char a, b, c, d;
414 if (unlikely(len<USHORT2SBUF_MAX_LEN))
418 buf[offs]=a+'0'; offs+=(a!=0);
420 buf[offs]=b+'0'; offs+=((offs|b)!=0);
422 buf[offs]=c+'0'; offs+=((offs|c)!=0);
424 buf[offs]=d+'0'; offs+=((offs|d)!=0);
425 buf[offs]=(unsigned char)u+'0';
431 #define USHORT2STR_MAX_LEN (USHORT2SBUF_MAX_LEN+1) /* 65535\0*/
432 /* converts an unsigned short (16 bits) to asciiz
433 * (optimized for port conversiob (4 or 5 digits most of the time)*/
434 static inline char* ushort2str(unsigned short u)
436 static char buf[USHORT2STR_MAX_LEN];
439 len=ushort2sbuf(u, buf, sizeof(buf)-1);
446 /* faster memchr version */
447 static inline char* q_memchr(char* p, int c, unsigned int size)
453 if (*p==(unsigned char)c) return p;
459 /* returns -1 on error, 1! on success (consistent with int2reverse_hex) */
460 inline static int reverse_hex2int( char *c, int len, unsigned int* res)
466 for (pc=c+len-1; len>0; pc--, len--) {
469 if ( mychar >='0' && mychar <='9') *res+=mychar -'0';
470 else if (mychar >='a' && mychar <='f') *res+=mychar -'a'+10;
471 else if (mychar >='A' && mychar <='F') *res+=mychar -'A'+10;
477 inline static int int2reverse_hex( char **c, int *size, unsigned int nr )
479 unsigned short digit;
481 if (*size && nr==0) {
488 while (*size && nr ) {
490 **c= digit >= 10 ? digit + 'a' - 10 : digit + '0';
495 return nr ? -1 /* number not processed; too little space */ : 1;
498 /* double output length assumed ; does NOT zero-terminate */
499 inline static int string2hex(
500 /* input */ unsigned char *str, int len,
501 /* output */ char *hex )
513 *hex=fourbits2char[(*str) >> 4];
515 *hex=fourbits2char[(*str) & 0xf];
524 /* portable sleep in microseconds (no interrupt handling now) */
526 inline static void sleep_us( unsigned int nusecs )
529 tval.tv_sec =nusecs/1000000;
530 tval.tv_usec=nusecs%1000000;
531 select(0, NULL, NULL, NULL, &tval );
535 /* portable determination of max_path */
536 inline static int pathmax()
539 static int pathmax=PATH_MAX;
541 static int pathmax=0;
543 if (pathmax==0) { /* init */
544 pathmax=pathconf("/", _PC_PATH_MAX);
545 pathmax=(pathmax<=0)?PATH_MAX_GUESS:pathmax+1;
550 inline static int hex2int(char hex_digit)
552 if (hex_digit>='0' && hex_digit<='9')
553 return hex_digit-'0';
554 if (hex_digit>='a' && hex_digit<='f')
555 return hex_digit-'a'+10;
556 if (hex_digit>='A' && hex_digit<='F')
557 return hex_digit-'A'+10;
558 /* no valid hex digit ... */
559 LOG(L_ERR, "ERROR: hex2int: '%c' is no hex char\n", hex_digit );
563 /* Un-escape URI user -- it takes a pointer to original user
564 str, as well as the new, unescaped one, which MUST have
565 an allocated buffer linked to the 'str' structure ;
566 (the buffer can be allocated with the same length as
567 the original string -- the output string is always
568 shorter (if escaped characters occur) or same-long
569 as the original one).
571 only printable characters are permitted
573 <0 is returned on an unescaping error, length of the
574 unescaped string otherwise
576 inline static int un_escape(str *user, str *new_user )
581 if( new_user==0 || new_user->s==0) {
582 LOG(L_CRIT, "BUG: un_escape: called with invalid param\n");
589 for (i = 0; i < user->len; i++) {
590 if (user->s[i] == '%') {
591 if (i + 2 >= user->len) {
592 LOG(L_ERR, "ERROR: un_escape: escape sequence too short in"
594 user->len, user->s, i );
597 hi=hex2int(user->s[i + 1]);
599 LOG(L_ERR, "ERROR: un_escape: non-hex high digit in an escape sequence in"
601 user->len, user->s, i+1 );
604 lo=hex2int(user->s[i + 2]);
606 LOG(L_ERR, "ERROR: non-hex low digit in an escape sequence in "
608 user->len, user->s, i+2 );
612 if (value < 32 || value > 126) {
613 LOG(L_ERR, "ERROR: non-ASCII escaped character in '%.*s' @ %d\n",
614 user->len, user->s, i );
617 new_user->s[j] = value;
618 i+=2; /* consume the two hex digits, for cycle will move to the next char */
620 new_user->s[j] = user->s[i];
622 j++; /* good -- we translated another character */
634 * Convert a string to lower case
636 static inline void strlower(str* _s)
640 for(i = 0; i < _s->len; i++) {
641 _s->s[i] = tolower(_s->s[i]);
647 * Convert a str into integer
649 static inline int str2int(str* _s, unsigned int* _r)
654 for(i = 0; i < _s->len; i++) {
655 if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
657 *_r += _s->s[i] - '0';
667 * Convert an str to signed integer
669 static inline int str2sint(str* _s, int* _r)
674 if (_s->len == 0) return -1;
679 if (_s->s[0] == '+') {
681 } else if (_s->s[0] == '-') {
685 for(; i < _s->len; i++) {
686 if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
688 *_r += _s->s[i] - '0';
702 * \brief Make a copy of a str structure using shm_malloc
703 * \param dst destination
705 * \return 0 on success, -1 on failure
707 static inline int shm_str_dup(str* dst, const str* src)
709 dst->s = shm_malloc(src->len);
715 memcpy(dst->s, src->s, src->len);
724 * \brief Make a copy of a str structure using pkg_malloc
725 * \param dst destination
727 * \return 0 on success, -1 on failure
729 static inline int pkg_str_dup(str* dst, const str* src)
731 dst->s = pkg_malloc(src->len);
738 memcpy(dst->s, src->s, src->len);
744 * \brief Compare two str's case sensitive
745 * \param str1 first str
746 * \param str2 second str
747 * \return 0 if both are equal, positive if str1 is greater, negative if str2 is greater, -2 on errors
749 static inline int str_strcmp(const str *str1, const str *str2)
751 if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
753 LM_ERR("bad parameters\n");
757 if (str1->len < str2->len)
759 else if (str1->len > str2->len)
762 return strncmp(str1->s, str2->s, str1->len);
766 * \brief Compare two str's case insensitive
767 * \param str1 first str
768 * \param str2 second str
769 * \return 0 if both are equal, positive if str1 is greater, negative if str2 is greater, -2 on errors
771 static inline int str_strcasecmp(const str *str1, const str *str2)
773 if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
775 LM_ERR("bad parameters\n");
778 if (str1->len < str2->len)
780 else if (str1->len > str2->len)
783 return strncasecmp(str1->s, str2->s, str1->len);
786 /* converts a username into uid:gid,
787 * returns -1 on error & 0 on success */
788 int user2uid(int* uid, int* gid, char* user);
790 /* converts a group name into a gid
791 * returns -1 on error, 0 on success */
792 int group2gid(int* gid, char* group);
795 * Replacement of timegm (does not exists on all platforms
797 * http://lists.samba.org/archive/samba-technical/2002-November/025737.html
799 time_t _timegm(struct tm* t);
801 /* Convert time_t value that is relative to local timezone to UTC */
802 time_t local2utc(time_t in);
804 /* Convert time_t value in UTC to to value relative to local time zone */
805 time_t utc2local(time_t in);
808 * Return str as zero terminated string allocated
811 char* as_asciiz(str* s);
814 /* return system version (major.minor.minor2) as
815 * (major<<16)|(minor)<<8|(minor2)
816 * (if some of them are missing, they are set to 0)
817 * if the parameters are not null they are set to the coresp. part */
818 unsigned int get_sys_version(int* major, int* minor, int* minor2);
820 /** Converts relative pathnames to absolute pathnames. This function returns
821 * the full pathname of a file in parameter. If the file pathname does not
822 * start with / then it will be converted into an absolute pathname. The
823 * function gets the absolute directory pathname from \c base and appends \c
824 * file to it. The first parameter can be NULL, in this case the function will
825 * use the location of the main SER configuration file as reference.
826 * @param base filename to be used as reference when \c file is relative. It
827 * must be absolute. The location of the SER configuration file
828 * will be used as reference if you set the value of this
830 * @param file A pathname to be converted to absolute.
831 * @return A string containing absolute pathname, the string must be freed
832 * with free. NULL on error.
834 char* get_abs_pathname(str* base, str* file);