00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef ut_h
00033 #define ut_h
00034
00035 #include <sys/types.h>
00036 #include <sys/select.h>
00037 #include <sys/time.h>
00038 #include <limits.h>
00039 #include <unistd.h>
00040 #include <ctype.h>
00041 #include <strings.h>
00042
00043 #include "config.h"
00044 #include "dprint.h"
00045 #include "str.h"
00046
00047 #include "mem/mem.h"
00048 #include "mem/shm_mem.h"
00049
00050 struct sip_msg;
00051
00052
00053
00054 #define ZSW(_c) ((_c)?(_c):"")
00055
00056
00057
00058 #define str_init(_string) {_string, sizeof(_string) - 1}
00059
00060
00061
00062 #define trim_len( _len, _begin, _mystr ) \
00063 do{ static char _c; \
00064 (_len)=(_mystr).len; \
00065 while ((_len) && ((_c=(_mystr).s[(_len)-1])==0 || _c=='\r' || \
00066 _c=='\n' || _c==' ' || _c=='\t' )) \
00067 (_len)--; \
00068 (_begin)=(_mystr).s; \
00069 while ((_len) && ((_c=*(_begin))==' ' || _c=='\t')) { \
00070 (_len)--;\
00071 (_begin)++; \
00072 } \
00073 }while(0)
00074
00075
00076
00077 #define trim_r( _mystr ) \
00078 do{ static char _c; \
00079 while( ((_mystr).len) && ( ((_c=(_mystr).s[(_mystr).len-1]))==0 ||\
00080 _c=='\r' || _c=='\n' ) \
00081 ) \
00082 (_mystr).len--; \
00083 }while(0)
00084
00085
00086
00087 #define trim_spaces_lr(_s_) \
00088 do{\
00089 for(;(_s_).s[(_s_).len-1]==' ';(_s_).s[--(_s_).len]=0);\
00090 for(;(_s_).s[0]==' ';(_s_).s=(_s_).s+1,(_s_).len--);\
00091 }while(0);
00092
00093
00094
00095 #define translate_pointer( _new_buf , _org_buf , _p) \
00096 ( (_p)?(_new_buf + (_p-_org_buf)):(0) )
00097
00098
00099
00100 #define via_len(_via) \
00101 ((_via)->bsize-((_via)->name.s-\
00102 ((_via)->hdr.s+(_via)->hdr.len)))
00103
00104
00105
00106 #define append_str(_dest,_src,_len) \
00107 do{ \
00108 memcpy( (_dest) , (_src) , (_len) );\
00109 (_dest) += (_len) ;\
00110 }while(0);
00111
00112
00113 #define append_chr(_dest,_c) \
00114 *((_dest)++) = _c;
00115
00116 #ifndef MIN
00117 #define MIN(a, b) (a<b?a:b)
00118 #endif
00119 #ifndef MAX
00120 #define MAX(a, b) (a>b?a:b)
00121 #endif
00122
00123
00124
00125 static char fourbits2char[16] = { '0', '1', '2', '3', '4', '5',
00126 '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
00127
00128
00129
00130
00131
00132
00133
00134 static inline unsigned short str2s(const char* s, unsigned int len,
00135 int *err)
00136 {
00137 unsigned short ret;
00138 int i;
00139 unsigned char *limit;
00140 unsigned char *init;
00141 unsigned char* str;
00142
00143
00144 str=(unsigned char*)s;
00145 ret=i=0;
00146 limit=str+len;
00147 init=str;
00148
00149 for(;str<limit ;str++){
00150 if ( (*str <= '9' ) && (*str >= '0') ){
00151 ret=ret*10+*str-'0';
00152 i++;
00153 if (i>5) goto error_digits;
00154 }else{
00155
00156 goto error_char;
00157 }
00158 }
00159 if (err) *err=0;
00160 return ret;
00161
00162 error_digits:
00163 LM_DBG("too many letters in [%.*s]\n", (int)len, init);
00164 if (err) *err=1;
00165 return 0;
00166 error_char:
00167 LM_DBG("unexpected char %c in %.*s\n", *str, (int)len, init);
00168 if (err) *err=1;
00169 return 0;
00170 }
00171
00172
00173
00174 #define INT2STR_MAX_LEN (1+19+1+1)
00175
00176
00177
00178 static inline char* int2bstr(unsigned long l, char *s, int* len)
00179 {
00180 int i;
00181
00182 i=INT2STR_MAX_LEN-2;
00183 s[INT2STR_MAX_LEN-1]=0;
00184 do{
00185 s[i]=l%10+'0';
00186 i--;
00187 l/=10;
00188 }while(l && (i>=0));
00189 if (l && (i<0)){
00190 LM_CRIT("overflow error\n");
00191 }
00192 if (len) *len=(INT2STR_MAX_LEN-2)-i;
00193 return &s[i+1];
00194 }
00195
00196
00197
00198
00199 extern char int2str_buf[INT2STR_MAX_LEN];
00200 static inline char* int2str(unsigned long l, int* len)
00201 {
00202 return int2bstr( l, int2str_buf, len);
00203 }
00204
00205
00206
00207
00208 static inline char* sint2str(long l, int* len)
00209 {
00210 int sign;
00211 char *p;
00212
00213 sign = 0;
00214 if(l<0) {
00215 sign = 1;
00216 l = -l;
00217 }
00218 p = int2str((unsigned long)l, len);
00219 if(sign) {
00220 *(--p) = '-';
00221 if (len) (*len)++;
00222 }
00223 return p;
00224 }
00225
00226
00227 inline static int reverse_hex2int( char *c, int len )
00228 {
00229 char *pc;
00230 int r;
00231 char mychar;
00232
00233 r=0;
00234 for (pc=c+len-1; len>0; pc--, len--) {
00235 r <<= 4 ;
00236 mychar=*pc;
00237 if ( mychar >='0' && mychar <='9') r+=mychar -'0';
00238 else if (mychar >='a' && mychar <='f') r+=mychar -'a'+10;
00239 else if (mychar >='A' && mychar <='F') r+=mychar -'A'+10;
00240 else return -1;
00241 }
00242 return r;
00243 }
00244
00245 inline static int int2reverse_hex( char **c, int *size, int nr )
00246 {
00247 unsigned short digit;
00248
00249 if (*size && nr==0) {
00250 **c = '0';
00251 (*c)++;
00252 (*size)--;
00253 return 1;
00254 }
00255
00256 while (*size && nr ) {
00257 digit = nr & 0xf ;
00258 **c= digit >= 10 ? digit + 'a' - 10 : digit + '0';
00259 nr >>= 4;
00260 (*c)++;
00261 (*size)--;
00262 }
00263 return nr ? -1 : 1;
00264 }
00265
00266 inline static int hexstr2int(char *c, int len, unsigned int *val)
00267 {
00268 char *pc;
00269 int r;
00270 char mychar;
00271
00272 r=0;
00273 for (pc=c; pc<c+len; pc++) {
00274 r <<= 4 ;
00275 mychar=*pc;
00276 if ( mychar >='0' && mychar <='9') r+=mychar -'0';
00277 else if (mychar >='a' && mychar <='f') r+=mychar -'a'+10;
00278 else if (mychar >='A' && mychar <='F') r+=mychar -'A'+10;
00279 else return -1;
00280 }
00281 *val = r;
00282 return 0;
00283 }
00284
00285
00286
00287 inline static int string2hex(
00288 unsigned char *str, int len,
00289 char *hex )
00290 {
00291 int orig_len;
00292
00293 if (len==0) {
00294 *hex='0';
00295 return 1;
00296 }
00297
00298 orig_len=len;
00299 while ( len ) {
00300
00301 *hex=fourbits2char[((*str) >> 4) & 0x0f];
00302 hex++;
00303 *hex=fourbits2char[(*str) & 0x0f];
00304 hex++;
00305 len--;
00306 str++;
00307
00308 }
00309 return orig_len-len;
00310 }
00311
00312
00313
00314 inline static void sleep_us( unsigned int nusecs )
00315 {
00316 struct timeval tval;
00317 tval.tv_sec=nusecs/1000000;
00318 tval.tv_usec=nusecs%1000000;
00319 select(0, NULL, NULL, NULL, &tval );
00320 }
00321
00322
00323
00324 inline static int pathmax(void)
00325 {
00326 #ifdef PATH_MAX
00327 static int pathmax=PATH_MAX;
00328 #else
00329 static int pathmax=0;
00330 #endif
00331 if (pathmax==0) {
00332 pathmax=pathconf("/", _PC_PATH_MAX);
00333 pathmax=(pathmax<=0)?PATH_MAX_GUESS:pathmax+1;
00334 }
00335 return pathmax;
00336 }
00337
00338 inline static int hex2int(char hex_digit)
00339 {
00340 if (hex_digit>='0' && hex_digit<='9')
00341 return hex_digit-'0';
00342 if (hex_digit>='a' && hex_digit<='f')
00343 return hex_digit-'a'+10;
00344 if (hex_digit>='A' && hex_digit<='F')
00345 return hex_digit-'A'+10;
00346
00347 LM_ERR("'%c' is no hex char\n", hex_digit );
00348 return -1;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 inline static int un_escape(str *user, str *new_user )
00365 {
00366 int i, j, value;
00367 int hi, lo;
00368
00369 if( new_user==0 || new_user->s==0) {
00370 LM_CRIT("called with invalid param\n");
00371 return -1;
00372 }
00373
00374 new_user->len = 0;
00375 j = 0;
00376
00377 for (i = 0; i < user->len; i++) {
00378 if (user->s[i] == '%') {
00379 if (i + 2 >= user->len) {
00380 LM_ERR("escape sequence too short in"
00381 " '%.*s' @ %d\n",
00382 user->len, user->s, i );
00383 goto error;
00384 }
00385 hi=hex2int(user->s[i + 1]);
00386 if (hi<0) {
00387 LM_ERR(" non-hex high digit in an escape"
00388 " sequence in '%.*s' @ %d\n",
00389 user->len, user->s, i+1 );
00390 goto error;
00391 }
00392 lo=hex2int(user->s[i + 2]);
00393 if (lo<0) {
00394 LM_ERR("non-hex low digit in an escape sequence in "
00395 "'%.*s' @ %d\n",
00396 user->len, user->s, i+2 );
00397 goto error;
00398 }
00399 value=(hi<<4)+lo;
00400 if (value < 32 || value > 126) {
00401 LM_ERR("non-ASCII escaped character in '%.*s' @ %d\n",
00402 user->len, user->s, i );
00403 goto error;
00404 }
00405 new_user->s[j] = value;
00406 i+=2;
00407 } else {
00408 new_user->s[j] = user->s[i];
00409 }
00410 j++;
00411 }
00412 new_user->len = j;
00413 return j;
00414
00415 error:
00416 new_user->len = j;
00417 return -1;
00418 }
00419
00420
00421
00422
00423
00424 static inline void strlower(str* _s)
00425 {
00426 int i;
00427
00428 for(i = 0; i < _s->len; i++) {
00429 _s->s[i] = tolower(_s->s[i]);
00430 }
00431 }
00432
00433
00434
00435
00436
00437 static inline int str2int(str* _s, unsigned int* _r)
00438 {
00439 int i;
00440
00441 *_r = 0;
00442 for(i = 0; i < _s->len; i++) {
00443 if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
00444 *_r *= 10;
00445 *_r += _s->s[i] - '0';
00446 } else {
00447 return -1;
00448 }
00449 }
00450
00451 return 0;
00452 }
00453
00454
00455
00456
00457 static inline int str2sint(str* _s, int* _r)
00458 {
00459 int i;
00460 int s;
00461
00462 *_r = 0;
00463 s = 1;
00464 i=0;
00465 if(_s->s[i]=='-') {
00466 s=-1;
00467 i++;
00468 }
00469 for(; i < _s->len; i++) {
00470 if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
00471 *_r *= 10;
00472 *_r += _s->s[i] - '0';
00473 } else {
00474 return -1;
00475 }
00476 }
00477 *_r *= s;
00478 return 0;
00479 }
00480
00481
00482
00483
00484
00485 static inline int strno2int( str *val, unsigned int *mask )
00486 {
00487
00488 if (val->len>2 && val->s[0]=='0' && val->s[1]=='x') {
00489 return hexstr2int( val->s+2, val->len-2, mask);
00490 } else {
00491 return str2int( val, mask);
00492 }
00493 }
00494
00495
00496
00497
00498
00499 static inline int shm_str_dup(str* dst, const str* src)
00500 {
00501 dst->s = shm_malloc(src->len);
00502 if (!dst->s) {
00503 LM_ERR("no shared memory left\n");
00504 return -1;
00505 }
00506
00507 memcpy(dst->s, src->s, src->len);
00508 dst->len = src->len;
00509 return 0;
00510 }
00511
00512
00513
00514
00515 static inline int pkg_str_dup(str* dst, const str* src)
00516 {
00517 dst->s = pkg_malloc(src->len);
00518 if (dst->s==NULL)
00519 {
00520 LM_ERR("no private memory left\n");
00521 return -1;
00522 }
00523
00524 memcpy(dst->s, src->s, src->len);
00525 dst->len = src->len;
00526 return 0;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535 static inline int str_strcmp(const str *str1, const str *str2)
00536 {
00537 if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
00538 {
00539 LM_ERR("bad parameters\n");
00540 return -2;
00541 }
00542
00543 if (str1->len < str2->len)
00544 return -1;
00545 else if (str1->len > str2->len)
00546 return 1;
00547 else
00548 return strncmp(str1->s, str2->s, str1->len);
00549 }
00550
00551
00552
00553
00554
00555
00556
00557 static inline int str_strcasecmp(const str *str1, const str *str2)
00558 {
00559 if(str1==NULL || str2==NULL || str1->s ==NULL || str2->s==NULL || str1->len<0 || str2->len<0)
00560 {
00561 LM_ERR("bad parameters\n");
00562 return -2;
00563 }
00564 if (str1->len < str2->len)
00565 return -1;
00566 else if (str1->len > str2->len)
00567 return 1;
00568 else
00569 return strncasecmp(str1->s, str2->s, str1->len);
00570 }
00571
00572 int user2uid(int* uid, int* gid, char* user);
00573
00574 int group2gid(int* gid, char* group);
00575
00576
00577 void seed_child(unsigned int seed);
00578
00579 #endif