| 1 | /* |
|---|
| 2 | The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) |
|---|
| 3 | Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Aymeric MOIZARD jack@atosc.org |
|---|
| 4 | |
|---|
| 5 | This library is free software; you can redistribute it and/or |
|---|
| 6 | modify it under the terms of the GNU Lesser General Public |
|---|
| 7 | License as published by the Free Software Foundation; either |
|---|
| 8 | version 2.1 of the License, or (at your option) any later version. |
|---|
| 9 | |
|---|
| 10 | This library is distributed in the hope that it will be useful, |
|---|
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | Lesser General Public License for more details. |
|---|
| 14 | |
|---|
| 15 | You should have received a copy of the GNU Lesser General Public |
|---|
| 16 | License along with this library; if not, write to the Free Software |
|---|
| 17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 18 | */ |
|---|
| 19 | |
|---|
| 20 | #ifdef _WIN32_WCE |
|---|
| 21 | #define _INC_TIME /* for wce.h */ |
|---|
| 22 | #include <windows.h> |
|---|
| 23 | #endif |
|---|
| 24 | |
|---|
| 25 | |
|---|
| 26 | |
|---|
| 27 | #include <stdlib.h> |
|---|
| 28 | #include <stdio.h> |
|---|
| 29 | #include <stdarg.h> |
|---|
| 30 | |
|---|
| 31 | #include <osipparser2/osip_port.h> |
|---|
| 32 | |
|---|
| 33 | #ifdef HAVE_SYS_TYPES_H |
|---|
| 34 | #include <sys/types.h> |
|---|
| 35 | #endif |
|---|
| 36 | #ifdef HAVE_SYS_STAT_H |
|---|
| 37 | #include <sys/stat.h> |
|---|
| 38 | #endif |
|---|
| 39 | #ifdef HAVE_FCNTL_H |
|---|
| 40 | #include <fcntl.h> |
|---|
| 41 | #endif |
|---|
| 42 | |
|---|
| 43 | #ifdef HAVE_CTYPE_H |
|---|
| 44 | #include <ctype.h> |
|---|
| 45 | #endif |
|---|
| 46 | |
|---|
| 47 | #if defined(__PALMOS__) && (__PALMOS__ < 0x06000000) |
|---|
| 48 | # include <TimeMgr.h> |
|---|
| 49 | # include <SysUtils.h> |
|---|
| 50 | # include <SystemMgr.h> |
|---|
| 51 | # include <StringMgr.h> |
|---|
| 52 | #else |
|---|
| 53 | # include <time.h> |
|---|
| 54 | #endif |
|---|
| 55 | |
|---|
| 56 | #if defined(__VXWORKS_OS__) |
|---|
| 57 | #include <selectLib.h> |
|---|
| 58 | |
|---|
| 59 | /* needed for snprintf replacement */ |
|---|
| 60 | #include <vxWorks.h> |
|---|
| 61 | #include <fioLib.h> |
|---|
| 62 | #include <string.h> |
|---|
| 63 | |
|---|
| 64 | #elif defined(__PALMOS__) |
|---|
| 65 | # if __PALMOS__ >= 0x06000000 |
|---|
| 66 | # include <sys/time.h> |
|---|
| 67 | # include <SysThread.h> |
|---|
| 68 | # endif |
|---|
| 69 | #elif (!defined(WIN32) && !defined(_WIN32_WCE)) |
|---|
| 70 | #include <sys/time.h> |
|---|
| 71 | #elif defined(WIN32) |
|---|
| 72 | #include <windows.h> |
|---|
| 73 | #ifdef WIN32_USE_CRYPTO |
|---|
| 74 | #include <Wincrypt.h> |
|---|
| 75 | #endif |
|---|
| 76 | #endif |
|---|
| 77 | |
|---|
| 78 | #if defined (__rtems__) |
|---|
| 79 | #include <rtems.h> |
|---|
| 80 | #endif |
|---|
| 81 | |
|---|
| 82 | #if defined (HAVE_SYS_UNISTD_H) |
|---|
| 83 | # include <sys/unistd.h> |
|---|
| 84 | #endif |
|---|
| 85 | |
|---|
| 86 | #if defined (HAVE_UNISTD_H) |
|---|
| 87 | # include <unistd.h> |
|---|
| 88 | #endif |
|---|
| 89 | |
|---|
| 90 | #if defined (HAVE_SYSLOG_H) && !defined(__arc__) |
|---|
| 91 | # include <syslog.h> |
|---|
| 92 | #endif |
|---|
| 93 | |
|---|
| 94 | #if defined (HAVE_SYS_SELECT_H) |
|---|
| 95 | # include <sys/select.h> |
|---|
| 96 | #endif |
|---|
| 97 | |
|---|
| 98 | #ifdef HAVE_PTH_PTHREAD_H |
|---|
| 99 | #include <pthread.h> |
|---|
| 100 | #endif |
|---|
| 101 | |
|---|
| 102 | #if defined(__arc__) |
|---|
| 103 | #define HAVE_LRAND48 |
|---|
| 104 | #endif |
|---|
| 105 | |
|---|
| 106 | FILE *logfile = NULL; |
|---|
| 107 | int tracing_table[END_TRACE_LEVEL]; |
|---|
| 108 | static int use_syslog = 0; |
|---|
| 109 | static osip_trace_func_t *trace_func = 0; |
|---|
| 110 | |
|---|
| 111 | static unsigned int random_seed_set = 0; |
|---|
| 112 | |
|---|
| 113 | #ifndef MINISIZE |
|---|
| 114 | #if !defined(WIN32) && !defined(_WIN32_WCE) |
|---|
| 115 | osip_malloc_func_t *osip_malloc_func = 0; |
|---|
| 116 | osip_realloc_func_t *osip_realloc_func = 0; |
|---|
| 117 | osip_free_func_t *osip_free_func = 0; |
|---|
| 118 | #endif |
|---|
| 119 | #endif |
|---|
| 120 | |
|---|
| 121 | const char *osip_error_table[] = { |
|---|
| 122 | "success", |
|---|
| 123 | "undefined error", |
|---|
| 124 | "bad parameter", |
|---|
| 125 | "wrong state", |
|---|
| 126 | "allocation failure", |
|---|
| 127 | "syntax error", |
|---|
| 128 | "not found", |
|---|
| 129 | "api not initialized", |
|---|
| 130 | "undefined", |
|---|
| 131 | "undefined", |
|---|
| 132 | "no network", /* -10 */ |
|---|
| 133 | "busy port", |
|---|
| 134 | "unknown host", |
|---|
| 135 | "undefined", |
|---|
| 136 | "undefined", |
|---|
| 137 | "undefined", |
|---|
| 138 | "undefined", |
|---|
| 139 | "undefined", |
|---|
| 140 | "undefined", |
|---|
| 141 | "undefined", |
|---|
| 142 | "undefined", |
|---|
| 143 | "undefined", |
|---|
| 144 | "undefined", |
|---|
| 145 | "undefined", |
|---|
| 146 | "undefined", |
|---|
| 147 | "undefined", |
|---|
| 148 | "undefined", |
|---|
| 149 | "undefined", |
|---|
| 150 | "undefined", |
|---|
| 151 | "undefined", |
|---|
| 152 | "disk full", /* -30 */ |
|---|
| 153 | "no rights", |
|---|
| 154 | "file not found", |
|---|
| 155 | "undefined", |
|---|
| 156 | "undefined", |
|---|
| 157 | "undefined", |
|---|
| 158 | "undefined", |
|---|
| 159 | "undefined", |
|---|
| 160 | "undefined", |
|---|
| 161 | "undefined", |
|---|
| 162 | "undefined", /* -40 */ |
|---|
| 163 | "undefined", |
|---|
| 164 | "undefined", |
|---|
| 165 | "undefined", |
|---|
| 166 | "undefined", |
|---|
| 167 | "undefined", |
|---|
| 168 | "undefined", |
|---|
| 169 | "undefined", |
|---|
| 170 | "undefined", |
|---|
| 171 | "undefined", |
|---|
| 172 | "time out", /* -50 */ |
|---|
| 173 | "too much call", |
|---|
| 174 | "wrong format", |
|---|
| 175 | "no common codec", |
|---|
| 176 | "undefined", |
|---|
| 177 | "undefined", |
|---|
| 178 | "undefined", |
|---|
| 179 | "undefined", |
|---|
| 180 | "undefined", |
|---|
| 181 | "undefined", |
|---|
| 182 | "undefined", /* -60 */ |
|---|
| 183 | }; |
|---|
| 184 | |
|---|
| 185 | const char *osip_strerror(int err) |
|---|
| 186 | { |
|---|
| 187 | if (err>0) |
|---|
| 188 | return osip_error_table[0]; |
|---|
| 189 | if (err>-60) |
|---|
| 190 | return osip_error_table[-err]; |
|---|
| 191 | return osip_error_table[59]; |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | #ifndef WIN32_USE_CRYPTO |
|---|
| 195 | unsigned int |
|---|
| 196 | osip_build_random_number () |
|---|
| 197 | #else |
|---|
| 198 | static unsigned int |
|---|
| 199 | osip_fallback_random_number () |
|---|
| 200 | #endif |
|---|
| 201 | { |
|---|
| 202 | if (!random_seed_set) |
|---|
| 203 | { |
|---|
| 204 | unsigned int ticks; |
|---|
| 205 | |
|---|
| 206 | #ifdef __PALMOS__ |
|---|
| 207 | # if __PALMOS__ < 0x06000000 |
|---|
| 208 | SysRandom ((Int32) TimGetTicks ()); |
|---|
| 209 | # else |
|---|
| 210 | struct timeval tv; |
|---|
| 211 | |
|---|
| 212 | gettimeofday (&tv, NULL); |
|---|
| 213 | srand (tv.tv_usec); |
|---|
| 214 | ticks = tv.tv_sec + tv.tv_usec; |
|---|
| 215 | # endif |
|---|
| 216 | #elif defined(WIN32) |
|---|
| 217 | LARGE_INTEGER lCount; |
|---|
| 218 | |
|---|
| 219 | QueryPerformanceCounter (&lCount); |
|---|
| 220 | ticks = lCount.LowPart + lCount.HighPart; |
|---|
| 221 | #elif defined(_WIN32_WCE) |
|---|
| 222 | ticks = GetTickCount (); |
|---|
| 223 | #elif defined(__PSOS__) |
|---|
| 224 | #elif defined(__rtems__) |
|---|
| 225 | rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &ticks); |
|---|
| 226 | #elif defined(__VXWORKS_OS__) |
|---|
| 227 | struct timespec tp; |
|---|
| 228 | |
|---|
| 229 | clock_gettime (CLOCK_REALTIME, &tp); |
|---|
| 230 | ticks = tp.tv_sec + tp.tv_nsec; |
|---|
| 231 | #else |
|---|
| 232 | struct timeval tv; |
|---|
| 233 | int fd; |
|---|
| 234 | |
|---|
| 235 | gettimeofday (&tv, NULL); |
|---|
| 236 | ticks = tv.tv_sec + tv.tv_usec; |
|---|
| 237 | fd = open ("/dev/urandom", O_RDONLY); |
|---|
| 238 | if (fd > 0) |
|---|
| 239 | { |
|---|
| 240 | unsigned int r; |
|---|
| 241 | int i; |
|---|
| 242 | |
|---|
| 243 | for (i = 0; i < 512; i++) |
|---|
| 244 | { |
|---|
| 245 | read (fd, &r, sizeof (r)); |
|---|
| 246 | ticks += r; |
|---|
| 247 | } |
|---|
| 248 | close (fd); |
|---|
| 249 | } |
|---|
| 250 | #endif |
|---|
| 251 | |
|---|
| 252 | #ifdef HAVE_LRAND48 |
|---|
| 253 | srand48 (ticks); |
|---|
| 254 | #else |
|---|
| 255 | srand (ticks); |
|---|
| 256 | #endif |
|---|
| 257 | random_seed_set = 1; |
|---|
| 258 | } |
|---|
| 259 | #ifdef HAVE_LRAND48 |
|---|
| 260 | { |
|---|
| 261 | int val = lrand48(); |
|---|
| 262 | if (val==0) |
|---|
| 263 | { |
|---|
| 264 | unsigned int ticks; |
|---|
| 265 | struct timeval tv; |
|---|
| 266 | gettimeofday (&tv, NULL); |
|---|
| 267 | ticks = tv.tv_sec + tv.tv_usec; |
|---|
| 268 | srand48 (ticks); |
|---|
| 269 | return lrand48 (); |
|---|
| 270 | } |
|---|
| 271 | |
|---|
| 272 | return val; |
|---|
| 273 | } |
|---|
| 274 | #else |
|---|
| 275 | return rand (); |
|---|
| 276 | #endif |
|---|
| 277 | } |
|---|
| 278 | |
|---|
| 279 | #ifdef WIN32_USE_CRYPTO |
|---|
| 280 | |
|---|
| 281 | unsigned int |
|---|
| 282 | osip_build_random_number () |
|---|
| 283 | { |
|---|
| 284 | HCRYPTPROV crypto; |
|---|
| 285 | BOOL err; |
|---|
| 286 | unsigned int num; |
|---|
| 287 | |
|---|
| 288 | err = |
|---|
| 289 | CryptAcquireContext (&crypto, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); |
|---|
| 290 | if (err) |
|---|
| 291 | { |
|---|
| 292 | err = CryptGenRandom (crypto, sizeof (num), (BYTE *) & num); |
|---|
| 293 | CryptReleaseContext (crypto, 0); |
|---|
| 294 | } |
|---|
| 295 | if (!err) |
|---|
| 296 | { |
|---|
| 297 | num = osip_fallback_random_number (); |
|---|
| 298 | } |
|---|
| 299 | return num; |
|---|
| 300 | } |
|---|
| 301 | |
|---|
| 302 | #endif |
|---|
| 303 | |
|---|
| 304 | #if defined(__linux) |
|---|
| 305 | #include <limits.h> |
|---|
| 306 | #endif |
|---|
| 307 | |
|---|
| 308 | |
|---|
| 309 | char * |
|---|
| 310 | osip_strncpy (char *dest, const char *src, size_t length) |
|---|
| 311 | { |
|---|
| 312 | strncpy (dest, src, length); |
|---|
| 313 | dest[length] = '\0'; |
|---|
| 314 | return dest; |
|---|
| 315 | } |
|---|
| 316 | |
|---|
| 317 | #undef osip_strdup |
|---|
| 318 | |
|---|
| 319 | char * |
|---|
| 320 | osip_strdup (const char *ch) |
|---|
| 321 | { |
|---|
| 322 | char *copy; |
|---|
| 323 | size_t length; |
|---|
| 324 | |
|---|
| 325 | if (ch == NULL) |
|---|
| 326 | return NULL; |
|---|
| 327 | length = strlen (ch); |
|---|
| 328 | copy = (char *) osip_malloc (length + 1); |
|---|
| 329 | if (copy==NULL) |
|---|
| 330 | return NULL; |
|---|
| 331 | osip_strncpy (copy, ch, length); |
|---|
| 332 | return copy; |
|---|
| 333 | } |
|---|
| 334 | |
|---|
| 335 | #ifndef MINISIZE |
|---|
| 336 | int |
|---|
| 337 | osip_atoi (const char *number) |
|---|
| 338 | { |
|---|
| 339 | #if defined(__linux) || defined(HAVE_STRTOL) |
|---|
| 340 | int i; |
|---|
| 341 | |
|---|
| 342 | if (number == NULL) |
|---|
| 343 | return OSIP_UNDEFINED_ERROR; |
|---|
| 344 | i = strtol (number, (char **) NULL, 10); |
|---|
| 345 | if (i == LONG_MIN || i == LONG_MAX) |
|---|
| 346 | return OSIP_UNDEFINED_ERROR; |
|---|
| 347 | return i; |
|---|
| 348 | #endif |
|---|
| 349 | |
|---|
| 350 | return atoi (number); |
|---|
| 351 | } |
|---|
| 352 | |
|---|
| 353 | #endif |
|---|
| 354 | |
|---|
| 355 | /* append string_osip_to_append to string at position cur |
|---|
| 356 | size is the current allocated size of the element |
|---|
| 357 | */ |
|---|
| 358 | char * |
|---|
| 359 | __osip_sdp_append_string (char *string, size_t size, char *cur, |
|---|
| 360 | char *string_osip_to_append) |
|---|
| 361 | { |
|---|
| 362 | size_t length = strlen (string_osip_to_append); |
|---|
| 363 | |
|---|
| 364 | if (cur - string + length > size) |
|---|
| 365 | { |
|---|
| 366 | size_t length2; |
|---|
| 367 | |
|---|
| 368 | length2 = cur - string; |
|---|
| 369 | string = osip_realloc (string, size + length + 10); |
|---|
| 370 | cur = string + length2; /* the initial allocation may have changed! */ |
|---|
| 371 | } |
|---|
| 372 | osip_strncpy (cur, string_osip_to_append, length); |
|---|
| 373 | return cur + strlen (cur); |
|---|
| 374 | } |
|---|
| 375 | |
|---|
| 376 | void |
|---|
| 377 | osip_usleep (int useconds) |
|---|
| 378 | { |
|---|
| 379 | #if defined(__PALMOS__) && (__PALMOS__ >= 0x06000000) |
|---|
| 380 | /* This bit will work for the Protein API, but not the Palm 68K API */ |
|---|
| 381 | nsecs_t nanoseconds = useconds * 1000; |
|---|
| 382 | |
|---|
| 383 | SysThreadDelay (nanoseconds, P_ABSOLUTE_TIMEOUT); |
|---|
| 384 | #elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000) |
|---|
| 385 | UInt32 stoptime = TimGetTicks () + (useconds / 1000000) * SysTicksPerSecond (); |
|---|
| 386 | |
|---|
| 387 | while (stoptime > TimGetTicks ()) |
|---|
| 388 | /* I wish there was some type of yield function here */ |
|---|
| 389 | ; |
|---|
| 390 | #elif defined(WIN32) |
|---|
| 391 | Sleep (useconds / 1000); |
|---|
| 392 | #elif defined(__rtems__) |
|---|
| 393 | rtems_task_wake_after( RTEMS_MICROSECONDS_TO_TICKS(useconds) ); |
|---|
| 394 | #elif defined(__arc__) |
|---|
| 395 | struct timespec req; |
|---|
| 396 | struct timespec rem; |
|---|
| 397 | req.tv_sec = (int) useconds / 1000000; |
|---|
| 398 | req.tv_nsec = (int) (useconds % 1000000)*1000; |
|---|
| 399 | nanosleep (&req, &rem); |
|---|
| 400 | #else |
|---|
| 401 | struct timeval delay; |
|---|
| 402 | int sec; |
|---|
| 403 | |
|---|
| 404 | sec = (int) useconds / 1000000; |
|---|
| 405 | if (sec > 0) |
|---|
| 406 | { |
|---|
| 407 | delay.tv_sec = sec; |
|---|
| 408 | delay.tv_usec = 0; |
|---|
| 409 | } else |
|---|
| 410 | { |
|---|
| 411 | delay.tv_sec = 0; |
|---|
| 412 | delay.tv_usec = useconds; |
|---|
| 413 | } |
|---|
| 414 | select (0, 0, 0, 0, &delay); |
|---|
| 415 | #endif |
|---|
| 416 | } |
|---|
| 417 | |
|---|
| 418 | char * |
|---|
| 419 | osip_strdup_without_quote (const char *ch) |
|---|
| 420 | { |
|---|
| 421 | char *copy = (char *) osip_malloc (strlen (ch) + 1); |
|---|
| 422 | if (copy==NULL) |
|---|
| 423 | return NULL; |
|---|
| 424 | |
|---|
| 425 | /* remove leading and trailing " */ |
|---|
| 426 | if ((*ch == '\"')) |
|---|
| 427 | { |
|---|
| 428 | osip_strncpy (copy, ch + 1, strlen (ch + 1)); |
|---|
| 429 | osip_strncpy (copy + strlen (copy) - 1, "\0", 1); |
|---|
| 430 | } else |
|---|
| 431 | osip_strncpy (copy, ch, strlen (ch)); |
|---|
| 432 | return copy; |
|---|
| 433 | } |
|---|
| 434 | |
|---|
| 435 | int |
|---|
| 436 | osip_tolower (char *word) |
|---|
| 437 | { |
|---|
| 438 | #if defined(HAVE_CTYPE_H) && !defined (_WIN32_WCE) |
|---|
| 439 | |
|---|
| 440 | for (; *word; word++) |
|---|
| 441 | *word = (char) tolower (*word); |
|---|
| 442 | #else |
|---|
| 443 | size_t i; |
|---|
| 444 | size_t len = strlen (word); |
|---|
| 445 | |
|---|
| 446 | for (i = 0; i <= len - 1; i++) |
|---|
| 447 | { |
|---|
| 448 | if ('A' <= word[i] && word[i] <= 'Z') |
|---|
| 449 | word[i] = word[i] + 32; |
|---|
| 450 | } |
|---|
| 451 | #endif |
|---|
| 452 | return OSIP_SUCCESS; |
|---|
| 453 | } |
|---|
| 454 | |
|---|
| 455 | #ifndef MINISIZE |
|---|
| 456 | int |
|---|
| 457 | osip_strcasecmp (const char *s1, const char *s2) |
|---|
| 458 | { |
|---|
| 459 | #if defined(__VXWORKS_OS__) || defined( __PSOS__) |
|---|
| 460 | while ((*s1 != '\0') && (tolower (*s1) == tolower (*s2))) |
|---|
| 461 | { |
|---|
| 462 | s1++; |
|---|
| 463 | s2++; |
|---|
| 464 | } |
|---|
| 465 | return (tolower (*s1) - tolower (*s2)); |
|---|
| 466 | #elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000) |
|---|
| 467 | return StrCaselessCompare (s1, s2); |
|---|
| 468 | #elif defined(__PALMOS__) || (!defined WIN32 && !defined _WIN32_WCE) |
|---|
| 469 | return strcasecmp (s1, s2); |
|---|
| 470 | #else |
|---|
| 471 | return _stricmp (s1, s2); |
|---|
| 472 | #endif |
|---|
| 473 | } |
|---|
| 474 | |
|---|
| 475 | int |
|---|
| 476 | osip_strncasecmp (const char *s1, const char *s2, size_t len) |
|---|
| 477 | { |
|---|
| 478 | #if defined(__VXWORKS_OS__) || defined( __PSOS__) |
|---|
| 479 | if (len == 0) |
|---|
| 480 | return OSIP_SUCCESS; |
|---|
| 481 | while ((len > 0) && (tolower (*s1) == tolower (*s2))) |
|---|
| 482 | { |
|---|
| 483 | len--; |
|---|
| 484 | if ((len == 0) || (*s1 == '\0') || (*s2 == '\0')) |
|---|
| 485 | break; |
|---|
| 486 | s1++; |
|---|
| 487 | s2++; |
|---|
| 488 | } |
|---|
| 489 | return tolower (*s1) - tolower (*s2); |
|---|
| 490 | #elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000) |
|---|
| 491 | return StrNCaselessCompare (s1, s2, len); |
|---|
| 492 | #elif defined(__PALMOS__) || (!defined WIN32 && !defined _WIN32_WCE) |
|---|
| 493 | return strncasecmp (s1, s2, len); |
|---|
| 494 | #else |
|---|
| 495 | return _strnicmp (s1, s2, len); |
|---|
| 496 | #endif |
|---|
| 497 | } |
|---|
| 498 | #endif |
|---|
| 499 | |
|---|
| 500 | /* remove SPACE before and after the content */ |
|---|
| 501 | int |
|---|
| 502 | osip_clrspace (char *word) |
|---|
| 503 | { |
|---|
| 504 | char *pbeg; |
|---|
| 505 | char *pend; |
|---|
| 506 | size_t len; |
|---|
| 507 | |
|---|
| 508 | if (word == NULL) |
|---|
| 509 | return OSIP_UNDEFINED_ERROR; |
|---|
| 510 | if (*word == '\0') |
|---|
| 511 | return OSIP_SUCCESS; |
|---|
| 512 | len = strlen (word); |
|---|
| 513 | |
|---|
| 514 | pbeg = word; |
|---|
| 515 | while ((' ' == *pbeg) || ('\r' == *pbeg) || ('\n' == *pbeg) || ('\t' == *pbeg)) |
|---|
| 516 | pbeg++; |
|---|
| 517 | |
|---|
| 518 | pend = word + len - 1; |
|---|
| 519 | while ((' ' == *pend) || ('\r' == *pend) || ('\n' == *pend) || ('\t' == *pend)) |
|---|
| 520 | { |
|---|
| 521 | pend--; |
|---|
| 522 | if (pend < pbeg) |
|---|
| 523 | { |
|---|
| 524 | *word = '\0'; |
|---|
| 525 | return OSIP_SUCCESS; |
|---|
| 526 | } |
|---|
| 527 | } |
|---|
| 528 | |
|---|
| 529 | /* Add terminating NULL only if we've cleared room for it */ |
|---|
| 530 | if (pend + 1 <= word + (len - 1)) |
|---|
| 531 | pend[1] = '\0'; |
|---|
| 532 | |
|---|
| 533 | if (pbeg != word) |
|---|
| 534 | memmove (word, pbeg, pend - pbeg + 2); |
|---|
| 535 | |
|---|
| 536 | return OSIP_SUCCESS; |
|---|
| 537 | } |
|---|
| 538 | |
|---|
| 539 | /* __osip_set_next_token: |
|---|
| 540 | dest is the place where the value will be allocated |
|---|
| 541 | buf is the string where the value is searched |
|---|
| 542 | end_separator is the character that MUST be found at the end of the value |
|---|
| 543 | next is the final location of the separator + 1 |
|---|
| 544 | |
|---|
| 545 | the element MUST be found before any "\r" "\n" "\0" and |
|---|
| 546 | end_separator |
|---|
| 547 | |
|---|
| 548 | return -1 on error |
|---|
| 549 | return 1 on success |
|---|
| 550 | */ |
|---|
| 551 | int |
|---|
| 552 | __osip_set_next_token (char **dest, char *buf, int end_separator, char **next) |
|---|
| 553 | { |
|---|
| 554 | char *sep; /* separator */ |
|---|
| 555 | |
|---|
| 556 | *next = NULL; |
|---|
| 557 | |
|---|
| 558 | sep = buf; |
|---|
| 559 | while ((*sep != end_separator) && (*sep != '\0') && (*sep != '\r') |
|---|
| 560 | && (*sep != '\n')) |
|---|
| 561 | sep++; |
|---|
| 562 | if ((*sep == '\r') || (*sep == '\n')) |
|---|
| 563 | { /* we should continue normally only if this is the separator asked! */ |
|---|
| 564 | if (*sep != end_separator) |
|---|
| 565 | return OSIP_UNDEFINED_ERROR; |
|---|
| 566 | } |
|---|
| 567 | if (*sep == '\0') |
|---|
| 568 | return OSIP_UNDEFINED_ERROR; /* value must not end with this separator! */ |
|---|
| 569 | if (sep == buf) |
|---|
| 570 | return OSIP_UNDEFINED_ERROR; /* empty value (or several space!) */ |
|---|
| 571 | |
|---|
| 572 | *dest = osip_malloc (sep - (buf) + 1); |
|---|
| 573 | if (*dest==NULL) |
|---|
| 574 | return OSIP_NOMEM; |
|---|
| 575 | osip_strncpy (*dest, buf, sep - buf); |
|---|
| 576 | |
|---|
| 577 | *next = sep + 1; /* return the position right after the separator */ |
|---|
| 578 | return OSIP_SUCCESS; |
|---|
| 579 | } |
|---|
| 580 | |
|---|
| 581 | #if 0 |
|---|
| 582 | /* not yet done!!! :-) |
|---|
| 583 | */ |
|---|
| 584 | int |
|---|
| 585 | __osip_set_next_token_better (char **dest, char *buf, int end_separator, |
|---|
| 586 | int *forbidden_tab[], int size_tab, char **next) |
|---|
| 587 | { |
|---|
| 588 | char *sep; /* separator */ |
|---|
| 589 | |
|---|
| 590 | *next = NULL; |
|---|
| 591 | |
|---|
| 592 | sep = buf; |
|---|
| 593 | while ((*sep != end_separator) && (*sep != '\0') && (*sep != '\r') |
|---|
| 594 | && (*sep != '\n')) |
|---|
| 595 | sep++; |
|---|
| 596 | if ((*sep == '\r') && (*sep == '\n')) |
|---|
| 597 | { /* we should continue normally only if this is the separator asked! */ |
|---|
| 598 | if (*sep != end_separator) |
|---|
| 599 | return OSIP_UNDEFINED_ERROR; |
|---|
| 600 | } |
|---|
| 601 | if (*sep == '\0') |
|---|
| 602 | return OSIP_UNDEFINED_ERROR; /* value must not end with this separator! */ |
|---|
| 603 | if (sep == buf) |
|---|
| 604 | return OSIP_UNDEFINED_ERROR; /* empty value (or several space!) */ |
|---|
| 605 | |
|---|
| 606 | *dest = osip_malloc (sep - (buf) + 1); |
|---|
| 607 | if (*dest==NULL) |
|---|
| 608 | return OSIP_NOMEM; |
|---|
| 609 | osip_strncpy (*dest, buf, sep - buf); |
|---|
| 610 | |
|---|
| 611 | *next = sep + 1; /* return the position right after the separator */ |
|---|
| 612 | return 1; |
|---|
| 613 | } |
|---|
| 614 | #endif |
|---|
| 615 | |
|---|
| 616 | /* in quoted-string, many characters can be escaped... */ |
|---|
| 617 | /* __osip_quote_find returns the next quote that is not escaped */ |
|---|
| 618 | char * |
|---|
| 619 | __osip_quote_find (const char *qstring) |
|---|
| 620 | { |
|---|
| 621 | char *quote; |
|---|
| 622 | |
|---|
| 623 | quote = strchr (qstring, '"'); |
|---|
| 624 | if (quote == qstring) /* the first char matches and is not escaped... */ |
|---|
| 625 | return quote; |
|---|
| 626 | |
|---|
| 627 | if (quote == NULL) |
|---|
| 628 | return NULL; /* no quote at all... */ |
|---|
| 629 | |
|---|
| 630 | /* this is now the nasty cases where '"' is escaped |
|---|
| 631 | '" jonathan ros \\\""' |
|---|
| 632 | | | |
|---|
| 633 | '" jonathan ros \\"' |
|---|
| 634 | | | |
|---|
| 635 | '" jonathan ros \""' |
|---|
| 636 | | | |
|---|
| 637 | we must count the number of preceeding '\' */ |
|---|
| 638 | { |
|---|
| 639 | int i = 1; |
|---|
| 640 | |
|---|
| 641 | for (;;) |
|---|
| 642 | { |
|---|
| 643 | if (0 == strncmp (quote - i, "\\", 1)) |
|---|
| 644 | i++; |
|---|
| 645 | else |
|---|
| 646 | { |
|---|
| 647 | if (i % 2 == 1) /* the '"' was not escaped */ |
|---|
| 648 | return quote; |
|---|
| 649 | |
|---|
| 650 | /* else continue with the next '"' */ |
|---|
| 651 | quote = strchr (quote + 1, '"'); |
|---|
| 652 | if (quote == NULL) |
|---|
| 653 | return NULL; |
|---|
| 654 | i = 1; |
|---|
| 655 | } |
|---|
| 656 | if (quote - i == qstring - 1) |
|---|
| 657 | /* example: "\"john" */ |
|---|
| 658 | /* example: "\\"jack" */ |
|---|
| 659 | { |
|---|
| 660 | /* special case where the string start with '\' */ |
|---|
| 661 | if (*qstring == '\\') |
|---|
| 662 | i++; /* an escape char was not counted */ |
|---|
| 663 | if (i % 2 == 0) /* the '"' was not escaped */ |
|---|
| 664 | return quote; |
|---|
| 665 | else |
|---|
| 666 | { /* else continue with the next '"' */ |
|---|
| 667 | qstring = quote + 1; /* reset qstring because |
|---|
| 668 | (*quote+1) may be also == to '\\' */ |
|---|
| 669 | quote = strchr (quote + 1, '"'); |
|---|
| 670 | if (quote == NULL) |
|---|
| 671 | return NULL; |
|---|
| 672 | i = 1; |
|---|
| 673 | } |
|---|
| 674 | |
|---|
| 675 | } |
|---|
| 676 | } |
|---|
| 677 | return NULL; |
|---|
| 678 | } |
|---|
| 679 | } |
|---|
| 680 | |
|---|
| 681 | char * |
|---|
| 682 | osip_enquote (const char *s) |
|---|
| 683 | { |
|---|
| 684 | char *rtn; |
|---|
| 685 | char *t; |
|---|
| 686 | |
|---|
| 687 | t = rtn = osip_malloc (strlen (s) * 2 + 3); |
|---|
| 688 | if (rtn==NULL) |
|---|
| 689 | return NULL; |
|---|
| 690 | *t++ = '"'; |
|---|
| 691 | for (; *s != '\0'; s++) |
|---|
| 692 | { |
|---|
| 693 | switch (*s) |
|---|
| 694 | { |
|---|
| 695 | case '"': |
|---|
| 696 | case '\\': |
|---|
| 697 | case 0x7f: |
|---|
| 698 | *t++ = '\\'; |
|---|
| 699 | *t++ = *s; |
|---|
| 700 | break; |
|---|
| 701 | case '\n': |
|---|
| 702 | case '\r': |
|---|
| 703 | *t++ = ' '; |
|---|
| 704 | break; |
|---|
| 705 | default: |
|---|
| 706 | *t++ = *s; |
|---|
| 707 | break; |
|---|
| 708 | } |
|---|
| 709 | } |
|---|
| 710 | *t++ = '"'; |
|---|
| 711 | *t++ = '\0'; |
|---|
| 712 | return rtn; |
|---|
| 713 | } |
|---|
| 714 | |
|---|
| 715 | void |
|---|
| 716 | osip_dequote (char *s) |
|---|
| 717 | { |
|---|
| 718 | size_t len; |
|---|
| 719 | |
|---|
| 720 | if (*s == '\0') |
|---|
| 721 | return; |
|---|
| 722 | if (*s != '"') |
|---|
| 723 | return; |
|---|
| 724 | len = strlen (s); |
|---|
| 725 | memmove (s, s + 1, len--); |
|---|
| 726 | if (len > 0 && s[len - 1] == '"') |
|---|
| 727 | s[--len] = '\0'; |
|---|
| 728 | for (; *s != '\0'; s++, len--) |
|---|
| 729 | { |
|---|
| 730 | if (*s == '\\') |
|---|
| 731 | memmove (s, s + 1, len--); |
|---|
| 732 | } |
|---|
| 733 | } |
|---|
| 734 | |
|---|
| 735 | /**********************************************************/ |
|---|
| 736 | /* only MACROS from osip/trace.h should be used by others */ |
|---|
| 737 | /* TRACE_INITIALIZE(level,file)) */ |
|---|
| 738 | /* TRACE_ENABLE_LEVEL(level) */ |
|---|
| 739 | /* TRACE_DISABLE_LEVEL(level) */ |
|---|
| 740 | /* IS_TRACE_LEVEL_ACTIVATE(level) */ |
|---|
| 741 | /**********************************************************/ |
|---|
| 742 | #ifndef ENABLE_TRACE |
|---|
| 743 | void |
|---|
| 744 | osip_trace_initialize_func (osip_trace_level_t level, osip_trace_func_t * func) |
|---|
| 745 | { |
|---|
| 746 | } |
|---|
| 747 | void |
|---|
| 748 | osip_trace_initialize_syslog (osip_trace_level_t level, char *ident) |
|---|
| 749 | { |
|---|
| 750 | } |
|---|
| 751 | void |
|---|
| 752 | osip_trace_initialize (osip_trace_level_t level, FILE * file) |
|---|
| 753 | { |
|---|
| 754 | } |
|---|
| 755 | void |
|---|
| 756 | osip_trace_enable_level (osip_trace_level_t level) |
|---|
| 757 | { |
|---|
| 758 | } |
|---|
| 759 | void |
|---|
| 760 | osip_trace_disable_level (osip_trace_level_t level) |
|---|
| 761 | { |
|---|
| 762 | } |
|---|
| 763 | |
|---|
| 764 | int |
|---|
| 765 | osip_is_trace_level_activate (osip_trace_level_t level) |
|---|
| 766 | { |
|---|
| 767 | return LOG_FALSE; |
|---|
| 768 | } |
|---|
| 769 | |
|---|
| 770 | #else |
|---|
| 771 | |
|---|
| 772 | /* initialize log */ |
|---|
| 773 | /* all lower levels of level are logged in file. */ |
|---|
| 774 | void |
|---|
| 775 | osip_trace_initialize (osip_trace_level_t level, FILE * file) |
|---|
| 776 | { |
|---|
| 777 | osip_trace_level_t i = 0; |
|---|
| 778 | |
|---|
| 779 | /* enable trace in log file by default */ |
|---|
| 780 | logfile = NULL; |
|---|
| 781 | if (file != NULL) |
|---|
| 782 | logfile = file; |
|---|
| 783 | #ifndef SYSTEM_LOGGER_ENABLED |
|---|
| 784 | else |
|---|
| 785 | logfile = stdout; |
|---|
| 786 | #endif |
|---|
| 787 | |
|---|
| 788 | /* enable all lower levels */ |
|---|
| 789 | while (i < END_TRACE_LEVEL) |
|---|
| 790 | { |
|---|
| 791 | if (i < level) |
|---|
| 792 | tracing_table[i] = LOG_TRUE; |
|---|
| 793 | else |
|---|
| 794 | tracing_table[i] = LOG_FALSE; |
|---|
| 795 | i++; |
|---|
| 796 | } |
|---|
| 797 | } |
|---|
| 798 | |
|---|
| 799 | void |
|---|
| 800 | osip_trace_initialize_syslog (osip_trace_level_t level, char *ident) |
|---|
| 801 | { |
|---|
| 802 | osip_trace_level_t i = 0; |
|---|
| 803 | |
|---|
| 804 | #if defined (HAVE_SYSLOG_H) && !defined(__arc__) |
|---|
| 805 | openlog (ident, LOG_CONS | LOG_PID, LOG_DAEMON); |
|---|
| 806 | use_syslog = 1; |
|---|
| 807 | #endif |
|---|
| 808 | /* enable all lower levels */ |
|---|
| 809 | while (i < END_TRACE_LEVEL) |
|---|
| 810 | { |
|---|
| 811 | if (i < level) |
|---|
| 812 | tracing_table[i] = LOG_TRUE; |
|---|
| 813 | else |
|---|
| 814 | tracing_table[i] = LOG_FALSE; |
|---|
| 815 | i++; |
|---|
| 816 | } |
|---|
| 817 | } |
|---|
| 818 | |
|---|
| 819 | void |
|---|
| 820 | osip_trace_enable_until_level (osip_trace_level_t level) |
|---|
| 821 | { |
|---|
| 822 | int i = 0; |
|---|
| 823 | |
|---|
| 824 | while (i < END_TRACE_LEVEL) |
|---|
| 825 | { |
|---|
| 826 | if (i < level) |
|---|
| 827 | tracing_table[i] = LOG_TRUE; |
|---|
| 828 | else |
|---|
| 829 | tracing_table[i] = LOG_FALSE; |
|---|
| 830 | i++; |
|---|
| 831 | } |
|---|
| 832 | } |
|---|
| 833 | |
|---|
| 834 | void |
|---|
| 835 | osip_trace_initialize_func (osip_trace_level_t level, osip_trace_func_t * func) |
|---|
| 836 | { |
|---|
| 837 | int i = 0; |
|---|
| 838 | |
|---|
| 839 | trace_func = func; |
|---|
| 840 | |
|---|
| 841 | /* enable all lower levels */ |
|---|
| 842 | while (i < END_TRACE_LEVEL) |
|---|
| 843 | { |
|---|
| 844 | if (i < level) |
|---|
| 845 | tracing_table[i] = LOG_TRUE; |
|---|
| 846 | else |
|---|
| 847 | tracing_table[i] = LOG_FALSE; |
|---|
| 848 | i++; |
|---|
| 849 | } |
|---|
| 850 | } |
|---|
| 851 | |
|---|
| 852 | /* enable a special debugging level! */ |
|---|
| 853 | void |
|---|
| 854 | osip_trace_enable_level (osip_trace_level_t level) |
|---|
| 855 | { |
|---|
| 856 | tracing_table[level] = LOG_TRUE; |
|---|
| 857 | } |
|---|
| 858 | |
|---|
| 859 | /* disable a special debugging level! */ |
|---|
| 860 | void |
|---|
| 861 | osip_trace_disable_level (osip_trace_level_t level) |
|---|
| 862 | { |
|---|
| 863 | tracing_table[level] = LOG_FALSE; |
|---|
| 864 | } |
|---|
| 865 | |
|---|
| 866 | /* not so usefull? */ |
|---|
| 867 | int |
|---|
| 868 | osip_is_trace_level_activate (osip_trace_level_t level) |
|---|
| 869 | { |
|---|
| 870 | return tracing_table[level]; |
|---|
| 871 | } |
|---|
| 872 | #endif |
|---|
| 873 | |
|---|
| 874 | #if defined(WIN32) && !defined(_WIN32_WCE) |
|---|
| 875 | |
|---|
| 876 | #include <time.h> |
|---|
| 877 | //#ifndef _WIN32_WCE |
|---|
| 878 | #include <sys/timeb.h> |
|---|
| 879 | //#endif /* !_WIN32_WCE */ |
|---|
| 880 | int |
|---|
| 881 | __osip_port_gettimeofday (struct timeval *tp, void *tz) |
|---|
| 882 | { |
|---|
| 883 | struct _timeb timebuffer; |
|---|
| 884 | |
|---|
| 885 | _ftime (&timebuffer); |
|---|
| 886 | tp->tv_sec = (long) timebuffer.time; |
|---|
| 887 | tp->tv_usec = timebuffer.millitm * 1000; |
|---|
| 888 | return OSIP_SUCCESS; |
|---|
| 889 | } |
|---|
| 890 | #elif defined(__linux) || defined(_WIN32_WCE) |
|---|
| 891 | //#include <sys/time.h> |
|---|
| 892 | #define __osip_port_gettimeofday gettimeofday |
|---|
| 893 | #endif |
|---|
| 894 | |
|---|
| 895 | int |
|---|
| 896 | osip_trace (char *fi, int li, osip_trace_level_t level, FILE * f, char *chfr, ...) |
|---|
| 897 | { |
|---|
| 898 | #ifdef ENABLE_TRACE |
|---|
| 899 | va_list ap; |
|---|
| 900 | int relative_time=0; |
|---|
| 901 | |
|---|
| 902 | #if (defined(WIN32) || defined(__linux)) && !defined(_WIN32_WCE) |
|---|
| 903 | static struct timeval start={0,0}; |
|---|
| 904 | struct timeval now; |
|---|
| 905 | |
|---|
| 906 | if (start.tv_sec==0 && start.tv_usec==0) |
|---|
| 907 | { |
|---|
| 908 | __osip_port_gettimeofday(&start, NULL); |
|---|
| 909 | } |
|---|
| 910 | __osip_port_gettimeofday(&now, NULL); |
|---|
| 911 | |
|---|
| 912 | relative_time = 1000*(now.tv_sec - start.tv_sec); |
|---|
| 913 | if (now.tv_usec - start.tv_usec>0) |
|---|
| 914 | relative_time = relative_time + ((now.tv_usec - start.tv_usec)/1000); |
|---|
| 915 | else |
|---|
| 916 | relative_time = relative_time -1 + ((now.tv_usec - start.tv_usec)/1000); |
|---|
| 917 | #endif |
|---|
| 918 | |
|---|
| 919 | #if !defined(WIN32) && !defined(SYSTEM_LOGGER_ENABLED) |
|---|
| 920 | if (logfile == NULL && use_syslog == 0 && trace_func == NULL) |
|---|
| 921 | { /* user did not initialize logger.. */ |
|---|
| 922 | return 1; |
|---|
| 923 | } |
|---|
| 924 | #endif |
|---|
| 925 | |
|---|
| 926 | if (tracing_table[level] == LOG_FALSE) |
|---|
| 927 | return OSIP_SUCCESS; |
|---|
| 928 | |
|---|
| 929 | if (f == NULL && trace_func == NULL) |
|---|
| 930 | f = logfile; |
|---|
| 931 | |
|---|
| 932 | VA_START (ap, chfr); |
|---|
| 933 | |
|---|
| 934 | #if defined(__VXWORKS_OS__) || defined(__rtems__) |
|---|
| 935 | /* vxworks can't have a local file */ |
|---|
| 936 | f = stdout; |
|---|
| 937 | #endif |
|---|
| 938 | |
|---|
| 939 | if (f && use_syslog == 0) |
|---|
| 940 | { |
|---|
| 941 | if (level == OSIP_FATAL) |
|---|
| 942 | fprintf (f, "| FATAL | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 943 | else if (level == OSIP_BUG) |
|---|
| 944 | fprintf (f, "| BUG | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 945 | else if (level == OSIP_ERROR) |
|---|
| 946 | fprintf (f, "| ERROR | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 947 | else if (level == OSIP_WARNING) |
|---|
| 948 | fprintf (f, "|WARNING| %i <%s: %i> ", relative_time, fi, li); |
|---|
| 949 | else if (level == OSIP_INFO1) |
|---|
| 950 | fprintf (f, "| INFO1 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 951 | else if (level == OSIP_INFO2) |
|---|
| 952 | fprintf (f, "| INFO2 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 953 | else if (level == OSIP_INFO3) |
|---|
| 954 | fprintf (f, "| INFO3 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 955 | else if (level == OSIP_INFO4) |
|---|
| 956 | fprintf (f, "| INFO4 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 957 | |
|---|
| 958 | vfprintf (f, chfr, ap); |
|---|
| 959 | |
|---|
| 960 | fflush (f); |
|---|
| 961 | } else if (trace_func) |
|---|
| 962 | { |
|---|
| 963 | trace_func (fi, li, level, chfr, ap); |
|---|
| 964 | } |
|---|
| 965 | #if defined (HAVE_SYSLOG_H) && !defined(__arc__) |
|---|
| 966 | else if (use_syslog == 1) |
|---|
| 967 | { |
|---|
| 968 | char buffer[512]; |
|---|
| 969 | int in = 0; |
|---|
| 970 | |
|---|
| 971 | memset (buffer, 0, sizeof (buffer)); |
|---|
| 972 | if (level == OSIP_FATAL) |
|---|
| 973 | in = snprintf (buffer, 511, "| FATAL | <%s: %i> ", fi, li); |
|---|
| 974 | else if (level == OSIP_BUG) |
|---|
| 975 | in = snprintf (buffer, 511, "| BUG | <%s: %i> ", fi, li); |
|---|
| 976 | else if (level == OSIP_ERROR) |
|---|
| 977 | in = snprintf (buffer, 511, "| ERROR | <%s: %i> ", fi, li); |
|---|
| 978 | else if (level == OSIP_WARNING) |
|---|
| 979 | in = snprintf (buffer, 511, "|WARNING| <%s: %i> ", fi, li); |
|---|
| 980 | else if (level == OSIP_INFO1) |
|---|
| 981 | in = snprintf (buffer, 511, "| INFO1 | <%s: %i> ", fi, li); |
|---|
| 982 | else if (level == OSIP_INFO2) |
|---|
| 983 | in = snprintf (buffer, 511, "| INFO2 | <%s: %i> ", fi, li); |
|---|
| 984 | else if (level == OSIP_INFO3) |
|---|
| 985 | in = snprintf (buffer, 511, "| INFO3 | <%s: %i> ", fi, li); |
|---|
| 986 | else if (level == OSIP_INFO4) |
|---|
| 987 | in = snprintf (buffer, 511, "| INFO4 | <%s: %i> ", fi, li); |
|---|
| 988 | |
|---|
| 989 | vsnprintf (buffer + in, 511 - in, chfr, ap); |
|---|
| 990 | if (level == OSIP_FATAL) |
|---|
| 991 | syslog (LOG_ERR, "%s", buffer); |
|---|
| 992 | else if (level == OSIP_BUG) |
|---|
| 993 | syslog (LOG_ERR, "%s", buffer); |
|---|
| 994 | else if (level == OSIP_ERROR) |
|---|
| 995 | syslog (LOG_ERR, "%s", buffer); |
|---|
| 996 | else if (level == OSIP_WARNING) |
|---|
| 997 | syslog (LOG_WARNING, "%s", buffer); |
|---|
| 998 | else if (level == OSIP_INFO1) |
|---|
| 999 | syslog (LOG_INFO, "%s", buffer); |
|---|
| 1000 | else if (level == OSIP_INFO2) |
|---|
| 1001 | syslog (LOG_INFO, "%s", buffer); |
|---|
| 1002 | else if (level == OSIP_INFO3) |
|---|
| 1003 | syslog (LOG_DEBUG, "%s", buffer); |
|---|
| 1004 | else if (level == OSIP_INFO4) |
|---|
| 1005 | syslog (LOG_DEBUG, "%s", buffer); |
|---|
| 1006 | } |
|---|
| 1007 | #endif |
|---|
| 1008 | #ifdef SYSTEM_LOGGER_ENABLED |
|---|
| 1009 | else |
|---|
| 1010 | { |
|---|
| 1011 | char buffer[512]; |
|---|
| 1012 | int in = 0; |
|---|
| 1013 | #ifdef DISPLAY_TIME |
|---|
| 1014 | int relative_time; |
|---|
| 1015 | #endif |
|---|
| 1016 | |
|---|
| 1017 | memset (buffer, 0, sizeof (buffer)); |
|---|
| 1018 | if (level == OSIP_FATAL) |
|---|
| 1019 | in = _snprintf (buffer, 511, "| FATAL | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1020 | else if (level == OSIP_BUG) |
|---|
| 1021 | in = _snprintf (buffer, 511, "| BUG | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1022 | else if (level == OSIP_ERROR) |
|---|
| 1023 | in = _snprintf (buffer, 511, "| ERROR | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1024 | else if (level == OSIP_WARNING) |
|---|
| 1025 | in = _snprintf (buffer, 511, "|WARNING| %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1026 | else if (level == OSIP_INFO1) |
|---|
| 1027 | in = _snprintf (buffer, 511, "| INFO1 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1028 | else if (level == OSIP_INFO2) |
|---|
| 1029 | in = _snprintf (buffer, 511, "| INFO2 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1030 | else if (level == OSIP_INFO3) |
|---|
| 1031 | in = _snprintf (buffer, 511, "| INFO3 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1032 | else if (level == OSIP_INFO4) |
|---|
| 1033 | in = _snprintf (buffer, 511, "| INFO4 | %i <%s: %i> ", relative_time, fi, li); |
|---|
| 1034 | |
|---|
| 1035 | _vsnprintf (buffer + in, 511 - in, chfr, ap); |
|---|
| 1036 | OutputDebugString (buffer); |
|---|
| 1037 | } |
|---|
| 1038 | #endif |
|---|
| 1039 | |
|---|
| 1040 | va_end (ap); |
|---|
| 1041 | #endif |
|---|
| 1042 | return OSIP_SUCCESS; |
|---|
| 1043 | } |
|---|
| 1044 | |
|---|
| 1045 | |
|---|
| 1046 | |
|---|
| 1047 | #if defined(WIN32) || defined(_WIN32_WCE) |
|---|
| 1048 | |
|---|
| 1049 | #undef osip_malloc |
|---|
| 1050 | void * |
|---|
| 1051 | osip_malloc (size_t size) |
|---|
| 1052 | { |
|---|
| 1053 | void *ptr = malloc (size); |
|---|
| 1054 | |
|---|
| 1055 | if (ptr != NULL) |
|---|
| 1056 | memset (ptr, 0, size); |
|---|
| 1057 | return ptr; |
|---|
| 1058 | } |
|---|
| 1059 | |
|---|
| 1060 | #undef osip_realloc |
|---|
| 1061 | void * |
|---|
| 1062 | osip_realloc (void *ptr, size_t size) |
|---|
| 1063 | { |
|---|
| 1064 | return realloc (ptr, size); |
|---|
| 1065 | } |
|---|
| 1066 | |
|---|
| 1067 | #undef osip_free |
|---|
| 1068 | void |
|---|
| 1069 | osip_free (void *ptr) |
|---|
| 1070 | { |
|---|
| 1071 | if (ptr == NULL) |
|---|
| 1072 | return; |
|---|
| 1073 | free (ptr); |
|---|
| 1074 | } |
|---|
| 1075 | |
|---|
| 1076 | #else |
|---|
| 1077 | |
|---|
| 1078 | #ifndef MINISIZE |
|---|
| 1079 | void |
|---|
| 1080 | osip_set_allocators (osip_malloc_func_t * malloc_func, |
|---|
| 1081 | osip_realloc_func_t * realloc_func, |
|---|
| 1082 | osip_free_func_t * free_func) |
|---|
| 1083 | { |
|---|
| 1084 | osip_malloc_func = malloc_func; |
|---|
| 1085 | osip_realloc_func = realloc_func; |
|---|
| 1086 | osip_free_func = free_func; |
|---|
| 1087 | } |
|---|
| 1088 | #endif |
|---|
| 1089 | |
|---|
| 1090 | #endif |
|---|
| 1091 | |
|---|
| 1092 | #if defined(__VXWORKS_OS__) |
|---|
| 1093 | |
|---|
| 1094 | typedef struct |
|---|
| 1095 | { |
|---|
| 1096 | char *str; |
|---|
| 1097 | int max; |
|---|
| 1098 | int len; |
|---|
| 1099 | } _context; |
|---|
| 1100 | |
|---|
| 1101 | STATUS _cb_snprintf (char *buffer, int nc, int arg); |
|---|
| 1102 | |
|---|
| 1103 | STATUS |
|---|
| 1104 | _cb_snprintf (char *buffer, int nc, int arg) |
|---|
| 1105 | { |
|---|
| 1106 | _context *ctx = (_context *) arg; |
|---|
| 1107 | |
|---|
| 1108 | if (ctx->max - ctx->len - nc < 1) /* retain 1 pos for terminating \0 */ |
|---|
| 1109 | { |
|---|
| 1110 | nc = ctx->max - ctx->len - 1; |
|---|
| 1111 | } |
|---|
| 1112 | |
|---|
| 1113 | if (nc > 0) |
|---|
| 1114 | { |
|---|
| 1115 | memcpy (ctx->str + ctx->len, buffer, nc); |
|---|
| 1116 | ctx->len += nc; |
|---|
| 1117 | } |
|---|
| 1118 | |
|---|
| 1119 | ctx->str[ctx->len] = '\0'; |
|---|
| 1120 | |
|---|
| 1121 | return OK; |
|---|
| 1122 | } |
|---|
| 1123 | |
|---|
| 1124 | |
|---|
| 1125 | int |
|---|
| 1126 | osip_vsnprintf (char *buf, int max, const char *fmt, va_list ap) |
|---|
| 1127 | { |
|---|
| 1128 | _context ctx; |
|---|
| 1129 | |
|---|
| 1130 | ctx.str = buf; |
|---|
| 1131 | ctx.max = max; |
|---|
| 1132 | ctx.len = 0; |
|---|
| 1133 | |
|---|
| 1134 | if (fioFormatV (fmt, ap, _cb_snprintf, (int) &ctx) != OK) |
|---|
| 1135 | { |
|---|
| 1136 | return OSIP_UNDEFINED_ERROR; |
|---|
| 1137 | } |
|---|
| 1138 | |
|---|
| 1139 | return ctx.len; |
|---|
| 1140 | } |
|---|
| 1141 | |
|---|
| 1142 | int |
|---|
| 1143 | osip_snprintf (char *buf, int max, const char *fmt, ...) |
|---|
| 1144 | { |
|---|
| 1145 | int retval; |
|---|
| 1146 | va_list ap; |
|---|
| 1147 | |
|---|
| 1148 | va_start (ap, fmt); |
|---|
| 1149 | retval = osip_vsnprintf (buf, max, fmt, ap); |
|---|
| 1150 | va_end (ap); |
|---|
| 1151 | return retval; |
|---|
| 1152 | } |
|---|
| 1153 | |
|---|
| 1154 | #endif |
|---|
| 1155 | |
|---|
| 1156 | |
|---|
| 1157 | #if defined(__PSOS__) |
|---|
| 1158 | |
|---|
| 1159 | int |
|---|
| 1160 | osip_snprintf (char *buf, int max, const char *fmt, ...) |
|---|
| 1161 | { |
|---|
| 1162 | static char buffer[1024]; |
|---|
| 1163 | int retval; |
|---|
| 1164 | va_list ap; |
|---|
| 1165 | |
|---|
| 1166 | buffer[0] = '\n'; |
|---|
| 1167 | va_start (ap, fmt); |
|---|
| 1168 | vsprintf (&(buffer[strlen (buffer)]), fmt, ap); |
|---|
| 1169 | va_end (ap); |
|---|
| 1170 | retval = strlen (buffer); |
|---|
| 1171 | memmove (buf, buffer, max); |
|---|
| 1172 | if (retval > max) |
|---|
| 1173 | return OSIP_UNDEFINED_ERROR; |
|---|
| 1174 | return retval; |
|---|
| 1175 | } |
|---|
| 1176 | |
|---|
| 1177 | #endif |
|---|
| 1178 | |
|---|
| 1179 | #ifdef DEBUG_MEM |
|---|
| 1180 | |
|---|
| 1181 | /* |
|---|
| 1182 | This is a debug facility for detecting memory leaks. |
|---|
| 1183 | I recommend to use external tools such as mpatrol |
|---|
| 1184 | when possible. On some fancy platform, you may not |
|---|
| 1185 | have any usefull tools: in this case, use this code! |
|---|
| 1186 | */ |
|---|
| 1187 | |
|---|
| 1188 | void * |
|---|
| 1189 | _osip_malloc (size_t size, char *file, unsigned short line) |
|---|
| 1190 | { |
|---|
| 1191 | void *mem; |
|---|
| 1192 | |
|---|
| 1193 | mem = osip_malloc_func (size + 20); |
|---|
| 1194 | if (mem != NULL) |
|---|
| 1195 | { |
|---|
| 1196 | char *s; |
|---|
| 1197 | |
|---|
| 1198 | memcpy (mem, &line, 2); |
|---|
| 1199 | for (s = file + strlen (file); s != file; s--) |
|---|
| 1200 | { |
|---|
| 1201 | if (*s == '\\' || *s == '/') |
|---|
| 1202 | { |
|---|
| 1203 | s++; |
|---|
| 1204 | break; |
|---|
| 1205 | } |
|---|
| 1206 | } |
|---|
| 1207 | strncpy ((char *) mem + 2, s, 18); |
|---|
| 1208 | return (void *) ((char *) mem + 20); |
|---|
| 1209 | } |
|---|
| 1210 | return NULL; |
|---|
| 1211 | } |
|---|
| 1212 | |
|---|
| 1213 | void |
|---|
| 1214 | _osip_free (void *ptr) |
|---|
| 1215 | { |
|---|
| 1216 | if (ptr != NULL) |
|---|
| 1217 | { |
|---|
| 1218 | osip_free_func ((char *) ptr - 20); |
|---|
| 1219 | } |
|---|
| 1220 | } |
|---|
| 1221 | |
|---|
| 1222 | void * |
|---|
| 1223 | _osip_realloc (void *ptr, size_t size, char *file, unsigned short line) |
|---|
| 1224 | { |
|---|
| 1225 | void *mem; |
|---|
| 1226 | |
|---|
| 1227 | mem = osip_realloc_func ((char *) ptr - 20, size + 20); |
|---|
| 1228 | if (mem != NULL) |
|---|
| 1229 | { |
|---|
| 1230 | char *s; |
|---|
| 1231 | |
|---|
| 1232 | memcpy (mem, &line, 2); |
|---|
| 1233 | |
|---|
| 1234 | for (s = file + strlen (file); s != file; s--) |
|---|
| 1235 | { |
|---|
| 1236 | if (*s == '\\' || *s == '/') |
|---|
| 1237 | { |
|---|
| 1238 | s++; |
|---|
| 1239 | break; |
|---|
| 1240 | } |
|---|
| 1241 | } |
|---|
| 1242 | strncpy ((char *) mem + 2, s, 18); |
|---|
| 1243 | return (char *) mem + 20; |
|---|
| 1244 | } |
|---|
| 1245 | return NULL; |
|---|
| 1246 | } |
|---|
| 1247 | |
|---|
| 1248 | #endif |
|---|
| 1249 | |
|---|
| 1250 | |
|---|
| 1251 | /* ---For better performance--- |
|---|
| 1252 | Calculates a hash value for the given string */ |
|---|
| 1253 | unsigned long |
|---|
| 1254 | osip_hash (const char *str) |
|---|
| 1255 | { |
|---|
| 1256 | unsigned int hash = 5381; |
|---|
| 1257 | int c; |
|---|
| 1258 | |
|---|
| 1259 | while (c = *str++) |
|---|
| 1260 | hash = ((hash << 5) + hash) + c; |
|---|
| 1261 | |
|---|
| 1262 | return hash & 0xFFFFFFFFu; |
|---|
| 1263 | } |
|---|
| 1264 | |
|---|
| 1265 | /* ---For better performance--- |
|---|
| 1266 | Appends src-string to dst-string. |
|---|
| 1267 | |
|---|
| 1268 | This was introduced to replace the |
|---|
| 1269 | inefficient constructions like: |
|---|
| 1270 | |
|---|
| 1271 | osip_strncpy (tmp, src, strlen(src) ); |
|---|
| 1272 | tmp = tmp + strlen (src); |
|---|
| 1273 | |
|---|
| 1274 | This function returns a pointer to the |
|---|
| 1275 | end of the destination string |
|---|
| 1276 | |
|---|
| 1277 | Pre: src is null terminated */ |
|---|
| 1278 | char * |
|---|
| 1279 | osip_str_append (char *dst, const char *src) |
|---|
| 1280 | { |
|---|
| 1281 | while (*src != '\0') |
|---|
| 1282 | { |
|---|
| 1283 | *dst = *src; |
|---|
| 1284 | src++; |
|---|
| 1285 | dst++; |
|---|
| 1286 | } |
|---|
| 1287 | *dst = '\0'; |
|---|
| 1288 | return dst; |
|---|
| 1289 | } |
|---|
| 1290 | |
|---|
| 1291 | /* ---For better performance--- |
|---|
| 1292 | Same as above, only this time we know the length */ |
|---|
| 1293 | char * |
|---|
| 1294 | osip_strn_append (char *dst, const char *src, size_t len) |
|---|
| 1295 | { |
|---|
| 1296 | memmove ((void *) dst, (void *) src, len); |
|---|
| 1297 | dst += len; |
|---|
| 1298 | *dst = '\0'; |
|---|
| 1299 | return dst; |
|---|
| 1300 | } |
|---|
| 1301 | |
|---|
| 1302 | |
|---|
| 1303 | /* ---For better performance--- |
|---|
| 1304 | This is to replace this construction: |
|---|
| 1305 | osip_strncpy ( dest, source, length); |
|---|
| 1306 | osip_clrspace ( dest ); */ |
|---|
| 1307 | #ifndef MINISIZE |
|---|
| 1308 | char * |
|---|
| 1309 | osip_clrncpy (char *dst, const char *src, size_t len) |
|---|
| 1310 | { |
|---|
| 1311 | const char *pbeg; |
|---|
| 1312 | const char *pend; |
|---|
| 1313 | char *p; |
|---|
| 1314 | size_t spaceless_length; |
|---|
| 1315 | |
|---|
| 1316 | if (src == NULL) |
|---|
| 1317 | return NULL; |
|---|
| 1318 | |
|---|
| 1319 | /* find the start of relevant text */ |
|---|
| 1320 | pbeg = src; |
|---|
| 1321 | while ((' ' == *pbeg) || ('\r' == *pbeg) || ('\n' == *pbeg) || ('\t' == *pbeg)) |
|---|
| 1322 | pbeg++; |
|---|
| 1323 | |
|---|
| 1324 | |
|---|
| 1325 | /* find the end of relevant text */ |
|---|
| 1326 | pend = src + len - 1; |
|---|
| 1327 | while ((' ' == *pend) || ('\r' == *pend) || ('\n' == *pend) || ('\t' == *pend)) |
|---|
| 1328 | { |
|---|
| 1329 | pend--; |
|---|
| 1330 | if (pend < pbeg) |
|---|
| 1331 | { |
|---|
| 1332 | *dst = '\0'; |
|---|
| 1333 | return dst; |
|---|
| 1334 | } |
|---|
| 1335 | } |
|---|
| 1336 | |
|---|
| 1337 | /* if pend == pbeg there is only one char to copy */ |
|---|
| 1338 | spaceless_length = pend - pbeg + 1; /* excluding any '\0' */ |
|---|
| 1339 | memmove (dst, pbeg, spaceless_length); |
|---|
| 1340 | p = dst + spaceless_length; |
|---|
| 1341 | |
|---|
| 1342 | /* terminate the string and pad dest with zeros until len */ |
|---|
| 1343 | do |
|---|
| 1344 | { |
|---|
| 1345 | *p = '\0'; |
|---|
| 1346 | p++; |
|---|
| 1347 | spaceless_length++; |
|---|
| 1348 | } |
|---|
| 1349 | while (spaceless_length < len); |
|---|
| 1350 | |
|---|
| 1351 | return dst; |
|---|
| 1352 | } |
|---|
| 1353 | |
|---|
| 1354 | #else |
|---|
| 1355 | |
|---|
| 1356 | char * |
|---|
| 1357 | osip_clrncpy (char *dst, const char *src, size_t len) |
|---|
| 1358 | { |
|---|
| 1359 | osip_strncpy ( dst, src, len); |
|---|
| 1360 | osip_clrspace ( dst ); |
|---|
| 1361 | return dst; |
|---|
| 1362 | } |
|---|
| 1363 | |
|---|
| 1364 | #endif |
|---|