changeset 14069:d594f0466585

[gaim-migrate @ 16690] Fix CID 221 I also fixed an imperial ton of leaks. It was quite amazing, actually. There is also some other cleanup stuff in here too. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 10 Aug 2006 23:42:17 +0000
parents 6cb8bdc3366f
children 72660065eb3e
files src/protocols/simple/simple.c src/protocols/simple/simple.h src/protocols/simple/sipmsg.c src/protocols/simple/sipmsg.h
diffstat 4 files changed, 113 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/simple/simple.c	Thu Aug 10 21:22:55 2006 +0000
+++ b/src/protocols/simple/simple.c	Thu Aug 10 23:42:17 2006 +0000
@@ -130,7 +130,8 @@
 	return NULL;
 }
 
-static struct simple_watcher *watcher_find(struct simple_account_data *sip, gchar *name) {
+static struct simple_watcher *watcher_find(struct simple_account_data *sip,
+		const gchar *name) {
 	struct simple_watcher *watcher;
 	GSList *entry = sip->watcher;
 	while(entry) {
@@ -141,7 +142,9 @@
 	return NULL;
 }
 
-static struct simple_watcher *watcher_create(struct simple_account_data *sip, gchar *name, gchar *callid, gchar *ourtag, gchar *theirtag, int needsxpidf) {
+static struct simple_watcher *watcher_create(struct simple_account_data *sip,
+		const gchar *name, const gchar *callid, const gchar *ourtag,
+		const gchar *theirtag, gboolean needsxpidf) {
 	struct simple_watcher *watcher = g_new0(struct simple_watcher, 1);
 	watcher->name = g_strdup(name);
 	watcher->dialog.callid = g_strdup(callid);
@@ -152,7 +155,7 @@
 	return watcher;
 }
 
-static void watcher_remove(struct simple_account_data *sip, gchar *name) {
+static void watcher_remove(struct simple_account_data *sip, const gchar *name) {
 	struct simple_watcher *watcher = watcher_find(sip, name);
 	sip->watcher = g_slist_remove(sip->watcher, watcher);
 	g_free(watcher->name);
@@ -299,8 +302,9 @@
 	return ret;
 }
 
-static char *parse_attribute(const char *attrname, char *source) {
-	char *tmp, *tmp2, *retval = NULL;
+static char *parse_attribute(const char *attrname, const char *source) {
+	const char *tmp, *tmp2;
+	char *retval = NULL;
 	int len = strlen(attrname);
 
 	if(!strncmp(source, attrname, len)) {
@@ -524,7 +528,8 @@
 	g_string_free(outstr, TRUE);
 }
 
-static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code, char *text, char *body) {
+static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code,
+		const char *text, const char *body) {
 	GSList *tmp = msg->headers;
 	gchar *name;
 	gchar *value;
@@ -560,7 +565,7 @@
 	g_free(trans);
 }
 
-static void transactions_add_buf(struct simple_account_data *sip, gchar *buf, void *callback) {
+static void transactions_add_buf(struct simple_account_data *sip, const gchar *buf, void *callback) {
 	struct transaction *trans = g_new0(struct transaction, 1);
 	trans->time = time(NULL);
 	trans->msg = sipmsg_parse_msg(buf);
@@ -593,6 +598,7 @@
 	char *auth = "";
 	const char *addh = "";
 	gchar *branch = genbranch();
+	gchar *tag = NULL;
 	char *buf;
 
 	if(!strcmp(method, "REGISTER")) {
@@ -618,6 +624,9 @@
 		gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth);
 	}
 
+	if (!dialog)
+		tag = gentag();
+
 	buf = g_strdup_printf("%s %s SIP/2.0\r\n"
 			"Via: SIP/2.0/%s %s:%d;branch=%s\r\n"
 			/* Don't know what epid is, but LCS wants it */
@@ -637,7 +646,7 @@
 			branch,
 			sip->username,
 			sip->servername,
-			dialog ? dialog->ourtag : gentag(),
+			dialog ? dialog->ourtag : tag,
 			to,
 			dialog ? ";tag=" : "",
 			dialog ? dialog->theirtag : "",
@@ -648,6 +657,9 @@
 			addh,
 			strlen(body),
 			body);
+
+	g_free(tag);
+	g_free(auth);
 	g_free(branch);
 	g_free(callid);
 
@@ -691,30 +703,30 @@
 	do_register_exp(sip, sip->registerexpire);
 }
 
-static gchar *parse_from(gchar *hdr) {
-	gchar *from = hdr;
-	gchar *tmp;
+static gchar *parse_from(const gchar *hdr) {
+	gchar *from;
+	const gchar *tmp, *tmp2 = hdr;
 
-	if(!from) return NULL;
-	gaim_debug_info("simple", "parsing address out of %s\n", from);
-	tmp = strchr(from, '<');
+	if(!hdr) return NULL;
+	gaim_debug_info("simple", "parsing address out of %s\n", hdr);
+	tmp = strchr(hdr, '<');
 
 	/* i hate the different SIP UA behaviours... */
 	if(tmp) { /* sip address in <...> */
-		from = tmp+1;
-		tmp = strchr(from, '>');
+		tmp2 = tmp + 1;
+		tmp = strchr(tmp2, '>');
 		if(tmp) {
-			from = g_strndup(from, tmp-from);
+			from = g_strndup(tmp2, tmp - tmp2);
 		} else {
 			gaim_debug_info("simple", "found < without > in From\n");
 			return NULL;
 		}
 	} else {
-		tmp = strchr(from, ';');
+		tmp = strchr(tmp2, ';');
 		if(tmp) {
-			from = g_strndup(from, tmp-from);
+			from = g_strndup(tmp2, tmp - tmp2);
 		} else {
-			from = g_strdup(from);
+			from = g_strdup(tmp2);
 		}
 	}
 	gaim_debug_info("simple", "got %s\n", from);
@@ -722,12 +734,14 @@
 }
 
 static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) {
-	gchar *to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */
+	gchar *to;
 
 	if(msg->response == 200 || msg->response == 202) {
 		return TRUE;
 	}
 
+	to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */
+
 	/* we can not subscribe -> user is offline (TODO unknown status?) */
 
 	gaim_prpl_got_user_status(sip->account, to, "offline", NULL);
@@ -740,7 +754,7 @@
 	gchar *to;
 	gchar *tmp;
 
-	if(strstr(buddy->name,"sip:"))
+	if(strstr(buddy->name, "sip:"))
 		to = g_strdup(buddy->name);
 	else
 		to = g_strdup_printf("sip:%s", buddy->name);
@@ -768,43 +782,50 @@
 	xmlnode *item, *group, *isc;
 	const char *name_group;
 	GaimBuddy *b;
-	GaimGroup *g;
+	GaimGroup *g = NULL;
 	struct simple_buddy *bs;
 	int len = msg->bodylen;
 
 
 	tmp = sipmsg_find_header(msg, "Event");
-	if(tmp && !strncmp(tmp,"vnd-microsoft-roaming-contacts",30)){
+	if(tmp && !strncmp(tmp, "vnd-microsoft-roaming-contacts", 30)){
 
-		gaim_debug_info("simple","simple_add_lcs_contacts->%s-%d\n",msg->body, len);
+		gaim_debug_info("simple", "simple_add_lcs_contacts->%s-%d\n", msg->body, len);
 		/*Convert the contact from XML to Gaim Buddies*/
-		isc = xmlnode_from_str(msg->body, len);  
+		isc = xmlnode_from_str(msg->body, len);
 
 		/* ToDo. Find for all groups */
-		group = xmlnode_get_child(isc, "group"); 
-		name_group = xmlnode_get_attrib(group, "name");
-		gaim_debug_info("simple","name_group->%s\n",name_group);  
-		g = gaim_find_group(name_group);
-		if(!g) {
+		if ((group = xmlnode_get_child(isc, "group"))) {
+			name_group = xmlnode_get_attrib(group, "name");
+			gaim_debug_info("simple", "name_group->%s\n", name_group);
+			g = gaim_find_group(name_group);
+			if(!g)
+				g = gaim_group_new(name_group);
+		}
+
+		if (!g) {
 			g = gaim_find_group("Buddies");
-			if(!g){
+			if(!g)
 				g = gaim_group_new("Buddies");
-			}
-		}else{
-			g = gaim_group_new(name_group);
 		}
 
 		for(item = xmlnode_get_child(isc, "contact"); item; item = xmlnode_get_next_twin(item))
 		{
 			const char *uri, *name, *groups;
+			char *buddy_name;
 			uri = xmlnode_get_attrib(item, "uri");
 			name = xmlnode_get_attrib(item, "name");
 			groups = xmlnode_get_attrib(item, "groups");
-			gaim_debug_info("simple","URI->%s\n",uri);
-			b = gaim_find_buddy(sip->account, g_strdup_printf("sip:%s",uri));
+			gaim_debug_info("simple", "URI->%s\n", uri);
+
+			buddy_name = g_strdup_printf("sip:%s", uri);
+
+			b = gaim_find_buddy(sip->account, buddy_name);
 			if(!b){
-				b = gaim_buddy_new(sip->account, g_strdup_printf("sip:%s",uri), uri);
+				b = gaim_buddy_new(sip->account, buddy_name, uri);
 			}
+			g_free(buddy_name);
+
 			gaim_blist_add_buddy(b, NULL, g, NULL);
 			gaim_blist_alias_buddy(b, uri);
 			bs = g_new0(struct simple_buddy, 1);
@@ -821,13 +842,13 @@
 	gchar *to;
 	gchar *tmp;
 	to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername);
-        
+
 	tmp = get_contact(sip);
-       
+
 	contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp);
 	g_free(tmp);
-	
-	send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, simple_add_lcs_contacts);
+
+	send_sip_request(sip->gc, "SUBSCRIBE", to, to, contact, "", NULL, simple_add_lcs_contacts);
 
 	g_free(to);
 	g_free(contact);
@@ -953,6 +974,8 @@
 		if(statedata) {
 			if(strstr(statedata, "active")) serv_got_typing(sip->gc, from, 0, GAIM_TYPING);
 			else serv_got_typing_stopped(sip->gc, from);
+
+			g_free(statedata);
 		}
 		xmlnode_free(isc);
 		send_sip_response(sip->gc, msg, 200, "OK", NULL);
@@ -984,7 +1007,7 @@
 
 			subscribe_timeout(sip);
 			tmp = sipmsg_find_header(msg, "Allow-Events");
-		        if(tmp && strstr(tmp,"vnd-microsoft-provisioning")){
+		        if(tmp && strstr(tmp, "vnd-microsoft-provisioning")){
 				simple_subscribe_buddylist(sip);
 			}
 
@@ -1044,6 +1067,8 @@
 		isonline = TRUE;
 	}
 
+	g_free(tmp2);
+
 	if(isonline) gaim_prpl_got_user_status(sip->account, from, "available", NULL);
 	else gaim_prpl_got_user_status(sip->account, from, "offline", NULL);
 
@@ -1084,16 +1109,13 @@
 	return 1;
 }
 
-static gchar *find_tag(gchar *hdr) {
-	gchar *tmp = strstr(hdr, ";tag=");
-	gchar *tmp2;
+static gchar *find_tag(const gchar *hdr) {
+	const gchar *tmp = strstr(hdr, ";tag="), *tmp2;
+
 	if(!tmp) return NULL;
 	tmp += 5;
 	if((tmp2 = strchr(tmp, ';'))) {
-		tmp2[0] = '\0';
-		tmp = g_strdup(tmp);
-		tmp2[0] = ';';
-		return tmp;
+		return g_strndup(tmp, tmp2 - tmp);
 	}
 	return g_strdup(tmp);
 }
@@ -1162,12 +1184,14 @@
 		"Content-Type: application/pidf+xml\r\n",
 		doc, NULL, process_publish_response);
 	sip->republish = time(NULL) + 500;
+	g_free(uri);
 	g_free(doc);
 }
 
 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) {
-	gchar *from = parse_from(sipmsg_find_header(msg, "From"));
-	gchar *theirtag = find_tag(sipmsg_find_header(msg, "From"));
+	const char *from_hdr = sipmsg_find_header(msg, "From");
+	gchar *from = parse_from(from_hdr);
+	gchar *theirtag = find_tag(from_hdr);
 	gchar *ourtag = find_tag(sipmsg_find_header(msg, "To"));
 	gboolean tagadded = FALSE;
 	gchar *callid = sipmsg_find_header(msg, "Call-ID");
@@ -1180,7 +1204,7 @@
 	}
 	if(!watcher) { /* new subscription */
 		gchar *acceptheader = sipmsg_find_header(msg, "Accept");
-		int needsxpidf = 0;
+		gboolean needsxpidf = FALSE;
 		if(!gaim_privacy_check(sip->account, from)) {
 			send_sip_response(sip->gc, msg, 202, "Ok", NULL);
 			goto privend;
@@ -1192,9 +1216,9 @@
 			while(tmp && tmp < acceptheader + strlen(acceptheader)) {
 				gchar *tmp2 = strchr(tmp, ',');
 				if(tmp2) *tmp2 = '\0';
-				if(!strcmp("application/pidf+xml",tmp))
+				if(!strcmp("application/pidf+xml", tmp))
 					foundpidf = 1;
-				if(!strcmp("application/xpidf+xml",tmp))
+				if(!strcmp("application/xpidf+xml", tmp))
 					foundxpidf = 1;
 				if(tmp2) {
 					*tmp2 = ',';
@@ -1203,7 +1227,7 @@
 				} else
 					tmp = 0;
 			}
-			if(!foundpidf && foundxpidf) needsxpidf = 1;
+			if(!foundpidf && foundxpidf) needsxpidf = TRUE;
 			g_free(acceptheader);
 		}
 		watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf);
@@ -1212,6 +1236,7 @@
 		gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag);
 		sipmsg_remove_header(msg, "To");
 		sipmsg_add_header(msg, "To", to);
+		g_free(to);
 	}
 	if(expire)
 		watcher->expire = time(NULL) + strtol(expire, NULL, 10);
@@ -1221,7 +1246,7 @@
 	tmp = get_contact(sip);
 	sipmsg_add_header(msg, "Contact", tmp);
 	g_free(tmp);
-	gaim_debug_info("simple","got subscribe: name %s ourtag %s theirtag %s callid %s\n", watcher->name, watcher->dialog.ourtag, watcher->dialog.theirtag, watcher->dialog.callid);
+	gaim_debug_info("simple", "got subscribe: name %s ourtag %s theirtag %s callid %s\n", watcher->name, watcher->dialog.ourtag, watcher->dialog.theirtag, watcher->dialog.callid);
 	send_sip_response(sip->gc, msg, 200, "Ok", NULL);
 	send_notify(sip, watcher);
 privend:
@@ -1274,7 +1299,7 @@
 					gaim_debug_info("simple", "got trying response\n");
 				} else {
 					sip->proxy.retries = 0;
-					if(!strcmp(trans->msg->method,"REGISTER")) {
+					if(!strcmp(trans->msg->method, "REGISTER")) {
 						if(msg->response == 401) sip->registrar.retries++;
 						else sip->registrar.retries = 0;
 					} else {
@@ -1327,7 +1352,7 @@
 		cur++;
 	}
 	if(cur != conn->inbuf) {
-		memmove(conn->inbuf, cur, conn->inbufused-(cur-conn->inbuf));
+		memmove(conn->inbuf, cur, conn->inbufused - (cur - conn->inbuf));
 		conn->inbufused = strlen(conn->inbuf);
 	}
 
@@ -1340,7 +1365,7 @@
 		msg = sipmsg_parse_header(conn->inbuf);
 		cur[0] = '\r';
 		cur += 2;
-		restlen = conn->inbufused - (cur-conn->inbuf);
+		restlen = conn->inbufused - (cur - conn->inbuf);
 		if(restlen >= msg->bodylen) {
 			dummy = g_malloc(msg->bodylen + 1);
 			memcpy(dummy, cur, msg->bodylen);
--- a/src/protocols/simple/simple.h	Thu Aug 10 21:22:55 2006 +0000
+++ b/src/protocols/simple/simple.h	Thu Aug 10 23:42:17 2006 +0000
@@ -44,7 +44,7 @@
 	gchar *name;
 	time_t expire;
 	struct sip_dialog dialog;
-	int needsxpidf;
+	gboolean needsxpidf;
 };
 
 struct simple_buddy {
--- a/src/protocols/simple/sipmsg.c	Thu Aug 10 21:22:55 2006 +0000
+++ b/src/protocols/simple/sipmsg.c	Thu Aug 10 23:42:17 2006 +0000
@@ -35,18 +35,23 @@
 #include "simple.h"
 #include "sipmsg.h"
 
-struct sipmsg *sipmsg_parse_msg(gchar *msg) {
-	char *tmp = strstr(msg, "\r\n\r\n");
+struct sipmsg *sipmsg_parse_msg(const gchar *msg) {
+	const char *tmp = strstr(msg, "\r\n\r\n");
+	char *line;
 	struct sipmsg *smsg;
+
 	if(!tmp) return NULL;
-	tmp[0]=0;
-	smsg = sipmsg_parse_header(msg);
-	tmp[0]='\r';
-	smsg->body = g_strdup(tmp+4);
+
+	line = g_strndup(msg, tmp - msg);
+
+	smsg = sipmsg_parse_header(line);
+	smsg->body = g_strdup(tmp + 4);
+
+	g_free(line);
 	return smsg;
 }
 
-struct sipmsg *sipmsg_parse_header(gchar *header) {
+struct sipmsg *sipmsg_parse_header(const gchar *header) {
 	struct sipmsg *msg = g_new0(struct sipmsg,1);
 	gchar **lines = g_strsplit(header,"\r\n",0);
 	gchar **parts;
@@ -110,7 +115,7 @@
 	return msg;
 }
 
-void sipmsg_print(struct sipmsg *msg) {
+void sipmsg_print(const struct sipmsg *msg) {
 	GSList *cur;
 	struct siphdrelement *elem;
 	gaim_debug(GAIM_DEBUG_MISC, "simple", "SIP MSG\n");
@@ -124,7 +129,7 @@
 	}
 }
 
-char *sipmsg_to_string(struct sipmsg *msg) {
+char *sipmsg_to_string(const struct sipmsg *msg) {
 	GSList *cur;
 	GString *outstr = g_string_new("");
 	struct siphdrelement *elem;
@@ -148,7 +153,7 @@
 
 	return g_string_free(outstr, FALSE);
 }
-void sipmsg_add_header(struct sipmsg *msg, gchar *name, gchar *value) {
+void sipmsg_add_header(struct sipmsg *msg, const gchar *name, const gchar *value) {
 	struct siphdrelement *element = g_new0(struct siphdrelement,1);
 	element->name = g_strdup(name);
 	element->value = g_strdup(value);
@@ -170,13 +175,16 @@
 	g_free(msg);
 }
 
-void sipmsg_remove_header(struct sipmsg *msg, gchar *name) {
+void sipmsg_remove_header(struct sipmsg *msg, const gchar *name) {
 	struct siphdrelement *elem;
 	GSList *tmp = msg->headers;
 	while(tmp) {
 		elem = tmp->data;
 		if(strcmp(elem->name, name)==0) {
 			msg->headers = g_slist_remove(msg->headers, elem);
+			g_free(elem->name);
+			g_free(elem->value);
+			g_free(elem);
 			return;
 		}
 		tmp = g_slist_next(tmp);
@@ -184,7 +192,7 @@
 	return;
 }
 
-gchar *sipmsg_find_header(struct sipmsg *msg, gchar *name) {
+gchar *sipmsg_find_header(struct sipmsg *msg, const gchar *name) {
 	GSList *tmp;
 	struct siphdrelement *elem;
 	tmp = msg->headers;
--- a/src/protocols/simple/sipmsg.h	Thu Aug 10 21:22:55 2006 +0000
+++ b/src/protocols/simple/sipmsg.h	Thu Aug 10 23:42:17 2006 +0000
@@ -39,12 +39,12 @@
 	gchar *value;
 };
 
-struct sipmsg *sipmsg_parse_msg(gchar *msg);
-struct sipmsg *sipmsg_parse_header(gchar *header);
-void sipmsg_add_header(struct sipmsg *msg, gchar *name, gchar *value);
+struct sipmsg *sipmsg_parse_msg(const gchar *msg);
+struct sipmsg *sipmsg_parse_header(const gchar *header);
+void sipmsg_add_header(struct sipmsg *msg, const gchar *name, const gchar *value);
 void sipmsg_free(struct sipmsg *msg);
-gchar *sipmsg_find_header(struct sipmsg *msg, gchar *name);
-void sipmsg_remove_header(struct sipmsg *msg, gchar *name);
-void sipmsg_print(struct sipmsg *msg);
-char *sipmsg_to_string(struct sipmsg *msg);
+gchar *sipmsg_find_header(struct sipmsg *msg, const gchar *name);
+void sipmsg_remove_header(struct sipmsg *msg, const gchar *name);
+void sipmsg_print(const struct sipmsg *msg);
+char *sipmsg_to_string(const struct sipmsg *msg);
 #endif /* _GAIM_SIMPLE_H */