Mercurial > pidgin
annotate src/protocols/simple/simple.c @ 12804:86d67bd4ef24
[gaim-migrate @ 15151]
I believe this fixes the "attempt to free unreferenced scalar" messages that
everyone was getting and doesn't seem to break anything else. Will Thompson
said it worked for him, so that's at least two of us. Let me know if this
breaks things for anyone.
committer: Tailor Script <tailor@pidgin.im>
| author | Etan Reisner <pidgin@unreliablesource.net> |
|---|---|
| date | Tue, 10 Jan 2006 05:14:30 +0000 |
| parents | ab00cea25ef2 |
| children | 8e3b85fe4a55 |
| rev | line source |
|---|---|
| 11181 | 1 /** |
| 2 * @file simple.c | |
| 3 * | |
| 4 * gaim | |
| 5 * | |
| 6 * Copyright (C) 2005 Thomas Butter <butter@uni-mannheim.de> | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
7 * |
| 11345 | 8 * *** |
| 9 * Thanks to Google's Summer of Code Program and the helpful mentors | |
| 10 * *** | |
| 11181 | 11 * |
| 12 * This program is free software; you can redistribute it and/or modify | |
| 13 * it under the terms of the GNU General Public License as published by | |
| 14 * the Free Software Foundation; either version 2 of the License, or | |
| 15 * (at your option) any later version. | |
| 16 * | |
| 17 * This program is distributed in the hope that it will be useful, | |
| 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 20 * GNU General Public License for more details. | |
| 21 * | |
| 22 * You should have received a copy of the GNU General Public License | |
| 23 * along with this program; if not, write to the Free Software | |
| 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 25 */ | |
| 26 | |
| 27 #include "internal.h" | |
| 28 | |
| 29 #include "accountopt.h" | |
| 30 #include "blist.h" | |
| 31 #include "conversation.h" | |
| 32 #include "debug.h" | |
| 33 #include "notify.h" | |
| 11345 | 34 #include "privacy.h" |
| 11181 | 35 #include "prpl.h" |
| 36 #include "plugin.h" | |
| 37 #include "util.h" | |
| 38 #include "version.h" | |
| 39 #include "network.h" | |
| 40 #include "xmlnode.h" | |
| 41 | |
| 42 #include "simple.h" | |
| 43 #include "sipmsg.h" | |
| 11383 | 44 #include "dnssrv.h" |
| 11409 | 45 #include "ntlm.h" |
| 11181 | 46 |
| 47 static char *gentag() { | |
| 48 return g_strdup_printf("%04d%04d", rand() & 0xFFFF, rand() & 0xFFFF); | |
| 49 } | |
| 50 | |
| 51 static char *genbranch() { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
52 return g_strdup_printf("z9hG4bK%04X%04X%04X%04X%04X", |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
53 rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF, |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
54 rand() & 0xFFFF, rand() & 0xFFFF); |
| 11181 | 55 } |
| 56 | |
| 57 static char *gencallid() { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
58 return g_strdup_printf("%04Xg%04Xa%04Xi%04Xm%04Xt%04Xb%04Xx%04Xx", |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
59 rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF, |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
60 rand() & 0xFFFF, rand() & 0xFFFF, rand() & 0xFFFF, |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
61 rand() & 0xFFFF, rand() & 0xFFFF); |
| 11181 | 62 } |
| 63 | |
| 12760 | 64 static char *get_my_ip() { |
| 65 static char my_ip[42]; | |
| 66 const char *tmp = gaim_network_get_public_ip(); | |
| 67 | |
| 68 if(!tmp || !strcmp(tmp,"0.0.0.0")) { | |
| 69 tmp = gaim_network_get_my_ip(-1); | |
| 70 } | |
|
12770
ab00cea25ef2
[gaim-migrate @ 15117]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12769
diff
changeset
|
71 strcpy(my_ip, tmp ? tmp : "0.0.0.0"); |
| 12760 | 72 return my_ip; |
| 73 } | |
| 74 | |
| 11181 | 75 static const char *simple_list_icon(GaimAccount *a, GaimBuddy *b) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
76 return "simple"; |
| 11181 | 77 } |
| 78 | |
| 79 static void simple_keep_alive(GaimConnection *gc) { | |
| 11194 | 80 struct simple_account_data *sip = gc->proto_data; |
| 11341 | 81 if(sip->udp) { /* in case of UDP send a packet only with a 0 byte to |
| 82 remain in the NAT table */ | |
| 11194 | 83 gchar buf[2]={0,0}; |
| 84 gaim_debug_info("simple", "sending keep alive\n"); | |
| 85 sendto(sip->fd, buf, 1, 0, (struct sockaddr*)&sip->serveraddr, sizeof(struct sockaddr_in)); | |
| 86 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
87 return; |
| 11181 | 88 } |
| 89 | |
| 90 static gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc); | |
| 91 static void send_notify(struct simple_account_data *sip, struct simple_watcher *); | |
| 92 | |
| 93 static void send_publish(struct simple_account_data *sip); | |
| 94 | |
| 95 static void do_notifies(struct simple_account_data *sip) { | |
| 96 GSList *tmp = sip->watcher; | |
| 97 gaim_debug_info("simple", "do_notifies()\n"); | |
| 11345 | 98 if((sip->republish != -1) || sip->republish < time(NULL)) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
99 if(gaim_account_get_bool(sip->account, "dopublish", TRUE)) { |
| 11345 | 100 send_publish(sip); |
| 101 } | |
| 102 } | |
| 11181 | 103 |
| 104 while(tmp) { | |
| 105 gaim_debug_info("simple", "notifying %s\n", ((struct simple_watcher*)tmp->data)->name); | |
| 106 send_notify(sip, tmp->data); | |
| 107 tmp = tmp->next; | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 static void simple_set_status(GaimAccount *account, GaimStatus *status) { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
112 GaimStatusPrimitive primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
| 11181 | 113 struct simple_account_data *sip = NULL; |
| 11718 | 114 |
| 11181 | 115 if (!gaim_status_is_active(status)) |
| 116 return; | |
| 117 | |
| 11718 | 118 if (account->gc) |
| 119 sip = account->gc->proto_data; | |
| 120 | |
| 121 if (sip) | |
| 122 { | |
| 11650 | 123 g_free(sip->status); |
| 11718 | 124 if (primitive == GAIM_STATUS_AVAILABLE) |
| 125 sip->status = g_strdup("available"); | |
| 126 else | |
| 127 sip->status = g_strdup("busy"); | |
| 11181 | 128 |
| 129 do_notifies(sip); | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 static struct sip_connection *connection_find(struct simple_account_data *sip, int fd) { | |
| 134 struct sip_connection *ret = NULL; | |
| 135 GSList *entry = sip->openconns; | |
| 136 while(entry) { | |
| 137 ret = entry->data; | |
| 138 if(ret->fd == fd) return ret; | |
| 139 entry = entry->next; | |
| 140 } | |
| 141 return NULL; | |
| 142 } | |
| 143 | |
| 144 static struct simple_watcher *watcher_find(struct simple_account_data *sip, gchar *name) { | |
| 145 struct simple_watcher *watcher; | |
| 146 GSList *entry = sip->watcher; | |
| 147 while(entry) { | |
| 148 watcher = entry->data; | |
| 149 if(!strcmp(name, watcher->name)) return watcher; | |
| 150 entry = entry->next; | |
| 151 } | |
| 152 return NULL; | |
| 153 } | |
| 154 | |
| 155 static struct simple_watcher *watcher_create(struct simple_account_data *sip, gchar *name, gchar *callid, gchar *ourtag, gchar *theirtag) { | |
| 156 struct simple_watcher *watcher = g_new0(struct simple_watcher,1); | |
| 157 watcher->name = g_strdup(name); | |
| 158 watcher->dialog.callid = g_strdup(callid); | |
| 159 watcher->dialog.ourtag = g_strdup(ourtag); | |
| 160 watcher->dialog.theirtag = g_strdup(theirtag); | |
| 161 sip->watcher = g_slist_append(sip->watcher, watcher); | |
| 162 return watcher; | |
| 163 } | |
| 164 | |
| 165 static void watcher_remove(struct simple_account_data *sip, gchar *name) { | |
| 166 struct simple_watcher *watcher = watcher_find(sip, name); | |
| 167 sip->watcher = g_slist_remove(sip->watcher, watcher); | |
| 168 g_free(watcher->name); | |
| 169 g_free(watcher->dialog.callid); | |
| 170 g_free(watcher->dialog.ourtag); | |
| 171 g_free(watcher->dialog.theirtag); | |
| 172 g_free(watcher); | |
| 173 } | |
| 174 | |
| 175 static struct sip_connection *connection_create(struct simple_account_data *sip, int fd) { | |
| 176 struct sip_connection *ret = g_new0(struct sip_connection,1); | |
| 177 ret->fd = fd; | |
| 178 sip->openconns = g_slist_append(sip->openconns, ret); | |
| 179 return ret; | |
| 180 } | |
| 181 | |
| 182 static void connection_remove(struct simple_account_data *sip, int fd) { | |
| 183 struct sip_connection *conn = connection_find(sip, fd); | |
| 184 sip->openconns = g_slist_remove(sip->openconns, conn); | |
| 185 if(conn->inputhandler) gaim_input_remove(conn->inputhandler); | |
| 11650 | 186 g_free(conn->inbuf); |
| 11181 | 187 g_free(conn); |
| 188 } | |
| 189 | |
| 11346 | 190 static void connection_free_all(struct simple_account_data *sip) { |
| 191 struct sip_connection *ret = NULL; | |
| 192 GSList *entry = sip->openconns; | |
| 193 while(entry) { | |
| 194 ret = entry->data; | |
| 195 connection_remove(sip, ret->fd); | |
| 196 entry = sip->openconns; | |
| 197 } | |
| 198 } | |
| 199 | |
| 11181 | 200 static void simple_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 201 { | |
| 202 struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; | |
| 203 struct simple_buddy *b; | |
| 204 if(strncmp("sip:", buddy->name,4)) { | |
| 12755 | 205 gchar *buf = g_strdup_printf("sip:%s",buddy->name); |
| 206 gaim_blist_rename_buddy(buddy, buf); | |
| 11181 | 207 g_free(buf); |
| 208 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
209 if(!g_hash_table_lookup(sip->buddies, buddy->name)) { |
| 11181 | 210 b = g_new0(struct simple_buddy, 1); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
211 gaim_debug_info("simple","simple_add_buddy %s\n",buddy->name); |
| 11181 | 212 b->name = g_strdup(buddy->name); |
| 213 g_hash_table_insert(sip->buddies, b->name, b); | |
| 214 } else { | |
| 215 gaim_debug_info("simple","buddy %s already in internal list\n", buddy->name); | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 static void simple_get_buddies(GaimConnection *gc) { | |
| 220 GaimBlistNode *gnode, *cnode, *bnode; | |
| 221 | |
| 222 gaim_debug_info("simple","simple_get_buddies\n"); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
223 |
| 11181 | 224 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { |
| 225 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) continue; | |
| 226 for(cnode = gnode->child; cnode; cnode = cnode->next) { | |
| 227 if(!GAIM_BLIST_NODE_IS_CONTACT(cnode)) continue; | |
| 228 for(bnode = cnode->child; bnode; bnode = bnode->next) { | |
| 229 if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) continue; | |
| 11192 | 230 if(((GaimBuddy*)bnode)->account == gc->account) |
| 231 simple_add_buddy(gc, (GaimBuddy*)bnode, (GaimGroup *)gnode); | |
| 11181 | 232 } |
| 233 } | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 static void simple_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) | |
| 238 { | |
| 239 struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; | |
| 240 struct simple_buddy *b = g_hash_table_lookup(sip->buddies, buddy->name); | |
| 241 g_hash_table_remove(sip->buddies, buddy->name); | |
| 242 g_free(b->name); | |
| 243 g_free(b); | |
| 244 } | |
| 245 | |
| 246 static GList *simple_status_types(GaimAccount *acc) { | |
| 247 GaimStatusType *type; | |
| 248 GList *types = NULL; | |
| 12456 | 249 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
250 type = gaim_status_type_new_with_attrs( |
|
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12571
diff
changeset
|
251 GAIM_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE, |
|
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12571
diff
changeset
|
252 "message", _("Message"), gaim_value_new(GAIM_TYPE_STRING), |
|
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12571
diff
changeset
|
253 NULL); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
254 types = g_list_append(types, type); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
255 |
| 12657 | 256 type = gaim_status_type_new_full( |
| 257 GAIM_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE); | |
| 258 types = g_list_append(types, type); | |
| 259 | |
| 11181 | 260 return types; |
| 261 } | |
| 262 | |
| 11346 | 263 static gchar *auth_header(struct simple_account_data *sip, struct sip_auth *auth, gchar *method, gchar *target) { |
| 264 gchar noncecount[9]; | |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
265 gchar *response; |
| 11346 | 266 gchar *ret; |
| 11409 | 267 gchar *tmp; |
| 268 | |
| 269 if(auth->type == 1) { /* Digest */ | |
| 270 sprintf(noncecount, "%08d", auth->nc++); | |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
271 response = gaim_cipher_http_digest_calculate_response( |
|
12389
e024601d45c7
[gaim-migrate @ 14695]
Richard Laager <rlaager@wiktel.com>
parents:
12382
diff
changeset
|
272 "md5", method, target, NULL, NULL, |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
273 auth->nonce, noncecount, NULL, auth->digest_session_key); |
| 11409 | 274 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s\n", response); |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
275 |
|
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
276 ret = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n", sip->username, auth->realm, auth->nonce, target, noncecount, response); |
|
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
277 g_free(response); |
| 11409 | 278 return ret; |
| 279 } else if(auth->type == 2) { /* NTLM */ | |
| 280 if(auth->nc == 3) { | |
| 281 ret = gaim_ntlm_gen_type3(sip->username, sip->password, "gaim", sip->servername, auth->nonce); | |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
282 tmp = g_strdup_printf("NTLM qop=\"auth\" realm=\"%s\" targetname=\"%s\" response=\"%s\"\r\n", auth->realm, auth->target, ret); |
| 11409 | 283 g_free(ret); |
| 284 return tmp; | |
| 285 } | |
| 286 ret = gaim_ntlm_gen_type1("gaim", sip->servername); | |
| 11483 | 287 tmp = g_strdup_printf("NTLM qop=\"auth\" realm=\"%s\" targetname=\"%s\" response=\"%s\"\r\n", auth->realm, auth->target, ret); |
| 11409 | 288 g_free(ret); |
| 289 return tmp; | |
| 290 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
291 |
| 11346 | 292 sprintf(noncecount, "%08d", auth->nc++); |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
293 response = gaim_cipher_http_digest_calculate_response( |
|
12389
e024601d45c7
[gaim-migrate @ 14695]
Richard Laager <rlaager@wiktel.com>
parents:
12382
diff
changeset
|
294 "md5", method, target, NULL, NULL, |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
295 auth->nonce, noncecount, NULL, auth->digest_session_key); |
| 11346 | 296 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s\n", response); |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
297 |
|
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
298 ret = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n", sip->username, auth->realm, auth->nonce, target, noncecount, response); |
|
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
299 g_free(response); |
| 11346 | 300 return ret; |
| 301 } | |
| 302 | |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
303 static char * parse_attribute(const char *attrname, char *source) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
304 char *tmp, *tmp2, *retval = NULL; |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
305 int len = strlen(attrname); |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
306 |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
307 if(!strncmp(source, attrname, len)) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
308 tmp = source + len; |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
309 tmp2 = g_strstr_len(tmp, strlen(tmp), "\""); |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
310 if(tmp2) |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
311 retval = g_strndup(tmp, tmp2 - tmp); |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
312 } |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
313 |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
314 return retval; |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
315 } |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
316 |
| 11346 | 317 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) { |
| 11409 | 318 int i=0; |
| 11424 | 319 char *tmp; |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
320 gchar **parts; |
| 11346 | 321 if(!hdr) { |
| 11409 | 322 gaim_debug_error("simple", "fill_auth: hdr==NULL\n"); |
| 11346 | 323 return; |
| 324 } | |
| 11409 | 325 |
| 326 if(!g_strncasecmp(hdr, "NTLM", 4)) { | |
| 327 gaim_debug_info("simple", "found NTLM\n"); | |
| 328 auth->type = 2; | |
| 329 if(!auth->nonce && !auth->nc) { | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
330 parts = g_strsplit(hdr, " ", 0); |
| 11424 | 331 while(parts[i]) { |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
332 if((tmp = parse_attribute("targetname=\"", |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
333 parts[i]))) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
334 auth->target = tmp; |
| 11424 | 335 } |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
336 else if((tmp = parse_attribute("realm=\"", |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
337 parts[i]))) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
338 auth->realm = tmp; |
| 11424 | 339 } |
| 340 i++; | |
| 341 } | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
342 g_strfreev(parts); |
|
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
343 parts = NULL; |
| 11409 | 344 auth->nc = 1; |
| 345 } | |
| 346 if(!auth->nonce && auth->nc==2) { | |
| 347 auth->nc = 3; | |
| 348 auth->nonce = gaim_ntlm_parse_type2(hdr+5); | |
| 349 } | |
| 350 return; | |
| 351 } | |
| 352 | |
| 353 auth->type = 1; | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
354 parts = g_strsplit(hdr, " ", 0); |
| 11346 | 355 while(parts[i]) { |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
356 if((tmp = parse_attribute("nonce=\"", parts[i]))) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
357 auth->nonce = tmp; |
| 11346 | 358 } |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
359 else if((tmp = parse_attribute("realm=\"", parts[i]))) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
360 auth->realm = tmp; |
| 11346 | 361 } |
| 362 i++; | |
| 363 } | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
364 g_strfreev(parts); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
365 |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
366 gaim_debug(GAIM_DEBUG_MISC, "simple", "nonce: %s realm: %s ", auth->nonce ? auth->nonce : "(null)", auth->realm ? auth->realm : "(null)"); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
367 |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
368 auth->digest_session_key = gaim_cipher_http_digest_calculate_session_key( |
|
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
369 "md5", sip->username, auth->realm, sip->password, auth->nonce, NULL); |
| 11346 | 370 |
| 371 auth->nc=1; | |
| 372 } | |
| 373 | |
| 11181 | 374 static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond); |
| 375 | |
| 376 static void send_later_cb(gpointer data, gint source, GaimInputCondition cond) { | |
| 377 GaimConnection *gc = data; | |
| 378 struct simple_account_data *sip = gc->proto_data; | |
| 379 struct sip_connection *conn; | |
| 380 | |
| 381 if( source < 0 ) { | |
| 382 gaim_connection_error(gc,"Could not connect"); | |
| 383 return; | |
| 384 } | |
| 385 | |
| 386 sip->fd = source; | |
| 387 sip->connecting = 0; | |
| 388 write(sip->fd, sip->sendlater, strlen(sip->sendlater)); | |
| 389 conn = connection_create(sip, source); | |
| 390 conn->inputhandler = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_input_cb, gc); | |
| 391 g_free(sip->sendlater); | |
| 392 sip->sendlater = 0; | |
| 393 } | |
| 394 | |
| 395 | |
| 396 static void sendlater(GaimConnection *gc, const char *buf) { | |
| 397 struct simple_account_data *sip = gc->proto_data; | |
| 398 int error = 0; | |
| 399 if(!sip->connecting) { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
400 gaim_debug_info("simple","connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
401 error = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, gc); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
402 if(error) { |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
403 gaim_connection_error(gc, _("Couldn't create socket")); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
404 } |
| 11181 | 405 sip->connecting = 1; |
| 406 } | |
| 407 if(sip->sendlater) { | |
| 408 gchar *old = sip->sendlater; | |
| 409 sip->sendlater = g_strdup_printf("%s\r\n%s",old, buf); | |
| 410 } else { | |
| 411 sip->sendlater = g_strdup(buf); | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 static int sendout_pkt(GaimConnection *gc, const char *buf) { | |
| 416 struct simple_account_data *sip = gc->proto_data; | |
| 417 time_t currtime = time(NULL); | |
| 11189 | 418 int ret = 0; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
419 |
| 11181 | 420 gaim_debug(GAIM_DEBUG_MISC, "simple", "\n\nsending - %s\n######\n%s\n######\n\n", ctime(&currtime), buf); |
| 11189 | 421 if(sip->udp) { |
| 422 if(sendto(sip->fd, buf, strlen(buf), 0, (struct sockaddr*)&sip->serveraddr, sizeof(struct sockaddr_in)) < strlen(buf)) { | |
| 423 gaim_debug_info("simple", "could not send packet\n"); | |
| 424 } | |
| 425 } else { | |
| 426 if(sip->fd <0 ) { | |
| 427 sendlater(gc, buf); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
428 return 0; |
| 11189 | 429 } |
| 430 ret = write(sip->fd, buf, strlen(buf)); | |
| 431 if(ret < 0) { | |
| 432 sendlater(gc,buf); | |
| 433 return 0; | |
| 434 } | |
| 11181 | 435 } |
| 436 return ret; | |
| 437 } | |
| 438 | |
| 11194 | 439 static void sendout_sipmsg(struct simple_account_data *sip, struct sipmsg *msg) { |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
440 GSList *tmp = msg->headers; |
| 11194 | 441 gchar *name; |
| 442 gchar *value; | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
443 GString *outstr = g_string_new(""); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
444 g_string_append_printf(outstr, "%s %s SIP/2.0\r\n", msg->method, msg->target); |
| 11194 | 445 while(tmp) { |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
446 name = ((struct siphdrelement*) (tmp->data))->name; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
447 value = ((struct siphdrelement*) (tmp->data))->value; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
448 g_string_append_printf(outstr, "%s: %s\r\n", name, value); |
| 11194 | 449 tmp = g_slist_next(tmp); |
| 450 } | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
451 g_string_append_printf(outstr, "\r\n%s", msg->body ? msg->body : ""); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
452 sendout_pkt(sip->gc, outstr->str); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
453 g_string_free(outstr, TRUE); |
| 11194 | 454 } |
| 455 | |
| 11181 | 456 static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code, char *text, char *body) { |
| 457 GSList *tmp = msg->headers; | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
458 gchar *name; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
459 gchar *value; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
460 GString *outstr = g_string_new(""); |
| 12754 | 461 |
| 462 /* When sending the acknowlegements and errors, the content length from the original | |
| 463 message is still here, but there is no body; we need to make sure we're sending the | |
| 464 correct content length */ | |
| 465 sipmsg_remove_header(msg, "Content-Length"); | |
| 466 if(body) { | |
| 467 gchar len[12]; | |
| 468 sprintf(len, "%" G_GSIZE_FORMAT , strlen(body)); | |
| 469 sipmsg_add_header(msg, "Content-Length",len); | |
| 470 } | |
| 471 else | |
| 472 sipmsg_add_header(msg, "Content-Length", "0"); | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
473 g_string_append_printf(outstr, "SIP/2.0 %d %s\r\n", code, text); |
| 11181 | 474 while(tmp) { |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
475 name = ((struct siphdrelement*) (tmp->data))->name; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
476 value = ((struct siphdrelement*) (tmp->data))->value; |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
477 |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
478 g_string_append_printf(outstr, "%s: %s\r\n", name, value); |
| 11181 | 479 tmp = g_slist_next(tmp); |
| 480 } | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
481 g_string_append_printf(outstr, "\r\n%s", body ? body : ""); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
482 sendout_pkt(gc, outstr->str); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
483 g_string_free(outstr, TRUE); |
| 11181 | 484 } |
| 485 | |
| 11194 | 486 static void transactions_remove(struct simple_account_data *sip, struct transaction *trans) { |
| 487 if(trans->msg) sipmsg_free(trans->msg); | |
| 488 sip->transactions = g_slist_remove(sip->transactions, trans); | |
| 489 g_free(trans); | |
| 490 } | |
| 491 | |
| 11181 | 492 static void transactions_add_buf(struct simple_account_data *sip, gchar *buf, void *callback) { |
| 493 struct transaction *trans = g_new0(struct transaction, 1); | |
| 494 trans->time = time(NULL); | |
| 495 trans->msg = sipmsg_parse_msg(buf); | |
| 496 trans->cseq = sipmsg_find_header(trans->msg, "CSeq"); | |
| 497 trans->callback = callback; | |
| 498 sip->transactions = g_slist_append(sip->transactions, trans); | |
| 499 } | |
| 500 | |
| 501 static struct transaction *transactions_find(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 502 struct transaction *trans; | |
| 503 GSList *transactions = sip->transactions; | |
| 504 gchar *cseq = sipmsg_find_header(msg, "CSeq"); | |
| 505 | |
| 506 while(transactions) { | |
| 507 trans = transactions->data; | |
| 508 if(!strcmp(trans->cseq, cseq)) { | |
| 509 return trans; | |
| 510 } | |
| 511 transactions = transactions->next; | |
| 512 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
513 |
| 11181 | 514 return (struct transaction *)NULL; |
| 515 } | |
| 516 | |
| 517 static void send_sip_request(GaimConnection *gc, gchar *method, gchar *url, gchar *to, gchar *addheaders, gchar *body, struct sip_dialog *dialog, TransCallback tc) { | |
| 518 struct simple_account_data *sip = gc->proto_data; | |
| 519 char *callid= dialog ? g_strdup(dialog->callid) : gencallid(); | |
| 12216 | 520 char *auth=""; |
| 521 char *addh=""; | |
| 522 gchar *branch = genbranch(); | |
| 523 char *buf; | |
| 524 | |
| 12196 | 525 if(!strcmp(method,"REGISTER")) { |
| 526 if(sip->regcallid) callid = g_strdup(sip->regcallid); | |
| 527 else sip->regcallid = g_strdup(callid); | |
| 528 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
529 |
| 11181 | 530 if(addheaders) addh=addheaders; |
| 11409 | 531 if(sip->registrar.type && !strcmp(method,"REGISTER")) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
532 buf = auth_header(sip, &sip->registrar, method, url); |
|
12563
b7f7f3a685ea
[gaim-migrate @ 14882]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12492
diff
changeset
|
533 auth = g_strdup_printf("Authorization: %s", buf); |
| 11346 | 534 g_free(buf); |
| 11181 | 535 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 536 } | |
| 537 | |
| 11409 | 538 if(sip->proxy.type && strcmp(method,"REGISTER")) { |
| 11346 | 539 buf = auth_header(sip, &sip->proxy, method, url); |
|
12563
b7f7f3a685ea
[gaim-migrate @ 14882]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12492
diff
changeset
|
540 auth = g_strdup_printf("Proxy-Authorization: %s", buf); |
| 11346 | 541 g_free(buf); |
| 11181 | 542 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 543 } | |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
544 |
| 11181 | 545 buf = g_strdup_printf("%s %s SIP/2.0\r\n" |
| 11190 | 546 "Via: SIP/2.0/%s %s:%d;branch=%s\r\n" |
| 11181 | 547 "From: <sip:%s@%s>;tag=%s\r\n" |
| 548 "To: <%s>%s%s\r\n" | |
| 549 "Max-Forwards: 10\r\n" | |
| 550 "CSeq: %d %s\r\n" | |
| 551 "User-Agent: Gaim SIP/SIMPLE Plugin\r\n" | |
| 552 "Call-ID: %s\r\n" | |
| 553 "%s%s" | |
| 11658 | 554 "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s", |
| 11181 | 555 method, |
| 556 url, | |
| 11190 | 557 sip->udp ? "UDP" : "TCP", |
| 12760 | 558 get_my_ip(), |
| 11181 | 559 sip->listenport, |
| 560 branch, | |
| 561 sip->username, | |
| 562 sip->servername, | |
| 563 dialog ? dialog->ourtag : gentag(), | |
| 564 to, | |
| 565 dialog ? ";tag=" : "", | |
| 566 dialog ? dialog->theirtag : "", | |
| 567 ++sip->cseq, | |
| 568 method, | |
| 569 callid, | |
| 570 auth, | |
| 571 addh, | |
| 572 strlen(body), | |
| 573 body); | |
| 574 g_free(branch); | |
| 575 g_free(callid); | |
| 576 | |
| 11341 | 577 /* add to ongoing transactions */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
578 |
| 11181 | 579 transactions_add_buf(sip, buf, tc); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
580 |
| 11181 | 581 sendout_pkt(gc,buf); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
582 |
| 11181 | 583 g_free(buf); |
| 584 } | |
| 585 | |
| 11194 | 586 static void do_register_exp(struct simple_account_data *sip, int expire) { |
| 11181 | 587 char *uri = g_strdup_printf("sip:%s",sip->servername); |
| 588 char *to = g_strdup_printf("sip:%s@%s",sip->username,sip->servername); | |
| 12760 | 589 char *contact = g_strdup_printf("Contact: <sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"\r\nExpires: %d\r\n", sip->username, get_my_ip(), sip->listenport, sip->udp ? "udp" : "tcp", expire); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
590 |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
591 sip->registerstatus = 1; |
|
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
592 |
| 11194 | 593 if(expire) { |
| 594 sip->reregister = time(NULL) + expire - 50; | |
| 595 } else { | |
| 596 sip->reregister = time(NULL) + 600; | |
| 597 } | |
| 598 send_sip_request(sip->gc,"REGISTER",uri,to, contact, "", NULL, process_register_response); | |
| 11341 | 599 g_free(contact); |
| 11181 | 600 g_free(uri); |
| 601 g_free(to); | |
| 602 } | |
| 603 | |
| 11194 | 604 static void do_register(struct simple_account_data *sip) { |
| 605 do_register_exp(sip, sip->registerexpire); | |
| 606 } | |
| 607 | |
| 11181 | 608 static gchar *parse_from(gchar *hdr) { |
| 609 gchar *from = hdr; | |
| 610 gchar *tmp; | |
| 611 | |
| 612 if(!from) return NULL; | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
613 gaim_debug_info("simple", "parsing address out of %s\n",from); |
| 11181 | 614 tmp = strchr(from, '<'); |
| 615 | |
| 11341 | 616 /* i hate the different SIP UA behaviours... */ |
| 617 if(tmp) { /* sip address in <...> */ | |
| 11181 | 618 from = tmp+1; |
| 619 tmp = strchr(from,'>'); | |
| 620 if(tmp) { | |
| 621 from = g_strndup(from,tmp-from); | |
| 622 } else { | |
| 623 gaim_debug_info("simple", "found < without > in From\n"); | |
| 624 return NULL; | |
| 625 } | |
| 626 } else { | |
| 627 tmp = strchr(from, ';'); | |
| 628 if(tmp) { | |
| 629 from = g_strndup(from,tmp-from); | |
| 11483 | 630 } else { |
| 631 from = g_strdup(from); | |
| 11181 | 632 } |
| 633 } | |
| 634 gaim_debug_info("simple", "got %s\n",from); | |
| 635 return from; | |
| 636 } | |
| 637 | |
| 638 static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | |
| 11341 | 639 gchar *to = parse_from(sipmsg_find_header(tc->msg,"To")); /* cant be NULL since it is our own msg */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
640 |
| 11181 | 641 if(msg->response==200 || msg->response==202) { |
| 642 return TRUE; | |
| 643 } | |
| 644 | |
| 11341 | 645 /* we can not subscribe -> user is offline (TODO unknown status?) */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
646 |
| 11181 | 647 gaim_prpl_got_user_status(sip->account, to, "offline", NULL); |
| 648 g_free(to); | |
| 649 return TRUE; | |
| 650 } | |
| 651 | |
| 652 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) { | |
| 11341 | 653 gchar *contact = "Expires: 300\r\nAccept: application/pidf+xml\r\nEvent: presence\r\n"; |
| 11181 | 654 gchar *to; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
655 if(strstr(buddy->name,"sip:")) to = g_strdup(buddy->name); |
| 11181 | 656 else to = g_strdup_printf("sip:%s",buddy->name); |
| 11341 | 657 contact = g_strdup_printf("%sContact: <%s@%s>\r\n", contact, sip->username, sip->servername); |
| 658 /* subscribe to buddy presence | |
| 659 * we dont need to know the status so we do not need a callback */ | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
660 |
| 11181 | 661 send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, process_subscribe_response); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
662 |
| 11181 | 663 g_free(to); |
| 11341 | 664 g_free(contact); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
665 |
| 11341 | 666 /* resubscribe before subscription expires */ |
| 667 /* add some jitter */ | |
| 668 buddy->resubscribe = time(NULL)+250+(rand()%50); | |
| 11181 | 669 } |
| 670 | |
| 671 static void simple_buddy_resub(char *name, struct simple_buddy *buddy, struct simple_account_data *sip) { | |
| 672 time_t curtime = time(NULL); | |
| 11341 | 673 gaim_debug_info("simple","buddy resub\n"); |
| 11181 | 674 if(buddy->resubscribe < curtime) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
675 gaim_debug(GAIM_DEBUG_MISC, "simple", "simple_buddy_resub %s\n",name); |
| 11181 | 676 simple_subscribe(sip, buddy); |
| 677 } | |
| 678 } | |
| 679 | |
| 11194 | 680 static gboolean resend_timeout(struct simple_account_data *sip) { |
| 681 GSList *tmp = sip->transactions; | |
| 682 time_t currtime = time(NULL); | |
| 683 while(tmp) { | |
| 684 struct transaction *trans = tmp->data; | |
| 685 tmp = tmp->next; | |
| 686 gaim_debug_info("simple", "have open transaction age: %d\n", currtime- trans->time); | |
| 687 if((currtime - trans->time > 5) && trans->retries >= 1) { | |
| 11341 | 688 /* TODO 408 */ |
| 11194 | 689 } else { |
| 690 if((currtime - trans->time > 2) && trans->retries == 0) { | |
| 691 trans->retries++; | |
| 692 sendout_sipmsg(sip, trans->msg); | |
| 693 } | |
| 694 } | |
| 695 } | |
| 696 return TRUE; | |
| 697 } | |
| 698 | |
| 12768 | 699 static gboolean subscribe_timeout(struct simple_account_data *sip) { |
| 11181 | 700 GSList *tmp; |
| 701 time_t curtime = time(NULL); | |
| 11341 | 702 /* register again if first registration expires */ |
| 11181 | 703 if(sip->reregister < curtime) { |
| 11194 | 704 do_register(sip); |
| 11181 | 705 } |
| 11341 | 706 /* check for every subscription if we need to resubscribe */ |
| 11181 | 707 g_hash_table_foreach(sip->buddies, (GHFunc)simple_buddy_resub, (gpointer)sip); |
| 708 | |
| 11341 | 709 /* remove a timed out suscriber */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
710 |
| 11181 | 711 tmp = sip->watcher; |
| 712 while(tmp) { | |
| 713 struct simple_watcher *watcher = tmp->data; | |
| 714 if(watcher->expire < curtime) { | |
| 715 watcher_remove(sip, watcher->name); | |
| 716 tmp = sip->watcher; | |
| 717 } | |
| 718 if(tmp) tmp = tmp->next; | |
| 719 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
720 |
| 11181 | 721 return TRUE; |
| 722 } | |
| 723 | |
| 724 static void simple_send_message(struct simple_account_data *sip, char *to, char *msg, char *type) { | |
| 725 gchar *hdr; | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
726 if(type) { |
| 11181 | 727 hdr = g_strdup_printf("Content-Type: %s\r\n",type); |
| 728 } else { | |
| 729 hdr = g_strdup("Content-Type: text/plain\r\n"); | |
| 730 } | |
| 731 send_sip_request(sip->gc, "MESSAGE", to, to, hdr, msg, NULL, NULL); | |
| 732 g_free(hdr); | |
| 733 } | |
| 734 | |
| 12216 | 735 static int simple_im_send(GaimConnection *gc, const char *who, const char *what, GaimMessageFlags flags) { |
| 11181 | 736 struct simple_account_data *sip = gc->proto_data; |
| 737 char *to = g_strdup(who); | |
| 12216 | 738 char *text = gaim_unescape_html(what); |
| 11181 | 739 simple_send_message(sip, to, text, NULL); |
| 740 g_free(to); | |
| 741 g_free(text); | |
| 742 return 1; | |
| 743 } | |
| 744 | |
| 745 static void process_incoming_message(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 746 gchar *from; | |
| 747 gchar *contenttype; | |
| 748 gboolean found = FALSE; | |
| 749 | |
| 750 from = parse_from(sipmsg_find_header(msg, "From")); | |
| 751 | |
| 752 if(!from) return; | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
753 |
| 11181 | 754 gaim_debug(GAIM_DEBUG_MISC, "simple", "got message from %s: %s\n", from, msg->body); |
| 755 | |
| 756 contenttype = sipmsg_find_header(msg, "Content-Type"); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
757 if(!contenttype || !strncmp(contenttype, "text/plain", 10) || !strncmp(contenttype, "text/html", 9)) { |
| 11181 | 758 serv_got_im(sip->gc, from, msg->body, 0, time(NULL)); |
| 759 send_sip_response(sip->gc, msg, 200, "OK", NULL); | |
| 760 found = TRUE; | |
| 761 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
762 if(!strncmp(contenttype, "application/im-iscomposing+xml",30)) { |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
763 xmlnode *isc = xmlnode_from_str(msg->body, msg->bodylen); |
| 11181 | 764 xmlnode *state; |
| 765 gchar *statedata; | |
| 766 | |
| 767 if(!isc) { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
768 gaim_debug_info("simple","process_incoming_message: can not parse iscomposing\n"); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
769 return; |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
770 } |
| 11181 | 771 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
772 state = xmlnode_get_child(isc, "state"); |
| 11181 | 773 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
774 if(!state) { |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
775 gaim_debug_info("simple","process_incoming_message: no state found\n"); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
776 return; |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
777 } |
| 11181 | 778 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
779 statedata = xmlnode_get_data(state); |
| 11181 | 780 if(statedata) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
781 if(strstr(statedata,"active")) serv_got_typing(sip->gc, from, 0, GAIM_TYPING); |
| 11181 | 782 else serv_got_typing_stopped(sip->gc, from); |
| 783 } | |
| 784 xmlnode_free(isc); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
785 send_sip_response(sip->gc, msg, 200, "OK", NULL); |
| 11181 | 786 found = TRUE; |
| 787 } | |
| 788 if(!found) { | |
| 789 gaim_debug_info("simple", "got unknown mime-type"); | |
| 790 send_sip_response(sip->gc, msg, 415, "Unsupported media type", NULL); | |
| 791 } | |
| 792 g_free(from); | |
| 793 } | |
| 794 | |
| 795 | |
| 796 gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | |
| 797 gchar *tmp; | |
| 798 gaim_debug(GAIM_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response); | |
| 799 switch (msg->response) { | |
| 800 case 200: | |
| 11341 | 801 if(sip->registerstatus<3) { /* registered */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
802 if(gaim_account_get_bool(sip->account, "dopublish", TRUE)) { |
| 11345 | 803 send_publish(sip); |
| 804 } | |
| 11181 | 805 } |
| 806 sip->registerstatus=3; | |
| 807 gaim_connection_set_state(sip->gc, GAIM_CONNECTED); | |
| 11341 | 808 |
| 809 /* get buddies from blist */ | |
| 810 simple_get_buddies(sip->gc); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
811 |
| 12768 | 812 subscribe_timeout(sip); |
| 11181 | 813 break; |
| 814 case 401: | |
| 815 if(sip->registerstatus!=2) { | |
| 11346 | 816 gaim_debug_info("simple","REGISTER retries %d\n",sip->registrar.retries); |
| 817 if(sip->registrar.retries>3) { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
818 gaim_connection_error(sip->gc,"Wrong Password"); |
| 11346 | 819 return TRUE; |
| 820 } | |
| 11181 | 821 tmp = sipmsg_find_header(msg, "WWW-Authenticate"); |
| 822 fill_auth(sip, tmp, &sip->registrar); | |
| 823 sip->registerstatus=2; | |
| 11194 | 824 do_register(sip); |
| 11181 | 825 } |
| 826 break; | |
| 827 } | |
| 828 return TRUE; | |
| 829 } | |
| 830 | |
| 831 static void process_incoming_notify(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 832 gchar *from; | |
| 833 gchar *fromhdr; | |
| 834 gchar *tmp2; | |
| 835 xmlnode *pidf; | |
| 836 xmlnode *basicstatus; | |
| 837 gboolean isonline = FALSE; | |
| 838 | |
| 839 fromhdr = sipmsg_find_header(msg,"From"); | |
| 840 from = parse_from(fromhdr); | |
| 841 if(!from) return; | |
| 842 | |
| 843 pidf = xmlnode_from_str(msg->body, msg->bodylen); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
844 |
| 11181 | 845 if(!pidf) { |
| 846 gaim_debug_info("simple","process_incoming_notify: no parseable pidf\n"); | |
| 847 return; | |
| 848 } | |
| 849 | |
| 850 basicstatus = xmlnode_get_child(xmlnode_get_child(xmlnode_get_child(pidf,"tuple"),"status"), "basic"); | |
| 851 | |
| 852 if(!basicstatus) { | |
| 853 gaim_debug_info("simple","process_incoming_notify: no basic found\n"); | |
| 854 return; | |
| 855 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
856 |
| 11181 | 857 tmp2 = xmlnode_get_data(basicstatus); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
858 |
| 11181 | 859 if(!tmp2) { |
| 860 gaim_debug_info("simple","process_incoming_notify: no basic data found\n"); | |
| 861 return; | |
| 862 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
863 |
| 11181 | 864 if(strstr(tmp2, "open")) { |
| 865 isonline = TRUE; | |
| 866 } | |
| 867 | |
| 868 if(isonline) gaim_prpl_got_user_status(sip->account, from, "available", NULL); | |
| 869 else gaim_prpl_got_user_status(sip->account, from, "offline", NULL); | |
| 870 | |
| 871 xmlnode_free(pidf); | |
| 872 | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
873 g_free(from); |
| 11181 | 874 send_sip_response(sip->gc, msg, 200, "OK", NULL); |
| 875 } | |
| 876 | |
| 877 static int simple_typing(GaimConnection *gc, const char *name, int typing) { | |
| 878 struct simple_account_data *sip = gc->proto_data; | |
| 879 | |
| 880 gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | |
| 881 "<isComposing xmlns=\"urn:ietf:params:xml:ns:im-iscomposing\"\n" | |
| 882 "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" | |
| 883 "xsi:schemaLocation=\"urn:ietf:params:xml:ns:im-composing iscomposing.xsd\">\n" | |
| 884 "<state>%s</state>\n" | |
| 885 "<contenttype>text/plain</contenttype>\n" | |
| 886 "<refresh>60</refresh>\n" | |
| 887 "</isComposing>"; | |
| 888 gchar *recv = g_strdup(name); | |
| 889 if(typing == GAIM_TYPING) { | |
| 890 gchar *msg = g_strdup_printf(xml, "active"); | |
| 891 simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); | |
| 892 g_free(msg); | |
| 893 } else { | |
| 894 gchar *msg = g_strdup_printf(xml, "idle"); | |
| 895 simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); | |
| 896 g_free(msg); | |
| 897 } | |
| 898 g_free(recv); | |
| 899 return 1; | |
| 900 } | |
| 901 | |
| 902 static gchar *find_tag(gchar *hdr) { | |
| 903 gchar *tmp = strstr(hdr, ";tag="); | |
| 904 gchar *tmp2; | |
| 905 if(!tmp) return NULL; | |
| 906 tmp += 5; | |
| 907 if((tmp2 = strchr(tmp, ';'))) { | |
| 908 tmp2[0] = '\0'; | |
| 909 tmp = g_strdup(tmp); | |
| 910 tmp2[0] = ';'; | |
| 911 return tmp; | |
| 912 } | |
| 913 return g_strdup(tmp); | |
| 914 } | |
| 915 | |
| 916 static gchar* gen_pidf(struct simple_account_data *sip) { | |
| 917 gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
918 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n" |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
919 "xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"\n" |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
920 "entity=\"sip:%s@%s\">\n" |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
921 "<tuple id=\"bs35r9f\">\n" |
| 11181 | 922 "<status>\n" |
| 923 "<basic>open</basic>\n" | |
| 924 "<im:im>%s</im:im>\n" | |
| 925 "</status>\n" | |
| 926 "</tuple>\n" | |
| 927 "</presence>", | |
| 928 sip->username, | |
| 929 sip->servername, | |
| 930 sip->status); | |
| 931 return doc; | |
| 932 } | |
| 933 | |
| 934 static void send_notify(struct simple_account_data *sip, struct simple_watcher *watcher) { | |
| 935 gchar *doc = gen_pidf(sip); | |
| 936 send_sip_request(sip->gc, "NOTIFY", watcher->name, watcher->name, "Event: presence\r\nContent-Type: application/pidf+xml\r\n", doc, &watcher->dialog, NULL); | |
| 937 g_free(doc); | |
| 938 } | |
| 939 | |
| 940 static gboolean process_publish_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | |
| 11345 | 941 if(msg->response != 200 && msg->response != 408) { |
| 11341 | 942 /* never send again */ |
| 11181 | 943 sip->republish = -1; |
| 944 } | |
| 945 return TRUE; | |
| 946 } | |
| 947 | |
| 948 static void send_publish(struct simple_account_data *sip) { | |
| 949 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); | |
| 950 gchar *doc = gen_pidf(sip); | |
| 11341 | 951 send_sip_request(sip->gc, "PUBLISH", uri, uri, "Expires: 600\r\nEvent: presence\r\nContent-Type: application/pidf+xml\r\n", doc, NULL, process_publish_response); |
| 11181 | 952 sip->republish = time(NULL) + 500; |
| 953 g_free(doc); | |
| 954 } | |
| 955 | |
| 956 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 957 gchar *from = parse_from(sipmsg_find_header(msg, "From")); | |
| 958 gchar *theirtag = find_tag(sipmsg_find_header(msg, "From")); | |
| 959 gchar *ourtag = find_tag(sipmsg_find_header(msg, "To")); | |
| 960 gboolean tagadded = FALSE; | |
| 961 gchar *callid = sipmsg_find_header(msg, "Call-ID"); | |
| 962 gchar *expire = sipmsg_find_header(msg, "Expire"); | |
| 963 gchar *tmp; | |
| 964 struct simple_watcher *watcher = watcher_find(sip, from); | |
| 965 if(!ourtag) { | |
| 966 tagadded = TRUE; | |
| 967 ourtag = gentag(); | |
| 968 } | |
| 11341 | 969 if(!watcher) { /* new subscription */ |
| 11345 | 970 if(!gaim_privacy_check(sip->account, from)) { |
| 971 send_sip_response(sip->gc, msg, 202, "Ok", NULL); | |
| 972 goto privend; | |
| 973 } | |
| 11181 | 974 watcher = watcher_create(sip, from, callid, ourtag, theirtag); |
| 975 } | |
| 976 if(tagadded) { | |
| 977 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag); | |
| 978 sipmsg_remove_header(msg, "To"); | |
| 979 sipmsg_add_header(msg, "To", to); | |
| 980 } | |
| 981 if(expire) | |
| 982 watcher->expire = time(NULL) + strtol(expire, NULL, 10); | |
| 983 else | |
| 984 watcher->expire = time(NULL) + 600; | |
| 985 sipmsg_remove_header(msg, "Contact"); | |
| 986 tmp = g_strdup_printf("<%s@%s>",sip->username, sip->servername); | |
| 987 sipmsg_add_header(msg, "Contact", tmp); | |
| 988 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); | |
| 989 send_sip_response(sip->gc, msg, 200, "Ok", NULL); | |
| 990 g_free(tmp); | |
| 991 send_notify(sip, watcher); | |
| 11345 | 992 privend: |
| 993 g_free(from); | |
| 994 g_free(theirtag); | |
| 995 g_free(ourtag); | |
| 996 g_free(callid); | |
| 997 g_free(expire); | |
| 11181 | 998 } |
| 999 | |
| 11189 | 1000 static void process_input_message(struct simple_account_data *sip, struct sipmsg *msg) { |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1001 gboolean found = FALSE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1002 if(msg->response == 0) { /* request */ |
| 11189 | 1003 if(!strcmp(msg->method, "MESSAGE")) { |
| 1004 process_incoming_message(sip, msg); | |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1005 found = TRUE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1006 } else if(!strcmp(msg->method, "NOTIFY")) { |
| 11189 | 1007 process_incoming_notify(sip, msg); |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1008 found = TRUE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1009 } else if(!strcmp(msg->method, "SUBSCRIBE")) { |
| 11189 | 1010 process_incoming_subscribe(sip, msg); |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1011 found = TRUE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1012 } else { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1013 send_sip_response(sip->gc, msg, 501, "Not implemented", NULL); |
| 11190 | 1014 } |
| 11341 | 1015 } else { /* response */ |
| 11189 | 1016 struct transaction *trans = transactions_find(sip, msg); |
| 1017 if(trans) { | |
| 1018 if(msg->response == 407) { | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
1019 gchar *resend, *auth, *ptmp; |
|
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
1020 |
| 11346 | 1021 if(sip->proxy.retries>3) return; |
| 1022 sip->proxy.retries++; | |
| 11341 | 1023 /* do proxy authentication */ |
| 11189 | 1024 |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
1025 ptmp = sipmsg_find_header(msg, "Proxy-Authenticate"); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1026 |
| 11189 | 1027 fill_auth(sip, ptmp, &sip->proxy); |
| 11346 | 1028 auth = auth_header(sip, &sip->proxy, trans->msg->method, trans->msg->target); |
| 11189 | 1029 sipmsg_remove_header(msg, "Proxy-Authorization"); |
| 1030 sipmsg_add_header(trans->msg, "Proxy-Authorization", auth); | |
| 1031 g_free(auth); | |
| 1032 resend = sipmsg_to_string(trans->msg); | |
| 11341 | 1033 /* resend request */ |
| 11189 | 1034 sendout_pkt(sip->gc, resend); |
| 1035 g_free(resend); | |
| 1036 } else { | |
| 11517 | 1037 if(msg->response == 100) { |
| 1038 /* ignore provisional response */ | |
| 1039 gaim_debug_info("simple","got trying response\n"); | |
| 1040 } else { | |
| 1041 sip->proxy.retries = 0; | |
| 1042 if(msg->response == 401) sip->registrar.retries++; | |
| 1043 else sip->registrar.retries = 0; | |
| 1044 if(trans->callback) { | |
| 1045 /* call the callback to process response*/ | |
| 1046 (trans->callback)(sip, msg, trans); | |
| 1047 } | |
| 1048 transactions_remove(sip, trans); | |
| 11189 | 1049 } |
| 1050 } | |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1051 found = TRUE; |
| 11189 | 1052 } else { |
| 1053 gaim_debug(GAIM_DEBUG_MISC, "simple", "received response to unknown transaction"); | |
| 1054 } | |
| 1055 } | |
| 1056 if(!found) { | |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
1057 gaim_debug(GAIM_DEBUG_MISC, "simple", "received a unknown sip message with method %s and response %d\n",msg->method, msg->response); |
| 11189 | 1058 } |
| 1059 } | |
| 1060 | |
| 11181 | 1061 static void process_input(struct simple_account_data *sip, struct sip_connection *conn) |
| 1062 { | |
| 1063 char *cur; | |
| 1064 char *dummy; | |
| 1065 struct sipmsg *msg; | |
| 1066 int restlen; | |
| 1067 cur = conn->inbuf; | |
| 1068 | |
| 11341 | 1069 /* according to the RFC remove CRLF at the beginning */ |
| 11181 | 1070 while(*cur == '\r' || *cur == '\n') { |
| 1071 cur++; | |
| 1072 } | |
| 1073 if(cur != conn->inbuf) { | |
| 1074 memmove(conn->inbuf, cur, conn->inbufused-(cur-conn->inbuf)); | |
| 1075 conn->inbufused=strlen(conn->inbuf); | |
| 1076 } | |
| 1077 | |
| 11341 | 1078 /* Received a full Header? */ |
| 11181 | 1079 if((cur = strstr(conn->inbuf, "\r\n\r\n"))!=NULL) { |
| 1080 time_t currtime = time(NULL); | |
| 1081 cur += 2; | |
| 1082 cur[0] = '\0'; | |
| 1083 gaim_debug_info("simple","\n\nreceived - %s\n######\n%s\n#######\n\n",ctime(&currtime), conn->inbuf); | |
| 1084 msg = sipmsg_parse_header(conn->inbuf); | |
| 1085 cur[0] = '\r'; | |
| 1086 cur += 2; | |
| 1087 restlen = conn->inbufused - (cur-conn->inbuf); | |
| 1088 if(restlen>=msg->bodylen) { | |
| 1089 dummy = g_malloc(msg->bodylen+1); | |
| 1090 memcpy(dummy, cur, msg->bodylen); | |
| 1091 dummy[msg->bodylen]='\0'; | |
| 1092 msg->body = dummy; | |
| 1093 cur+=msg->bodylen; | |
| 1094 memmove(conn->inbuf, cur, conn->inbuflen); | |
| 1095 conn->inbufused=strlen(conn->inbuf); | |
| 1096 } else { | |
| 1097 sipmsg_free(msg); | |
| 1098 return; | |
| 1099 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1100 gaim_debug(GAIM_DEBUG_MISC, "simple", "in process response response: %d\n", msg->response); |
| 11189 | 1101 process_input_message(sip,msg); |
| 11181 | 1102 } else { |
| 1103 gaim_debug(GAIM_DEBUG_MISC, "simple", "received a incomplete sip msg: %s\n", conn->inbuf); | |
| 1104 } | |
| 1105 } | |
| 1106 | |
| 11189 | 1107 static void simple_udp_process(gpointer data, gint source, GaimInputCondition con) { |
| 1108 GaimConnection *gc = data; | |
| 1109 struct simple_account_data *sip = gc->proto_data; | |
| 1110 struct sipmsg *msg; | |
| 1111 int len; | |
| 1112 time_t currtime; | |
| 1113 | |
| 1114 static char buffer[65536]; | |
|
12770
ab00cea25ef2
[gaim-migrate @ 15117]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12769
diff
changeset
|
1115 if((len = recv(source, buffer, sizeof(buffer) - 1, 0)) > 0) { |
|
12748
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1116 buffer[len] = '\0'; |
|
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1117 gaim_debug_info("simple","\n\nreceived - %s\n######\n%s\n#######\n\n",ctime(&currtime), buffer); |
|
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1118 msg = sipmsg_parse_msg(buffer); |
|
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1119 if(msg) process_input_message(sip, msg); |
|
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1120 } |
| 11189 | 1121 } |
| 1122 | |
| 11181 | 1123 static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond) |
| 1124 { | |
| 1125 GaimConnection *gc = data; | |
| 1126 struct simple_account_data *sip = gc->proto_data; | |
| 1127 int len; | |
| 1128 struct sip_connection *conn = connection_find(sip, source); | |
| 1129 if(!conn) { | |
| 1130 gaim_debug_error("simple", "Connection not found!\n"); | |
| 1131 return; | |
| 1132 } | |
| 1133 | |
| 1134 if (conn->inbuflen < conn->inbufused + SIMPLE_BUF_INC) { | |
| 1135 conn->inbuflen += SIMPLE_BUF_INC; | |
| 1136 conn->inbuf = g_realloc(conn->inbuf, conn->inbuflen); | |
| 1137 } | |
| 1138 | |
| 1139 if ((len = read(source, conn->inbuf + conn->inbufused, SIMPLE_BUF_INC - 1)) <= 0) { | |
| 1140 gaim_debug_info("simple","simple_input_cb: read error\n"); | |
| 1141 connection_remove(sip, source); | |
| 1142 if(sip->fd == source) sip->fd = -1; | |
| 1143 return; | |
| 1144 } | |
| 1145 if(len == 0) { | |
| 11341 | 1146 /* connection was closed */ |
| 11181 | 1147 connection_remove(sip, source); |
| 1148 if(sip->fd == source) sip->fd = -1; | |
| 1149 } | |
| 1150 | |
| 1151 conn->inbufused += len; | |
| 1152 conn->inbuf[conn->inbufused]='\0'; | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1153 |
| 11181 | 1154 process_input(sip, conn); |
| 1155 } | |
| 1156 | |
| 1157 /* Callback for new connections on incoming TCP port */ | |
| 1158 static void simple_newconn_cb(gpointer data, gint source, GaimInputCondition cond) { | |
| 1159 GaimConnection *gc = data; | |
| 1160 struct simple_account_data *sip = gc->proto_data; | |
| 1161 struct sip_connection *conn; | |
| 1162 | |
| 1163 int newfd = accept(source, NULL, NULL); | |
| 1164 | |
| 1165 conn = connection_create(sip, newfd); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1166 |
| 11181 | 1167 conn->inputhandler = gaim_input_add(newfd, GAIM_INPUT_READ, simple_input_cb, gc); |
| 1168 } | |
| 1169 | |
| 1170 static void login_cb(gpointer data, gint source, GaimInputCondition cond) { | |
| 1171 GaimConnection *gc = data; | |
| 1172 struct simple_account_data *sip = gc->proto_data; | |
| 1173 struct sip_connection *conn; | |
| 1174 | |
| 1175 if( source < 0 ) { | |
| 1176 gaim_connection_error(gc,"Could not connect"); | |
| 1177 return; | |
| 1178 } | |
| 1179 | |
| 1180 sip->fd = source; | |
| 1181 | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1182 conn = connection_create(sip, source); |
| 12768 | 1183 |
| 1184 sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip); | |
| 11181 | 1185 |
| 11194 | 1186 do_register(sip); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1187 |
| 11181 | 1188 conn->inputhandler = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_input_cb, gc); |
| 1189 } | |
| 1190 | |
| 1191 static guint simple_ht_hash_nick(const char *nick) { | |
| 1192 char *lc = g_utf8_strdown(nick, -1); | |
| 1193 guint bucket = g_str_hash(lc); | |
| 1194 g_free(lc); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1195 |
| 11181 | 1196 return bucket; |
| 1197 } | |
| 1198 | |
| 1199 static gboolean simple_ht_equals_nick(const char *nick1, const char *nick2) { | |
| 1200 return (gaim_utf8_strcasecmp(nick1, nick2) == 0); | |
| 1201 } | |
| 1202 | |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1203 static void simple_udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) { |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1204 struct simple_account_data *sip = (struct simple_account_data*) data; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1205 int addr_size; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1206 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1207 if (!hosts || !hosts->data) { |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1208 gaim_connection_error(sip->gc, _("Couldn't resolve host")); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1209 return; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1210 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1211 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1212 addr_size = GPOINTER_TO_INT(hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1213 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1214 memcpy(&(sip->serveraddr), hosts->data, addr_size); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1215 g_free(hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1216 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1217 while(hosts) { |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1218 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1219 g_free(hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1220 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1221 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1222 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1223 /* create socket for incoming connections */ |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1224 sip->fd = gaim_network_listen_range(5060, 5160, SOCK_DGRAM); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1225 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1226 if(sip->fd == -1) { |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1227 gaim_connection_error(sip->gc, _("Could not create listen socket")); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1228 return; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1229 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1230 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1231 sip->listenport = gaim_network_get_port_from_fd(sip->fd); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1232 sip->listenfd = sip->fd; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1233 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1234 sip->listenpa = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_udp_process, sip->gc); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1235 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1236 sip->resendtimeout = gaim_timeout_add(2500, (GSourceFunc) resend_timeout, sip); |
| 12768 | 1237 sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip); |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1238 do_register(sip); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1239 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1240 |
|
12686
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
12657
diff
changeset
|
1241 static void srvresolved(GaimSrvResponse *resp, int results, gpointer data) { |
| 11383 | 1242 struct simple_account_data *sip = (struct simple_account_data*) data; |
| 1243 | |
| 1244 gchar *hostname; | |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12689
diff
changeset
|
1245 int port = gaim_account_get_int(sip->account, "port", 0); |
| 11383 | 1246 |
| 1247 int error = 0; | |
| 1248 | |
| 1249 /* find the host to connect to */ | |
| 1250 if(results) { | |
| 1251 hostname = g_strdup(resp->hostname); | |
| 12769 | 1252 if(!port) |
| 1253 port = resp->port; | |
| 11383 | 1254 g_free(resp); |
| 1255 } else { | |
| 1256 if(!gaim_account_get_bool(sip->account, "useproxy", FALSE)) { | |
| 1257 hostname = g_strdup(sip->servername); | |
| 1258 } else { | |
| 1259 hostname = g_strdup(gaim_account_get_string(sip->account, "proxy", sip->servername)); | |
| 1260 } | |
| 1261 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1262 |
| 11383 | 1263 sip->realhostname = hostname; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1264 sip->realport = port; |
| 12769 | 1265 if(!sip->realport) sip->realport = 5060; |
| 11383 | 1266 /* TCP case */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1267 if(! sip->udp) { |
| 11409 | 1268 /* create socket for incoming connections */ |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12689
diff
changeset
|
1269 sip->listenfd = gaim_network_listen_range(5060, 5160, SOCK_STREAM); |
| 11409 | 1270 if(sip->listenfd == -1) { |
| 1271 gaim_connection_error(sip->gc, _("Could not create listen socket")); | |
| 1272 return; | |
| 1273 } | |
| 1274 gaim_debug_info("simple", "listenfd: %d\n", sip->listenfd); | |
| 1275 sip->listenport = gaim_network_get_port_from_fd(sip->listenfd); | |
| 1276 sip->listenpa = gaim_input_add(sip->listenfd, GAIM_INPUT_READ, simple_newconn_cb, sip->gc); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1277 gaim_debug_info("simple","connecting to %s port %d\n", hostname, port); |
| 11383 | 1278 /* open tcp connection to the server */ |
| 1279 error = gaim_proxy_connect(sip->account, hostname, port, login_cb, sip->gc); | |
| 1280 if(error) { | |
| 1281 gaim_connection_error(sip->gc, _("Couldn't create socket")); | |
| 1282 } | |
| 1283 | |
| 1284 } else { /* UDP */ | |
| 1285 gaim_debug_info("simple", "using udp with server %s and port %d\n", hostname, port); | |
|
12565
3f895385e841
[gaim-migrate @ 14884]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12563
diff
changeset
|
1286 |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1287 gaim_gethostbyname_async(hostname, port, simple_udp_host_resolved, sip); |
| 11383 | 1288 } |
| 1289 } | |
| 1290 | |
| 11837 | 1291 static void simple_login(GaimAccount *account) |
| 11181 | 1292 { |
| 1293 GaimConnection *gc; | |
| 1294 struct simple_account_data *sip; | |
| 1295 gchar **userserver; | |
| 11210 | 1296 gchar *hosttoconnect; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1297 |
| 11181 | 1298 const char *username = gaim_account_get_username(account); |
| 1299 | |
| 1300 gc = gaim_account_get_connection(account); | |
| 1301 gc->proto_data = sip = g_new0(struct simple_account_data,1); | |
| 1302 sip->gc=gc; | |
| 11189 | 1303 sip->account = account; |
| 11194 | 1304 sip->registerexpire = 900; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1305 sip->udp = gaim_account_get_bool(account, "udp", FALSE); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1306 if (strpbrk(username, " \t\v\r\n") != NULL) { |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1307 gaim_connection_error(gc, _("SIP usernames may not contain whitespaces or @ symbols")); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1308 return; |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1309 } |
| 11181 | 1310 |
| 1311 userserver = g_strsplit(username, "@", 2); | |
| 1312 gaim_connection_set_display_name(gc,userserver[0]); | |
| 1313 sip->username = g_strdup(userserver[0]); | |
| 1314 sip->servername = g_strdup(userserver[1]); | |
| 1315 sip->password = g_strdup(gaim_connection_get_password(gc)); | |
| 1316 g_strfreev(userserver); | |
| 1317 | |
| 1318 sip->buddies = g_hash_table_new((GHashFunc)simple_ht_hash_nick, (GEqualFunc)simple_ht_equals_nick); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1319 |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1320 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); |
| 11181 | 1321 |
| 11837 | 1322 /* TODO: Set the status correctly. */ |
| 11181 | 1323 sip->status = g_strdup("available"); |
| 11189 | 1324 |
| 11210 | 1325 if(!gaim_account_get_bool(account, "useproxy", FALSE)) { |
| 1326 hosttoconnect = g_strdup(sip->servername); | |
| 1327 } else { | |
| 1328 hosttoconnect = g_strdup(gaim_account_get_string(account, "proxy", sip->servername)); | |
| 1329 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1330 |
| 11341 | 1331 /* TCP case */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1332 if(! sip->udp) { |
| 11383 | 1333 gaim_srv_resolve("sip","tcp",hosttoconnect,srvresolved, sip); |
| 11341 | 1334 } else { /* UDP */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1335 gaim_srv_resolve("sip","udp",hosttoconnect,srvresolved, sip); |
| 11181 | 1336 } |
| 11210 | 1337 g_free(hosttoconnect); |
| 11181 | 1338 } |
| 1339 | |
| 1340 static void simple_close(GaimConnection *gc) | |
| 1341 { | |
| 1342 struct simple_account_data *sip = gc->proto_data; | |
| 11194 | 1343 |
| 11341 | 1344 /* unregister */ |
| 11194 | 1345 do_register_exp(sip, 0); |
| 11346 | 1346 connection_free_all(sip); |
| 11341 | 1347 if(sip) { |
| 11650 | 1348 g_free(sip->servername); |
| 1349 g_free(sip->username); | |
| 1350 g_free(sip->password); | |
| 1351 g_free(sip->registrar.nonce); | |
| 1352 g_free(sip->registrar.realm); | |
| 1353 g_free(sip->proxy.nonce); | |
| 1354 g_free(sip->proxy.realm); | |
| 1355 g_free(sip->sendlater); | |
| 1356 g_free(sip->realhostname); | |
| 11409 | 1357 if(sip->listenpa) gaim_input_remove(sip->listenpa); |
|
12571
2c73e08032a1
[gaim-migrate @ 14890]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12570
diff
changeset
|
1358 if(sip->resendtimeout) gaim_timeout_remove(sip->resendtimeout); |
| 11346 | 1359 if(sip->registertimeout) gaim_timeout_remove(sip->registertimeout); |
| 12760 | 1360 sip->servername = sip->username = sip->password = sip->registrar.nonce = sip->registrar.realm = sip->proxy.nonce = sip->proxy.realm = sip->sendlater = sip->realhostname = NULL; |
| 11181 | 1361 } |
| 11650 | 1362 g_free(gc->proto_data); |
|
12571
2c73e08032a1
[gaim-migrate @ 14890]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12570
diff
changeset
|
1363 gc->proto_data = NULL; |
| 11181 | 1364 } |
| 1365 | |
| 11345 | 1366 /* not needed since privacy is checked for every subscribe */ |
| 1367 static void dummy_add_deny(GaimConnection *gc, const char *name) { | |
| 1368 } | |
| 1369 | |
| 1370 static void dummy_permit_deny(GaimConnection *gc) { | |
| 1371 } | |
| 1372 | |
| 11181 | 1373 static GaimPluginProtocolInfo prpl_info = |
| 1374 { | |
| 1375 0, | |
| 1376 NULL, /* user_splits */ | |
| 1377 NULL, /* protocol_options */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1378 NO_BUDDY_ICONS, /* icon_spec */ |
| 11181 | 1379 simple_list_icon, /* list_icon */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1380 NULL, /* list_emblems */ |
| 11181 | 1381 NULL, /* status_text */ |
| 1382 NULL, /* tooltip_text */ | |
| 1383 simple_status_types, /* away_states */ | |
| 1384 NULL, /* blist_node_menu */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1385 NULL, /* chat_info */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1386 NULL, /* chat_info_defaults */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1387 simple_login, /* login */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1388 simple_close, /* close */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1389 simple_im_send, /* send_im */ |
| 11181 | 1390 NULL, /* set_info */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1391 simple_typing, /* send_typing */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1392 NULL, /* get_info */ |
| 11181 | 1393 simple_set_status, /* set_status */ |
| 1394 NULL, /* set_idle */ | |
| 1395 NULL, /* change_passwd */ | |
| 1396 simple_add_buddy, /* add_buddy */ | |
| 1397 NULL, /* add_buddies */ | |
| 1398 simple_remove_buddy, /* remove_buddy */ | |
| 1399 NULL, /* remove_buddies */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1400 dummy_add_deny, /* add_permit */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1401 dummy_add_deny, /* add_deny */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1402 dummy_add_deny, /* rem_permit */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1403 dummy_add_deny, /* rem_deny */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1404 dummy_permit_deny, /* set_permit_deny */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1405 NULL, /* join_chat */ |
| 11181 | 1406 NULL, /* reject_chat */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1407 NULL, /* get_chat_name */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1408 NULL, /* chat_invite */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1409 NULL, /* chat_leave */ |
| 11181 | 1410 NULL, /* chat_whisper */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1411 NULL, /* chat_send */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1412 simple_keep_alive, /* keepalive */ |
| 11181 | 1413 NULL, /* register_user */ |
| 1414 NULL, /* get_cb_info */ | |
| 1415 NULL, /* get_cb_away */ | |
| 1416 NULL, /* alias_buddy */ | |
| 1417 NULL, /* group_buddy */ | |
| 1418 NULL, /* rename_group */ | |
| 1419 NULL, /* buddy_free */ | |
| 1420 NULL, /* convo_closed */ | |
| 1421 NULL, /* normalize */ | |
| 1422 NULL, /* set_buddy_icon */ | |
| 1423 NULL, /* remove_group */ | |
| 1424 NULL, /* get_cb_real_name */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1425 NULL, /* set_chat_topic */ |
| 11181 | 1426 NULL, /* find_blist_chat */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1427 NULL, /* roomlist_get_list */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1428 NULL, /* roomlist_cancel */ |
| 11181 | 1429 NULL, /* roomlist_expand_category */ |
| 1430 NULL, /* can_receive_file */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1431 NULL, /* send_file */ |
|
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
1432 NULL, /* new_xfer */ |
|
12645
fc28451f5d96
[gaim-migrate @ 14983]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
1433 NULL, /* offline_message */ |
|
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
1434 NULL, /* whiteboard_prpl_ops */ |
|
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
1435 NULL, /* media_prpl_ops */ |
| 11181 | 1436 }; |
| 1437 | |
| 1438 | |
| 1439 static GaimPluginInfo info = | |
| 1440 { | |
| 1441 GAIM_PLUGIN_MAGIC, | |
| 1442 GAIM_MAJOR_VERSION, | |
| 1443 GAIM_MINOR_VERSION, | |
| 1444 GAIM_PLUGIN_PROTOCOL, /**< type */ | |
| 1445 NULL, /**< ui_requirement */ | |
| 1446 0, /**< flags */ | |
| 1447 NULL, /**< dependencies */ | |
| 1448 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
| 1449 | |
| 12489 | 1450 "prpl-simple", /**< id */ |
| 1451 "SIMPLE", /**< name */ | |
| 11181 | 1452 VERSION, /**< version */ |
| 12489 | 1453 N_("SIP/SIMPLE Protocol Plugin"), /** summary */ |
| 1454 N_("The SIP/SIMPLE Protocol Plugin"), /** description */ | |
| 1455 "Thomas Butter <butter@uni-mannheim.de>", /**< author */ | |
| 11181 | 1456 GAIM_WEBSITE, /**< homepage */ |
| 1457 | |
| 1458 NULL, /**< load */ | |
| 1459 NULL, /**< unload */ | |
| 1460 NULL, /**< destroy */ | |
| 1461 | |
| 1462 NULL, /**< ui_info */ | |
| 1463 &prpl_info, /**< extra_info */ | |
| 1464 NULL, | |
| 1465 NULL | |
| 1466 }; | |
| 1467 | |
| 1468 static void _init_plugin(GaimPlugin *plugin) | |
| 1469 { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1470 GaimAccountUserSplit *split; |
| 11189 | 1471 GaimAccountOption *option; |
| 11181 | 1472 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1473 split = gaim_account_user_split_new(_("Server"), "", '@'); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1474 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); |
| 11181 | 1475 |
| 12489 | 1476 option = gaim_account_option_bool_new(_("Publish status (note: everyone may watch you)"), "dopublish", TRUE); |
| 11345 | 1477 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
| 1478 | |
| 12769 | 1479 option = gaim_account_option_int_new(_("Connect port"), "port", 0); |
|
12730
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12689
diff
changeset
|
1480 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
|
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12689
diff
changeset
|
1481 |
|
d5b8f4dc1622
[gaim-migrate @ 15074]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12689
diff
changeset
|
1482 |
| 11189 | 1483 option = gaim_account_option_bool_new(_("Use UDP"), "udp", FALSE); |
| 1484 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 12489 | 1485 option = gaim_account_option_bool_new(_("Use proxy"), "useproxy", FALSE); |
| 11210 | 1486 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
| 1487 option = gaim_account_option_string_new(_("Proxy"), "proxy", ""); | |
| 1488 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 11181 | 1489 } |
| 1490 | |
| 1491 GAIM_INIT_PLUGIN(simple, _init_plugin, info); |
