ut.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. *$Id$
  3. *
  4. * - various general purpose functions
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  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
  14. *
  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:
  18. * [email protected]
  19. *
  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.
  24. *
  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
  28. *
  29. * History
  30. * ------
  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. */
  46. #ifndef ut_h
  47. #define ut_h
  48. #include "comp_defs.h"
  49. #include <sys/types.h>
  50. #include <sys/time.h>
  51. #include <limits.h>
  52. #include <time.h>
  53. #include <unistd.h>
  54. #include <ctype.h>
  55. #include "compiler_opt.h"
  56. #include "config.h"
  57. #include "dprint.h"
  58. #include "str.h"
  59. /* zero-string wrapper */
  60. #define ZSW(_c) ((_c)?(_c):"")
  61. /* returns string beginning and length without insignificant chars */
  62. #define trim_len( _len, _begin, _mystr ) \
  63. do{ static char _c; \
  64. (_len)=(_mystr).len; \
  65. while ((_len) && ((_c=(_mystr).s[(_len)-1])==0 || _c=='\r' || \
  66. _c=='\n' || _c==' ' || _c=='\t' )) \
  67. (_len)--; \
  68. (_begin)=(_mystr).s; \
  69. while ((_len) && ((_c=*(_begin))==' ' || _c=='\t')) { \
  70. (_len)--;\
  71. (_begin)++; \
  72. } \
  73. }while(0)
  74. #define trim_r( _mystr ) \
  75. do{ static char _c; \
  76. while( ((_mystr).len) && ( ((_c=(_mystr).s[(_mystr).len-1]))==0 ||\
  77. _c=='\r' || _c=='\n' ) \
  78. ) \
  79. (_mystr).len--; \
  80. }while(0)
  81. #define translate_pointer( _new_buf , _org_buf , _p) \
  82. ( (_p)?(_new_buf + (_p-_org_buf)):(0) )
  83. #define via_len(_via) \
  84. ((_via)->bsize-((_via)->name.s-\
  85. ((_via)->hdr.s+(_via)->hdr.len)))
  86. /* rounds to sizeof(type), but type must have a 2^k size (e.g. short, int,
  87. * long, void*) */
  88. #define ROUND2TYPE(s, type) \
  89. (((s)+(sizeof(type)-1))&(~(sizeof(type)-1)))
  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. /* rounds to sizeof(long) - the first 4 byte multiple on 32 bit archs
  94. * and the first 8 byte multiple on 64 bit archs (equiv. to ROUND_POINTER)*/
  95. #define ROUND_LONG(s) ROUND2TYPE(s, long)
  96. /* rounds to sizeof(int) - the first t byte multiple on 32 and 64 bit archs */
  97. #define ROUND_INT(s) ROUND2TYPE(s, int)
  98. /* rounds to sizeof(short) - the first 2 byte multiple */
  99. #define ROUND_SHORT(s) ROUND2TYPE(s, short)
  100. /* params: v - either a variable name, structure member or a type
  101. * returns an unsigned long containing the maximum possible value that will
  102. * fit in v, if v is unsigned or converted to an unsigned version
  103. * example: MAX_UVAR_VALUE(unsigned short); MAX_UVAR_VALUE(i);
  104. * MAX_UVAR_VALUE(((struct foo*)0)->bar) */
  105. #define MAX_UVAR_VALUE(v) \
  106. (((unsigned long)(-1))>>((sizeof(unsigned long)-sizeof(v))*8UL))
  107. #define MIN_int(a, b) (((a)<(b))?(a):(b))
  108. #define MAX_int(a, b) (((a)>(b))?(a):(b))
  109. #define MIN_unsigned(a, b) (unsigned)(((unsigned)(a)<(unsigned)(b))?(a):(b))
  110. #define MAX_unsigned(a, b) (unsigned)(((unsigned)(a)>(unsigned)(b))?(a):(b))
  111. #if 0
  112. #define MIN_int(a, b) ((b)+(((a)-(b))& -((a)<(b))))
  113. #define MAX_int(a, b) ((a)-(((a)-(b))& -((b)>(a))))
  114. /* depend on signed right shift result which depends on the compiler */
  115. #define MIN_int(a, b) ((b)+(((a)-(b))&(((a)-(b))>>(sizeof(int)*8-1))))
  116. #define MAX_int(a, b) ((a)-(((a)-(b))&(((a)-(b))>>(sizeof(int)*8-1))))
  117. #endif
  118. /* links a value to a msgid */
  119. struct msgid_var{
  120. union{
  121. char char_val;
  122. int int_val;
  123. long long_val;
  124. }u;
  125. unsigned int msgid;
  126. };
  127. /* return the value or 0 if the msg_id doesn't match */
  128. #define get_msgid_val(var, id, type)\
  129. (type)((type)((var).msgid!=(id))-1)&((var).u.type##_val)
  130. #define set_msgid_val(var, id, type, value)\
  131. do{\
  132. (var).msgid=(id); \
  133. (var).u.type##_val=(value); \
  134. }while(0)
  135. /* char to hex conversion table */
  136. static char fourbits2char[16] = { '0', '1', '2', '3', '4', '5',
  137. '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
  138. /* converts a str to an u. short, returns the u. short and sets *err on
  139. * error and if err!=null
  140. */
  141. static inline unsigned short str2s(const char* s, unsigned int len,
  142. int *err)
  143. {
  144. unsigned short ret;
  145. int i;
  146. unsigned char *limit;
  147. unsigned char *init;
  148. unsigned char* str;
  149. /*init*/
  150. str=(unsigned char*)s;
  151. ret=i=0;
  152. limit=str+len;
  153. init=str;
  154. for(;str<limit ;str++){
  155. if ( (*str <= '9' ) && (*str >= '0') ){
  156. ret=ret*10+*str-'0';
  157. i++;
  158. if (i>5) goto error_digits;
  159. }else{
  160. /* error unknown char */
  161. goto error_char;
  162. }
  163. }
  164. if (err) *err=0;
  165. return ret;
  166. error_digits:
  167. /*DBG("str2s: ERROR: too many letters in [%.*s]\n", (int)len, init); */
  168. if (err) *err=1;
  169. return 0;
  170. error_char:
  171. /*DBG("str2s: ERROR: unexpected char %c in %.*s\n", *str, (int)len, init);
  172. * */
  173. if (err) *err=1;
  174. return 0;
  175. }
  176. static inline int btostr( char *p, unsigned char val)
  177. {
  178. unsigned int a,b,i =0;
  179. if ( (a=val/100)!=0 )
  180. *(p+(i++)) = a+'0'; /*first digit*/
  181. if ( (b=val%100/10)!=0 || a)
  182. *(p+(i++)) = b+'0'; /*second digit*/
  183. *(p+(i++)) = '0'+val%10; /*third digit*/
  184. return i;
  185. }
  186. #define INT2STR_MAX_LEN (19+1+1) /* 2^64~= 16*10^18 => 19+1 digits + \0 */
  187. /*
  188. * returns a pointer to a static buffer containing l in asciiz (with base "base") & sets len
  189. * left padded with 0 to "size"
  190. */
  191. static inline char* int2str_base_0pad(unsigned int l, int* len, int base,
  192. int size)
  193. {
  194. static char r[INT2STR_MAX_LEN];
  195. int i, j;
  196. if (base < 2) {
  197. BUG("base underflow\n");
  198. return NULL;
  199. }
  200. if (base > 36) {
  201. BUG("base overflow\n");
  202. return NULL;
  203. }
  204. i=INT2STR_MAX_LEN-2;
  205. j=i-size;
  206. r[INT2STR_MAX_LEN-1]=0; /* null terminate */
  207. do{
  208. r[i]=l%base;
  209. if (r[i]<10)
  210. r[i]+='0';
  211. else
  212. r[i]+='a'-10;
  213. i--;
  214. l/=base;
  215. }while((l || i>j) && (i>=0));
  216. if (l && (i<0)){
  217. BUG("result buffer overflow\n");
  218. }
  219. if (len) *len=(INT2STR_MAX_LEN-2)-i;
  220. return &r[i+1];
  221. }
  222. /* returns a pointer to a static buffer containing l in asciiz (with base "base") & sets len */
  223. static inline char* int2str_base(unsigned int l, int* len, int base)
  224. {
  225. return int2str_base_0pad(l, len, base, 0);
  226. }
  227. /* returns a pointer to a static buffer containing l in asciiz & sets len */
  228. static inline char* int2str(unsigned int l, int* len)
  229. {
  230. static char r[INT2STR_MAX_LEN];
  231. int i;
  232. i=INT2STR_MAX_LEN-2;
  233. r[INT2STR_MAX_LEN-1]=0; /* null terminate */
  234. do{
  235. r[i]=l%10+'0';
  236. i--;
  237. l/=10;
  238. }while(l && (i>=0));
  239. if (l && (i<0)){
  240. LOG(L_CRIT, "BUG: int2str: overflow\n");
  241. }
  242. if (len) *len=(INT2STR_MAX_LEN-2)-i;
  243. return &r[i+1];
  244. }
  245. #define USHORT2SBUF_MAX_LEN 5 /* 65535*/
  246. /* converts an unsigned short (16 bits) to asciiz
  247. * returns bytes written or 0 on error
  248. * the passed len must be at least USHORT2SBUF_MAX chars or error
  249. * would be returned.
  250. * (optimized for port conversion (4 or 5 digits most of the time)*/
  251. static inline int ushort2sbuf(unsigned short u, char* buf, int len)
  252. {
  253. int offs;
  254. unsigned char a, b, c, d;
  255. if (unlikely(len<USHORT2SBUF_MAX_LEN))
  256. return 0;
  257. offs=0;
  258. a=u/10000; u%=10000;
  259. buf[offs]=a+'0'; offs+=(a!=0);
  260. b=u/1000; u%=1000;
  261. buf[offs]=b+'0'; offs+=((offs|b)!=0);
  262. c=u/100; u%=100;
  263. buf[offs]=c+'0'; offs+=((offs|c)!=0);
  264. d=u/10; u%=10;
  265. buf[offs]=d+'0'; offs+=((offs|d)!=0);
  266. buf[offs]=(unsigned char)u+'0';
  267. return offs+1;
  268. }
  269. #define USHORT2STR_MAX_LEN (USHORT2SBUF_MAX_LEN+1) /* 65535\0*/
  270. /* converts an unsigned short (16 bits) to asciiz
  271. * (optimized for port conversiob (4 or 5 digits most of the time)*/
  272. static inline char* ushort2str(unsigned short u)
  273. {
  274. static char buf[USHORT2STR_MAX_LEN];
  275. int len;
  276. len=ushort2sbuf(u, buf, sizeof(buf)-1);
  277. buf[len]=0;
  278. return buf;
  279. }
  280. /* faster memchr version */
  281. static inline char* q_memchr(char* p, int c, unsigned int size)
  282. {
  283. char* end;
  284. end=p+size;
  285. for(;p<end;p++){
  286. if (*p==(unsigned char)c) return p;
  287. }
  288. return 0;
  289. }
  290. /* returns -1 on error, 1! on success (consistent with int2reverse_hex) */
  291. inline static int reverse_hex2int( char *c, int len, unsigned int* res)
  292. {
  293. char *pc;
  294. char mychar;
  295. *res=0;
  296. for (pc=c+len-1; len>0; pc--, len--) {
  297. *res <<= 4 ;
  298. mychar=*pc;
  299. if ( mychar >='0' && mychar <='9') *res+=mychar -'0';
  300. else if (mychar >='a' && mychar <='f') *res+=mychar -'a'+10;
  301. else if (mychar >='A' && mychar <='F') *res+=mychar -'A'+10;
  302. else return -1;
  303. }
  304. return 1;
  305. }
  306. inline static int int2reverse_hex( char **c, int *size, unsigned int nr )
  307. {
  308. unsigned short digit;
  309. if (*size && nr==0) {
  310. **c = '0';
  311. (*c)++;
  312. (*size)--;
  313. return 1;
  314. }
  315. while (*size && nr ) {
  316. digit = nr & 0xf ;
  317. **c= digit >= 10 ? digit + 'a' - 10 : digit + '0';
  318. nr >>= 4;
  319. (*c)++;
  320. (*size)--;
  321. }
  322. return nr ? -1 /* number not processed; too little space */ : 1;
  323. }
  324. /* double output length assumed ; does NOT zero-terminate */
  325. inline static int string2hex(
  326. /* input */ unsigned char *str, int len,
  327. /* output */ char *hex )
  328. {
  329. int orig_len;
  330. if (len==0) {
  331. *hex='0';
  332. return 1;
  333. }
  334. orig_len=len;
  335. while ( len ) {
  336. *hex=fourbits2char[(*str) >> 4];
  337. hex++;
  338. *hex=fourbits2char[(*str) & 0xf];
  339. hex++;
  340. len--;
  341. str++;
  342. }
  343. return orig_len-len;
  344. }
  345. /* portable sleep in microseconds (no interrupt handling now) */
  346. inline static void sleep_us( unsigned int nusecs )
  347. {
  348. struct timeval tval;
  349. tval.tv_sec =nusecs/1000000;
  350. tval.tv_usec=nusecs%1000000;
  351. select(0, NULL, NULL, NULL, &tval );
  352. }
  353. /* portable determination of max_path */
  354. inline static int pathmax()
  355. {
  356. #ifdef PATH_MAX
  357. static int pathmax=PATH_MAX;
  358. #else
  359. static int pathmax=0;
  360. #endif
  361. if (pathmax==0) { /* init */
  362. pathmax=pathconf("/", _PC_PATH_MAX);
  363. pathmax=(pathmax<=0)?PATH_MAX_GUESS:pathmax+1;
  364. }
  365. return pathmax;
  366. }
  367. inline static int hex2int(char hex_digit)
  368. {
  369. if (hex_digit>='0' && hex_digit<='9')
  370. return hex_digit-'0';
  371. if (hex_digit>='a' && hex_digit<='f')
  372. return hex_digit-'a'+10;
  373. if (hex_digit>='A' && hex_digit<='F')
  374. return hex_digit-'A'+10;
  375. /* no valid hex digit ... */
  376. LOG(L_ERR, "ERROR: hex2int: '%c' is no hex char\n", hex_digit );
  377. return -1;
  378. }
  379. /* Un-escape URI user -- it takes a pointer to original user
  380. str, as well as the new, unescaped one, which MUST have
  381. an allocated buffer linked to the 'str' structure ;
  382. (the buffer can be allocated with the same length as
  383. the original string -- the output string is always
  384. shorter (if escaped characters occur) or same-long
  385. as the original one).
  386. only printable characters are permitted
  387. <0 is returned on an unescaping error, length of the
  388. unescaped string otherwise
  389. */
  390. inline static int un_escape(str *user, str *new_user )
  391. {
  392. int i, j, value;
  393. int hi, lo;
  394. if( new_user==0 || new_user->s==0) {
  395. LOG(L_CRIT, "BUG: un_escape: called with invalid param\n");
  396. return -1;
  397. }
  398. new_user->len = 0;
  399. j = 0;
  400. for (i = 0; i < user->len; i++) {
  401. if (user->s[i] == '%') {
  402. if (i + 2 >= user->len) {
  403. LOG(L_ERR, "ERROR: un_escape: escape sequence too short in"
  404. " '%.*s' @ %d\n",
  405. user->len, user->s, i );
  406. goto error;
  407. }
  408. hi=hex2int(user->s[i + 1]);
  409. if (hi<0) {
  410. LOG(L_ERR, "ERROR: un_escape: non-hex high digit in an escape sequence in"
  411. " '%.*s' @ %d\n",
  412. user->len, user->s, i+1 );
  413. goto error;
  414. }
  415. lo=hex2int(user->s[i + 2]);
  416. if (lo<0) {
  417. LOG(L_ERR, "ERROR: non-hex low digit in an escape sequence in "
  418. "'%.*s' @ %d\n",
  419. user->len, user->s, i+2 );
  420. goto error;
  421. }
  422. value=(hi<<4)+lo;
  423. if (value < 32 || value > 126) {
  424. LOG(L_ERR, "ERROR: non-ASCII escaped character in '%.*s' @ %d\n",
  425. user->len, user->s, i );
  426. goto error;
  427. }
  428. new_user->s[j] = value;
  429. i+=2; /* consume the two hex digits, for cycle will move to the next char */
  430. } else {
  431. new_user->s[j] = user->s[i];
  432. }
  433. j++; /* good -- we translated another character */
  434. }
  435. new_user->len = j;
  436. return j;
  437. error:
  438. new_user->len = j;
  439. return -1;
  440. }
  441. /*
  442. * Convert a string to lower case
  443. */
  444. static inline void strlower(str* _s)
  445. {
  446. int i;
  447. for(i = 0; i < _s->len; i++) {
  448. _s->s[i] = tolower(_s->s[i]);
  449. }
  450. }
  451. /*
  452. * Convert a str into integer
  453. */
  454. static inline int str2int(str* _s, unsigned int* _r)
  455. {
  456. int i;
  457. *_r = 0;
  458. for(i = 0; i < _s->len; i++) {
  459. if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
  460. *_r *= 10;
  461. *_r += _s->s[i] - '0';
  462. } else {
  463. return -1;
  464. }
  465. }
  466. return 0;
  467. }
  468. /*
  469. * Convert an str to signed integer
  470. */
  471. static inline int str2sint(str* _s, int* _r)
  472. {
  473. int i;
  474. int sign;
  475. if (_s->len == 0) return -1;
  476. *_r = 0;
  477. sign = 1;
  478. i = 0;
  479. if (_s->s[0] == '+') {
  480. i++;
  481. } else if (_s->s[0] == '-') {
  482. sign = -1;
  483. i++;
  484. }
  485. for(; i < _s->len; i++) {
  486. if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
  487. *_r *= 10;
  488. *_r += _s->s[i] - '0';
  489. } else {
  490. return -1;
  491. }
  492. }
  493. *_r *= sign;
  494. return 0;
  495. }
  496. /* converts a username into uid:gid,
  497. * returns -1 on error & 0 on success */
  498. int user2uid(int* uid, int* gid, char* user);
  499. /* converts a group name into a gid
  500. * returns -1 on error, 0 on success */
  501. int group2gid(int* gid, char* group);
  502. /*
  503. * Replacement of timegm (does not exists on all platforms
  504. * Taken from
  505. * http://lists.samba.org/archive/samba-technical/2002-November/025737.html
  506. */
  507. time_t _timegm(struct tm* t);
  508. /* Convert time_t value that is relative to local timezone to UTC */
  509. time_t local2utc(time_t in);
  510. /* Convert time_t value in UTC to to value relative to local time zone */
  511. time_t utc2local(time_t in);
  512. /*
  513. * Return str as zero terminated string allocated
  514. * using pkg_malloc
  515. */
  516. char* as_asciiz(str* s);
  517. /* return system version (major.minor.minor2) as
  518. * (major<<16)|(minor)<<8|(minor2)
  519. * (if some of them are missing, they are set to 0)
  520. * if the parameters are not null they are set to the coresp. part */
  521. unsigned int get_sys_version(int* major, int* minor, int* minor2);
  522. /** Converts relative pathnames to absolute pathnames. This function returns
  523. * the full pathname of a file in parameter. If the file pathname does not
  524. * start with / then it will be converted into an absolute pathname. The
  525. * function gets the absolute directory pathname from \c base and appends \c
  526. * file to it. The first parameter can be NULL, in this case the function will
  527. * use the location of the main SER configuration file as reference.
  528. * @param base filename to be used as reference when \c file is relative. It
  529. * must be absolute. The location of the SER configuration file
  530. * will be used as reference if you set the value of this
  531. * parameter to NULL.
  532. * @param file A pathname to be converted to absolute.
  533. * @return A string containing absolute pathname, the string must be freed
  534. * with free. NULL on error.
  535. */
  536. char* get_abs_pathname(str* base, str* file);
  537. #endif