comparison libpurple/protocols/simple/simple.c @ 21418:38cc722159ff

propagate from branch 'im.pidgin.pidgin' (head d8103be97302efb404e2f6922925f661c807ad23) to branch 'im.pidgin.cpw.resiak.disconnectreason' (head 0ac25a1f38ae28654c967caa143f1c0d12ef2e1c)
author Will Thompson <will.thompson@collabora.co.uk>
date Sat, 10 Nov 2007 12:10:04 +0000
parents e747ac0c42d6 b2d9f859663e
children c38d72677c8a 60f5abc6cf0c
comparison
equal deleted inserted replaced
21417:21bea7c72a80 21418:38cc722159ff
319 } 319 }
320 320
321 return retval; 321 return retval;
322 } 322 }
323 323
324 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) { 324 static void fill_auth(struct simple_account_data *sip, const gchar *hdr, struct sip_auth *auth) {
325 int i = 0; 325 int i = 0;
326 const char *authuser; 326 const char *authuser;
327 char *tmp; 327 char *tmp;
328 gchar **parts; 328 gchar **parts;
329 329
594 } 594 }
595 595
596 static struct transaction *transactions_find(struct simple_account_data *sip, struct sipmsg *msg) { 596 static struct transaction *transactions_find(struct simple_account_data *sip, struct sipmsg *msg) {
597 struct transaction *trans; 597 struct transaction *trans;
598 GSList *transactions = sip->transactions; 598 GSList *transactions = sip->transactions;
599 gchar *cseq = sipmsg_find_header(msg, "CSeq"); 599 const gchar *cseq = sipmsg_find_header(msg, "CSeq");
600 600
601 if (cseq) { 601 if (cseq) {
602 while(transactions) { 602 while(transactions) {
603 trans = transactions->data; 603 trans = transactions->data;
604 if(!strcmp(trans->cseq, cseq)) { 604 if(!strcmp(trans->cseq, cseq)) {
692 692
693 g_free(buf); 693 g_free(buf);
694 } 694 }
695 695
696 static char *get_contact(struct simple_account_data *sip) { 696 static char *get_contact(struct simple_account_data *sip) {
697 return g_strdup_printf("<sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"", sip->username, purple_network_get_my_ip(-1), sip->listenport, sip->udp ? "udp" : "tcp"); 697 return g_strdup_printf("<sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"",
698 sip->username, purple_network_get_my_ip(-1),
699 sip->listenport,
700 sip->udp ? "udp" : "tcp");
698 } 701 }
699 702
700 static void do_register_exp(struct simple_account_data *sip, int expire) { 703 static void do_register_exp(struct simple_account_data *sip, int expire) {
701 char *uri, *to, *contact, *hdr; 704 char *uri, *to, *contact, *hdr;
702
703 /* Set our default expiration to 900,
704 * as done in the initialization of the simple_account_data
705 * structure.
706 */
707 if (!expire)
708 expire = 900;
709 705
710 sip->reregister = time(NULL) + expire - 50; 706 sip->reregister = time(NULL) + expire - 50;
711 707
712 uri = g_strdup_printf("sip:%s", sip->servername); 708 uri = g_strdup_printf("sip:%s", sip->servername);
713 to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); 709 to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername);
756 } 752 }
757 } 753 }
758 purple_debug_info("simple", "got %s\n", from); 754 purple_debug_info("simple", "got %s\n", from);
759 return from; 755 return from;
760 } 756 }
757 static gchar *find_tag(const gchar *);
761 758
762 static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { 759 static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) {
763 gchar *to; 760 gchar *to = NULL;
761 struct simple_buddy *b = NULL;
762 gchar *theirtag = NULL, *ourtag = NULL;
763 const gchar *callid = NULL;
764
765 purple_debug_info("simple", "process subscribe response\n");
764 766
765 if(msg->response == 200 || msg->response == 202) { 767 if(msg->response == 200 || msg->response == 202) {
768 if ( (to = parse_from(sipmsg_find_header(msg, "To"))) &&
769 (b = g_hash_table_lookup(sip->buddies, to)) &&
770 !(b->dialog))
771 {
772 purple_debug_info("simple", "creating dialog"
773 " information for a subscription.\n");
774
775 theirtag = find_tag(sipmsg_find_header(msg, "To"));
776 ourtag = find_tag(sipmsg_find_header(msg, "From"));
777 callid = sipmsg_find_header(msg, "Call-ID");
778
779 if (theirtag && ourtag && callid)
780 {
781 b->dialog = g_new0(struct sip_dialog, 1);
782 b->dialog->ourtag = g_strdup(ourtag);
783 b->dialog->theirtag = g_strdup(theirtag);
784 b->dialog->callid = g_strdup(callid);
785
786 purple_debug_info("simple", "ourtag: %s\n",
787 ourtag);
788 purple_debug_info("simple", "theirtag: %s\n",
789 theirtag);
790 purple_debug_info("simple", "callid: %s\n",
791 callid);
792 g_free(theirtag);
793 g_free(ourtag);
794 }
795 }
796 else
797 {
798 purple_debug_info("simple", "cannot create dialog!\n");
799 }
766 return TRUE; 800 return TRUE;
767 } 801 }
768 802
769 to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */ 803 to = parse_from(sipmsg_find_header(tc->msg, "To")); /* cant be NULL since it is our own msg */
770 804
773 purple_prpl_got_user_status(sip->account, to, "offline", NULL); 807 purple_prpl_got_user_status(sip->account, to, "offline", NULL);
774 g_free(to); 808 g_free(to);
775 return TRUE; 809 return TRUE;
776 } 810 }
777 811
778 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) { 812 static void simple_subscribe_exp(struct simple_account_data *sip, struct simple_buddy *buddy, int expiration) {
779 gchar *contact = "Expires: 1200\r\nAccept: application/pidf+xml, application/xpidf+xml\r\nEvent: presence\r\n"; 813 gchar *contact, *to, *tmp, *tmp2;
780 gchar *to; 814
781 gchar *tmp; 815 tmp2 = g_strdup_printf(
816 "Expires: %d\r\n"
817 "Accept: application/pidf+xml, application/xpidf+xml\r\n"
818 "Event: presence\r\n",
819 expiration);
782 820
783 if(strstr(buddy->name, "sip:")) 821 if(strstr(buddy->name, "sip:"))
784 to = g_strdup(buddy->name); 822 to = g_strdup(buddy->name);
785 else 823 else
786 to = g_strdup_printf("sip:%s", buddy->name); 824 to = g_strdup_printf("sip:%s", buddy->name);
787 825
788 tmp = get_contact(sip); 826 tmp = get_contact(sip);
789 contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp); 827 contact = g_strdup_printf("%sContact: %s\r\n", tmp2, tmp);
790 g_free(tmp); 828 g_free(tmp);
791 829 g_free(tmp2);
792 /* subscribe to buddy presence 830
793 * we dont need to know the status so we do not need a callback */ 831 send_sip_request(sip->gc, "SUBSCRIBE", to, to, contact,"",buddy->dialog,
794 832 (expiration > 0) ? process_subscribe_response : NULL);
795 send_sip_request(sip->gc, "SUBSCRIBE", to, to, contact, "", NULL,
796 process_subscribe_response);
797 833
798 g_free(to); 834 g_free(to);
799 g_free(contact); 835 g_free(contact);
800 836
801 /* resubscribe before subscription expires */ 837 /* resubscribe before subscription expires */
802 /* add some jitter */ 838 /* add some jitter */
803 buddy->resubscribe = time(NULL)+1140+(rand()%50); 839 if (expiration > 60)
840 buddy->resubscribe = time(NULL) + (expiration - 60) + (rand() % 50);
841 else if (expiration > 0)
842 buddy->resubscribe = time(NULL) + ((int) (expiration / 2));
843 }
844
845 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) {
846 simple_subscribe_exp(sip, buddy, SUBSCRIBE_EXPIRATION);
847 }
848
849 static void simple_unsubscribe(char *name, struct simple_buddy *buddy, struct simple_account_data *sip) {
850 if (buddy->dialog)
851 {
852 purple_debug_info("simple", "Unsubscribing from %s\n", name);
853 simple_subscribe_exp(sip, buddy, 0);
854 }
804 } 855 }
805 856
806 static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { 857 static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) {
807 gchar *tmp; 858 const gchar *tmp;
808 xmlnode *item, *group, *isc; 859 xmlnode *item, *group, *isc;
809 const char *name_group; 860 const char *name_group;
810 PurpleBuddy *b; 861 PurpleBuddy *b;
811 PurpleGroup *g = NULL; 862 PurpleGroup *g = NULL;
812 struct simple_buddy *bs; 863 struct simple_buddy *bs;
914 time_t curtime = time(NULL); 965 time_t curtime = time(NULL);
915 /* register again if first registration expires */ 966 /* register again if first registration expires */
916 if(sip->reregister < curtime) { 967 if(sip->reregister < curtime) {
917 do_register(sip); 968 do_register(sip);
918 } 969 }
970
971 /* publish status again if our last update is about to expire. */
972 if (sip->republish != -1 &&
973 sip->republish < curtime &&
974 purple_account_get_bool(sip->account, "dopublish", TRUE))
975 {
976 purple_debug_info("simple", "subscribe_timeout: republishing status.\n");
977 send_open_publish(sip);
978 }
979
919 /* check for every subscription if we need to resubscribe */ 980 /* check for every subscription if we need to resubscribe */
920 g_hash_table_foreach(sip->buddies, (GHFunc)simple_buddy_resub, (gpointer)sip); 981 g_hash_table_foreach(sip->buddies, (GHFunc)simple_buddy_resub, (gpointer)sip);
921 982
922 /* remove a timed out suscriber */ 983 /* remove a timed out suscriber */
923
924 tmp = sip->watcher; 984 tmp = sip->watcher;
925 while(tmp) { 985 while(tmp) {
926 struct simple_watcher *watcher = tmp->data; 986 struct simple_watcher *watcher = tmp->data;
927 if(watcher->expire < curtime) { 987 if(watcher->expire < curtime) {
928 watcher_remove(sip, watcher->name); 988 watcher_remove(sip, watcher->name);
962 return 1; 1022 return 1;
963 } 1023 }
964 1024
965 static void process_incoming_message(struct simple_account_data *sip, struct sipmsg *msg) { 1025 static void process_incoming_message(struct simple_account_data *sip, struct sipmsg *msg) {
966 gchar *from; 1026 gchar *from;
967 gchar *contenttype; 1027 const gchar *contenttype;
968 gboolean found = FALSE; 1028 gboolean found = FALSE;
969 1029
970 from = parse_from(sipmsg_find_header(msg, "From")); 1030 from = parse_from(sipmsg_find_header(msg, "From"));
971 1031
972 if(!from) return; 1032 if(!from) return;
1017 g_free(from); 1077 g_free(from);
1018 } 1078 }
1019 1079
1020 1080
1021 gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { 1081 gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) {
1022 gchar *tmp; 1082 const gchar *tmp;
1023 purple_debug(PURPLE_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response); 1083 purple_debug(PURPLE_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response);
1024 switch (msg->response) { 1084 switch (msg->response) {
1025 case 200: 1085 case 200:
1026 if(sip->registerstatus < SIMPLE_REGISTER_COMPLETE) { /* registered */ 1086 if(sip->registerstatus < SIMPLE_REGISTER_COMPLETE) { /* registered */
1027 if(purple_account_get_bool(sip->account, "dopublish", TRUE)) { 1087 if(purple_account_get_bool(sip->account, "dopublish", TRUE)) {
1073 break; 1133 break;
1074 } 1134 }
1075 return TRUE; 1135 return TRUE;
1076 } 1136 }
1077 1137
1138 static gboolean dialog_match(struct sip_dialog *dialog, struct sipmsg *msg)
1139 {
1140 const gchar *fromhdr;
1141 const gchar *tohdr;
1142 const gchar *callid;
1143 gchar *ourtag, *theirtag;
1144 gboolean match = FALSE;
1145
1146 fromhdr = sipmsg_find_header(msg, "From");
1147 tohdr = sipmsg_find_header(msg, "To");
1148 callid = sipmsg_find_header(msg, "Call-ID");
1149
1150 if (!fromhdr || !tohdr || !callid)
1151 return FALSE;
1152
1153 ourtag = find_tag(tohdr);
1154 theirtag = find_tag(fromhdr);
1155
1156 if (ourtag && theirtag &&
1157 !strcmp(dialog->callid, callid) &&
1158 !strcmp(dialog->ourtag, ourtag) &&
1159 !strcmp(dialog->theirtag, theirtag))
1160 match = TRUE;
1161
1162 g_free(ourtag);
1163 g_free(theirtag);
1164
1165 return match;
1166 }
1167
1078 static void process_incoming_notify(struct simple_account_data *sip, struct sipmsg *msg) { 1168 static void process_incoming_notify(struct simple_account_data *sip, struct sipmsg *msg) {
1079 gchar *from; 1169 gchar *from;
1080 gchar *fromhdr; 1170 const gchar *fromhdr;
1081 gchar *basicstatus_data; 1171 gchar *basicstatus_data;
1082 xmlnode *pidf; 1172 xmlnode *pidf;
1083 xmlnode *basicstatus = NULL, *tuple, *status; 1173 xmlnode *basicstatus = NULL, *tuple, *status;
1084 gboolean isonline = FALSE; 1174 gboolean isonline = FALSE;
1175 struct simple_buddy *b = NULL;
1176 const gchar *sshdr = NULL;
1085 1177
1086 fromhdr = sipmsg_find_header(msg, "From"); 1178 fromhdr = sipmsg_find_header(msg, "From");
1087 from = parse_from(fromhdr); 1179 from = parse_from(fromhdr);
1088 if(!from) return; 1180 if(!from) return;
1089 1181
1182 b = g_hash_table_lookup(sip->buddies, from);
1183 if (!b)
1184 {
1185 g_free(from);
1186 purple_debug_info("simple", "Could not find the buddy.\n");
1187 return;
1188 }
1189
1190 if (b->dialog && !dialog_match(b->dialog, msg))
1191 {
1192 /* We only accept notifies from people that
1193 * we already have a dialog with.
1194 */
1195 purple_debug_info("simple","No corresponding dialog for notify--discard\n");
1196 g_free(from);
1197 return;
1198 }
1199
1090 pidf = xmlnode_from_str(msg->body, msg->bodylen); 1200 pidf = xmlnode_from_str(msg->body, msg->bodylen);
1091 1201
1092 if(!pidf) { 1202 if(!pidf) {
1093 purple_debug_info("simple", "process_incoming_notify: no parseable pidf\n"); 1203 purple_debug_info("simple", "process_incoming_notify: no parseable pidf\n");
1094 purple_prpl_got_user_status(sip->account, from, "offline", NULL); 1204 sshdr = sipmsg_find_header(msg, "Subscription-State");
1205 if (sshdr)
1206 {
1207 int i = 0;
1208 gchar **ssparts = g_strsplit(sshdr, ":", 0);
1209 while (ssparts[i])
1210 {
1211 g_strchug(ssparts[i]);
1212 if (g_str_has_prefix(ssparts[i], "terminated"))
1213 {
1214 purple_debug_info("simple", "Subscription expired!");
1215 g_free(b->dialog->ourtag);
1216 g_free(b->dialog->theirtag);
1217 g_free(b->dialog->callid);
1218 g_free(b->dialog);
1219 b->dialog = NULL;
1220
1221 purple_prpl_got_user_status(sip->account, from, "offline", NULL);
1222 break;
1223 }
1224 i++;
1225 }
1226 g_strfreev(ssparts);
1227 }
1095 send_sip_response(sip->gc, msg, 200, "OK", NULL); 1228 send_sip_response(sip->gc, msg, 200, "OK", NULL);
1096 g_free(from); 1229 g_free(from);
1097 return; 1230 return;
1098 } 1231 }
1099 1232
1229 } 1362 }
1230 return TRUE; 1363 return TRUE;
1231 } 1364 }
1232 1365
1233 static void send_open_publish(struct simple_account_data *sip) { 1366 static void send_open_publish(struct simple_account_data *sip) {
1367 gchar *add_headers = NULL;
1234 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); 1368 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername);
1235 gchar *doc = gen_pidf(sip, TRUE); 1369 gchar *doc = gen_pidf(sip, TRUE);
1370
1371 add_headers = g_strdup_printf("%s%d%s",
1372 "Expires: ",
1373 PUBLISH_EXPIRATION,
1374 "\r\nEvent: presence\r\n"
1375 "Content-Type: application/pidf+xml\r\n");
1376
1236 send_sip_request(sip->gc, "PUBLISH", uri, uri, 1377 send_sip_request(sip->gc, "PUBLISH", uri, uri,
1237 "Expires: 600\r\nEvent: presence\r\n" 1378 add_headers, doc, NULL, process_publish_response);
1238 "Content-Type: application/pidf+xml\r\n", 1379 sip->republish = time(NULL) + PUBLISH_EXPIRATION - 50;
1239 doc, NULL, process_publish_response);
1240 sip->republish = time(NULL) + 500;
1241 g_free(uri); 1380 g_free(uri);
1242 g_free(doc); 1381 g_free(doc);
1382 g_free(add_headers);
1243 } 1383 }
1244 1384
1245 static void send_closed_publish(struct simple_account_data *sip) { 1385 static void send_closed_publish(struct simple_account_data *sip) {
1246 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); 1386 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername);
1247 gchar *doc = gen_pidf(sip, FALSE); 1387 gchar *doc = gen_pidf(sip, FALSE);
1258 const char *from_hdr = sipmsg_find_header(msg, "From"); 1398 const char *from_hdr = sipmsg_find_header(msg, "From");
1259 gchar *from = parse_from(from_hdr); 1399 gchar *from = parse_from(from_hdr);
1260 gchar *theirtag = find_tag(from_hdr); 1400 gchar *theirtag = find_tag(from_hdr);
1261 gchar *ourtag = find_tag(sipmsg_find_header(msg, "To")); 1401 gchar *ourtag = find_tag(sipmsg_find_header(msg, "To"));
1262 gboolean tagadded = FALSE; 1402 gboolean tagadded = FALSE;
1263 gchar *callid = sipmsg_find_header(msg, "Call-ID"); 1403 const gchar *callid = sipmsg_find_header(msg, "Call-ID");
1264 gchar *expire = sipmsg_find_header(msg, "Expire"); 1404 const gchar *expire = sipmsg_find_header(msg, "Expire");
1265 gchar *tmp; 1405 gchar *tmp;
1266 struct simple_watcher *watcher = watcher_find(sip, from); 1406 struct simple_watcher *watcher = watcher_find(sip, from);
1267 if(!ourtag) { 1407 if(!ourtag) {
1268 tagadded = TRUE; 1408 tagadded = TRUE;
1269 ourtag = gentag(); 1409 ourtag = gentag();
1270 } 1410 }
1271 if(!watcher) { /* new subscription */ 1411 if(!watcher) { /* new subscription */
1272 gchar *acceptheader = sipmsg_find_header(msg, "Accept"); 1412 const gchar *acceptheader = sipmsg_find_header(msg, "Accept");
1273 gboolean needsxpidf = FALSE; 1413 gboolean needsxpidf = FALSE;
1274 if(!purple_privacy_check(sip->account, from)) { 1414 if(!purple_privacy_check(sip->account, from)) {
1275 send_sip_response(sip->gc, msg, 202, "Ok", NULL); 1415 send_sip_response(sip->gc, msg, 202, "Ok", NULL);
1276 goto privend; 1416 goto privend;
1277 } 1417 }
1278 if(acceptheader) { 1418 if(acceptheader) {
1279 gchar *tmp = acceptheader; 1419 const gchar *tmp = acceptheader;
1280 gboolean foundpidf = FALSE; 1420 gboolean foundpidf = FALSE;
1281 gboolean foundxpidf = FALSE; 1421 gboolean foundxpidf = FALSE;
1282 while(tmp && tmp < acceptheader + strlen(acceptheader)) { 1422 while(tmp && tmp < acceptheader + strlen(acceptheader)) {
1283 gchar *tmp2 = strchr(tmp, ','); 1423 gchar *tmp2 = strchr(tmp, ',');
1284 if(tmp2) *tmp2 = '\0'; 1424 if(tmp2) *tmp2 = '\0';
1292 while(*tmp == ' ') tmp++; 1432 while(*tmp == ' ') tmp++;
1293 } else 1433 } else
1294 tmp = 0; 1434 tmp = 0;
1295 } 1435 }
1296 if(!foundpidf && foundxpidf) needsxpidf = TRUE; 1436 if(!foundpidf && foundxpidf) needsxpidf = TRUE;
1297 g_free(acceptheader);
1298 } 1437 }
1299 watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf); 1438 watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf);
1300 } 1439 }
1301 if(tagadded) { 1440 if(tagadded) {
1302 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag); 1441 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag);
1317 send_notify(sip, watcher); 1456 send_notify(sip, watcher);
1318 privend: 1457 privend:
1319 g_free(from); 1458 g_free(from);
1320 g_free(theirtag); 1459 g_free(theirtag);
1321 g_free(ourtag); 1460 g_free(ourtag);
1322 g_free(callid);
1323 g_free(expire);
1324 } 1461 }
1325 1462
1326 static void process_input_message(struct simple_account_data *sip, struct sipmsg *msg) { 1463 static void process_input_message(struct simple_account_data *sip, struct sipmsg *msg) {
1327 gboolean found = FALSE; 1464 gboolean found = FALSE;
1328 if(msg->response == 0) { /* request */ 1465 if(msg->response == 0) { /* request */
1340 } 1477 }
1341 } else { /* response */ 1478 } else { /* response */
1342 struct transaction *trans = transactions_find(sip, msg); 1479 struct transaction *trans = transactions_find(sip, msg);
1343 if(trans) { 1480 if(trans) {
1344 if(msg->response == 407) { 1481 if(msg->response == 407) {
1345 gchar *resend, *auth, *ptmp; 1482 gchar *resend, *auth;
1483 const gchar *ptmp;
1346 1484
1347 if(sip->proxy.retries > 3) return; 1485 if(sip->proxy.retries > 3) return;
1348 sip->proxy.retries++; 1486 sip->proxy.retries++;
1349 /* do proxy authentication */ 1487 /* do proxy authentication */
1350 1488
1384 } else { 1522 } else {
1385 if(msg->response == 401) { 1523 if(msg->response == 401) {
1386 /* This is encountered when a generic (MESSAGE, NOTIFY, etc) 1524 /* This is encountered when a generic (MESSAGE, NOTIFY, etc)
1387 * was denied until further authorization is provided. 1525 * was denied until further authorization is provided.
1388 */ 1526 */
1389 gchar *resend, *auth, *ptmp; 1527 gchar *resend, *auth;
1528 const gchar *ptmp;
1390 1529
1391 if(sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) return; 1530 if(sip->registrar.retries > SIMPLE_REGISTER_RETRY_MAX) return;
1392 sip->registrar.retries++; 1531 sip->registrar.retries++;
1393 1532
1394 ptmp = sipmsg_find_header(msg, "WWW-Authenticate"); 1533 ptmp = sipmsg_find_header(msg, "WWW-Authenticate");
1773 1912
1774 if(sip) { 1913 if(sip) {
1775 /* unregister */ 1914 /* unregister */
1776 if (sip->registerstatus == SIMPLE_REGISTER_COMPLETE) 1915 if (sip->registerstatus == SIMPLE_REGISTER_COMPLETE)
1777 { 1916 {
1778 if(purple_account_get_bool(sip->account, 1917 g_hash_table_foreach(sip->buddies,
1779 "dopublish", 1918 (GHFunc)simple_unsubscribe,
1780 TRUE)) 1919 (gpointer)sip);
1920
1921 if(purple_account_get_bool(sip->account,
1922 "dopublish", TRUE))
1781 send_closed_publish(sip); 1923 send_closed_publish(sip);
1782 1924
1783 do_register_exp(sip, 0); 1925 do_register_exp(sip, 0);
1784 } 1926 }
1785 connection_free_all(sip); 1927 connection_free_all(sip);
1786 1928
1787 if (sip->query_data != NULL) 1929 if (sip->query_data != NULL)
1909 NULL, /**< dependencies */ 2051 NULL, /**< dependencies */
1910 PURPLE_PRIORITY_DEFAULT, /**< priority */ 2052 PURPLE_PRIORITY_DEFAULT, /**< priority */
1911 2053
1912 "prpl-simple", /**< id */ 2054 "prpl-simple", /**< id */
1913 "SIMPLE", /**< name */ 2055 "SIMPLE", /**< name */
1914 VERSION, /**< version */ 2056 DISPLAY_VERSION, /**< version */
1915 N_("SIP/SIMPLE Protocol Plugin"), /** summary */ 2057 N_("SIP/SIMPLE Protocol Plugin"), /** summary */
1916 N_("The SIP/SIMPLE Protocol Plugin"), /** description */ 2058 N_("The SIP/SIMPLE Protocol Plugin"), /** description */
1917 "Thomas Butter <butter@uni-mannheim.de>", /**< author */ 2059 "Thomas Butter <butter@uni-mannheim.de>", /**< author */
1918 PURPLE_WEBSITE, /**< homepage */ 2060 PURPLE_WEBSITE, /**< homepage */
1919 2061