Module: sip-router
Branch: janakj/kcore
Commit: b38ce3c5b7b3cbe36c75422cd9aff7760ccb66b6
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=b38ce3c…
Author: Jan Janak <jan(a)iptel.org>
Committer: Jan Janak <jan(a)iptel.org>
Date: Tue Mar 3 17:10:47 2009 +0100
Moving strcommon.[ch] from kamailio core to libkcore
---
lib/kcore/strcommon.c | 369 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/kcore/strcommon.h | 54 +++++++
2 files changed, 423 insertions(+), 0 deletions(-)
diff --git a/lib/kcore/strcommon.c b/lib/kcore/strcommon.c
new file mode 100644
index 0000000..84c54bf
--- /dev/null
+++ b/lib/kcore/strcommon.c
@@ -0,0 +1,369 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2007 voice-system.ro
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+
+ */
+/*!
+ * \file
+ * \brief Generic string handling functions
+ */
+
+#include "../../ut.h"
+#include "strcommon.h"
+
+/*! \brief
+ * add backslashes to special characters
+ */
+int escape_common(char *dst, char *src, int src_len)
+{
+ int i, j;
+
+ if(dst==0 || src==0 || src_len<=0)
+ return 0;
+ j = 0;
+ for(i=0; i<src_len; i++)
+ {
+ switch(src[i])
+ {
+ case '\'':
+ dst[j++] = '\\';
+ dst[j++] = src[i];
+ break;
+ case '"':
+ dst[j++] = '\\';
+ dst[j++] = src[i];
+ break;
+ case '\\':
+ dst[j++] = '\\';
+ dst[j++] = src[i];
+ break;
+ case '\0':
+ dst[j++] = '\\';
+ dst[j++] = '0';
+ break;
+ default:
+ dst[j++] = src[i];
+ }
+ }
+ return j;
+}
+
+/*! \brief
+ * remove backslashes to special characters
+ */
+int unescape_common(char *dst, char *src, int src_len)
+{
+ int i, j;
+
+ if(dst==0 || src==0 || src_len<=0)
+ return 0;
+ j = 0;
+ i = 0;
+ while(i<src_len)
+ {
+ if(src[i]=='\\' && i+1<src_len)
+ {
+ switch(src[i+1])
+ {
+ case '\'':
+ dst[j++] = '\'';
+ i++;
+ break;
+ case '"':
+ dst[j++] = '"';
+ i++;
+ break;
+ case '\\':
+ dst[j++] = '\\';
+ i++;
+ break;
+ case '0':
+ dst[j++] = '\0';
+ i++;
+ break;
+ default:
+ dst[j++] = src[i];
+ }
+ } else {
+ dst[j++] = src[i];
+ }
+ i++;
+ }
+ return j;
+}
+
+/*! \brief Compute MD5 checksum */
+void compute_md5(char *dst, char *src, int src_len)
+{
+ MD5_CTX context;
+ unsigned char digest[16];
+ MD5Init (&context);
+ MD5Update (&context, src, src_len);
+ MD5Final (digest, &context);
+ string2hex(digest, 16, dst);
+}
+
+/*! \brief Unscape all printable ASCII characters */
+int unescape_user(str *sin, str *sout)
+{
+ char *at, *p, c;
+
+ if(sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL
+ || sin->len<0 || sout->len < sin->len+1)
+ return -1;
+
+ at = sout->s;
+ p = sin->s;
+ while(p < sin->s+sin->len)
+ {
+ if (*p == '%')
+ {
+ p++;
+ switch (*p)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ c = (*p - '0') << 4;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ c = (*p - 'a' + 10) << 4;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ c = (*p - 'A' + 10) << 4;
+ break;
+ default:
+ LM_ERR("invalid hex digit <%u>\n", (unsigned int)*p);
+ return -1;
+ }
+ p++;
+ switch (*p)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ c = c + (*p - '0');
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ c = c + (*p - 'a' + 10);
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ c = c + (*p - 'A' + 10);
+ break;
+ default:
+ LM_ERR("invalid hex digit <%u>\n", (unsigned int)*p);
+ return -1;
+ }
+ if ((c < 32) || (c > 126))
+ {
+ LM_ERR("invalid escaped character <%u>\n", (unsigned int)c);
+ return -1;
+ }
+ *at++ = c;
+ } else {
+ *at++ = *p;
+ }
+ p++;
+ }
+
+ *at = 0;
+ sout->len = at - sout->s;
+
+ LM_DBG("unescaped string is <%s>\n", sout->s);
+ return 0;
+}
+
+/*! \brief
+ * Escape all printable characters that are not valid in user
+ * part of request uri
+ * no_need_to_escape = unreserved | user-unreserved
+ * unreserved = aplhanum | mark
+ * mark = - | _ | . | ! | ~ | * | ' | ( | )
+ * user-unreserved = & | = | + | $ | , | ; | ? | /
+ */
+int escape_user(str *sin, str *sout)
+{
+
+ char *at, *p;
+ unsigned char x;
+
+ if(sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL
+ || sin->len<0 || sout->len < 3*sin->len+1)
+ return -1;
+
+
+ at = sout->s;
+ p = sin->s;
+ while (p < sin->s+sin->len)
+ {
+ if (*p < 32 || *p > 126)
+ {
+ LM_ERR("invalid escaped character <%u>\n", (unsigned int)*p);
+ return -1;
+ }
+ if (isdigit((int)*p) || ((*p >= 'A') && (*p <= 'Z'))
||
+ ((*p >= 'a') && (*p <= 'z')))
+ {
+ *at = *p;
+ } else {
+ switch (*p) {
+ case '-':
+ case '_':
+ case '.':
+ case '!':
+ case '~':
+ case '*':
+ case '\'':
+ case '(':
+ case ')':
+ case '&':
+ case '=':
+ case '+':
+ case '$':
+ case ',':
+ case ';':
+ case '?':
+ *at = *p;
+ break;
+ default:
+ *at++ = '%';
+ x = (*p) >> 4;
+ if (x < 10)
+ {
+ *at++ = x + '0';
+ } else {
+ *at++ = x - 10 + 'a';
+ }
+ x = (*p) & 0x0f;
+ if (x < 10) {
+ *at = x + '0';
+ } else {
+ *at = x - 10 + 'a';
+ }
+ }
+ }
+ at++;
+ p++;
+ }
+ *at = 0;
+ sout->len = at - sout->s;
+ LM_DBG("escaped string is <%s>\n", sout->s);
+ return 0;
+}
+
+
+int unescape_param(str *sin, str *sout)
+{
+ return unescape_user(sin, sout);
+}
+
+
+/*! \brief
+ * Escape all printable characters that are not valid in
+ * a param part of request uri: = | ; | , | | " | ? | &
+ */
+int escape_param(str *sin, str *sout)
+{
+ char *at, *p;
+ unsigned char x;
+
+ if (sin==NULL || sout==NULL || sin->s==NULL || sout->s==NULL ||
+ sin->len<0 || sout->len < 3*sin->len+1)
+ return -1;
+
+ at = sout->s;
+ p = sin->s;
+ while (p < sin->s+sin->len) {
+ if (*p < 32 || *p > 126) {
+ LM_ERR("invalid escaped character <%u>\n", (unsigned
int)*p);
+ return -1;
+ }
+ switch (*p) {
+ case ' ':
+ case '?':
+ case '&':
+ case '=':
+ case ',':
+ case ';':
+ case '"':
+ case '+':
+ *at++ = '%';
+ x = (*p) >> 4;
+ if (x < 10)
+ {
+ *at++ = x + '0';
+ } else {
+ *at++ = x - 10 + 'a';
+ }
+ x = (*p) & 0x0f;
+ if (x < 10) {
+ *at = x + '0';
+ } else {
+ *at = x - 10 + 'a';
+ }
+ break;
+ default:
+ *at = *p;
+ }
+ at++;
+ p++;
+ }
+ *at = 0;
+ sout->len = at - sout->s;
+ LM_DBG("escaped string is <%s>\n", sout->s);
+
+ return 0;
+}
+
diff --git a/lib/kcore/strcommon.h b/lib/kcore/strcommon.h
new file mode 100644
index 0000000..8d7d61e
--- /dev/null
+++ b/lib/kcore/strcommon.h
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2007 voice-system.ro
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+/*!
+ * \file
+ * \brief Common string handling functions
+ */
+
+#ifndef _STRCOMMON_H_
+#define _STRCOMMON_H_
+
+#include "../../str.h"
+#include "../../md5.h"
+
+/*
+ * add backslashes to special characters
+ */
+int escape_common(char *dst, char *src, int src_len);
+/*
+ * remove backslashes to special characters
+ */
+int unescape_common(char *dst, char *src, int src_len);
+
+void compute_md5(char *dst, char *src, int src_len);
+
+int escape_user(str *sin, str *sout);
+
+int unescape_user(str *sin, str *sout);
+
+int escape_param(str *sin, str *sout);
+
+int unescape_param(str *sin, str *sout);
+
+#endif
+