source: verona/libosip2/src/osipparser2/osip_port.c @ 37:4fe9562edc7c

Last change on this file since 37:4fe9562edc7c was 37:4fe9562edc7c, checked in by nikita <>, 3 years ago

include debug

File size: 29.7 KB
Line 
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
106FILE *logfile = NULL;
107int tracing_table[END_TRACE_LEVEL];
108static int use_syslog = 0;
109static osip_trace_func_t *trace_func = 0;
110
111static unsigned int random_seed_set = 0;
112
113#ifndef MINISIZE
114#if !defined(WIN32) && !defined(_WIN32_WCE)
115osip_malloc_func_t *osip_malloc_func = 0;
116osip_realloc_func_t *osip_realloc_func = 0;
117osip_free_func_t *osip_free_func = 0;
118#endif
119#endif
120
121const 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
185const 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
195unsigned int
196osip_build_random_number ()
197#else
198static unsigned int
199osip_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
281unsigned int
282osip_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
309char *
310osip_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
319char *
320osip_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
336int
337osip_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*/
358char *
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
376void
377osip_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
418char *
419osip_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
435int
436osip_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
456int
457osip_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
475int
476osip_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 */
501int
502osip_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*/
551int
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 */
584int
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 */
618char *
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
681char *
682osip_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
715void
716osip_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
743void
744osip_trace_initialize_func (osip_trace_level_t level, osip_trace_func_t * func)
745{
746}
747void
748osip_trace_initialize_syslog (osip_trace_level_t level, char *ident)
749{
750}
751void
752osip_trace_initialize (osip_trace_level_t level, FILE * file)
753{
754}
755void
756osip_trace_enable_level (osip_trace_level_t level)
757{
758}
759void
760osip_trace_disable_level (osip_trace_level_t level)
761{
762}
763
764int
765osip_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. */
774void
775osip_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
799void
800osip_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
819void
820osip_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
834void
835osip_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! */
853void
854osip_trace_enable_level (osip_trace_level_t level)
855{
856  tracing_table[level] = LOG_TRUE;
857}
858
859/* disable a special debugging level! */
860void
861osip_trace_disable_level (osip_trace_level_t level)
862{
863  tracing_table[level] = LOG_FALSE;
864}
865
866/* not so usefull? */
867int
868osip_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 */
880int
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
895int
896osip_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
1050void *
1051osip_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
1061void *
1062osip_realloc (void *ptr, size_t size)
1063{
1064  return realloc (ptr, size);
1065}
1066
1067#undef osip_free
1068void
1069osip_free (void *ptr)
1070{
1071  if (ptr == NULL)
1072    return;
1073  free (ptr);
1074}
1075
1076#else
1077
1078#ifndef MINISIZE
1079void
1080osip_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
1094typedef struct
1095{
1096  char *str;
1097  int max;
1098  int len;
1099} _context;
1100
1101STATUS _cb_snprintf (char *buffer, int nc, int arg);
1102
1103STATUS
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
1125int
1126osip_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
1142int
1143osip_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
1159int
1160osip_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
1188void *
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
1213void
1214_osip_free (void *ptr)
1215{
1216  if (ptr != NULL)
1217    {
1218      osip_free_func ((char *) ptr - 20);
1219    }
1220}
1221
1222void *
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 */
1253unsigned long
1254osip_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 */
1278char *
1279osip_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 */
1293char *
1294osip_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
1308char *
1309osip_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
1356char *
1357osip_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
Note: See TracBrowser for help on using the repository browser.