📄 osip_port.c
字号:
/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Aymeric MOIZARD jack@atosc.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#ifdef _WIN32_WCE#define _INC_TIME /* for wce.h */#include <windows.h>#endif#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <osipparser2/osip_port.h>#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef HAVE_CTYPE_H#include <ctype.h>#endif#if defined(__PALMOS__) && (__PALMOS__ < 0x06000000)# include <TimeMgr.h># include <SysUtils.h># include <SystemMgr.h># include <StringMgr.h>#else# include <time.h>#endif#if defined(__VXWORKS_OS__)#include <selectLib.h>/* needed for snprintf replacement */#include <vxWorks.h>#include <fioLib.h>#include <string.h>#elif defined(__PALMOS__)# if __PALMOS__ >= 0x06000000# include <sys/time.h># include <SysThread.h># endif#elif (!defined(WIN32) && !defined(_WIN32_WCE))#include <sys/time.h>#elif defined(WIN32)#include <windows.h>#ifdef WIN32_USE_CRYPTO#include <Wincrypt.h>#endif#endif#if defined (__rtems__)#include <rtems.h>#endif #if defined (HAVE_SYS_UNISTD_H)# include <sys/unistd.h>#endif#if defined (HAVE_UNISTD_H)# include <unistd.h>#endif#if defined (HAVE_SYSLOG_H) && !defined(__arc__)# include <syslog.h>#endif#if defined (HAVE_SYS_SELECT_H)# include <sys/select.h>#endif#ifdef HAVE_PTH_PTHREAD_H#include <pthread.h>#endif#if defined(__arc__)#define HAVE_LRAND48#endifFILE *logfile = NULL;int tracing_table[END_TRACE_LEVEL];static int use_syslog = 0;static osip_trace_func_t *trace_func = 0;static unsigned int random_seed_set = 0;#ifndef MINISIZE#if !defined(WIN32) && !defined(_WIN32_WCE)osip_malloc_func_t *osip_malloc_func = 0;osip_realloc_func_t *osip_realloc_func = 0;osip_free_func_t *osip_free_func = 0;#endif#endif#ifndef WIN32_USE_CRYPTOunsigned intosip_build_random_number ()#elsestatic unsigned intosip_fallback_random_number ()#endif{ if (!random_seed_set) { unsigned int ticks;#ifdef __PALMOS__# if __PALMOS__ < 0x06000000 SysRandom ((Int32) TimGetTicks ());# else struct timeval tv; gettimeofday (&tv, NULL); srand (tv.tv_usec); ticks = tv.tv_sec + tv.tv_usec;# endif#elif defined(WIN32) LARGE_INTEGER lCount; QueryPerformanceCounter (&lCount); ticks = lCount.LowPart + lCount.HighPart;#elif defined(_WIN32_WCE) ticks = GetTickCount ();#elif defined(__PSOS__)#elif defined(__rtems__) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &ticks);#elif defined(__VXWORKS_OS__) struct timespec tp; clock_gettime (CLOCK_REALTIME, &tp); ticks = tp.tv_sec + tp.tv_nsec;#else struct timeval tv; int fd; gettimeofday (&tv, NULL); ticks = tv.tv_sec + tv.tv_usec; fd = open ("/dev/urandom", O_RDONLY); if (fd > 0) { unsigned int r; int i; for (i = 0; i < 512; i++) { read (fd, &r, sizeof (r)); ticks += r; } close (fd); }#endif#ifdef HAVE_LRAND48 srand48 (ticks);#else srand (ticks);#endif random_seed_set = 1; }#ifdef HAVE_LRAND48 { int val = lrand48(); if (val==0) { unsigned int ticks; struct timeval tv; gettimeofday (&tv, NULL); ticks = tv.tv_sec + tv.tv_usec; srand48 (ticks); return lrand48 (); } return val; }#else return rand ();#endif}#ifdef WIN32_USE_CRYPTOunsigned intosip_build_random_number (){ HCRYPTPROV crypto; BOOL err; unsigned int num; err = CryptAcquireContext (&crypto, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (err) { err = CryptGenRandom (crypto, sizeof (num), (BYTE *) & num); CryptReleaseContext (crypto, 0); } if (!err) { num = osip_fallback_random_number (); } return num;}#endif#if defined(__linux)#include <limits.h>#endifchar *osip_strncpy (char *dest, const char *src, size_t length){ strncpy (dest, src, length); dest[length] = '\0'; return dest;}#undef osip_strdupchar *osip_strdup (const char *ch){ char *copy; size_t length; if (ch == NULL) return NULL; length = strlen (ch); copy = (char *) osip_malloc (length + 1); osip_strncpy (copy, ch, length); return copy;}#ifndef MINISIZEintosip_atoi (const char *number){#if defined(__linux) || defined(HAVE_STRTOL) int i; if (number == NULL) return -1; i = strtol (number, (char **) NULL, 10); if (i == LONG_MIN || i == LONG_MAX) return -1; return i;#endif return atoi (number);}#endif/* append string_osip_to_append to string at position cur size is the current allocated size of the element*/char *__osip_sdp_append_string (char *string, size_t size, char *cur, char *string_osip_to_append){ size_t length = strlen (string_osip_to_append); if (cur - string + length > size) { size_t length2; length2 = cur - string; string = osip_realloc (string, size + length + 10); cur = string + length2; /* the initial allocation may have changed! */ } osip_strncpy (cur, string_osip_to_append, length); return cur + strlen (cur);}voidosip_usleep (int useconds){#if defined(__PALMOS__) && (__PALMOS__ >= 0x06000000) /* This bit will work for the Protein API, but not the Palm 68K API */ nsecs_t nanoseconds = useconds * 1000; SysThreadDelay (nanoseconds, P_ABSOLUTE_TIMEOUT);#elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000) UInt32 stoptime = TimGetTicks () + (useconds / 1000000) * SysTicksPerSecond (); while (stoptime > TimGetTicks ()) /* I wish there was some type of yield function here */ ;#elif defined(WIN32) Sleep (useconds / 1000);#elif defined(__rtems__) rtems_task_wake_after( RTEMS_MICROSECONDS_TO_TICKS(useconds) );#elif defined(__arc__) struct timespec req; struct timespec rem; req.tv_sec = (int) useconds / 1000000; req.tv_nsec = (int) (useconds % 1000000)*1000; nanosleep (&req, &rem);#else struct timeval delay; int sec; sec = (int) useconds / 1000000; if (sec > 0) { delay.tv_sec = sec; delay.tv_usec = 0; } else { delay.tv_sec = 0; delay.tv_usec = useconds; } select (0, 0, 0, 0, &delay);#endif}char *osip_strdup_without_quote (const char *ch){ char *copy = (char *) osip_malloc (strlen (ch) + 1); /* remove leading and trailing " */ if ((*ch == '\"')) { osip_strncpy (copy, ch + 1, strlen (ch + 1)); osip_strncpy (copy + strlen (copy) - 1, "\0", 1); } else osip_strncpy (copy, ch, strlen (ch)); return copy;}intosip_tolower (char *word){#if defined(HAVE_CTYPE_H) && !defined (_WIN32_WCE) for (; *word; word++) *word = (char) tolower (*word);#else size_t i; size_t len = strlen (word); for (i = 0; i <= len - 1; i++) { if ('A' <= word[i] && word[i] <= 'Z') word[i] = word[i] + 32; }#endif return 0;}#ifndef MINISIZEintosip_strcasecmp (const char *s1, const char *s2){#if defined(__VXWORKS_OS__) || defined( __PSOS__) while ((*s1 != '\0') && (tolower (*s1) == tolower (*s2))) { s1++; s2++; } return (tolower (*s1) - tolower (*s2));#elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000) return StrCaselessCompare (s1, s2);#elif defined(__PALMOS__) || (!defined WIN32 && !defined _WIN32_WCE) return strcasecmp (s1, s2);#else return _stricmp (s1, s2);#endif}intosip_strncasecmp (const char *s1, const char *s2, size_t len){#if defined(__VXWORKS_OS__) || defined( __PSOS__) if (len == 0) return 0; while ((len > 0) && (tolower (*s1) == tolower (*s2))) { len--; if ((len == 0) || (*s1 == '\0') || (*s2 == '\0')) break; s1++; s2++; } return tolower (*s1) - tolower (*s2);#elif defined(__PALMOS__) && (__PALMOS__ < 0x06000000) return StrNCaselessCompare (s1, s2, len);#elif defined(__PALMOS__) || (!defined WIN32 && !defined _WIN32_WCE) return strncasecmp (s1, s2, len);#else return _strnicmp (s1, s2, len);#endif}#endif/* remove SPACE before and after the content */intosip_clrspace (char *word){ char *pbeg; char *pend; size_t len; if (word == NULL) return -1; if (*word == '\0') return 0; len = strlen (word); pbeg = word; while ((' ' == *pbeg) || ('\r' == *pbeg) || ('\n' == *pbeg) || ('\t' == *pbeg)) pbeg++; pend = word + len - 1; while ((' ' == *pend) || ('\r' == *pend) || ('\n' == *pend) || ('\t' == *pend)) { pend--; if (pend < pbeg) { *word = '\0'; return 0; } } /* Add terminating NULL only if we've cleared room for it */ if (pend + 1 <= word + (len - 1)) pend[1] = '\0'; if (pbeg != word) memmove (word, pbeg, pend - pbeg + 2); return 0;}/* __osip_set_next_token: dest is the place where the value will be allocated buf is the string where the value is searched end_separator is the character that MUST be found at the end of the value next is the final location of the separator + 1 the element MUST be found before any "\r" "\n" "\0" and end_separator return -1 on error return 1 on success*/int__osip_set_next_token (char **dest, char *buf, int end_separator, char **next){ char *sep; /* separator */ *next = NULL; sep = buf; while ((*sep != end_separator) && (*sep != '\0') && (*sep != '\r') && (*sep != '\n')) sep++; if ((*sep == '\r') || (*sep == '\n')) { /* we should continue normally only if this is the separator asked! */ if (*sep != end_separator) return -1; } if (*sep == '\0') return -1; /* value must not end with this separator! */ if (sep == buf) return -1; /* empty value (or several space!) */ *dest = osip_malloc (sep - (buf) + 1); osip_strncpy (*dest, buf, sep - buf); *next = sep + 1; /* return the position right after the separator */ return 0;}#if 0/* not yet done!!! :-) */int__osip_set_next_token_better (char **dest, char *buf, int end_separator, int *forbidden_tab[], int size_tab, char **next){ char *sep; /* separator */ *next = NULL; sep = buf; while ((*sep != end_separator) && (*sep != '\0') && (*sep != '\r') && (*sep != '\n')) sep++; if ((*sep == '\r') && (*sep == '\n')) { /* we should continue normally only if this is the separator asked! */ if (*sep != end_separator) return -1; } if (*sep == '\0') return -1; /* value must not end with this separator! */ if (sep == buf) return -1; /* empty value (or several space!) */ *dest = osip_malloc (sep - (buf) + 1); osip_strncpy (*dest, buf, sep - buf); *next = sep + 1; /* return the position right after the separator */ return 1;}#endif/* in quoted-string, many characters can be escaped... *//* __osip_quote_find returns the next quote that is not escaped */char *__osip_quote_find (const char *qstring){ char *quote; quote = strchr (qstring, '"'); if (quote == qstring) /* the first char matches and is not escaped... */ return quote; if (quote == NULL) return NULL; /* no quote at all... */ /* this is now the nasty cases where '"' is escaped '" jonathan ros \\\""' | | '" jonathan ros \\"' | | '" jonathan ros \""' | | we must count the number of preceeding '\' */ { int i = 1; for (;;) { if (0 == strncmp (quote - i, "\\", 1)) i++; else { if (i % 2 == 1) /* the '"' was not escaped */ return quote; /* else continue with the next '"' */ quote = strchr (quote + 1, '"'); if (quote == NULL) return NULL; i = 1; } if (quote - i == qstring - 1) /* example: "\"john" */ /* example: "\\"jack" */ { /* special case where the string start with '\' */ if (*qstring == '\\') i++; /* an escape char was not counted */ if (i % 2 == 0) /* the '"' was not escaped */ return quote; else { /* else continue with the next '"' */ qstring = quote + 1; /* reset qstring because (*quote+1) may be also == to '\\' */ quote = strchr (quote + 1, '"'); if (quote == NULL) return NULL; i = 1; } } } return NULL; }}char *osip_enquote (const char *s){ char *rtn; char *t; t = rtn = osip_malloc (strlen (s) * 2 + 3); *t++ = '"'; for (; *s != '\0'; s++) { switch (*s) { case '"': case '\\': case 0x7f: *t++ = '\\'; *t++ = *s; break; case '\n': case '\r': *t++ = ' '; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -