* Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de> * This program 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. * This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA #define MAX_CONTENT_LENGTH 30000000 struct sipmsg *sipmsg_parse_msg(const gchar *msg) { const char *tmp = strstr(msg, "\r\n\r\n"); line = g_strndup(msg, tmp - msg); smsg = sipmsg_parse_header(line); smsg->body = g_strdup(tmp + 4); purple_debug_error("SIMPLE", "No header parsed from line: %s\n", line); struct sipmsg *sipmsg_parse_header(const gchar *header) { gchar *dummy, *dummy2, *tmp; lines = g_strsplit(header,"\r\n",0); parts = g_strsplit(lines[0], " ", 3); if(!parts[0] || !parts[1] || !parts[2]) { msg = g_new0(struct sipmsg,1); if(strstr(parts[0],"SIP")) { /* numeric response */ msg->method = g_strdup(parts[2]); msg->response = strtol(parts[1],NULL,10); msg->method = g_strdup(parts[0]); msg->target = g_strdup(parts[1]); for(i=1; lines[i] && strlen(lines[i])>2; i++) { parts = g_strsplit(lines[i], ":", 2); if(!parts[0] || !parts[1]) { while(*dummy==' ' || *dummy=='\t') dummy++; dummy2 = g_strdup(dummy); while(lines[i+1] && (lines[i+1][0]==' ' || lines[i+1][0]=='\t')) { while(*dummy==' ' || *dummy=='\t') dummy++; tmp = g_strdup_printf("%s %s",dummy2, dummy); sipmsg_add_header(msg, parts[0], dummy2); tmp2 = sipmsg_find_header(msg, "Content-Length"); msg->bodylen = strtol(tmp2, NULL, 10); purple_debug_warning("simple", "Invalid body length: %d", } else if (msg->bodylen > MAX_CONTENT_LENGTH) { purple_debug_warning("simple", "Got Content-Length of %d bytes on " "incoming message (max is %u bytes). Ignoring message body.\n", msg->bodylen, MAX_CONTENT_LENGTH); tmp2 = sipmsg_find_header(msg, "CSeq"); parts = g_strsplit(tmp2, " ", 2); msg->method = g_strdup(parts[1]); void sipmsg_print(const struct sipmsg *msg) { struct siphdrelement *elem; purple_debug(PURPLE_DEBUG_MISC, "simple", "SIP MSG\n"); purple_debug(PURPLE_DEBUG_MISC, "simple", "response: %d\nmethod: %s\nbodylen: %d\n",msg->response,msg->method,msg->bodylen); if(msg->target) purple_debug(PURPLE_DEBUG_MISC, "simple", "target: %s\n",msg->target); purple_debug(PURPLE_DEBUG_MISC, "simple", "name: %s value: %s\n",elem->name, elem->value); char *sipmsg_to_string(const struct sipmsg *msg) { GString *outstr = g_string_new(""); struct siphdrelement *elem; g_string_append_printf(outstr, "SIP/2.0 %d Unknown\r\n", g_string_append_printf(outstr, "%s %s SIP/2.0\r\n", msg->method, msg->target); g_string_append_printf(outstr, "%s: %s\r\n", elem->name, g_string_append_printf(outstr, "\r\n%s", msg->bodylen ? msg->body : ""); return g_string_free(outstr, FALSE); void sipmsg_add_header(struct sipmsg *msg, const gchar *name, const gchar *value) { struct siphdrelement *element = g_new(struct siphdrelement,1); element->name = g_strdup(name); element->value = g_strdup(value); msg->headers = g_slist_append(msg->headers, element); sipmsg_free_header(struct siphdrelement *elem) void sipmsg_free(struct sipmsg *msg) { g_slist_free_full(msg->headers, (GDestroyNotify)sipmsg_free_header); void sipmsg_remove_header(struct sipmsg *msg, const gchar *name) { GSList *tmp = g_slist_find_custom(msg->headers, name, (GCompareFunc)g_ascii_strcasecmp); struct siphdrelement *elem = tmp->data; msg->headers = g_slist_delete_link(msg->headers, tmp); sipmsg_free_header(elem); const gchar *sipmsg_find_header(struct sipmsg *msg, const gchar *name) { GSList *tmp = g_slist_find_custom(msg->headers, name, (GCompareFunc)g_ascii_strcasecmp); struct siphdrelement *elem = tmp->data;