comparison src/protocols/simple/simple.c @ 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 91a4cc3ee221
children 72660065eb3e
comparison
equal deleted inserted replaced
14068:6cb8bdc3366f 14069:d594f0466585
128 entry = entry->next; 128 entry = entry->next;
129 } 129 }
130 return NULL; 130 return NULL;
131 } 131 }
132 132
133 static struct simple_watcher *watcher_find(struct simple_account_data *sip, gchar *name) { 133 static struct simple_watcher *watcher_find(struct simple_account_data *sip,
134 const gchar *name) {
134 struct simple_watcher *watcher; 135 struct simple_watcher *watcher;
135 GSList *entry = sip->watcher; 136 GSList *entry = sip->watcher;
136 while(entry) { 137 while(entry) {
137 watcher = entry->data; 138 watcher = entry->data;
138 if(!strcmp(name, watcher->name)) return watcher; 139 if(!strcmp(name, watcher->name)) return watcher;
139 entry = entry->next; 140 entry = entry->next;
140 } 141 }
141 return NULL; 142 return NULL;
142 } 143 }
143 144
144 static struct simple_watcher *watcher_create(struct simple_account_data *sip, gchar *name, gchar *callid, gchar *ourtag, gchar *theirtag, int needsxpidf) { 145 static struct simple_watcher *watcher_create(struct simple_account_data *sip,
146 const gchar *name, const gchar *callid, const gchar *ourtag,
147 const gchar *theirtag, gboolean needsxpidf) {
145 struct simple_watcher *watcher = g_new0(struct simple_watcher, 1); 148 struct simple_watcher *watcher = g_new0(struct simple_watcher, 1);
146 watcher->name = g_strdup(name); 149 watcher->name = g_strdup(name);
147 watcher->dialog.callid = g_strdup(callid); 150 watcher->dialog.callid = g_strdup(callid);
148 watcher->dialog.ourtag = g_strdup(ourtag); 151 watcher->dialog.ourtag = g_strdup(ourtag);
149 watcher->dialog.theirtag = g_strdup(theirtag); 152 watcher->dialog.theirtag = g_strdup(theirtag);
150 watcher->needsxpidf = needsxpidf; 153 watcher->needsxpidf = needsxpidf;
151 sip->watcher = g_slist_append(sip->watcher, watcher); 154 sip->watcher = g_slist_append(sip->watcher, watcher);
152 return watcher; 155 return watcher;
153 } 156 }
154 157
155 static void watcher_remove(struct simple_account_data *sip, gchar *name) { 158 static void watcher_remove(struct simple_account_data *sip, const gchar *name) {
156 struct simple_watcher *watcher = watcher_find(sip, name); 159 struct simple_watcher *watcher = watcher_find(sip, name);
157 sip->watcher = g_slist_remove(sip->watcher, watcher); 160 sip->watcher = g_slist_remove(sip->watcher, watcher);
158 g_free(watcher->name); 161 g_free(watcher->name);
159 g_free(watcher->dialog.callid); 162 g_free(watcher->dialog.callid);
160 g_free(watcher->dialog.ourtag); 163 g_free(watcher->dialog.ourtag);
297 ret = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n", authuser, auth->realm, auth->nonce, target, noncecount, response); 300 ret = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n", authuser, auth->realm, auth->nonce, target, noncecount, response);
298 g_free(response); 301 g_free(response);
299 return ret; 302 return ret;
300 } 303 }
301 304
302 static char *parse_attribute(const char *attrname, char *source) { 305 static char *parse_attribute(const char *attrname, const char *source) {
303 char *tmp, *tmp2, *retval = NULL; 306 const char *tmp, *tmp2;
307 char *retval = NULL;
304 int len = strlen(attrname); 308 int len = strlen(attrname);
305 309
306 if(!strncmp(source, attrname, len)) { 310 if(!strncmp(source, attrname, len)) {
307 tmp = source + len; 311 tmp = source + len;
308 tmp2 = g_strstr_len(tmp, strlen(tmp), "\""); 312 tmp2 = g_strstr_len(tmp, strlen(tmp), "\"");
522 g_string_append_printf(outstr, "\r\n%s", msg->body ? msg->body : ""); 526 g_string_append_printf(outstr, "\r\n%s", msg->body ? msg->body : "");
523 sendout_pkt(sip->gc, outstr->str); 527 sendout_pkt(sip->gc, outstr->str);
524 g_string_free(outstr, TRUE); 528 g_string_free(outstr, TRUE);
525 } 529 }
526 530
527 static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code, char *text, char *body) { 531 static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code,
532 const char *text, const char *body) {
528 GSList *tmp = msg->headers; 533 GSList *tmp = msg->headers;
529 gchar *name; 534 gchar *name;
530 gchar *value; 535 gchar *value;
531 GString *outstr = g_string_new(""); 536 GString *outstr = g_string_new("");
532 537
558 if(trans->msg) sipmsg_free(trans->msg); 563 if(trans->msg) sipmsg_free(trans->msg);
559 sip->transactions = g_slist_remove(sip->transactions, trans); 564 sip->transactions = g_slist_remove(sip->transactions, trans);
560 g_free(trans); 565 g_free(trans);
561 } 566 }
562 567
563 static void transactions_add_buf(struct simple_account_data *sip, gchar *buf, void *callback) { 568 static void transactions_add_buf(struct simple_account_data *sip, const gchar *buf, void *callback) {
564 struct transaction *trans = g_new0(struct transaction, 1); 569 struct transaction *trans = g_new0(struct transaction, 1);
565 trans->time = time(NULL); 570 trans->time = time(NULL);
566 trans->msg = sipmsg_parse_msg(buf); 571 trans->msg = sipmsg_parse_msg(buf);
567 trans->cseq = sipmsg_find_header(trans->msg, "CSeq"); 572 trans->cseq = sipmsg_find_header(trans->msg, "CSeq");
568 trans->callback = callback; 573 trans->callback = callback;
591 struct simple_account_data *sip = gc->proto_data; 596 struct simple_account_data *sip = gc->proto_data;
592 char *callid = dialog ? g_strdup(dialog->callid) : gencallid(); 597 char *callid = dialog ? g_strdup(dialog->callid) : gencallid();
593 char *auth = ""; 598 char *auth = "";
594 const char *addh = ""; 599 const char *addh = "";
595 gchar *branch = genbranch(); 600 gchar *branch = genbranch();
601 gchar *tag = NULL;
596 char *buf; 602 char *buf;
597 603
598 if(!strcmp(method, "REGISTER")) { 604 if(!strcmp(method, "REGISTER")) {
599 if(sip->regcallid) { 605 if(sip->regcallid) {
600 g_free(callid); 606 g_free(callid);
615 buf = auth_header(sip, &sip->proxy, method, url); 621 buf = auth_header(sip, &sip->proxy, method, url);
616 auth = g_strdup_printf("Proxy-Authorization: %s", buf); 622 auth = g_strdup_printf("Proxy-Authorization: %s", buf);
617 g_free(buf); 623 g_free(buf);
618 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); 624 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth);
619 } 625 }
626
627 if (!dialog)
628 tag = gentag();
620 629
621 buf = g_strdup_printf("%s %s SIP/2.0\r\n" 630 buf = g_strdup_printf("%s %s SIP/2.0\r\n"
622 "Via: SIP/2.0/%s %s:%d;branch=%s\r\n" 631 "Via: SIP/2.0/%s %s:%d;branch=%s\r\n"
623 /* Don't know what epid is, but LCS wants it */ 632 /* Don't know what epid is, but LCS wants it */
624 "From: <sip:%s@%s>;tag=%s;epid=1234567890\r\n" 633 "From: <sip:%s@%s>;tag=%s;epid=1234567890\r\n"
635 gaim_network_get_my_ip(-1), 644 gaim_network_get_my_ip(-1),
636 sip->listenport, 645 sip->listenport,
637 branch, 646 branch,
638 sip->username, 647 sip->username,
639 sip->servername, 648 sip->servername,
640 dialog ? dialog->ourtag : gentag(), 649 dialog ? dialog->ourtag : tag,
641 to, 650 to,
642 dialog ? ";tag=" : "", 651 dialog ? ";tag=" : "",
643 dialog ? dialog->theirtag : "", 652 dialog ? dialog->theirtag : "",
644 ++sip->cseq, 653 ++sip->cseq,
645 method, 654 method,
646 callid, 655 callid,
647 auth, 656 auth,
648 addh, 657 addh,
649 strlen(body), 658 strlen(body),
650 body); 659 body);
660
661 g_free(tag);
662 g_free(auth);
651 g_free(branch); 663 g_free(branch);
652 g_free(callid); 664 g_free(callid);
653 665
654 /* add to ongoing transactions */ 666 /* add to ongoing transactions */
655 667
689 701
690 static void do_register(struct simple_account_data *sip) { 702 static void do_register(struct simple_account_data *sip) {
691 do_register_exp(sip, sip->registerexpire); 703 do_register_exp(sip, sip->registerexpire);
692 } 704 }
693 705
694 static gchar *parse_from(gchar *hdr) { 706 static gchar *parse_from(const gchar *hdr) {
695 gchar *from = hdr; 707 gchar *from;
696 gchar *tmp; 708 const gchar *tmp, *tmp2 = hdr;
697 709
698 if(!from) return NULL; 710 if(!hdr) return NULL;
699 gaim_debug_info("simple", "parsing address out of %s\n", from); 711 gaim_debug_info("simple", "parsing address out of %s\n", hdr);
700 tmp = strchr(from, '<'); 712 tmp = strchr(hdr, '<');
701 713
702 /* i hate the different SIP UA behaviours... */ 714 /* i hate the different SIP UA behaviours... */
703 if(tmp) { /* sip address in <...> */ 715 if(tmp) { /* sip address in <...> */
704 from = tmp+1; 716 tmp2 = tmp + 1;
705 tmp = strchr(from, '>'); 717 tmp = strchr(tmp2, '>');
706 if(tmp) { 718 if(tmp) {
707 from = g_strndup(from, tmp-from); 719 from = g_strndup(tmp2, tmp - tmp2);
708 } else { 720 } else {
709 gaim_debug_info("simple", "found < without > in From\n"); 721 gaim_debug_info("simple", "found < without > in From\n");
710 return NULL; 722 return NULL;
711 } 723 }
712 } else { 724 } else {
713 tmp = strchr(from, ';'); 725 tmp = strchr(tmp2, ';');
714 if(tmp) { 726 if(tmp) {
715 from = g_strndup(from, tmp-from); 727 from = g_strndup(tmp2, tmp - tmp2);
716 } else { 728 } else {
717 from = g_strdup(from); 729 from = g_strdup(tmp2);
718 } 730 }
719 } 731 }
720 gaim_debug_info("simple", "got %s\n", from); 732 gaim_debug_info("simple", "got %s\n", from);
721 return from; 733 return from;
722 } 734 }
723 735
724 static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { 736 static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) {
725 gchar *to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */ 737 gchar *to;
726 738
727 if(msg->response == 200 || msg->response == 202) { 739 if(msg->response == 200 || msg->response == 202) {
728 return TRUE; 740 return TRUE;
729 } 741 }
742
743 to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */
730 744
731 /* we can not subscribe -> user is offline (TODO unknown status?) */ 745 /* we can not subscribe -> user is offline (TODO unknown status?) */
732 746
733 gaim_prpl_got_user_status(sip->account, to, "offline", NULL); 747 gaim_prpl_got_user_status(sip->account, to, "offline", NULL);
734 g_free(to); 748 g_free(to);
738 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) { 752 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) {
739 gchar *contact = "Expires: 1200\r\nAccept: application/pidf+xml, application/xpidf+xml\r\nEvent: presence\r\n"; 753 gchar *contact = "Expires: 1200\r\nAccept: application/pidf+xml, application/xpidf+xml\r\nEvent: presence\r\n";
740 gchar *to; 754 gchar *to;
741 gchar *tmp; 755 gchar *tmp;
742 756
743 if(strstr(buddy->name,"sip:")) 757 if(strstr(buddy->name, "sip:"))
744 to = g_strdup(buddy->name); 758 to = g_strdup(buddy->name);
745 else 759 else
746 to = g_strdup_printf("sip:%s", buddy->name); 760 to = g_strdup_printf("sip:%s", buddy->name);
747 761
748 tmp = get_contact(sip); 762 tmp = get_contact(sip);
766 static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { 780 static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) {
767 gchar *tmp; 781 gchar *tmp;
768 xmlnode *item, *group, *isc; 782 xmlnode *item, *group, *isc;
769 const char *name_group; 783 const char *name_group;
770 GaimBuddy *b; 784 GaimBuddy *b;
771 GaimGroup *g; 785 GaimGroup *g = NULL;
772 struct simple_buddy *bs; 786 struct simple_buddy *bs;
773 int len = msg->bodylen; 787 int len = msg->bodylen;
774 788
775 789
776 tmp = sipmsg_find_header(msg, "Event"); 790 tmp = sipmsg_find_header(msg, "Event");
777 if(tmp && !strncmp(tmp,"vnd-microsoft-roaming-contacts",30)){ 791 if(tmp && !strncmp(tmp, "vnd-microsoft-roaming-contacts", 30)){
778 792
779 gaim_debug_info("simple","simple_add_lcs_contacts->%s-%d\n",msg->body, len); 793 gaim_debug_info("simple", "simple_add_lcs_contacts->%s-%d\n", msg->body, len);
780 /*Convert the contact from XML to Gaim Buddies*/ 794 /*Convert the contact from XML to Gaim Buddies*/
781 isc = xmlnode_from_str(msg->body, len); 795 isc = xmlnode_from_str(msg->body, len);
782 796
783 /* ToDo. Find for all groups */ 797 /* ToDo. Find for all groups */
784 group = xmlnode_get_child(isc, "group"); 798 if ((group = xmlnode_get_child(isc, "group"))) {
785 name_group = xmlnode_get_attrib(group, "name"); 799 name_group = xmlnode_get_attrib(group, "name");
786 gaim_debug_info("simple","name_group->%s\n",name_group); 800 gaim_debug_info("simple", "name_group->%s\n", name_group);
787 g = gaim_find_group(name_group); 801 g = gaim_find_group(name_group);
788 if(!g) { 802 if(!g)
803 g = gaim_group_new(name_group);
804 }
805
806 if (!g) {
789 g = gaim_find_group("Buddies"); 807 g = gaim_find_group("Buddies");
790 if(!g){ 808 if(!g)
791 g = gaim_group_new("Buddies"); 809 g = gaim_group_new("Buddies");
792 }
793 }else{
794 g = gaim_group_new(name_group);
795 } 810 }
796 811
797 for(item = xmlnode_get_child(isc, "contact"); item; item = xmlnode_get_next_twin(item)) 812 for(item = xmlnode_get_child(isc, "contact"); item; item = xmlnode_get_next_twin(item))
798 { 813 {
799 const char *uri, *name, *groups; 814 const char *uri, *name, *groups;
815 char *buddy_name;
800 uri = xmlnode_get_attrib(item, "uri"); 816 uri = xmlnode_get_attrib(item, "uri");
801 name = xmlnode_get_attrib(item, "name"); 817 name = xmlnode_get_attrib(item, "name");
802 groups = xmlnode_get_attrib(item, "groups"); 818 groups = xmlnode_get_attrib(item, "groups");
803 gaim_debug_info("simple","URI->%s\n",uri); 819 gaim_debug_info("simple", "URI->%s\n", uri);
804 b = gaim_find_buddy(sip->account, g_strdup_printf("sip:%s",uri)); 820
821 buddy_name = g_strdup_printf("sip:%s", uri);
822
823 b = gaim_find_buddy(sip->account, buddy_name);
805 if(!b){ 824 if(!b){
806 b = gaim_buddy_new(sip->account, g_strdup_printf("sip:%s",uri), uri); 825 b = gaim_buddy_new(sip->account, buddy_name, uri);
807 } 826 }
827 g_free(buddy_name);
828
808 gaim_blist_add_buddy(b, NULL, g, NULL); 829 gaim_blist_add_buddy(b, NULL, g, NULL);
809 gaim_blist_alias_buddy(b, uri); 830 gaim_blist_alias_buddy(b, uri);
810 bs = g_new0(struct simple_buddy, 1); 831 bs = g_new0(struct simple_buddy, 1);
811 bs->name = g_strdup(b->name); 832 bs->name = g_strdup(b->name);
812 g_hash_table_insert(sip->buddies, bs->name, bs); 833 g_hash_table_insert(sip->buddies, bs->name, bs);
819 static void simple_subscribe_buddylist(struct simple_account_data *sip) { 840 static void simple_subscribe_buddylist(struct simple_account_data *sip) {
820 gchar *contact = "Event: vnd-microsoft-roaming-contacts\r\nAccept: application/vnd-microsoft-roaming-contacts+xml\r\nSupported: com.microsoft.autoextend\r\nSupported: ms-benotify\r\nProxy-Require: ms-benotify\r\nSupported: ms-piggyback-first-notify\r\n"; 841 gchar *contact = "Event: vnd-microsoft-roaming-contacts\r\nAccept: application/vnd-microsoft-roaming-contacts+xml\r\nSupported: com.microsoft.autoextend\r\nSupported: ms-benotify\r\nProxy-Require: ms-benotify\r\nSupported: ms-piggyback-first-notify\r\n";
821 gchar *to; 842 gchar *to;
822 gchar *tmp; 843 gchar *tmp;
823 to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); 844 to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername);
824 845
825 tmp = get_contact(sip); 846 tmp = get_contact(sip);
826 847
827 contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp); 848 contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp);
828 g_free(tmp); 849 g_free(tmp);
829 850
830 send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, simple_add_lcs_contacts); 851 send_sip_request(sip->gc, "SUBSCRIBE", to, to, contact, "", NULL, simple_add_lcs_contacts);
831 852
832 g_free(to); 853 g_free(to);
833 g_free(contact); 854 g_free(contact);
834 } 855 }
835 856
951 972
952 statedata = xmlnode_get_data(state); 973 statedata = xmlnode_get_data(state);
953 if(statedata) { 974 if(statedata) {
954 if(strstr(statedata, "active")) serv_got_typing(sip->gc, from, 0, GAIM_TYPING); 975 if(strstr(statedata, "active")) serv_got_typing(sip->gc, from, 0, GAIM_TYPING);
955 else serv_got_typing_stopped(sip->gc, from); 976 else serv_got_typing_stopped(sip->gc, from);
977
978 g_free(statedata);
956 } 979 }
957 xmlnode_free(isc); 980 xmlnode_free(isc);
958 send_sip_response(sip->gc, msg, 200, "OK", NULL); 981 send_sip_response(sip->gc, msg, 200, "OK", NULL);
959 found = TRUE; 982 found = TRUE;
960 } 983 }
982 /* get buddies from blist */ 1005 /* get buddies from blist */
983 simple_get_buddies(sip->gc); 1006 simple_get_buddies(sip->gc);
984 1007
985 subscribe_timeout(sip); 1008 subscribe_timeout(sip);
986 tmp = sipmsg_find_header(msg, "Allow-Events"); 1009 tmp = sipmsg_find_header(msg, "Allow-Events");
987 if(tmp && strstr(tmp,"vnd-microsoft-provisioning")){ 1010 if(tmp && strstr(tmp, "vnd-microsoft-provisioning")){
988 simple_subscribe_buddylist(sip); 1011 simple_subscribe_buddylist(sip);
989 } 1012 }
990 1013
991 break; 1014 break;
992 case 401: 1015 case 401:
1041 } 1064 }
1042 1065
1043 if(strstr(tmp2, "open")) { 1066 if(strstr(tmp2, "open")) {
1044 isonline = TRUE; 1067 isonline = TRUE;
1045 } 1068 }
1069
1070 g_free(tmp2);
1046 1071
1047 if(isonline) gaim_prpl_got_user_status(sip->account, from, "available", NULL); 1072 if(isonline) gaim_prpl_got_user_status(sip->account, from, "available", NULL);
1048 else gaim_prpl_got_user_status(sip->account, from, "offline", NULL); 1073 else gaim_prpl_got_user_status(sip->account, from, "offline", NULL);
1049 1074
1050 xmlnode_free(pidf); 1075 xmlnode_free(pidf);
1082 * then return 0 instead. 1107 * then return 0 instead.
1083 */ 1108 */
1084 return 1; 1109 return 1;
1085 } 1110 }
1086 1111
1087 static gchar *find_tag(gchar *hdr) { 1112 static gchar *find_tag(const gchar *hdr) {
1088 gchar *tmp = strstr(hdr, ";tag="); 1113 const gchar *tmp = strstr(hdr, ";tag="), *tmp2;
1089 gchar *tmp2; 1114
1090 if(!tmp) return NULL; 1115 if(!tmp) return NULL;
1091 tmp += 5; 1116 tmp += 5;
1092 if((tmp2 = strchr(tmp, ';'))) { 1117 if((tmp2 = strchr(tmp, ';'))) {
1093 tmp2[0] = '\0'; 1118 return g_strndup(tmp, tmp2 - tmp);
1094 tmp = g_strdup(tmp);
1095 tmp2[0] = ';';
1096 return tmp;
1097 } 1119 }
1098 return g_strdup(tmp); 1120 return g_strdup(tmp);
1099 } 1121 }
1100 1122
1101 static gchar* gen_xpidf(struct simple_account_data *sip) { 1123 static gchar* gen_xpidf(struct simple_account_data *sip) {
1160 send_sip_request(sip->gc, "PUBLISH", uri, uri, 1182 send_sip_request(sip->gc, "PUBLISH", uri, uri,
1161 "Expires: 600\r\nEvent: presence\r\n" 1183 "Expires: 600\r\nEvent: presence\r\n"
1162 "Content-Type: application/pidf+xml\r\n", 1184 "Content-Type: application/pidf+xml\r\n",
1163 doc, NULL, process_publish_response); 1185 doc, NULL, process_publish_response);
1164 sip->republish = time(NULL) + 500; 1186 sip->republish = time(NULL) + 500;
1187 g_free(uri);
1165 g_free(doc); 1188 g_free(doc);
1166 } 1189 }
1167 1190
1168 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) { 1191 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) {
1169 gchar *from = parse_from(sipmsg_find_header(msg, "From")); 1192 const char *from_hdr = sipmsg_find_header(msg, "From");
1170 gchar *theirtag = find_tag(sipmsg_find_header(msg, "From")); 1193 gchar *from = parse_from(from_hdr);
1194 gchar *theirtag = find_tag(from_hdr);
1171 gchar *ourtag = find_tag(sipmsg_find_header(msg, "To")); 1195 gchar *ourtag = find_tag(sipmsg_find_header(msg, "To"));
1172 gboolean tagadded = FALSE; 1196 gboolean tagadded = FALSE;
1173 gchar *callid = sipmsg_find_header(msg, "Call-ID"); 1197 gchar *callid = sipmsg_find_header(msg, "Call-ID");
1174 gchar *expire = sipmsg_find_header(msg, "Expire"); 1198 gchar *expire = sipmsg_find_header(msg, "Expire");
1175 gchar *tmp; 1199 gchar *tmp;
1178 tagadded = TRUE; 1202 tagadded = TRUE;
1179 ourtag = gentag(); 1203 ourtag = gentag();
1180 } 1204 }
1181 if(!watcher) { /* new subscription */ 1205 if(!watcher) { /* new subscription */
1182 gchar *acceptheader = sipmsg_find_header(msg, "Accept"); 1206 gchar *acceptheader = sipmsg_find_header(msg, "Accept");
1183 int needsxpidf = 0; 1207 gboolean needsxpidf = FALSE;
1184 if(!gaim_privacy_check(sip->account, from)) { 1208 if(!gaim_privacy_check(sip->account, from)) {
1185 send_sip_response(sip->gc, msg, 202, "Ok", NULL); 1209 send_sip_response(sip->gc, msg, 202, "Ok", NULL);
1186 goto privend; 1210 goto privend;
1187 } 1211 }
1188 if(acceptheader) { 1212 if(acceptheader) {
1190 int foundpidf = 0; 1214 int foundpidf = 0;
1191 int foundxpidf = 0; 1215 int foundxpidf = 0;
1192 while(tmp && tmp < acceptheader + strlen(acceptheader)) { 1216 while(tmp && tmp < acceptheader + strlen(acceptheader)) {
1193 gchar *tmp2 = strchr(tmp, ','); 1217 gchar *tmp2 = strchr(tmp, ',');
1194 if(tmp2) *tmp2 = '\0'; 1218 if(tmp2) *tmp2 = '\0';
1195 if(!strcmp("application/pidf+xml",tmp)) 1219 if(!strcmp("application/pidf+xml", tmp))
1196 foundpidf = 1; 1220 foundpidf = 1;
1197 if(!strcmp("application/xpidf+xml",tmp)) 1221 if(!strcmp("application/xpidf+xml", tmp))
1198 foundxpidf = 1; 1222 foundxpidf = 1;
1199 if(tmp2) { 1223 if(tmp2) {
1200 *tmp2 = ','; 1224 *tmp2 = ',';
1201 tmp = tmp2; 1225 tmp = tmp2;
1202 while(*tmp == ' ') tmp++; 1226 while(*tmp == ' ') tmp++;
1203 } else 1227 } else
1204 tmp = 0; 1228 tmp = 0;
1205 } 1229 }
1206 if(!foundpidf && foundxpidf) needsxpidf = 1; 1230 if(!foundpidf && foundxpidf) needsxpidf = TRUE;
1207 g_free(acceptheader); 1231 g_free(acceptheader);
1208 } 1232 }
1209 watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf); 1233 watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf);
1210 } 1234 }
1211 if(tagadded) { 1235 if(tagadded) {
1212 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag); 1236 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag);
1213 sipmsg_remove_header(msg, "To"); 1237 sipmsg_remove_header(msg, "To");
1214 sipmsg_add_header(msg, "To", to); 1238 sipmsg_add_header(msg, "To", to);
1239 g_free(to);
1215 } 1240 }
1216 if(expire) 1241 if(expire)
1217 watcher->expire = time(NULL) + strtol(expire, NULL, 10); 1242 watcher->expire = time(NULL) + strtol(expire, NULL, 10);
1218 else 1243 else
1219 watcher->expire = time(NULL) + 600; 1244 watcher->expire = time(NULL) + 600;
1220 sipmsg_remove_header(msg, "Contact"); 1245 sipmsg_remove_header(msg, "Contact");
1221 tmp = get_contact(sip); 1246 tmp = get_contact(sip);
1222 sipmsg_add_header(msg, "Contact", tmp); 1247 sipmsg_add_header(msg, "Contact", tmp);
1223 g_free(tmp); 1248 g_free(tmp);
1224 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); 1249 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);
1225 send_sip_response(sip->gc, msg, 200, "Ok", NULL); 1250 send_sip_response(sip->gc, msg, 200, "Ok", NULL);
1226 send_notify(sip, watcher); 1251 send_notify(sip, watcher);
1227 privend: 1252 privend:
1228 g_free(from); 1253 g_free(from);
1229 g_free(theirtag); 1254 g_free(theirtag);
1272 if(msg->response == 100) { 1297 if(msg->response == 100) {
1273 /* ignore provisional response */ 1298 /* ignore provisional response */
1274 gaim_debug_info("simple", "got trying response\n"); 1299 gaim_debug_info("simple", "got trying response\n");
1275 } else { 1300 } else {
1276 sip->proxy.retries = 0; 1301 sip->proxy.retries = 0;
1277 if(!strcmp(trans->msg->method,"REGISTER")) { 1302 if(!strcmp(trans->msg->method, "REGISTER")) {
1278 if(msg->response == 401) sip->registrar.retries++; 1303 if(msg->response == 401) sip->registrar.retries++;
1279 else sip->registrar.retries = 0; 1304 else sip->registrar.retries = 0;
1280 } else { 1305 } else {
1281 if(msg->response == 401) { 1306 if(msg->response == 401) {
1282 gchar *resend, *auth, *ptmp; 1307 gchar *resend, *auth, *ptmp;
1325 /* according to the RFC remove CRLF at the beginning */ 1350 /* according to the RFC remove CRLF at the beginning */
1326 while(*cur == '\r' || *cur == '\n') { 1351 while(*cur == '\r' || *cur == '\n') {
1327 cur++; 1352 cur++;
1328 } 1353 }
1329 if(cur != conn->inbuf) { 1354 if(cur != conn->inbuf) {
1330 memmove(conn->inbuf, cur, conn->inbufused-(cur-conn->inbuf)); 1355 memmove(conn->inbuf, cur, conn->inbufused - (cur - conn->inbuf));
1331 conn->inbufused = strlen(conn->inbuf); 1356 conn->inbufused = strlen(conn->inbuf);
1332 } 1357 }
1333 1358
1334 /* Received a full Header? */ 1359 /* Received a full Header? */
1335 if((cur = strstr(conn->inbuf, "\r\n\r\n")) != NULL) { 1360 if((cur = strstr(conn->inbuf, "\r\n\r\n")) != NULL) {
1338 cur[0] = '\0'; 1363 cur[0] = '\0';
1339 gaim_debug_info("simple", "\n\nreceived - %s\n######\n%s\n#######\n\n", ctime(&currtime), conn->inbuf); 1364 gaim_debug_info("simple", "\n\nreceived - %s\n######\n%s\n#######\n\n", ctime(&currtime), conn->inbuf);
1340 msg = sipmsg_parse_header(conn->inbuf); 1365 msg = sipmsg_parse_header(conn->inbuf);
1341 cur[0] = '\r'; 1366 cur[0] = '\r';
1342 cur += 2; 1367 cur += 2;
1343 restlen = conn->inbufused - (cur-conn->inbuf); 1368 restlen = conn->inbufused - (cur - conn->inbuf);
1344 if(restlen >= msg->bodylen) { 1369 if(restlen >= msg->bodylen) {
1345 dummy = g_malloc(msg->bodylen + 1); 1370 dummy = g_malloc(msg->bodylen + 1);
1346 memcpy(dummy, cur, msg->bodylen); 1371 memcpy(dummy, cur, msg->bodylen);
1347 dummy[msg->bodylen] = '\0'; 1372 dummy[msg->bodylen] = '\0';
1348 msg->body = dummy; 1373 msg->body = dummy;