osip_port.c

Go to the documentation of this file.
00001 
00024 #ifdef _WIN32_WCE
00025 #define _INC_TIME               /* for wce.h */
00026 #include <windows.h>
00027 #endif
00028 
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <stdarg.h>
00032 
00033 #include "osip_port.h"
00034 
00035 #ifdef HAVE_SYS_TYPES_H
00036 #include <sys/types.h>
00037 #endif
00038 #ifdef HAVE_SYS_STAT_H
00039 #include <sys/stat.h>
00040 #endif
00041 #ifdef HAVE_FCNTL_H
00042 #include <fcntl.h>
00043 #endif
00044 
00045 #ifdef HAVE_CTYPE_H
00046 #include <ctype.h>
00047 #endif
00048 
00049 #if defined(__PALMOS__) && (__PALMOS__ < 0x06000000)
00050 #       include <TimeMgr.h>
00051 #       include <SysUtils.h>
00052 #       include <SystemMgr.h>
00053 #       include <StringMgr.h>
00054 #else
00055 #       include <time.h>
00056 #endif
00057 
00058 #if defined(__VXWORKS_OS__)
00059 #include <selectLib.h>
00060 
00061 /* needed for snprintf replacement */
00062   #include <vxWorks.h>
00063   #include <fioLib.h>
00064   #include <string.h>
00065 
00066 #elif defined(__PALMOS__)
00067 #       if __PALMOS__ >= 0x06000000
00068 #               include <sys/time.h>
00069 #               include <SysThread.h>
00070 #       endif
00071 #elif (!defined(WIN32) && !defined(_WIN32_WCE))
00072 #include <sys/time.h>
00073 #elif defined(WIN32)
00074 #include <windows.h>
00075 #ifdef WIN32_USE_CRYPTO
00076 #include <Wincrypt.h>
00077 #endif
00078 #endif
00079 
00080 #if defined (HAVE_SYS_UNISTD_H)
00081 #  include <sys/unistd.h>
00082 #endif
00083 
00084 #if defined (HAVE_UNISTD_H)
00085 #  include <unistd.h>
00086 #endif
00087 
00088 #if defined (HAVE_SYSLOG_H)
00089 #  include <syslog.h>
00090 #endif
00091 
00092 #if defined (HAVE_SYS_SELECT_H)
00093 #  include <sys/select.h>
00094 #endif
00095 
00096 #ifdef HAVE_PTH_PTHREAD_H
00097 #include <pthread.h>
00098 #endif
00099 
00100 
00101 FILE *logfile = NULL;
00102 int tracing_table[END_TRACE_LEVEL];
00103 static int use_syslog = 0;
00104 static osip_trace_func_t *trace_func = 0;
00105 
00106 static unsigned int random_seed_set = 0;
00107 
00108 #ifndef WIN32
00109 osip_malloc_func_t *osip_malloc_func = 0;
00110 osip_realloc_func_t *osip_realloc_func = 0;
00111 osip_free_func_t *osip_free_func = 0;
00112 #endif
00113 
00114 #ifndef WIN32_USE_CRYPTO
00115 unsigned int
00116 osip_build_random_number ()
00117 #else
00118 static unsigned int
00119 osip_fallback_random_number ()
00120 #endif
00121 {
00122   if (!random_seed_set)
00123     {
00124       unsigned int ticks;
00125 
00126 #ifdef __PALMOS__
00127 #       if __PALMOS__ < 0x06000000
00128       SysRandom ((Int32) TimGetTicks ());
00129 #       else
00130       struct timeval tv;
00131 
00132       gettimeofday (&tv, NULL);
00133       srand (tv.tv_usec);
00134       ticks = tv.tv_sec + tv.tv_usec;
00135 #       endif
00136 #elif defined(WIN32)
00137       LARGE_INTEGER lCount;
00138 
00139       QueryPerformanceCounter (&lCount);
00140       ticks = lCount.LowPart + lCount.HighPart;
00141 #elif defined(_WIN32_WCE)
00142       ticks = GetTickCount ();
00143 #elif defined(__PSOS__)
00144 #elif defined(__VXWORKS_OS__)
00145       struct timespec tp;
00146 
00147       clock_gettime (CLOCK_REALTIME, &tp);
00148       ticks = tp.tv_sec + tp.tv_nsec;
00149 #else
00150       struct timeval tv;
00151       int fd;
00152 
00153       gettimeofday (&tv, NULL);
00154       ticks = tv.tv_sec + tv.tv_usec;
00155       fd = open ("/dev/urandom", O_RDONLY);
00156       if (fd > 0)
00157         {
00158           unsigned int r;
00159           int i;
00160 
00161           for (i = 0; i < 512; i++)
00162             {
00163               read (fd, &r, sizeof (r));
00164               ticks += r;
00165             }
00166           close (fd);
00167         }
00168 #endif
00169 
00170 #ifdef HAVE_LRAND48
00171       srand48 (ticks);
00172 #else
00173       srand (ticks);
00174 #endif
00175       random_seed_set = 1;
00176     }
00177 #ifdef HAVE_LRAND48
00178   return lrand48 ();
00179 #else
00180   return rand ();
00181 #endif
00182 }
00183 
00184 #ifdef WIN32_USE_CRYPTO
00185 
00186 unsigned int
00187 osip_build_random_number ()
00188 {
00189   HCRYPTPROV crypto;
00190   BOOL err;
00191   unsigned int num;
00192 
00193   err =
00194     CryptAcquireContext (&crypto, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
00195   if (err)
00196     {
00197       err = CryptGenRandom (crypto, sizeof (num), (BYTE *) & num);
00198       CryptReleaseContext (crypto, 0);
00199     }
00200   if (!err)
00201     {
00202       num = osip_fallback_random_number ();
00203     }
00204   return num;
00205 }
00206 
00207 #endif
00208 
00209 #if defined(__linux)
00210 #include <limits.h>
00211 #endif
00212 
00213 int
00214 osip_atoi (const char *number)
00215 {
00216 #if defined(__linux) || defined(HAVE_STRTOL)
00217   int i;
00218 
00219   if (number == NULL)
00220     return -1;
00221   i = strtol (number, (char **) NULL, 10);
00222   if (i == LONG_MIN || i == LONG_MAX)
00223     return -1;
00224   return i;
00225 #endif
00226 
00227   return atoi (number);
00228 }
00229 
00230 char *
00231 osip_strncpy (char *dest, const char *src, size_t length)
00232 {
00233   strncpy (dest, src, length);
00234   dest[length] = '\0';
00235   return dest;
00236 }
00237 
00238 /* append string_osip_to_append to string at position cur
00239    size is the current allocated size of the element
00240 */
00241 char *
00242 __osip_sdp_append_string (char *string, size_t size, char *cur,
00243                           char *string_osip_to_append)
00244 {
00245   size_t length = strlen (string_osip_to_append);
00246 
00247   if (cur - string + length > size)
00248     {
00249       size_t length2;
00250 
00251       length2 = cur - string;
00252       string = osip_realloc (string, size + length + 10);
00253       cur = string + length2;   /* the initial allocation may have changed! */
00254     }
00255   osip_strncpy (cur, string_osip_to_append, length);
00256   return cur + strlen (cur);
00257 }
00258 
00259 void
00260 osip_usleep (int useconds)
00261 {
00262 #if defined(__PALMOS__) && (__PALMOS__ >= 0x06000000)
00263   /* This bit will work for the Protein API, but not the Palm 68K API */
00264   nsecs_t nanoseconds = useconds * 1000;
00265 
00266   SysThreadDelay (nanoseconds, P_ABSOLUTE_TIMEOUT);
00267 #elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000)
00268   UInt32 stoptime = TimGetTicks () + (useconds / 1000000) * SysTicksPerSecond ();
00269 
00270   while (stoptime > TimGetTicks ())
00271     /* I wish there was some type of yield function here */
00272     ;
00273 #elif defined(WIN32)
00274   Sleep (useconds / 1000);
00275 #else
00276   struct timeval delay;
00277   int sec;
00278 
00279   sec = (int) useconds / 1000000;
00280   if (sec > 0)
00281     {
00282       delay.tv_sec = sec;
00283       delay.tv_usec = 0;
00284   } else
00285     {
00286       delay.tv_sec = 0;
00287       delay.tv_usec = useconds;
00288     }
00289   select (0, 0, 0, 0, &delay);
00290 #endif
00291 }
00292 
00293 #undef osip_strdup
00294 
00295 char *
00296 osip_strdup (const char *ch)
00297 {
00298   char *copy;
00299   size_t length;
00300 
00301   if (ch == NULL)
00302     return NULL;
00303   length = strlen (ch);
00304   copy = (char *) osip_malloc (length + 1);
00305   osip_strncpy (copy, ch, length);
00306   return copy;
00307 }
00308 
00309 char *
00310 osip_strdup_without_quote (const char *ch)
00311 {
00312   char *copy = (char *) osip_malloc (strlen (ch) + 1);
00313 
00314   /* remove leading and trailing " */
00315   if ((*ch == '\"'))
00316     {
00317       osip_strncpy (copy, ch + 1, strlen (ch + 1));
00318       osip_strncpy (copy + strlen (copy) - 1, "\0", 1);
00319   } else
00320     osip_strncpy (copy, ch, strlen (ch));
00321   return copy;
00322 }
00323 
00324 int
00325 osip_tolower (char *word)
00326 {
00327 #ifdef HAVE_CTYPE_H
00328   for (; *word; word++)
00329     *word = (char) tolower (*word);
00330 #else
00331   size_t i;
00332   size_t len = strlen (word);
00333 
00334   for (i = 0; i <= len - 1; i++)
00335     {
00336       if ('A' <= word[i] && word[i] <= 'Z')
00337         word[i] = word[i] + 32;
00338     }
00339 #endif
00340   return 0;
00341 }
00342 
00343 int
00344 osip_strcasecmp (const char *s1, const char *s2)
00345 {
00346 #if defined(__VXWORKS_OS__) || defined( __PSOS__)
00347   while ((*s1 != '\0') && (tolower (*s1) == tolower (*s2)))
00348     {
00349       s1++;
00350       s2++;
00351     }
00352   return (tolower (*s1) - tolower (*s2));
00353 #elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000)
00354   return StrCaselessCompare (s1, s2);
00355 #elif defined(__PALMOS__) || (!defined WIN32 && !defined _WIN32_WCE)
00356   return strcasecmp (s1, s2);
00357 #else
00358   return _stricmp (s1, s2);
00359 #endif
00360 }
00361 
00362 int
00363 osip_strncasecmp (const char *s1, const char *s2, size_t len)
00364 {
00365 #if defined(__VXWORKS_OS__) || defined( __PSOS__)
00366   if (len == 0)
00367     return 0;
00368   while ((len > 0) && (tolower (*s1) == tolower (*s2)))
00369     {
00370       len--;
00371       if ((len == 0) || (*s1 == '\0') || (*s2 == '\0'))
00372         break;
00373       s1++;
00374       s2++;
00375     }
00376   return tolower (*s1) - tolower (*s2);
00377 #elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000)
00378   return StrNCaselessCompare (s1, s2, len);
00379 #elif defined(__PALMOS__) || (!defined WIN32 && !defined _WIN32_WCE)
00380   return strncasecmp (s1, s2, len);
00381 #else
00382   return _strnicmp (s1, s2, len);
00383 #endif
00384 }
00385 
00386 /* remove SPACE before and after the content */
00387 int
00388 osip_clrspace (char *word)
00389 {
00390   char *pbeg;
00391   char *pend;
00392   size_t len;
00393 
00394   if (word == NULL)
00395     return -1;
00396   if (*word == '\0')
00397     return 0;
00398   len = strlen (word);
00399 
00400   pbeg = word;
00401   while ((' ' == *pbeg) || ('\r' == *pbeg) || ('\n' == *pbeg) || ('\t' == *pbeg))
00402     pbeg++;
00403 
00404   pend = word + len - 1;
00405   while ((' ' == *pend) || ('\r' == *pend) || ('\n' == *pend) || ('\t' == *pend))
00406     {
00407       pend--;
00408       if (pend < pbeg)
00409         {
00410           *word = '\0';
00411           return 0;
00412         }
00413     }
00414 
00415   /* Add terminating NULL only if we've cleared room for it */
00416   if (pend + 1 <= word + (len - 1))
00417     pend[1] = '\0';
00418 
00419   if (pbeg != word)
00420     memmove (word, pbeg, pend - pbeg + 2);
00421 
00422   return 0;
00423 }
00424 
00425 /* __osip_set_next_token:
00426    dest is the place where the value will be allocated
00427    buf is the string where the value is searched
00428    end_separator is the character that MUST be found at the end of the value
00429    next is the final location of the separator + 1
00430 
00431    the element MUST be found before any "\r" "\n" "\0" and
00432    end_separator
00433 
00434    return -1 on error
00435    return 1 on success
00436 */
00437 int
00438 __osip_set_next_token (char **dest, char *buf, int end_separator, char **next)
00439 {
00440   char *sep;                    /* separator */
00441 
00442   *next = NULL;
00443 
00444   sep = buf;
00445   while ((*sep != end_separator) && (*sep != '\0') && (*sep != '\r')
00446          && (*sep != '\n'))
00447     sep++;
00448   if ((*sep == '\r') || (*sep == '\n'))
00449     {                           /* we should continue normally only if this is the separator asked! */
00450       if (*sep != end_separator)
00451         return -1;
00452     }
00453   if (*sep == '\0')
00454     return -1;                  /* value must not end with this separator! */
00455   if (sep == buf)
00456     return -1;                  /* empty value (or several space!) */
00457 
00458   *dest = osip_malloc (sep - (buf) + 1);
00459   osip_strncpy (*dest, buf, sep - buf);
00460 
00461   *next = sep + 1;              /* return the position right after the separator */
00462   return 0;
00463 }
00464 
00465 #if 0
00466 /*  not yet done!!! :-)
00467  */
00468 int
00469 __osip_set_next_token_better (char **dest, char *buf, int end_separator,
00470                               int *forbidden_tab[], int size_tab, char **next)
00471 {
00472   char *sep;                    /* separator */
00473 
00474   *next = NULL;
00475 
00476   sep = buf;
00477   while ((*sep != end_separator) && (*sep != '\0') && (*sep != '\r')
00478          && (*sep != '\n'))
00479     sep++;
00480   if ((*sep == '\r') && (*sep == '\n'))
00481     {                           /* we should continue normally only if this is the separator asked! */
00482       if (*sep != end_separator)
00483         return -1;
00484     }
00485   if (*sep == '\0')
00486     return -1;                  /* value must not end with this separator! */
00487   if (sep == buf)
00488     return -1;                  /* empty value (or several space!) */
00489 
00490   *dest = osip_malloc (sep - (buf) + 1);
00491   osip_strncpy (*dest, buf, sep - buf);
00492 
00493   *next = sep + 1;              /* return the position right after the separator */
00494   return 1;
00495 }
00496 #endif
00497 
00498 /* in quoted-string, many characters can be escaped...   */
00499 /* __osip_quote_find returns the next quote that is not escaped */
00500 char *
00501 __osip_quote_find (const char *qstring)
00502 {
00503   char *quote;
00504 
00505   quote = strchr (qstring, '"');
00506   if (quote == qstring)         /* the first char matches and is not escaped... */
00507     return quote;
00508 
00509   if (quote == NULL)
00510     return NULL;                /* no quote at all... */
00511 
00512   /* this is now the nasty cases where '"' is escaped
00513      '" jonathan ros \\\""'
00514      |                  |
00515      '" jonathan ros \\"'
00516      |                |
00517      '" jonathan ros \""'
00518      |                |
00519      we must count the number of preceeding '\' */
00520   {
00521     int i = 1;
00522 
00523     for (;;)
00524       {
00525         if (0 == strncmp (quote - i, "\\", 1))
00526           i++;
00527         else
00528           {
00529             if (i % 2 == 1)     /* the '"' was not escaped */
00530               return quote;
00531 
00532             /* else continue with the next '"' */
00533             quote = strchr (quote + 1, '"');
00534             if (quote == NULL)
00535               return NULL;
00536             i = 1;
00537           }
00538         if (quote - i == qstring - 1)
00539           /* example: "\"john"  */
00540           /* example: "\\"jack" */
00541           {
00542             /* special case where the string start with '\' */
00543             if (*qstring == '\\')
00544               i++;              /* an escape char was not counted */
00545             if (i % 2 == 0)     /* the '"' was not escaped */
00546               return quote;
00547             else
00548               {                 /* else continue with the next '"' */
00549                 qstring = quote + 1;    /* reset qstring because
00550                                            (*quote+1) may be also == to '\\' */
00551                 quote = strchr (quote + 1, '"');
00552                 if (quote == NULL)
00553                   return NULL;
00554                 i = 1;
00555               }
00556 
00557           }
00558       }
00559     return NULL;
00560   }
00561 }
00562 
00563 char *
00564 osip_enquote (const char *s)
00565 {
00566   char *rtn;
00567   char *t;
00568 
00569   t = rtn = osip_malloc (strlen (s) * 2 + 3);
00570   *t++ = '"';
00571   for (; *s != '\0'; s++)
00572     {
00573       switch (*s)
00574         {
00575           case '"':
00576           case '\\':
00577           case 0x7f:
00578             *t++ = '\\';
00579             *t++ = *s;
00580             break;
00581           case '\n':
00582           case '\r':
00583             *t++ = ' ';
00584             break;
00585           default:
00586             *t++ = *s;
00587             break;
00588         }
00589     }
00590   *t++ = '"';
00591   *t++ = '\0';
00592   return rtn;
00593 }
00594 
00595 void
00596 osip_dequote (char *s)
00597 {
00598   size_t len;
00599 
00600   if (*s == '\0')
00601     return;
00602   if (*s != '"')
00603     return;
00604   len = strlen (s);
00605   memmove (s, s + 1, len--);
00606   if (len > 0 && s[len - 1] == '"')
00607     s[--len] = '\0';
00608   for (; *s != '\0'; s++, len--)
00609     {
00610       if (*s == '\\')
00611         memmove (s, s + 1, len--);
00612     }
00613 }
00614 
00615 /**********************************************************/
00616 /* only MACROS from osip/trace.h should be used by others */
00617 /* TRACE_INITIALIZE(level,file))                          */
00618 /* TRACE_ENABLE_LEVEL(level)                              */
00619 /* TRACE_DISABLE_LEVEL(level)                             */
00620 /* IS_TRACE_LEVEL_ACTIVATE(level)                         */
00621 /**********************************************************/
00622 #ifndef ENABLE_TRACE
00623 void
00624 osip_trace_initialize_func (osip_trace_level_t level, osip_trace_func_t * func)
00625 {
00626 }
00627 void
00628 osip_trace_initialize_syslog (osip_trace_level_t level, char *ident)
00629 {
00630 }
00631 void
00632 osip_trace_initialize (osip_trace_level_t level, FILE * file)
00633 {
00634 }
00635 void
00636 osip_trace_enable_level (osip_trace_level_t level)
00637 {
00638 }
00639 void
00640 osip_trace_disable_level (osip_trace_level_t level)
00641 {
00642 }
00643 
00644 int
00645 osip_is_trace_level_activate (osip_trace_level_t level)
00646 {
00647   return LOG_FALSE;
00648 }
00649 
00650 #else
00651 
00652 /* initialize log */
00653 /* all lower levels of level are logged in file. */
00654 void
00655 osip_trace_initialize (osip_trace_level_t level, FILE * file)
00656 {
00657   osip_trace_level_t i = 0;
00658 
00659   /* enable trace in log file by default */
00660   logfile = NULL;
00661   if (file != NULL)
00662     logfile = file;
00663 #ifndef SYSTEM_LOGGER_ENABLED
00664   else
00665     logfile = stdout;
00666 #endif
00667 
00668   /* enable all lower levels */
00669   while (i < END_TRACE_LEVEL)
00670     {
00671       if (i < level)
00672         tracing_table[i] = LOG_TRUE;
00673       else
00674         tracing_table[i] = LOG_FALSE;
00675       i++;
00676     }
00677 }
00678 
00679 void
00680 osip_trace_initialize_syslog (osip_trace_level_t level, char *ident)
00681 {
00682   osip_trace_level_t i = 0;
00683 
00684 #if defined (HAVE_SYSLOG_H)
00685   openlog (ident, LOG_CONS | LOG_PID, LOG_DAEMON);
00686   use_syslog = 1;
00687 #endif
00688   /* enable all lower levels */
00689   while (i < END_TRACE_LEVEL)
00690     {
00691       if (i < level)
00692         tracing_table[i] = LOG_TRUE;
00693       else
00694         tracing_table[i] = LOG_FALSE;
00695       i++;
00696     }
00697 }
00698 
00699 void
00700 osip_trace_enable_until_level (osip_trace_level_t level)
00701 {
00702   int i = 0;
00703 
00704   while (i < END_TRACE_LEVEL)
00705     {
00706       if (i < level)
00707         tracing_table[i] = LOG_TRUE;
00708       else
00709         tracing_table[i] = LOG_FALSE;
00710       i++;
00711     }
00712 }
00713 
00714 void
00715 osip_trace_initialize_func (osip_trace_level_t level, osip_trace_func_t * func)
00716 {
00717   int i = 0;
00718 
00719   trace_func = func;
00720 
00721   /* enable all lower levels */
00722   while (i < END_TRACE_LEVEL)
00723     {
00724       if (i < level)
00725         tracing_table[i] = LOG_TRUE;
00726       else
00727         tracing_table[i] = LOG_FALSE;
00728       i++;
00729     }
00730 }
00731 
00732 /* enable a special debugging level! */
00733 void
00734 osip_trace_enable_level (osip_trace_level_t level)
00735 {
00736   tracing_table[level] = LOG_TRUE;
00737 }
00738 
00739 /* disable a special debugging level! */
00740 void
00741 osip_trace_disable_level (osip_trace_level_t level)
00742 {
00743   tracing_table[level] = LOG_FALSE;
00744 }
00745 
00746 /* not so usefull? */
00747 int
00748 osip_is_trace_level_activate (osip_trace_level_t level)
00749 {
00750   return tracing_table[level];
00751 }
00752 #endif
00753 
00754 int
00755 osip_trace (char *fi, int li, osip_trace_level_t level, FILE * f, char *chfr, ...)
00756 {
00757 #ifdef ENABLE_TRACE
00758   va_list ap;
00759 
00760 #if !defined(WIN32) && !defined(SYSTEM_LOGGER_ENABLED)
00761   if (logfile == NULL && use_syslog == 0 && trace_func == NULL)
00762     {                           /* user did not initialize logger.. */
00763       return 1;
00764     }
00765 #endif
00766 
00767   if (tracing_table[level] == LOG_FALSE)
00768     return 0;
00769 
00770   if (f == NULL && trace_func == NULL)
00771     f = logfile;
00772 
00773   VA_START (ap, chfr);
00774 
00775 #ifdef __VXWORKS_OS__
00776   /* vxworks can't have a local file */
00777   f = stdout;
00778 #endif
00779 
00780   if (f && use_syslog == 0)
00781     {
00782       if (level == OSIP_FATAL)
00783         fprintf (f, "| FATAL | <%s: %i> ", fi, li);
00784       else if (level == OSIP_BUG)
00785         fprintf (f, "|  BUG  | <%s: %i> ", fi, li);
00786       else if (level == OSIP_ERROR)
00787         fprintf (f, "| ERROR | <%s: %i> ", fi, li);
00788       else if (level == OSIP_WARNING)
00789         fprintf (f, "|WARNING| <%s: %i> ", fi, li);
00790       else if (level == OSIP_INFO1)
00791         fprintf (f, "| INFO1 | <%s: %i> ", fi, li);
00792       else if (level == OSIP_INFO2)
00793         fprintf (f, "| INFO2 | <%s: %i> ", fi, li);
00794       else if (level == OSIP_INFO3)
00795         fprintf (f, "| INFO3 | <%s: %i> ", fi, li);
00796       else if (level == OSIP_INFO4)
00797         fprintf (f, "| INFO4 | <%s: %i> ", fi, li);
00798 
00799       vfprintf (f, chfr, ap);
00800 
00801       fflush (f);
00802   } else if (trace_func)
00803     {
00804       trace_func (fi, li, level, chfr, ap);
00805     }
00806 #if defined (HAVE_SYSLOG_H)
00807   else if (use_syslog == 1)
00808     {
00809       char buffer[512];
00810       int in = 0;
00811 
00812       memset (buffer, 0, sizeof (buffer));
00813       if (level == OSIP_FATAL)
00814         in = snprintf (buffer, 511, "| FATAL | <%s: %i> ", fi, li);
00815       else if (level == OSIP_BUG)
00816         in = snprintf (buffer, 511, "|  BUG  | <%s: %i> ", fi, li);
00817       else if (level == OSIP_ERROR)
00818         in = snprintf (buffer, 511, "| ERROR | <%s: %i> ", fi, li);
00819       else if (level == OSIP_WARNING)
00820         in = snprintf (buffer, 511, "|WARNING| <%s: %i> ", fi, li);
00821       else if (level == OSIP_INFO1)
00822         in = snprintf (buffer, 511, "| INFO1 | <%s: %i> ", fi, li);
00823       else if (level == OSIP_INFO2)
00824         in = snprintf (buffer, 511, "| INFO2 | <%s: %i> ", fi, li);
00825       else if (level == OSIP_INFO3)
00826         in = snprintf (buffer, 511, "| INFO3 | <%s: %i> ", fi, li);
00827       else if (level == OSIP_INFO4)
00828         in = snprintf (buffer, 511, "| INFO4 | <%s: %i> ", fi, li);
00829 
00830       vsnprintf (buffer + in, 511 - in, chfr, ap);
00831       if (level == OSIP_FATAL)
00832         syslog (LOG_ERR, "%s", buffer);
00833       else if (level == OSIP_BUG)
00834         syslog (LOG_ERR, "%s", buffer);
00835       else if (level == OSIP_ERROR)
00836         syslog (LOG_ERR, "%s", buffer);
00837       else if (level == OSIP_WARNING)
00838         syslog (LOG_WARNING, "%s", buffer);
00839       else if (level == OSIP_INFO1)
00840         syslog (LOG_INFO, "%s", buffer);
00841       else if (level == OSIP_INFO2)
00842         syslog (LOG_INFO, "%s", buffer);
00843       else if (level == OSIP_INFO3)
00844         syslog (LOG_DEBUG, "%s", buffer);
00845       else if (level == OSIP_INFO4)
00846         syslog (LOG_DEBUG, "%s", buffer);
00847     }
00848 #endif
00849 #ifdef SYSTEM_LOGGER_ENABLED
00850   else
00851     {
00852       char buffer[512];
00853       int in = 0;
00854 
00855       memset (buffer, 0, sizeof (buffer));
00856       if (level == OSIP_FATAL)
00857         in = _snprintf (buffer, 511, "| FATAL | <%s: %i> ", fi, li);
00858       else if (level == OSIP_BUG)
00859         in = _snprintf (buffer, 511, "|  BUG  | <%s: %i> ", fi, li);
00860       else if (level == OSIP_ERROR)
00861         in = _snprintf (buffer, 511, "| ERROR | <%s: %i> ", fi, li);
00862       else if (level == OSIP_WARNING)
00863         in = _snprintf (buffer, 511, "|WARNING| <%s: %i> ", fi, li);
00864       else if (level == OSIP_INFO1)
00865         in = _snprintf (buffer, 511, "| INFO1 | <%s: %i> ", fi, li);
00866       else if (level == OSIP_INFO2)
00867         in = _snprintf (buffer, 511, "| INFO2 | <%s: %i> ", fi, li);
00868       else if (level == OSIP_INFO3)
00869         in = _snprintf (buffer, 511, "| INFO3 | <%s: %i> ", fi, li);
00870       else if (level == OSIP_INFO4)
00871         in = _snprintf (buffer, 511, "| INFO4 | <%s: %i> ", fi, li);
00872 
00873       _vsnprintf (buffer + in, 511 - in, chfr, ap);
00874       OutputDebugString (buffer);
00875     }
00876 #endif
00877 
00878   va_end (ap);
00879 #endif
00880   return 0;
00881 }
00882 
00883 
00884 
00885 #ifdef WIN32
00886 
00887 #undef osip_malloc
00888 void *
00889 osip_malloc (size_t size)
00890 {
00891   void *ptr = malloc (size);
00892 
00893   if (ptr != NULL)
00894     memset (ptr, 0, size);
00895   return ptr;
00896 }
00897 
00898 #undef osip_realloc
00899 void *
00900 osip_realloc (void *ptr, size_t size)
00901 {
00902   return realloc (ptr, size);
00903 }
00904 
00905 #undef osip_free
00906 void
00907 osip_free (void *ptr)
00908 {
00909   if (ptr == NULL)
00910     return;
00911   free (ptr);
00912 }
00913 
00914 #else
00915 
00916 void
00917 osip_set_allocators (osip_malloc_func_t * malloc_func,
00918                      osip_realloc_func_t * realloc_func,
00919                      osip_free_func_t * free_func)
00920 {
00921   osip_malloc_func = malloc_func;
00922   osip_realloc_func = realloc_func;
00923   osip_free_func = free_func;
00924 }
00925 
00926 #endif
00927 
00928 #if defined(__VXWORKS_OS__)
00929 
00930 typedef struct
00931 {
00932   char *str;
00933   int max;
00934   int len;
00935 } _context;
00936 
00937 STATUS _cb_snprintf (char *buffer, int nc, int arg);
00938 
00939 STATUS
00940 _cb_snprintf (char *buffer, int nc, int arg)
00941 {
00942   _context *ctx = (_context *) arg;
00943 
00944   if (ctx->max - ctx->len - nc < 1)     /* retain 1 pos for terminating \0 */
00945     {
00946       nc = ctx->max - ctx->len - 1;
00947     }
00948 
00949   if (nc > 0)
00950     {
00951       memcpy (ctx->str + ctx->len, buffer, nc);
00952       ctx->len += nc;
00953     }
00954 
00955   ctx->str[ctx->len] = '\0';
00956 
00957   return OK;
00958 }
00959 
00960 
00961 int
00962 osip_vsnprintf (char *buf, int max, const char *fmt, va_list ap)
00963 {
00964   _context ctx;
00965 
00966   ctx.str = buf;
00967   ctx.max = max;
00968   ctx.len = 0;
00969 
00970   if (fioFormatV (fmt, ap, _cb_snprintf, (int) &ctx) != OK)
00971     {
00972       return -1;
00973     }
00974 
00975   return ctx.len;
00976 }
00977 
00978 int
00979 osip_snprintf (char *buf, int max, const char *fmt, ...)
00980 {
00981   int retval;
00982   va_list ap;
00983 
00984   va_start (ap, fmt);
00985   retval = osip_vsnprintf (buf, max, fmt, ap);
00986   va_end (ap);
00987   return retval;
00988 }
00989 
00990 #endif
00991 
00992 
00993 #if defined(__PSOS__)
00994 
00995 int
00996 osip_snprintf (char *buf, int max, const char *fmt, ...)
00997 {
00998   static char buffer[1024];
00999   int retval;
01000   va_list ap;
01001 
01002   buffer[0] = '\n';
01003   va_start (ap, fmt);
01004   vsprintf (&(buffer[strlen (buffer)]), fmt, ap);
01005   va_end (ap);
01006   retval = strlen (buffer);
01007   memmove (buf, buffer, max);
01008   if (retval > max)
01009     return -1;
01010   return retval;
01011 }
01012 
01013 #endif
01014 
01015 #ifdef DEBUG_MEM
01016 
01017 /*
01018   This is a debug facility for detecting memory leaks.
01019   I recommend to use external tools such as mpatrol
01020   when possible. On some fancy platform, you may not
01021   have any usefull tools: in this case, use this code!
01022  */
01023 
01024 void *
01025 _osip_malloc (size_t size, char *file, unsigned short line)
01026 {
01027   void *mem;
01028 
01029   mem = osip_malloc_func (size + 20);
01030   if (mem != NULL)
01031     {
01032       char *s;
01033 
01034       memcpy (mem, &line, 2);
01035       for (s = file + strlen (file); s != file; s--)
01036         {
01037           if (*s == '\\' || *s == '/')
01038             {
01039               s++;
01040               break;
01041             }
01042         }
01043       strncpy ((char *) mem + 2, s, 18);
01044       return (void *) ((char *) mem + 20);
01045     }
01046   return NULL;
01047 }
01048 
01049 void
01050 _osip_free (void *ptr)
01051 {
01052   if (ptr != NULL)
01053     {
01054       osip_free_func ((char *) ptr - 20);
01055     }
01056 }
01057 
01058 void *
01059 _osip_realloc (void *ptr, size_t size, char *file, unsigned short line)
01060 {
01061   void *mem;
01062 
01063   mem = osip_realloc_func ((char *) ptr - 20, size + 20);
01064   if (mem != NULL)
01065     {
01066       char *s;
01067 
01068       memcpy (mem, &line, 2);
01069 
01070       for (s = file + strlen (file); s != file; s--)
01071         {
01072           if (*s == '\\' || *s == '/')
01073             {
01074               s++;
01075               break;
01076             }
01077         }
01078       strncpy ((char *) mem + 2, s, 18);
01079       return (char *) mem + 20;
01080     }
01081   return NULL;
01082 }
01083 
01084 #endif
01085 
01086 
01087 /* ---For better performance---
01088    Calculates a hash value for the given string */
01089 unsigned long
01090 osip_hash (const char *str)
01091 {
01092   unsigned long hash = 5381;
01093   int c;
01094 
01095   while (c = *str++)
01096     hash = ((hash << 5) + hash) + c;
01097 
01098   return hash;
01099 }
01100 
01101 /* ---For better performance---
01102    Appends src-string to dst-string.
01103    
01104    This was introduced to replace the 
01105    inefficient constructions like:
01106    
01107    osip_strncpy (tmp, src, strlen(src) );
01108    tmp = tmp + strlen (src);
01109    
01110    This function returns a pointer to the
01111    end of the destination string
01112    
01113    Pre: src is null terminated */
01114 char *
01115 osip_str_append (char *dst, const char *src)
01116 {
01117   while (*src != '\0')
01118     {
01119       *dst = *src;
01120       src++;
01121       dst++;
01122     }
01123   *dst = '\0';
01124   return dst;
01125 }
01126 
01127 /* ---For better performance---
01128    Same as above, only this time we know the length */
01129 char *
01130 osip_strn_append (char *dst, const char *src, size_t len)
01131 {
01132   memmove ((void *) dst, (void *) src, len);
01133   dst += len;
01134   *dst = '\0';
01135   return dst;
01136 }
01137 
01138 
01139 /* ---For better performance---
01140    This is to replace this construction:
01141    osip_strncpy (  dest, source, length);
01142    osip_clrspace ( dest ); */
01143 char *
01144 osip_clrncpy (char *dst, const char *src, size_t len)
01145 {
01146   const char *pbeg;
01147   const char *pend;
01148   char *p;
01149   size_t spaceless_length;
01150 
01151   if (src == NULL)
01152     return NULL;
01153 
01154   /* find the start of relevant text */
01155   pbeg = src;
01156   while ((' ' == *pbeg) || ('\r' == *pbeg) || ('\n' == *pbeg) || ('\t' == *pbeg))
01157     pbeg++;
01158 
01159 
01160   /* find the end of relevant text */
01161   pend = src + len - 1;
01162   while ((' ' == *pend) || ('\r' == *pend) || ('\n' == *pend) || ('\t' == *pend))
01163     {
01164       pend--;
01165       if (pend < pbeg)
01166         {
01167           *dst = '\0';
01168           return dst;
01169         }
01170     }
01171 
01172   /* if pend == pbeg there is only one char to copy */
01173   spaceless_length = pend - pbeg + 1;   /* excluding any '\0' */
01174   memmove (dst, pbeg, spaceless_length);
01175   p = dst + spaceless_length;
01176 
01177   /* terminate the string and pad dest with zeros until len */
01178   do
01179     {
01180       *p = '\0';
01181       p++;
01182       spaceless_length++;
01183     }
01184   while (spaceless_length < len);
01185 
01186   return dst;
01187 }

Generated on Fri Mar 9 19:59:55 2007 for MAD-FCL by  doxygen 1.5.0