hdr->parsed for Route & Record-Route fields will be also freed if not empty
[sip-router] / ut.h
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  *    info@iptel.org
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-02-28 scratchpad compatibility abandoned (jiri)
32  * 2003-02-13 strlower added (janakj)
33  * 2003-01-29 pathmax added (jiri)
34  * 2003-01-28 scratchpad removed (jiri)
35  * 2003-01-18 un_escape function introduced for convenience of code needing
36  *            the complex&slow feature of unescaping
37  */
38
39
40 #ifndef ut_h
41 #define ut_h
42
43 #include "comp_defs.h"
44
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <limits.h>
48 #include <unistd.h>
49 #include <ctype.h>
50
51 #include "config.h"
52 #include "dprint.h"
53 #include "str.h"
54
55
56 struct sip_msg;
57
58 /* returns string beginning and length without insignificant chars */
59 #define trim_len( _len, _begin, _mystr ) \
60         do{     static char _c; \
61                 (_len)=(_mystr).len; \
62                 while ((_len) && ((_c=(_mystr).s[(_len)-1])==0 || _c=='\r' || \
63                                         _c=='\n' || _c==' ' || _c=='\t' )) \
64                         (_len)--; \
65                 (_begin)=(_mystr).s; \
66                 while ((_len) && ((_c=*(_begin))==' ' || _c=='\t')) { \
67                         (_len)--;\
68                         (_begin)++; \
69                 } \
70         }while(0)
71
72 #define trim_r( _mystr ) \
73         do{     static char _c; \
74                 while( ((_mystr).len) && ( ((_c=(_mystr).s[(_mystr).len-1]))==0 ||\
75                                                                         _c=='\r' || _c=='\n' ) \
76                                 ) \
77                         (_mystr).len--; \
78         }while(0)
79
80
81 #define  translate_pointer( _new_buf , _org_buf , _p) \
82         ( (_p)?(_new_buf + (_p-_org_buf)):(0) )
83
84 #define via_len(_via) \
85         ((_via)->bsize-((_via)->name.s-\
86                 ((_via)->hdr.s+(_via)->hdr.len)))
87
88
89 /* char to hex conversion table */
90 static char fourbits2char[16] = { '0', '1', '2', '3', '4', '5',
91         '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
92
93
94 /* converts a str to an u. short, returns the u. short and sets *err on
95  * error and if err!=null
96   */
97 static inline unsigned short str2s(char* s, unsigned int len,
98                                                                         int *err)
99 {
100         unsigned short ret;
101         int i;
102         unsigned char *limit;
103         unsigned char *init;
104         unsigned char* str;
105
106         /*init*/
107         str=(unsigned char*)s;
108         ret=i=0;
109         limit=str+len;
110         init=str;
111
112         for(;str<limit ;str++){
113                 if ( (*str <= '9' ) && (*str >= '0') ){
114                                 ret=ret*10+*str-'0';
115                                 i++;
116                                 if (i>5) goto error_digits;
117                 }else{
118                                 //error unknown char
119                                 goto error_char;
120                 }
121         }
122         if (err) *err=0;
123         return ret;
124
125 error_digits:
126         DBG("str2s: ERROR: too many letters in [%.*s]\n", (int)len, init);
127         if (err) *err=1;
128         return 0;
129 error_char:
130         DBG("str2s: ERROR: unexpected char %c in %.*s\n", *str, (int)len, init);
131         if (err) *err=1;
132         return 0;
133 }
134
135
136
137 static inline int btostr( char *p,  unsigned char val)
138 {
139         unsigned int a,b,i =0;
140
141         if ( (a=val/100)!=0 )
142                 *(p+(i++)) = a+'0';         /*first digit*/
143         if ( (b=val%100/10)!=0 || a)
144                 *(p+(i++)) = b+'0';        /*second digit*/
145         *(p+(i++)) = '0'+val%10;              /*third digit*/
146
147         return i;
148 }
149
150
151
152 /* returns a pointer to a static buffer containing l in asciiz & sets len */
153 static inline char* int2str(unsigned int l, int* len)
154 {
155         static char r[11]; /* 10 digits + 0 */
156         int i;
157         
158         i=9;
159         r[10]=0; /* null terminate */
160         do{
161                 r[i]=l%10+'0';
162                 i--;
163                 l/=10;
164         }while(l && (i>=0));
165         if (l && (i<0)){
166                 LOG(L_CRIT, "BUG: int2str: overflow\n");
167         }
168         if (len) *len=9-i;
169         return &r[i+1];
170 }
171
172
173
174 /* faster memchr version */
175 static inline char* q_memchr(char* p, int c, unsigned int size)
176 {
177         char* end;
178
179         end=p+size;
180         for(;p<end;p++){
181                 if (*p==(unsigned char)c) return p;
182         }
183         return 0;
184 }
185         
186
187 inline static int reverse_hex2int( char *c, int len )
188 {
189         char *pc;
190         int r;
191         char mychar;
192
193         r=0;
194         for (pc=c+len-1; len>0; pc--, len--) {
195                 r <<= 4 ;
196                 mychar=*pc;
197                 if ( mychar >='0' && mychar <='9') r+=mychar -'0';
198                 else if (mychar >='a' && mychar <='f') r+=mychar -'a'+10;
199                 else if (mychar  >='A' && mychar <='F') r+=mychar -'A'+10;
200                 else return -1;
201         }
202         return r;
203 }
204
205 inline static int int2reverse_hex( char **c, int *size, int nr )
206 {
207         unsigned short digit;
208
209         if (*size && nr==0) {
210                 **c = '0';
211                 (*c)++;
212                 (*size)--;
213                 return 1;
214         }
215
216         while (*size && nr ) {
217                 digit = nr & 0xf ;
218                 **c= digit >= 10 ? digit + 'a' - 10 : digit + '0';
219                 nr >>= 4;
220                 (*c)++;
221                 (*size)--;
222         }
223         return nr ? -1 /* number not processed; too little space */ : 1;
224 }
225
226 /* double output length assumed ; does NOT zero-terminate */
227 inline static int string2hex( 
228         /* input */ unsigned char *str, int len,
229         /* output */ char *hex )
230 {
231         int orig_len;
232
233         if (len==0) {
234                 *hex='0';
235                 return 1;
236         }
237
238         orig_len=len;
239         while ( len ) {
240
241                 *hex=fourbits2char[(*str) >> 4];
242                 hex++;
243                 *hex=fourbits2char[(*str) & 0xf];
244                 hex++;
245                 len--;
246                 str++;
247
248         }
249         return orig_len-len;
250 }
251
252 /* portable sleep in microseconds (no interrupt handling now) */
253
254 inline static void sleep_us( unsigned int nusecs )
255 {
256         struct timeval tval;
257         tval.tv_sec=nusecs/100000;
258         tval.tv_usec=nusecs%1000000;
259         select(0, NULL, NULL, NULL, &tval );
260 }
261
262
263 /* portable determination of max_path */
264 inline static int pathmax()
265 {
266 #ifdef PATH_MAX
267         static int pathmax=PATH_MAX;
268 #else
269         static int pathmax=0;
270 #endif
271         if (pathmax==0) { /* init */
272                 pathmax=pathconf("/", _PC_PATH_MAX);
273                 pathmax=(pathmax<=0)?PATH_MAX_GUESS:pathmax+1;
274         }
275         return pathmax;
276 }
277
278 inline static int hex2int(char hex_digit)
279 {
280         if (hex_digit>='0' && hex_digit<='9')
281                 return hex_digit-'0';
282         if (hex_digit>='a' && hex_digit<='f')
283                 return hex_digit-'a'+10;
284         if (hex_digit>='A' && hex_digit<='F')
285                 return hex_digit-'A'+10;
286         /* no valid hex digit ... */
287         LOG(L_ERR, "ERROR: hex2int: '%c' is no hex char\n", hex_digit );
288         return -1;
289 }
290
291 /* Un-escape URI user  -- it takes a pointer to original user
292    str, as well as the new, unescaped one, which MUST have
293    an allocated buffer linked to the 'str' structure ;
294    (the buffer can be allocated with the same length as
295    the original string -- the output string is always
296    shorter (if escaped characters occur) or same-long
297    as the original one).
298
299    only printeable characters are permitted
300
301         <0 is returned on an uneascaping error, length of the
302         unescaped string otherwise
303 */
304 inline static int un_escape(str *user, str *new_user ) 
305 {
306         int i, j, value;
307         int hi, lo;
308
309         if( new_user==0 || new_user->s==0) {
310                 LOG(L_CRIT, "BUG: un_escape: called with invalid param\n");
311                 return -1;
312         }
313
314         new_user->len = 0;
315         j = 0;
316
317         for (i = 0; i < user->len; i++) {
318                 if (user->s[i] == '%') {
319                         if (i + 2 >= user->len) {
320                                 LOG(L_ERR, "ERROR: un_escape: escape sequence too short in"
321                                         " '%.*s' @ %d\n",
322                                         user->len, user->s, i );
323                                 goto error;
324                         }
325                         hi=hex2int(user->s[i + 1]);
326                         if (hi<0) {
327                                 LOG(L_ERR, "ERROR: un_escape: non-hex high digit in an escape sequence in"
328                                         " '%.*s' @ %d\n",
329                                         user->len, user->s, i+1 );
330                                 goto error;
331                         }
332                         lo=hex2int(user->s[i + 2]);
333                         if (lo<0) {
334                                 LOG(L_ERR, "ERROR: non-hex low digit in an escape sequence in "
335                                         "'%.*s' @ %d\n",
336                                         user->len, user->s, i+2 );
337                                 goto error;
338                         }
339                         value=(hi<<4)+lo;
340                         if (value < 32 || value > 126) {
341                                 LOG(L_ERR, "ERROR: non-ASCII escaped character in '%.*s' @ %d\n",
342                                         user->len, user->s, i );
343                                 goto error;
344                         }
345                         new_user->s[j] = value;
346                         i+=2; /* consume the two hex digits, for cycle will move to the next char */
347                 } else {
348                         new_user->s[j] = user->s[i];
349                 }
350         j++; /* good -- we translated another character */
351         }
352         new_user->len = j;
353         return j;
354
355 error:
356         new_user->len = j;
357         return -1;
358
359
360
361 /*
362  * Convert a string to lower case
363  */
364 static inline void strlower(str* _s)
365 {
366         int i;
367
368         for(i = 0; i < _s->len; i++) {
369                 _s->s[i] = tolower(_s->s[i]);
370         }
371 }
372
373
374 #endif