Mercurial > pidgin
annotate src/protocols/simple/simple.c @ 13771:463259ea22ff
[gaim-migrate @ 16183]
Apparently if you just use --with-python the autotools decide you must mean
you want to use yes(1) as your python interpreter, this results in an
infinitely growing output file the first time the dbus stuff tries to generate
a header. That's bad. This should make it a bit clearer.
committer: Tailor Script <tailor@pidgin.im>
| author | Etan Reisner <pidgin@unreliablesource.net> |
|---|---|
| date | Fri, 12 May 2006 22:08:34 +0000 |
| parents | e4a4983752a9 |
| children | a9ff4499d9ce |
| 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 | |
| 64 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
|
65 return "simple"; |
| 11181 | 66 } |
| 67 | |
| 68 static void simple_keep_alive(GaimConnection *gc) { | |
| 11194 | 69 struct simple_account_data *sip = gc->proto_data; |
| 11341 | 70 if(sip->udp) { /* in case of UDP send a packet only with a 0 byte to |
| 71 remain in the NAT table */ | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
72 gchar buf[2] = {0, 0}; |
| 11194 | 73 gaim_debug_info("simple", "sending keep alive\n"); |
| 74 sendto(sip->fd, buf, 1, 0, (struct sockaddr*)&sip->serveraddr, sizeof(struct sockaddr_in)); | |
| 75 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
76 return; |
| 11181 | 77 } |
| 78 | |
| 79 static gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc); | |
| 80 static void send_notify(struct simple_account_data *sip, struct simple_watcher *); | |
| 81 | |
| 82 static void send_publish(struct simple_account_data *sip); | |
| 83 | |
| 84 static void do_notifies(struct simple_account_data *sip) { | |
| 85 GSList *tmp = sip->watcher; | |
| 86 gaim_debug_info("simple", "do_notifies()\n"); | |
| 11345 | 87 if((sip->republish != -1) || sip->republish < time(NULL)) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
88 if(gaim_account_get_bool(sip->account, "dopublish", TRUE)) { |
| 11345 | 89 send_publish(sip); |
| 90 } | |
| 91 } | |
| 11181 | 92 |
| 93 while(tmp) { | |
| 94 gaim_debug_info("simple", "notifying %s\n", ((struct simple_watcher*)tmp->data)->name); | |
| 95 send_notify(sip, tmp->data); | |
| 96 tmp = tmp->next; | |
| 97 } | |
| 98 } | |
| 99 | |
| 100 static void simple_set_status(GaimAccount *account, GaimStatus *status) { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
101 GaimStatusPrimitive primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
| 11181 | 102 struct simple_account_data *sip = NULL; |
| 11718 | 103 |
| 11181 | 104 if (!gaim_status_is_active(status)) |
| 105 return; | |
| 106 | |
| 11718 | 107 if (account->gc) |
| 108 sip = account->gc->proto_data; | |
| 109 | |
| 110 if (sip) | |
| 111 { | |
| 11650 | 112 g_free(sip->status); |
| 11718 | 113 if (primitive == GAIM_STATUS_AVAILABLE) |
| 114 sip->status = g_strdup("available"); | |
| 115 else | |
| 116 sip->status = g_strdup("busy"); | |
| 11181 | 117 |
| 118 do_notifies(sip); | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 static struct sip_connection *connection_find(struct simple_account_data *sip, int fd) { | |
| 123 struct sip_connection *ret = NULL; | |
| 124 GSList *entry = sip->openconns; | |
| 125 while(entry) { | |
| 126 ret = entry->data; | |
| 127 if(ret->fd == fd) return ret; | |
| 128 entry = entry->next; | |
| 129 } | |
| 130 return NULL; | |
| 131 } | |
| 132 | |
| 133 static struct simple_watcher *watcher_find(struct simple_account_data *sip, gchar *name) { | |
| 134 struct simple_watcher *watcher; | |
| 135 GSList *entry = sip->watcher; | |
| 136 while(entry) { | |
| 137 watcher = entry->data; | |
| 138 if(!strcmp(name, watcher->name)) return watcher; | |
| 139 entry = entry->next; | |
| 140 } | |
| 141 return NULL; | |
| 142 } | |
| 143 | |
| 13177 | 144 static struct simple_watcher *watcher_create(struct simple_account_data *sip, gchar *name, gchar *callid, gchar *ourtag, gchar *theirtag, int needsxpidf) { |
|
13092
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
145 struct simple_watcher *watcher = g_new0(struct simple_watcher, 1); |
| 11181 | 146 watcher->name = g_strdup(name); |
| 147 watcher->dialog.callid = g_strdup(callid); | |
| 148 watcher->dialog.ourtag = g_strdup(ourtag); | |
| 149 watcher->dialog.theirtag = g_strdup(theirtag); | |
| 13177 | 150 watcher->needsxpidf = needsxpidf; |
| 11181 | 151 sip->watcher = g_slist_append(sip->watcher, watcher); |
| 152 return watcher; | |
| 153 } | |
| 154 | |
| 155 static void watcher_remove(struct simple_account_data *sip, gchar *name) { | |
| 156 struct simple_watcher *watcher = watcher_find(sip, name); | |
| 157 sip->watcher = g_slist_remove(sip->watcher, watcher); | |
| 158 g_free(watcher->name); | |
| 159 g_free(watcher->dialog.callid); | |
| 160 g_free(watcher->dialog.ourtag); | |
| 161 g_free(watcher->dialog.theirtag); | |
| 162 g_free(watcher); | |
| 163 } | |
| 164 | |
| 165 static struct sip_connection *connection_create(struct simple_account_data *sip, int fd) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
166 struct sip_connection *ret = g_new0(struct sip_connection, 1); |
| 11181 | 167 ret->fd = fd; |
| 168 sip->openconns = g_slist_append(sip->openconns, ret); | |
| 169 return ret; | |
| 170 } | |
| 171 | |
| 172 static void connection_remove(struct simple_account_data *sip, int fd) { | |
| 173 struct sip_connection *conn = connection_find(sip, fd); | |
| 174 sip->openconns = g_slist_remove(sip->openconns, conn); | |
| 175 if(conn->inputhandler) gaim_input_remove(conn->inputhandler); | |
| 11650 | 176 g_free(conn->inbuf); |
| 11181 | 177 g_free(conn); |
| 178 } | |
| 179 | |
| 11346 | 180 static void connection_free_all(struct simple_account_data *sip) { |
| 181 struct sip_connection *ret = NULL; | |
| 182 GSList *entry = sip->openconns; | |
| 183 while(entry) { | |
| 184 ret = entry->data; | |
| 185 connection_remove(sip, ret->fd); | |
| 186 entry = sip->openconns; | |
| 187 } | |
| 188 } | |
| 189 | |
| 11181 | 190 static void simple_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 191 { | |
| 192 struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; | |
| 193 struct simple_buddy *b; | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
194 if(strncmp("sip:", buddy->name, 4)) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
195 gchar *buf = g_strdup_printf("sip:%s", buddy->name); |
| 12755 | 196 gaim_blist_rename_buddy(buddy, buf); |
| 11181 | 197 g_free(buf); |
| 198 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
199 if(!g_hash_table_lookup(sip->buddies, buddy->name)) { |
| 11181 | 200 b = g_new0(struct simple_buddy, 1); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
201 gaim_debug_info("simple", "simple_add_buddy %s\n", buddy->name); |
| 11181 | 202 b->name = g_strdup(buddy->name); |
| 203 g_hash_table_insert(sip->buddies, b->name, b); | |
| 204 } else { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
205 gaim_debug_info("simple", "buddy %s already in internal list\n", buddy->name); |
| 11181 | 206 } |
| 207 } | |
| 208 | |
| 209 static void simple_get_buddies(GaimConnection *gc) { | |
| 210 GaimBlistNode *gnode, *cnode, *bnode; | |
| 211 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
212 gaim_debug_info("simple", "simple_get_buddies\n"); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
213 |
| 11181 | 214 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { |
| 215 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) continue; | |
| 216 for(cnode = gnode->child; cnode; cnode = cnode->next) { | |
| 217 if(!GAIM_BLIST_NODE_IS_CONTACT(cnode)) continue; | |
| 218 for(bnode = cnode->child; bnode; bnode = bnode->next) { | |
| 219 if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) continue; | |
| 11192 | 220 if(((GaimBuddy*)bnode)->account == gc->account) |
| 221 simple_add_buddy(gc, (GaimBuddy*)bnode, (GaimGroup *)gnode); | |
| 11181 | 222 } |
| 223 } | |
| 224 } | |
| 225 } | |
| 226 | |
| 227 static void simple_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) | |
| 228 { | |
| 229 struct simple_account_data *sip = (struct simple_account_data *)gc->proto_data; | |
| 230 struct simple_buddy *b = g_hash_table_lookup(sip->buddies, buddy->name); | |
| 231 g_hash_table_remove(sip->buddies, buddy->name); | |
| 232 g_free(b->name); | |
| 233 g_free(b); | |
| 234 } | |
| 235 | |
| 236 static GList *simple_status_types(GaimAccount *acc) { | |
| 237 GaimStatusType *type; | |
| 238 GList *types = NULL; | |
| 12456 | 239 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
240 type = gaim_status_type_new_with_attrs( |
|
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12571
diff
changeset
|
241 GAIM_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE, |
|
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12571
diff
changeset
|
242 "message", _("Message"), gaim_value_new(GAIM_TYPE_STRING), |
|
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12571
diff
changeset
|
243 NULL); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
244 types = g_list_append(types, type); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
245 |
| 12657 | 246 type = gaim_status_type_new_full( |
| 247 GAIM_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE); | |
| 248 types = g_list_append(types, type); | |
| 249 | |
| 11181 | 250 return types; |
| 251 } | |
| 252 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
253 static gchar *auth_header(struct simple_account_data *sip, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
254 struct sip_auth *auth, const gchar *method, const gchar *target) { |
| 11346 | 255 gchar noncecount[9]; |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
256 gchar *response; |
| 11346 | 257 gchar *ret; |
| 11409 | 258 gchar *tmp; |
| 13088 | 259 const char *authdomain; |
| 260 const char *authuser; | |
| 261 | |
| 262 authdomain = gaim_account_get_string(sip->account, "authdomain", ""); | |
| 263 authuser = gaim_account_get_string(sip->account, "authuser", sip->username); | |
| 264 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
265 if(!authuser || strlen(authuser) < 1) { |
| 13084 | 266 authuser = sip->username; |
| 267 } | |
| 11409 | 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 |
| 13084 | 276 ret = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n", authuser, auth->realm, auth->nonce, target, noncecount, response); |
|
12382
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 */ | |
| 13084 | 280 if(auth->nc == 3 && auth->nonce) { |
| 13698 | 281 /* TODO: Don't hardcode "gaim" as the hostname */ |
| 282 ret = gaim_ntlm_gen_type3(authuser, sip->password, "gaim", authdomain, (const guint8 *)auth->nonce, &auth->flags); | |
| 13084 | 283 tmp = g_strdup_printf("NTLM qop=\"auth\", opaque=\"%s\", realm=\"%s\", targetname=\"%s\", gssapi-data=\"%s\"\r\n", auth->opaque, auth->realm, auth->target, ret); |
| 11409 | 284 g_free(ret); |
| 285 return tmp; | |
| 286 } | |
| 13084 | 287 tmp = g_strdup_printf("NTLM qop=\"auth\", realm=\"%s\", targetname=\"%s\", gssapi-data=\"\"\r\n", auth->realm, auth->target); |
| 11409 | 288 return tmp; |
| 289 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
290 |
| 11346 | 291 sprintf(noncecount, "%08d", auth->nc++); |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
292 response = gaim_cipher_http_digest_calculate_response( |
|
12389
e024601d45c7
[gaim-migrate @ 14695]
Richard Laager <rlaager@wiktel.com>
parents:
12382
diff
changeset
|
293 "md5", method, target, NULL, NULL, |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
294 auth->nonce, noncecount, NULL, auth->digest_session_key); |
| 11346 | 295 gaim_debug(GAIM_DEBUG_MISC, "simple", "response %s\n", response); |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
296 |
| 13084 | 297 ret = g_strdup_printf("Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", nc=\"%s\", response=\"%s\"\r\n", authuser, auth->realm, auth->nonce, target, noncecount, response); |
|
12382
cfc808463763
[gaim-migrate @ 14688]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
298 g_free(response); |
| 11346 | 299 return ret; |
| 300 } | |
| 301 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
302 static char *parse_attribute(const char *attrname, char *source) { |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
303 char *tmp, *tmp2, *retval = NULL; |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
304 int len = strlen(attrname); |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
305 |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
306 if(!strncmp(source, attrname, len)) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
307 tmp = source + len; |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
308 tmp2 = g_strstr_len(tmp, strlen(tmp), "\""); |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
309 if(tmp2) |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
310 retval = g_strndup(tmp, tmp2 - tmp); |
| 13085 | 311 else |
| 312 retval = g_strdup(tmp); | |
|
12746
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 |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
315 return retval; |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
316 } |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
317 |
| 11346 | 318 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
319 int i = 0; |
| 13088 | 320 const char *authuser; |
| 11424 | 321 char *tmp; |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
322 gchar **parts; |
| 13084 | 323 |
| 13088 | 324 authuser = gaim_account_get_string(sip->account, "authuser", sip->username); |
| 325 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
326 if(!authuser || strlen(authuser) < 1) { |
| 13084 | 327 authuser = sip->username; |
| 328 } | |
| 13088 | 329 |
| 11346 | 330 if(!hdr) { |
| 11409 | 331 gaim_debug_error("simple", "fill_auth: hdr==NULL\n"); |
| 11346 | 332 return; |
| 333 } | |
| 11409 | 334 |
| 335 if(!g_strncasecmp(hdr, "NTLM", 4)) { | |
| 336 gaim_debug_info("simple", "found NTLM\n"); | |
| 337 auth->type = 2; | |
| 13347 | 338 parts = g_strsplit(hdr+5, "\", ", 0); |
| 339 i = 0; | |
| 340 while(parts[i]) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
341 gaim_debug_info("simple", "parts[i] %s\n", parts[i]); |
| 13347 | 342 if((tmp = parse_attribute("gssapi-data=\"", parts[i]))) { |
| 13698 | 343 auth->nonce = g_memdup(gaim_ntlm_parse_type2(tmp, &auth->flags), 8); |
| 13347 | 344 g_free(tmp); |
| 345 } | |
| 346 if((tmp = parse_attribute("targetname=\"", | |
| 347 parts[i]))) { | |
| 348 auth->target = tmp; | |
| 11424 | 349 } |
| 13347 | 350 else if((tmp = parse_attribute("realm=\"", |
| 351 parts[i]))) { | |
| 352 auth->realm = tmp; | |
| 353 } | |
| 354 else if((tmp = parse_attribute("opaque=\"", parts[i]))) { | |
| 355 auth->opaque = tmp; | |
| 356 } | |
| 357 i++; | |
| 358 } | |
| 359 g_strfreev(parts); | |
| 360 auth->nc = 1; | |
| 361 if(!strstr(hdr, "gssapi-data")) { | |
| 11409 | 362 auth->nc = 1; |
| 13084 | 363 } else { |
| 11409 | 364 auth->nc = 3; |
| 13347 | 365 } |
| 11409 | 366 return; |
| 367 } | |
| 368 | |
| 369 auth->type = 1; | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
370 parts = g_strsplit(hdr, " ", 0); |
| 11346 | 371 while(parts[i]) { |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
372 if((tmp = parse_attribute("nonce=\"", parts[i]))) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
373 auth->nonce = tmp; |
| 11346 | 374 } |
|
12746
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
375 else if((tmp = parse_attribute("realm=\"", parts[i]))) { |
|
4f7dab030b1a
[gaim-migrate @ 15093]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12745
diff
changeset
|
376 auth->realm = tmp; |
| 11346 | 377 } |
| 378 i++; | |
| 379 } | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
380 g_strfreev(parts); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
381 |
| 13749 | 382 gaim_debug(GAIM_DEBUG_MISC, "simple", "nonce: %s realm: %s\n", auth->nonce ? auth->nonce : "(null)", auth->realm ? auth->realm : "(null)"); |
| 13656 | 383 if(auth->realm) { |
| 384 auth->digest_session_key = gaim_cipher_http_digest_calculate_session_key( | |
| 385 "md5", authuser, auth->realm, sip->password, auth->nonce, NULL); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
386 |
| 13656 | 387 auth->nc = 1; |
| 388 } | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
389 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
390 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
391 static void simple_canwrite_cb(gpointer data, gint source, GaimInputCondition cond) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
392 GaimConnection *gc = data; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
393 struct simple_account_data *sip = gc->proto_data; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
394 gsize max_write; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
395 gssize written; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
396 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
397 max_write = gaim_circ_buffer_get_max_read(sip->txbuf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
398 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
399 if(max_write == 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
400 gaim_input_remove(sip->tx_handler); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
401 sip->tx_handler = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
402 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
403 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
404 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
405 written = write(sip->fd, sip->txbuf->outptr, max_write); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
406 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
407 if(written < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
408 written = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
409 else if(written <= 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
410 /*TODO: do we really want to disconnect on a failure to write?*/ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
411 gaim_connection_error(gc, _("Could not write")); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
412 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
413 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
414 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
415 gaim_circ_buffer_mark_read(sip->txbuf, written); |
| 11346 | 416 } |
| 417 | |
| 11181 | 418 static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond); |
| 419 | |
| 420 static void send_later_cb(gpointer data, gint source, GaimInputCondition cond) { | |
| 421 GaimConnection *gc = data; | |
| 422 struct simple_account_data *sip = gc->proto_data; | |
| 423 struct sip_connection *conn; | |
| 424 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
425 if(source < 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
426 gaim_connection_error(gc, _("Could not connect")); |
| 11181 | 427 return; |
| 428 } | |
| 429 | |
| 430 sip->fd = source; | |
|
13058
256abf4dd912
[gaim-migrate @ 15420]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12909
diff
changeset
|
431 sip->connecting = FALSE; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
432 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
433 simple_canwrite_cb(gc, sip->fd, GAIM_INPUT_WRITE); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
434 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
435 /* If there is more to write now, we need to register a handler */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
436 if(sip->txbuf->bufused > 0) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
437 sip->tx_handler = gaim_input_add(sip->fd, GAIM_INPUT_WRITE, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
438 simple_canwrite_cb, gc); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
439 |
| 11181 | 440 conn = connection_create(sip, source); |
| 441 conn->inputhandler = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_input_cb, gc); | |
| 442 } | |
| 443 | |
| 444 | |
| 445 static void sendlater(GaimConnection *gc, const char *buf) { | |
| 446 struct simple_account_data *sip = gc->proto_data; | |
| 447 int error = 0; | |
| 448 if(!sip->connecting) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
449 gaim_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
450 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
|
451 if(error) { |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
452 gaim_connection_error(gc, _("Couldn't create socket")); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
453 } |
|
13058
256abf4dd912
[gaim-migrate @ 15420]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12909
diff
changeset
|
454 sip->connecting = TRUE; |
| 11181 | 455 } |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
456 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
457 if(gaim_circ_buffer_get_max_read(sip->txbuf) > 0) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
458 gaim_circ_buffer_append(sip->txbuf, "\r\n", 2); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
459 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
460 gaim_circ_buffer_append(sip->txbuf, buf, strlen(buf)); |
| 11181 | 461 } |
| 462 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
463 static void sendout_pkt(GaimConnection *gc, const char *buf) { |
| 11181 | 464 struct simple_account_data *sip = gc->proto_data; |
| 465 time_t currtime = time(NULL); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
466 int writelen = strlen(buf); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
467 |
| 11181 | 468 gaim_debug(GAIM_DEBUG_MISC, "simple", "\n\nsending - %s\n######\n%s\n######\n\n", ctime(&currtime), buf); |
| 11189 | 469 if(sip->udp) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
470 if(sendto(sip->fd, buf, writelen, 0, (struct sockaddr*)&sip->serveraddr, sizeof(struct sockaddr_in)) < writelen) { |
| 11189 | 471 gaim_debug_info("simple", "could not send packet\n"); |
| 472 } | |
| 473 } else { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
474 int ret; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
475 if(sip->fd < 0) { |
| 11189 | 476 sendlater(gc, buf); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
477 return; |
| 11189 | 478 } |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
479 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
480 if(sip->tx_handler) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
481 ret = -1; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
482 errno = EAGAIN; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
483 } else |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
484 ret = write(sip->fd, buf, writelen); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
485 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
486 if (ret < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
487 ret = 0; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
488 else if(ret <= 0) { /* XXX: When does this happen legitimately? */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
489 sendlater(gc, buf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
490 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
491 } |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
492 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
493 if (ret < writelen) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
494 if(!sip->tx_handler) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
495 sip->tx_handler = gaim_input_add(sip->fd, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
496 GAIM_INPUT_WRITE, simple_canwrite_cb, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
497 gc); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
498 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
499 /* XXX: is it OK to do this? You might get part of a request sent |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
500 with part of another. */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
501 if(sip->txbuf->bufused > 0) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
502 gaim_circ_buffer_append(sip->txbuf, "\r\n", 2); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
503 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
504 gaim_circ_buffer_append(sip->txbuf, buf + ret, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
505 writelen - ret); |
| 11189 | 506 } |
| 11181 | 507 } |
| 508 } | |
| 509 | |
| 11194 | 510 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
|
511 GSList *tmp = msg->headers; |
| 11194 | 512 gchar *name; |
| 513 gchar *value; | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
514 GString *outstr = g_string_new(""); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
515 g_string_append_printf(outstr, "%s %s SIP/2.0\r\n", msg->method, msg->target); |
| 11194 | 516 while(tmp) { |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
517 name = ((struct siphdrelement*) (tmp->data))->name; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
518 value = ((struct siphdrelement*) (tmp->data))->value; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
519 g_string_append_printf(outstr, "%s: %s\r\n", name, value); |
| 11194 | 520 tmp = g_slist_next(tmp); |
| 521 } | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
522 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
|
523 sendout_pkt(sip->gc, outstr->str); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
524 g_string_free(outstr, TRUE); |
| 11194 | 525 } |
| 526 | |
| 11181 | 527 static void send_sip_response(GaimConnection *gc, struct sipmsg *msg, int code, char *text, char *body) { |
| 528 GSList *tmp = msg->headers; | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
529 gchar *name; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
530 gchar *value; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
531 GString *outstr = g_string_new(""); |
|
13092
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
532 |
| 12754 | 533 /* When sending the acknowlegements and errors, the content length from the original |
| 534 message is still here, but there is no body; we need to make sure we're sending the | |
| 535 correct content length */ | |
| 536 sipmsg_remove_header(msg, "Content-Length"); | |
| 537 if(body) { | |
| 538 gchar len[12]; | |
| 539 sprintf(len, "%" G_GSIZE_FORMAT , strlen(body)); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
540 sipmsg_add_header(msg, "Content-Length", len); |
| 12754 | 541 } |
| 542 else | |
| 543 sipmsg_add_header(msg, "Content-Length", "0"); | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
544 g_string_append_printf(outstr, "SIP/2.0 %d %s\r\n", code, text); |
| 11181 | 545 while(tmp) { |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
546 name = ((struct siphdrelement*) (tmp->data))->name; |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
547 value = ((struct siphdrelement*) (tmp->data))->value; |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
548 |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
549 g_string_append_printf(outstr, "%s: %s\r\n", name, value); |
| 11181 | 550 tmp = g_slist_next(tmp); |
| 551 } | |
|
12741
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
552 g_string_append_printf(outstr, "\r\n%s", body ? body : ""); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
553 sendout_pkt(gc, outstr->str); |
|
2b61e6ed85c3
[gaim-migrate @ 15088]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12730
diff
changeset
|
554 g_string_free(outstr, TRUE); |
| 11181 | 555 } |
| 556 | |
| 11194 | 557 static void transactions_remove(struct simple_account_data *sip, struct transaction *trans) { |
| 558 if(trans->msg) sipmsg_free(trans->msg); | |
| 559 sip->transactions = g_slist_remove(sip->transactions, trans); | |
| 560 g_free(trans); | |
| 561 } | |
| 562 | |
| 11181 | 563 static void transactions_add_buf(struct simple_account_data *sip, gchar *buf, void *callback) { |
| 564 struct transaction *trans = g_new0(struct transaction, 1); | |
| 565 trans->time = time(NULL); | |
| 566 trans->msg = sipmsg_parse_msg(buf); | |
| 567 trans->cseq = sipmsg_find_header(trans->msg, "CSeq"); | |
| 568 trans->callback = callback; | |
| 569 sip->transactions = g_slist_append(sip->transactions, trans); | |
| 570 } | |
| 571 | |
| 572 static struct transaction *transactions_find(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 573 struct transaction *trans; | |
| 574 GSList *transactions = sip->transactions; | |
| 575 gchar *cseq = sipmsg_find_header(msg, "CSeq"); | |
| 576 | |
| 577 while(transactions) { | |
| 578 trans = transactions->data; | |
| 579 if(!strcmp(trans->cseq, cseq)) { | |
| 580 return trans; | |
| 581 } | |
| 582 transactions = transactions->next; | |
| 583 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
584 |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
585 return NULL; |
| 11181 | 586 } |
| 587 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
588 static void send_sip_request(GaimConnection *gc, const gchar *method, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
589 const gchar *url, const gchar *to, const gchar *addheaders, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
590 const gchar *body, struct sip_dialog *dialog, TransCallback tc) { |
| 11181 | 591 struct simple_account_data *sip = gc->proto_data; |
|
13092
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
592 char *callid = dialog ? g_strdup(dialog->callid) : gencallid(); |
|
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
593 char *auth = ""; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
594 const char *addh = ""; |
| 12216 | 595 gchar *branch = genbranch(); |
| 596 char *buf; | |
| 597 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
598 if(!strcmp(method, "REGISTER")) { |
|
13092
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
599 if(sip->regcallid) { |
|
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
600 g_free(callid); |
|
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
601 callid = g_strdup(sip->regcallid); |
|
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
602 } |
| 12196 | 603 else sip->regcallid = g_strdup(callid); |
| 604 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
605 |
|
13092
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
606 if(addheaders) addh = addheaders; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
607 if(sip->registrar.type && !strcmp(method, "REGISTER")) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
608 buf = auth_header(sip, &sip->registrar, method, url); |
|
12563
b7f7f3a685ea
[gaim-migrate @ 14882]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12492
diff
changeset
|
609 auth = g_strdup_printf("Authorization: %s", buf); |
| 11346 | 610 g_free(buf); |
| 11181 | 611 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 612 } | |
| 613 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
614 if(sip->proxy.type && strcmp(method, "REGISTER")) { |
| 11346 | 615 buf = auth_header(sip, &sip->proxy, method, url); |
|
12563
b7f7f3a685ea
[gaim-migrate @ 14882]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12492
diff
changeset
|
616 auth = g_strdup_printf("Proxy-Authorization: %s", buf); |
| 11346 | 617 g_free(buf); |
| 11181 | 618 gaim_debug(GAIM_DEBUG_MISC, "simple", "header %s", auth); |
| 619 } | |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
620 |
| 11181 | 621 buf = g_strdup_printf("%s %s SIP/2.0\r\n" |
| 11190 | 622 "Via: SIP/2.0/%s %s:%d;branch=%s\r\n" |
| 13084 | 623 /* Don't know what epid is, but LCS wants it */ |
| 624 "From: <sip:%s@%s>;tag=%s;epid=1234567890\r\n" | |
| 11181 | 625 "To: <%s>%s%s\r\n" |
| 626 "Max-Forwards: 10\r\n" | |
| 627 "CSeq: %d %s\r\n" | |
| 13678 | 628 "User-Agent: Gaim/" VERSION "\r\n" |
| 11181 | 629 "Call-ID: %s\r\n" |
| 630 "%s%s" | |
| 11658 | 631 "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n%s", |
| 11181 | 632 method, |
| 633 url, | |
| 11190 | 634 sip->udp ? "UDP" : "TCP", |
| 13129 | 635 gaim_network_get_my_ip(-1), |
| 11181 | 636 sip->listenport, |
| 637 branch, | |
| 638 sip->username, | |
| 639 sip->servername, | |
| 640 dialog ? dialog->ourtag : gentag(), | |
| 641 to, | |
| 642 dialog ? ";tag=" : "", | |
| 643 dialog ? dialog->theirtag : "", | |
| 644 ++sip->cseq, | |
| 645 method, | |
| 646 callid, | |
| 647 auth, | |
| 648 addh, | |
| 649 strlen(body), | |
| 650 body); | |
| 651 g_free(branch); | |
| 652 g_free(callid); | |
| 653 | |
| 11341 | 654 /* add to ongoing transactions */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
655 |
| 11181 | 656 transactions_add_buf(sip, buf, tc); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
657 |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
658 sendout_pkt(gc, buf); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
659 |
| 11181 | 660 g_free(buf); |
| 661 } | |
| 662 | |
| 13177 | 663 static char *get_contact(struct simple_account_data *sip) { |
| 664 return g_strdup_printf("<sip:%s@%s:%d;transport=%s>;methods=\"MESSAGE, SUBSCRIBE, NOTIFY\"", sip->username, gaim_network_get_my_ip(-1), sip->listenport, sip->udp ? "udp" : "tcp"); | |
| 665 } | |
| 666 | |
| 11194 | 667 static void do_register_exp(struct simple_account_data *sip, int expire) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
668 char *uri = g_strdup_printf("sip:%s", sip->servername); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
669 char *to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); |
| 13177 | 670 char *contact = get_contact(sip); |
| 671 char *hdr = g_strdup_printf("Contact: %s\r\nExpires: %d\r\n", contact, expire); | |
| 672 g_free(contact); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
673 |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
674 sip->registerstatus = 1; |
|
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
675 |
| 11194 | 676 if(expire) { |
| 677 sip->reregister = time(NULL) + expire - 50; | |
| 678 } else { | |
| 679 sip->reregister = time(NULL) + 600; | |
| 680 } | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
681 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
682 send_sip_request(sip->gc, "REGISTER", uri, to, hdr, "", NULL, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
683 process_register_response); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
684 |
| 13177 | 685 g_free(hdr); |
| 11181 | 686 g_free(uri); |
| 687 g_free(to); | |
| 688 } | |
| 689 | |
| 11194 | 690 static void do_register(struct simple_account_data *sip) { |
| 691 do_register_exp(sip, sip->registerexpire); | |
| 692 } | |
| 693 | |
| 11181 | 694 static gchar *parse_from(gchar *hdr) { |
| 695 gchar *from = hdr; | |
| 696 gchar *tmp; | |
| 697 | |
| 698 if(!from) return NULL; | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
699 gaim_debug_info("simple", "parsing address out of %s\n", from); |
| 11181 | 700 tmp = strchr(from, '<'); |
| 701 | |
| 11341 | 702 /* i hate the different SIP UA behaviours... */ |
| 703 if(tmp) { /* sip address in <...> */ | |
| 11181 | 704 from = tmp+1; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
705 tmp = strchr(from, '>'); |
| 11181 | 706 if(tmp) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
707 from = g_strndup(from, tmp-from); |
| 11181 | 708 } else { |
| 709 gaim_debug_info("simple", "found < without > in From\n"); | |
| 710 return NULL; | |
| 711 } | |
| 712 } else { | |
| 713 tmp = strchr(from, ';'); | |
| 714 if(tmp) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
715 from = g_strndup(from, tmp-from); |
| 11483 | 716 } else { |
| 717 from = g_strdup(from); | |
| 11181 | 718 } |
| 719 } | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
720 gaim_debug_info("simple", "got %s\n", from); |
| 11181 | 721 return from; |
| 722 } | |
| 723 | |
| 724 static gboolean process_subscribe_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
725 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
|
726 |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
727 if(msg->response == 200 || msg->response == 202) { |
| 11181 | 728 return TRUE; |
| 729 } | |
| 730 | |
| 11341 | 731 /* 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
|
732 |
| 11181 | 733 gaim_prpl_got_user_status(sip->account, to, "offline", NULL); |
| 734 g_free(to); | |
| 735 return TRUE; | |
| 736 } | |
| 737 | |
| 738 static void simple_subscribe(struct simple_account_data *sip, struct simple_buddy *buddy) { | |
| 13347 | 739 gchar *contact = "Expires: 1200\r\nAccept: application/pidf+xml, application/xpidf+xml\r\nEvent: presence\r\n"; |
| 11181 | 740 gchar *to; |
| 13177 | 741 gchar *tmp; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
742 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
743 if(strstr(buddy->name,"sip:")) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
744 to = g_strdup(buddy->name); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
745 else |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
746 to = g_strdup_printf("sip:%s", buddy->name); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
747 |
| 13177 | 748 tmp = get_contact(sip); |
| 749 contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp); | |
| 750 g_free(tmp); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
751 |
| 11341 | 752 /* subscribe to buddy presence |
| 753 * 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
|
754 |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
755 send_sip_request(sip->gc, "SUBSCRIBE", to, to, contact, "", NULL, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
756 process_subscribe_response); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
757 |
| 11181 | 758 g_free(to); |
| 11341 | 759 g_free(contact); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
760 |
| 11341 | 761 /* resubscribe before subscription expires */ |
| 762 /* add some jitter */ | |
| 13347 | 763 buddy->resubscribe = time(NULL)+1140+(rand()%50); |
| 11181 | 764 } |
| 765 | |
| 13347 | 766 static gboolean simple_add_lcs_contacts(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { |
| 767 gchar *tmp; | |
| 768 xmlnode *item, *group, *isc; | |
| 769 const char *name_group; | |
| 770 GaimBuddy *b; | |
| 771 GaimGroup *g; | |
| 772 struct simple_buddy *bs; | |
| 773 int len = msg->bodylen; | |
| 774 | |
| 775 | |
| 776 tmp = sipmsg_find_header(msg, "Event"); | |
| 777 if(tmp && !strncmp(tmp,"vnd-microsoft-roaming-contacts",30)){ | |
| 778 | |
| 779 gaim_debug_info("simple","simple_add_lcs_contacts->%s-%d\n",msg->body, len); | |
| 780 /*Convert the contact from XML to Gaim Buddies*/ | |
| 781 isc = xmlnode_from_str(msg->body, len); | |
| 782 | |
| 783 /* ToDo. Find for all groups */ | |
| 784 group = xmlnode_get_child(isc, "group"); | |
| 785 name_group = xmlnode_get_attrib(group, "name"); | |
| 786 gaim_debug_info("simple","name_group->%s\n",name_group); | |
| 787 g = gaim_find_group(name_group); | |
| 788 if(!g) { | |
| 789 g = gaim_find_group("Buddies"); | |
| 790 if(!g){ | |
| 791 g = gaim_group_new("Buddies"); | |
| 792 } | |
| 793 }else{ | |
| 794 g = gaim_group_new(name_group); | |
| 795 } | |
| 796 | |
| 797 for(item = xmlnode_get_child(isc, "contact"); item; item = xmlnode_get_next_twin(item)) | |
| 798 { | |
| 799 const char *uri, *name, *groups; | |
| 800 uri = xmlnode_get_attrib(item, "uri"); | |
| 801 name = xmlnode_get_attrib(item, "name"); | |
| 802 groups = xmlnode_get_attrib(item, "groups"); | |
| 803 gaim_debug_info("simple","URI->%s\n",uri); | |
| 804 b = gaim_find_buddy(sip->account, g_strdup_printf("sip:%s",uri)); | |
| 805 if(!b){ | |
| 806 b = gaim_buddy_new(sip->account, g_strdup_printf("sip:%s",uri), uri); | |
| 807 } | |
| 808 gaim_blist_add_buddy(b, NULL, g, NULL); | |
| 809 gaim_blist_alias_buddy(b, uri); | |
| 810 bs = g_new0(struct simple_buddy, 1); | |
| 811 bs->name = g_strdup(b->name); | |
| 812 g_hash_table_insert(sip->buddies, bs->name, bs); | |
| 813 } | |
| 814 xmlnode_free(isc); | |
| 815 } | |
| 816 return 0; | |
| 817 } | |
| 818 | |
| 819 static void simple_subscribe_buddylist(struct simple_account_data *sip) { | |
| 820 gchar *contact = "Event: vnd-microsoft-roaming-contacts\r\nAccept: application/vnd-microsoft-roaming-contacts+xml\r\nSupported: com.microsoft.autoextend\r\nSupported: ms-benotify\r\nProxy-Require: ms-benotify\r\nSupported: ms-piggyback-first-notify\r\n"; | |
| 821 gchar *to; | |
| 822 gchar *tmp; | |
| 823 to = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); | |
| 824 | |
| 825 tmp = get_contact(sip); | |
| 826 | |
| 827 contact = g_strdup_printf("%sContact: %s\r\n", contact, tmp); | |
| 828 g_free(tmp); | |
| 829 | |
| 830 send_sip_request(sip->gc, "SUBSCRIBE",to, to, contact, "", NULL, simple_add_lcs_contacts); | |
| 831 | |
| 832 g_free(to); | |
| 833 g_free(contact); | |
| 834 } | |
| 835 | |
| 836 | |
| 11181 | 837 static void simple_buddy_resub(char *name, struct simple_buddy *buddy, struct simple_account_data *sip) { |
| 838 time_t curtime = time(NULL); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
839 gaim_debug_info("simple", "buddy resub\n"); |
| 11181 | 840 if(buddy->resubscribe < curtime) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
841 gaim_debug(GAIM_DEBUG_MISC, "simple", "simple_buddy_resub %s\n", name); |
| 11181 | 842 simple_subscribe(sip, buddy); |
| 843 } | |
| 844 } | |
| 845 | |
| 11194 | 846 static gboolean resend_timeout(struct simple_account_data *sip) { |
| 847 GSList *tmp = sip->transactions; | |
| 848 time_t currtime = time(NULL); | |
| 849 while(tmp) { | |
| 850 struct transaction *trans = tmp->data; | |
| 851 tmp = tmp->next; | |
| 852 gaim_debug_info("simple", "have open transaction age: %d\n", currtime- trans->time); | |
| 853 if((currtime - trans->time > 5) && trans->retries >= 1) { | |
| 11341 | 854 /* TODO 408 */ |
| 11194 | 855 } else { |
| 856 if((currtime - trans->time > 2) && trans->retries == 0) { | |
| 857 trans->retries++; | |
| 858 sendout_sipmsg(sip, trans->msg); | |
| 859 } | |
| 860 } | |
| 861 } | |
| 862 return TRUE; | |
| 863 } | |
| 864 | |
| 12768 | 865 static gboolean subscribe_timeout(struct simple_account_data *sip) { |
| 11181 | 866 GSList *tmp; |
| 867 time_t curtime = time(NULL); | |
| 11341 | 868 /* register again if first registration expires */ |
| 11181 | 869 if(sip->reregister < curtime) { |
| 11194 | 870 do_register(sip); |
| 11181 | 871 } |
| 11341 | 872 /* check for every subscription if we need to resubscribe */ |
| 11181 | 873 g_hash_table_foreach(sip->buddies, (GHFunc)simple_buddy_resub, (gpointer)sip); |
| 874 | |
| 11341 | 875 /* remove a timed out suscriber */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
876 |
| 11181 | 877 tmp = sip->watcher; |
| 878 while(tmp) { | |
| 879 struct simple_watcher *watcher = tmp->data; | |
| 880 if(watcher->expire < curtime) { | |
| 881 watcher_remove(sip, watcher->name); | |
| 882 tmp = sip->watcher; | |
| 883 } | |
| 884 if(tmp) tmp = tmp->next; | |
| 885 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
886 |
| 11181 | 887 return TRUE; |
| 888 } | |
| 889 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
890 static void simple_send_message(struct simple_account_data *sip, const char *to, const char *msg, const char *type) { |
| 11181 | 891 gchar *hdr; |
| 13184 | 892 gchar *fullto; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
893 if(strncmp("sip:", to, 4)) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
894 fullto = g_strdup_printf("sip:%s", to); |
| 13184 | 895 } else { |
| 896 fullto = g_strdup(to); | |
| 897 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
898 if(type) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
899 hdr = g_strdup_printf("Content-Type: %s\r\n", type); |
| 11181 | 900 } else { |
| 901 hdr = g_strdup("Content-Type: text/plain\r\n"); | |
| 902 } | |
| 13184 | 903 send_sip_request(sip->gc, "MESSAGE", fullto, fullto, hdr, msg, NULL, NULL); |
| 11181 | 904 g_free(hdr); |
| 13184 | 905 g_free(fullto); |
| 11181 | 906 } |
| 907 | |
| 12216 | 908 static int simple_im_send(GaimConnection *gc, const char *who, const char *what, GaimMessageFlags flags) { |
| 11181 | 909 struct simple_account_data *sip = gc->proto_data; |
| 910 char *to = g_strdup(who); | |
| 12216 | 911 char *text = gaim_unescape_html(what); |
| 11181 | 912 simple_send_message(sip, to, text, NULL); |
| 913 g_free(to); | |
| 914 g_free(text); | |
| 915 return 1; | |
| 916 } | |
| 917 | |
| 918 static void process_incoming_message(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 919 gchar *from; | |
| 920 gchar *contenttype; | |
| 921 gboolean found = FALSE; | |
| 922 | |
| 923 from = parse_from(sipmsg_find_header(msg, "From")); | |
| 924 | |
| 925 if(!from) return; | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
926 |
| 11181 | 927 gaim_debug(GAIM_DEBUG_MISC, "simple", "got message from %s: %s\n", from, msg->body); |
| 928 | |
| 929 contenttype = sipmsg_find_header(msg, "Content-Type"); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
930 if(!contenttype || !strncmp(contenttype, "text/plain", 10) || !strncmp(contenttype, "text/html", 9)) { |
| 11181 | 931 serv_got_im(sip->gc, from, msg->body, 0, time(NULL)); |
| 932 send_sip_response(sip->gc, msg, 200, "OK", NULL); | |
| 933 found = TRUE; | |
| 934 } | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
935 if(!strncmp(contenttype, "application/im-iscomposing+xml", 30)) { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
936 xmlnode *isc = xmlnode_from_str(msg->body, msg->bodylen); |
| 11181 | 937 xmlnode *state; |
| 938 gchar *statedata; | |
| 939 | |
| 940 if(!isc) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
941 gaim_debug_info("simple", "process_incoming_message: can not parse iscomposing\n"); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
942 return; |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
943 } |
| 11181 | 944 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
945 state = xmlnode_get_child(isc, "state"); |
| 11181 | 946 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
947 if(!state) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
948 gaim_debug_info("simple", "process_incoming_message: no state found\n"); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
949 return; |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
950 } |
| 11181 | 951 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
952 statedata = xmlnode_get_data(state); |
| 11181 | 953 if(statedata) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
954 if(strstr(statedata, "active")) serv_got_typing(sip->gc, from, 0, GAIM_TYPING); |
| 11181 | 955 else serv_got_typing_stopped(sip->gc, from); |
| 956 } | |
| 957 xmlnode_free(isc); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
958 send_sip_response(sip->gc, msg, 200, "OK", NULL); |
| 11181 | 959 found = TRUE; |
| 960 } | |
| 961 if(!found) { | |
| 962 gaim_debug_info("simple", "got unknown mime-type"); | |
| 963 send_sip_response(sip->gc, msg, 415, "Unsupported media type", NULL); | |
| 964 } | |
| 965 g_free(from); | |
| 966 } | |
| 967 | |
| 968 | |
| 969 gboolean process_register_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | |
| 970 gchar *tmp; | |
| 971 gaim_debug(GAIM_DEBUG_MISC, "simple", "in process register response response: %d\n", msg->response); | |
| 972 switch (msg->response) { | |
| 973 case 200: | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
974 if(sip->registerstatus < 3) { /* registered */ |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
975 if(gaim_account_get_bool(sip->account, "dopublish", TRUE)) { |
| 11345 | 976 send_publish(sip); |
| 977 } | |
| 11181 | 978 } |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
979 sip->registerstatus = 3; |
| 11181 | 980 gaim_connection_set_state(sip->gc, GAIM_CONNECTED); |
| 11341 | 981 |
| 982 /* get buddies from blist */ | |
| 983 simple_get_buddies(sip->gc); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
984 |
| 12768 | 985 subscribe_timeout(sip); |
| 13347 | 986 tmp = sipmsg_find_header(msg, "Allow-Events"); |
| 987 if(tmp && strstr(tmp,"vnd-microsoft-provisioning")){ | |
| 988 simple_subscribe_buddylist(sip); | |
| 989 } | |
| 990 | |
| 11181 | 991 break; |
| 992 case 401: | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
993 if(sip->registerstatus != 2) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
994 gaim_debug_info("simple", "REGISTER retries %d\n", sip->registrar.retries); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
995 if(sip->registrar.retries > 3) { |
| 13678 | 996 sip->gc->wants_to_die = TRUE; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
997 gaim_connection_error(sip->gc, _("Wrong Password")); |
| 11346 | 998 return TRUE; |
| 999 } | |
| 11181 | 1000 tmp = sipmsg_find_header(msg, "WWW-Authenticate"); |
| 1001 fill_auth(sip, tmp, &sip->registrar); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1002 sip->registerstatus = 2; |
| 11194 | 1003 do_register(sip); |
| 11181 | 1004 } |
| 1005 break; | |
| 1006 } | |
| 1007 return TRUE; | |
| 1008 } | |
| 1009 | |
| 1010 static void process_incoming_notify(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 1011 gchar *from; | |
| 1012 gchar *fromhdr; | |
| 1013 gchar *tmp2; | |
| 1014 xmlnode *pidf; | |
| 1015 xmlnode *basicstatus; | |
| 1016 gboolean isonline = FALSE; | |
| 1017 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1018 fromhdr = sipmsg_find_header(msg, "From"); |
| 11181 | 1019 from = parse_from(fromhdr); |
| 1020 if(!from) return; | |
| 1021 | |
| 1022 pidf = xmlnode_from_str(msg->body, msg->bodylen); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1023 |
| 11181 | 1024 if(!pidf) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1025 gaim_debug_info("simple", "process_incoming_notify: no parseable pidf\n"); |
| 11181 | 1026 return; |
| 1027 } | |
| 1028 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1029 basicstatus = xmlnode_get_child(xmlnode_get_child(xmlnode_get_child(pidf, "tuple"), "status"), "basic"); |
| 11181 | 1030 |
| 1031 if(!basicstatus) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1032 gaim_debug_info("simple", "process_incoming_notify: no basic found\n"); |
| 11181 | 1033 return; |
| 1034 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1035 |
| 11181 | 1036 tmp2 = xmlnode_get_data(basicstatus); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1037 |
| 11181 | 1038 if(!tmp2) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1039 gaim_debug_info("simple", "process_incoming_notify: no basic data found\n"); |
| 11181 | 1040 return; |
| 1041 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1042 |
| 11181 | 1043 if(strstr(tmp2, "open")) { |
| 1044 isonline = TRUE; | |
| 1045 } | |
| 1046 | |
| 1047 if(isonline) gaim_prpl_got_user_status(sip->account, from, "available", NULL); | |
| 1048 else gaim_prpl_got_user_status(sip->account, from, "offline", NULL); | |
| 1049 | |
| 1050 xmlnode_free(pidf); | |
| 1051 | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1052 g_free(from); |
| 11181 | 1053 send_sip_response(sip->gc, msg, 200, "OK", NULL); |
| 1054 } | |
| 1055 | |
| 1056 static int simple_typing(GaimConnection *gc, const char *name, int typing) { | |
| 1057 struct simple_account_data *sip = gc->proto_data; | |
| 1058 | |
| 1059 gchar *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | |
| 1060 "<isComposing xmlns=\"urn:ietf:params:xml:ns:im-iscomposing\"\n" | |
| 1061 "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" | |
| 1062 "xsi:schemaLocation=\"urn:ietf:params:xml:ns:im-composing iscomposing.xsd\">\n" | |
| 1063 "<state>%s</state>\n" | |
| 1064 "<contenttype>text/plain</contenttype>\n" | |
| 1065 "<refresh>60</refresh>\n" | |
| 1066 "</isComposing>"; | |
| 1067 gchar *recv = g_strdup(name); | |
| 1068 if(typing == GAIM_TYPING) { | |
| 1069 gchar *msg = g_strdup_printf(xml, "active"); | |
| 1070 simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); | |
| 1071 g_free(msg); | |
| 1072 } else { | |
| 1073 gchar *msg = g_strdup_printf(xml, "idle"); | |
| 1074 simple_send_message(sip, recv, msg, "application/im-iscomposing+xml"); | |
| 1075 g_free(msg); | |
| 1076 } | |
| 1077 g_free(recv); | |
| 1078 return 1; | |
| 1079 } | |
| 1080 | |
| 1081 static gchar *find_tag(gchar *hdr) { | |
| 1082 gchar *tmp = strstr(hdr, ";tag="); | |
| 1083 gchar *tmp2; | |
| 1084 if(!tmp) return NULL; | |
| 1085 tmp += 5; | |
| 1086 if((tmp2 = strchr(tmp, ';'))) { | |
| 1087 tmp2[0] = '\0'; | |
| 1088 tmp = g_strdup(tmp); | |
| 1089 tmp2[0] = ';'; | |
| 1090 return tmp; | |
| 1091 } | |
| 1092 return g_strdup(tmp); | |
| 1093 } | |
| 1094 | |
| 13177 | 1095 static gchar* gen_xpidf(struct simple_account_data *sip) { |
| 1096 gchar *doc = g_strdup_printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | |
| 1097 "<presence>\n" | |
| 1098 "<presentity uri=\"sip:%s@%s;method=SUBSCRIBE\"/>\n" | |
| 1099 "<display name=\"sip:%s@%s\"/>\n" | |
| 1100 "<atom id=\"1234\">\n" | |
| 1101 "<address uri=\"sip:%s@%s\">\n" | |
| 1102 "<status status=\"%s\"/>\n" | |
| 1103 "</address>\n" | |
| 1104 "</atom>\n" | |
| 1105 "</presence>\n", | |
| 1106 sip->username, | |
| 1107 sip->servername, | |
| 1108 sip->username, | |
| 1109 sip->servername, | |
| 1110 sip->username, | |
| 1111 sip->servername, | |
| 1112 sip->status); | |
| 1113 return doc; | |
| 1114 } | |
| 1115 | |
| 1116 | |
| 1117 | |
| 11181 | 1118 static gchar* gen_pidf(struct simple_account_data *sip) { |
| 1119 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
|
1120 "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n" |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1121 "xmlns:im=\"urn:ietf:params:xml:ns:pidf:im\"\n" |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1122 "entity=\"sip:%s@%s\">\n" |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1123 "<tuple id=\"bs35r9f\">\n" |
| 11181 | 1124 "<status>\n" |
| 1125 "<basic>open</basic>\n" | |
| 1126 "</status>\n" | |
| 13655 | 1127 "<note>%s</note>\n" |
| 11181 | 1128 "</tuple>\n" |
| 1129 "</presence>", | |
| 1130 sip->username, | |
| 1131 sip->servername, | |
| 1132 sip->status); | |
| 1133 return doc; | |
| 1134 } | |
| 1135 | |
| 1136 static void send_notify(struct simple_account_data *sip, struct simple_watcher *watcher) { | |
| 13177 | 1137 gchar *doc = watcher->needsxpidf ? gen_xpidf(sip) : gen_pidf(sip); |
| 1138 gchar *hdr = watcher->needsxpidf ? "Event: presence\r\nContent-Type: application/xpidf+xml\r\n" : "Event: presence\r\nContent-Type: application/pidf+xml\r\n"; | |
| 1139 send_sip_request(sip->gc, "NOTIFY", watcher->name, watcher->name, hdr, doc, &watcher->dialog, NULL); | |
| 11181 | 1140 g_free(doc); |
| 1141 } | |
| 1142 | |
| 1143 static gboolean process_publish_response(struct simple_account_data *sip, struct sipmsg *msg, struct transaction *tc) { | |
| 11345 | 1144 if(msg->response != 200 && msg->response != 408) { |
| 11341 | 1145 /* never send again */ |
| 11181 | 1146 sip->republish = -1; |
| 1147 } | |
| 1148 return TRUE; | |
| 1149 } | |
| 1150 | |
| 1151 static void send_publish(struct simple_account_data *sip) { | |
| 1152 gchar *uri = g_strdup_printf("sip:%s@%s", sip->username, sip->servername); | |
| 1153 gchar *doc = gen_pidf(sip); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1154 send_sip_request(sip->gc, "PUBLISH", uri, uri, |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1155 "Expires: 600\r\nEvent: presence\r\n" |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1156 "Content-Type: application/pidf+xml\r\n", |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1157 doc, NULL, process_publish_response); |
| 11181 | 1158 sip->republish = time(NULL) + 500; |
| 1159 g_free(doc); | |
| 1160 } | |
| 1161 | |
| 1162 static void process_incoming_subscribe(struct simple_account_data *sip, struct sipmsg *msg) { | |
| 1163 gchar *from = parse_from(sipmsg_find_header(msg, "From")); | |
| 1164 gchar *theirtag = find_tag(sipmsg_find_header(msg, "From")); | |
| 1165 gchar *ourtag = find_tag(sipmsg_find_header(msg, "To")); | |
| 1166 gboolean tagadded = FALSE; | |
| 1167 gchar *callid = sipmsg_find_header(msg, "Call-ID"); | |
| 1168 gchar *expire = sipmsg_find_header(msg, "Expire"); | |
| 1169 gchar *tmp; | |
| 1170 struct simple_watcher *watcher = watcher_find(sip, from); | |
| 1171 if(!ourtag) { | |
| 1172 tagadded = TRUE; | |
| 1173 ourtag = gentag(); | |
| 1174 } | |
| 11341 | 1175 if(!watcher) { /* new subscription */ |
| 13177 | 1176 gchar *acceptheader = sipmsg_find_header(msg, "Accept"); |
| 1177 int needsxpidf = 0; | |
| 11345 | 1178 if(!gaim_privacy_check(sip->account, from)) { |
| 1179 send_sip_response(sip->gc, msg, 202, "Ok", NULL); | |
| 1180 goto privend; | |
| 1181 } | |
| 13177 | 1182 if(acceptheader) { |
| 1183 gchar *tmp = acceptheader; | |
| 1184 int foundpidf = 0; | |
| 1185 int foundxpidf = 0; | |
| 1186 while(tmp && tmp < acceptheader + strlen(acceptheader)) { | |
| 1187 gchar *tmp2 = strchr(tmp, ','); | |
| 1188 if(tmp2) *tmp2 = '\0'; | |
| 1189 if(!strcmp("application/pidf+xml",tmp)) | |
| 1190 foundpidf = 1; | |
| 1191 if(!strcmp("application/xpidf+xml",tmp)) | |
| 1192 foundxpidf = 1; | |
| 1193 if(tmp2) { | |
| 1194 *tmp2 = ','; | |
| 1195 tmp = tmp2; | |
| 1196 while(*tmp == ' ') tmp++; | |
| 1197 } else | |
| 1198 tmp = 0; | |
| 1199 } | |
| 1200 if(!foundpidf && foundxpidf) needsxpidf = 1; | |
| 1201 g_free(acceptheader); | |
| 1202 } | |
| 1203 watcher = watcher_create(sip, from, callid, ourtag, theirtag, needsxpidf); | |
| 11181 | 1204 } |
| 1205 if(tagadded) { | |
| 1206 gchar *to = g_strdup_printf("%s;tag=%s", sipmsg_find_header(msg, "To"), ourtag); | |
| 1207 sipmsg_remove_header(msg, "To"); | |
| 1208 sipmsg_add_header(msg, "To", to); | |
| 1209 } | |
| 1210 if(expire) | |
| 1211 watcher->expire = time(NULL) + strtol(expire, NULL, 10); | |
| 1212 else | |
| 1213 watcher->expire = time(NULL) + 600; | |
| 1214 sipmsg_remove_header(msg, "Contact"); | |
| 13177 | 1215 tmp = get_contact(sip); |
| 11181 | 1216 sipmsg_add_header(msg, "Contact", tmp); |
| 13177 | 1217 g_free(tmp); |
| 11181 | 1218 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); |
| 1219 send_sip_response(sip->gc, msg, 200, "Ok", NULL); | |
| 1220 send_notify(sip, watcher); | |
| 11345 | 1221 privend: |
| 1222 g_free(from); | |
| 1223 g_free(theirtag); | |
| 1224 g_free(ourtag); | |
| 1225 g_free(callid); | |
| 1226 g_free(expire); | |
| 11181 | 1227 } |
| 1228 | |
| 11189 | 1229 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
|
1230 gboolean found = FALSE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1231 if(msg->response == 0) { /* request */ |
| 11189 | 1232 if(!strcmp(msg->method, "MESSAGE")) { |
| 1233 process_incoming_message(sip, msg); | |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1234 found = TRUE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1235 } else if(!strcmp(msg->method, "NOTIFY")) { |
| 11189 | 1236 process_incoming_notify(sip, msg); |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1237 found = TRUE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1238 } else if(!strcmp(msg->method, "SUBSCRIBE")) { |
| 11189 | 1239 process_incoming_subscribe(sip, msg); |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1240 found = TRUE; |
|
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1241 } else { |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1242 send_sip_response(sip->gc, msg, 501, "Not implemented", NULL); |
| 11190 | 1243 } |
| 11341 | 1244 } else { /* response */ |
| 11189 | 1245 struct transaction *trans = transactions_find(sip, msg); |
| 1246 if(trans) { | |
| 1247 if(msg->response == 407) { | |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
1248 gchar *resend, *auth, *ptmp; |
|
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
1249 |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1250 if(sip->proxy.retries > 3) return; |
| 11346 | 1251 sip->proxy.retries++; |
| 11341 | 1252 /* do proxy authentication */ |
| 11189 | 1253 |
|
11439
617e67e1c985
[gaim-migrate @ 13676]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11424
diff
changeset
|
1254 ptmp = sipmsg_find_header(msg, "Proxy-Authenticate"); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1255 |
| 11189 | 1256 fill_auth(sip, ptmp, &sip->proxy); |
| 11346 | 1257 auth = auth_header(sip, &sip->proxy, trans->msg->method, trans->msg->target); |
| 13272 | 1258 sipmsg_remove_header(trans->msg, "Proxy-Authorization"); |
| 11189 | 1259 sipmsg_add_header(trans->msg, "Proxy-Authorization", auth); |
| 1260 g_free(auth); | |
| 1261 resend = sipmsg_to_string(trans->msg); | |
| 11341 | 1262 /* resend request */ |
| 11189 | 1263 sendout_pkt(sip->gc, resend); |
| 1264 g_free(resend); | |
| 1265 } else { | |
| 11517 | 1266 if(msg->response == 100) { |
| 1267 /* ignore provisional response */ | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1268 gaim_debug_info("simple", "got trying response\n"); |
| 11517 | 1269 } else { |
| 1270 sip->proxy.retries = 0; | |
| 13347 | 1271 if(!strcmp(trans->msg->method,"REGISTER")) { |
| 1272 if(msg->response == 401) sip->registrar.retries++; | |
| 1273 else sip->registrar.retries = 0; | |
| 1274 } else { | |
| 1275 if(msg->response == 401) { | |
| 1276 gchar *resend, *auth, *ptmp; | |
| 1277 | |
| 1278 if(sip->registrar.retries > 4) return; | |
| 1279 sip->registrar.retries++; | |
| 1280 | |
| 1281 ptmp = sipmsg_find_header(msg, "WWW-Authenticate"); | |
| 1282 | |
| 1283 fill_auth(sip, ptmp, &sip->registrar); | |
| 1284 auth = auth_header(sip, &sip->registrar, trans->msg->method, trans->msg->target); | |
| 1285 sipmsg_remove_header(trans->msg, "Authorization"); | |
| 1286 sipmsg_add_header(trans->msg, "Authorization", auth); | |
| 1287 g_free(auth); | |
| 1288 resend = sipmsg_to_string(trans->msg); | |
| 1289 /* resend request */ | |
| 1290 sendout_pkt(sip->gc, resend); | |
| 1291 g_free(resend); | |
| 1292 } | |
| 1293 } | |
| 11517 | 1294 if(trans->callback) { |
| 1295 /* call the callback to process response*/ | |
| 1296 (trans->callback)(sip, msg, trans); | |
| 1297 } | |
| 1298 transactions_remove(sip, trans); | |
| 11189 | 1299 } |
| 1300 } | |
|
12745
e788741f4840
[gaim-migrate @ 15092]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12741
diff
changeset
|
1301 found = TRUE; |
| 11189 | 1302 } else { |
| 1303 gaim_debug(GAIM_DEBUG_MISC, "simple", "received response to unknown transaction"); | |
| 1304 } | |
| 1305 } | |
| 1306 if(!found) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1307 gaim_debug(GAIM_DEBUG_MISC, "simple", "received a unknown sip message with method %s and response %d\n", msg->method, msg->response); |
| 11189 | 1308 } |
| 1309 } | |
| 1310 | |
| 11181 | 1311 static void process_input(struct simple_account_data *sip, struct sip_connection *conn) |
| 1312 { | |
| 1313 char *cur; | |
| 1314 char *dummy; | |
| 1315 struct sipmsg *msg; | |
| 1316 int restlen; | |
| 1317 cur = conn->inbuf; | |
| 1318 | |
| 11341 | 1319 /* according to the RFC remove CRLF at the beginning */ |
| 11181 | 1320 while(*cur == '\r' || *cur == '\n') { |
| 1321 cur++; | |
| 1322 } | |
| 1323 if(cur != conn->inbuf) { | |
| 1324 memmove(conn->inbuf, cur, conn->inbufused-(cur-conn->inbuf)); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1325 conn->inbufused = strlen(conn->inbuf); |
| 11181 | 1326 } |
| 1327 | |
| 11341 | 1328 /* Received a full Header? */ |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1329 if((cur = strstr(conn->inbuf, "\r\n\r\n")) != NULL) { |
| 11181 | 1330 time_t currtime = time(NULL); |
| 1331 cur += 2; | |
| 1332 cur[0] = '\0'; | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1333 gaim_debug_info("simple", "\n\nreceived - %s\n######\n%s\n#######\n\n", ctime(&currtime), conn->inbuf); |
| 11181 | 1334 msg = sipmsg_parse_header(conn->inbuf); |
| 1335 cur[0] = '\r'; | |
| 1336 cur += 2; | |
| 1337 restlen = conn->inbufused - (cur-conn->inbuf); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1338 if(restlen >= msg->bodylen) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1339 dummy = g_malloc(msg->bodylen + 1); |
| 11181 | 1340 memcpy(dummy, cur, msg->bodylen); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1341 dummy[msg->bodylen] = '\0'; |
| 11181 | 1342 msg->body = dummy; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1343 cur += msg->bodylen; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1344 memmove(conn->inbuf, cur, conn->inbuflen - (cur - conn->inbuf)); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1345 conn->inbufused = strlen(conn->inbuf); |
| 11181 | 1346 } else { |
| 1347 sipmsg_free(msg); | |
| 1348 return; | |
| 1349 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1350 gaim_debug(GAIM_DEBUG_MISC, "simple", "in process response response: %d\n", msg->response); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1351 process_input_message(sip, msg); |
| 11181 | 1352 } else { |
| 1353 gaim_debug(GAIM_DEBUG_MISC, "simple", "received a incomplete sip msg: %s\n", conn->inbuf); | |
| 1354 } | |
| 1355 } | |
| 1356 | |
| 11189 | 1357 static void simple_udp_process(gpointer data, gint source, GaimInputCondition con) { |
| 1358 GaimConnection *gc = data; | |
| 1359 struct simple_account_data *sip = gc->proto_data; | |
| 1360 struct sipmsg *msg; | |
| 1361 int len; | |
| 1362 time_t currtime; | |
| 1363 | |
| 1364 static char buffer[65536]; | |
|
12770
ab00cea25ef2
[gaim-migrate @ 15117]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12769
diff
changeset
|
1365 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
|
1366 buffer[len] = '\0'; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1367 gaim_debug_info("simple", "\n\nreceived - %s\n######\n%s\n#######\n\n", ctime(&currtime), buffer); |
|
12748
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1368 msg = sipmsg_parse_msg(buffer); |
|
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1369 if(msg) process_input_message(sip, msg); |
|
dd271caf25b0
[gaim-migrate @ 15095]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12746
diff
changeset
|
1370 } |
| 11189 | 1371 } |
| 1372 | |
| 11181 | 1373 static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond) |
| 1374 { | |
| 1375 GaimConnection *gc = data; | |
| 1376 struct simple_account_data *sip = gc->proto_data; | |
| 1377 int len; | |
| 1378 struct sip_connection *conn = connection_find(sip, source); | |
| 1379 if(!conn) { | |
| 1380 gaim_debug_error("simple", "Connection not found!\n"); | |
| 1381 return; | |
| 1382 } | |
| 1383 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1384 if(conn->inbuflen < conn->inbufused + SIMPLE_BUF_INC) { |
| 11181 | 1385 conn->inbuflen += SIMPLE_BUF_INC; |
| 1386 conn->inbuf = g_realloc(conn->inbuf, conn->inbuflen); | |
| 1387 } | |
| 1388 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1389 len = read(source, conn->inbuf + conn->inbufused, SIMPLE_BUF_INC - 1); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1390 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1391 if(len < 0 && errno == EAGAIN) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1392 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1393 else if(len <= 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1394 gaim_debug_info("simple", "simple_input_cb: read error\n"); |
| 11181 | 1395 connection_remove(sip, source); |
| 1396 if(sip->fd == source) sip->fd = -1; | |
| 1397 return; | |
| 1398 } | |
| 1399 | |
| 1400 conn->inbufused += len; | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1401 conn->inbuf[conn->inbufused] = '\0'; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1402 |
| 11181 | 1403 process_input(sip, conn); |
| 1404 } | |
| 1405 | |
| 1406 /* Callback for new connections on incoming TCP port */ | |
| 1407 static void simple_newconn_cb(gpointer data, gint source, GaimInputCondition cond) { | |
| 1408 GaimConnection *gc = data; | |
| 1409 struct simple_account_data *sip = gc->proto_data; | |
| 1410 struct sip_connection *conn; | |
| 1411 | |
| 1412 int newfd = accept(source, NULL, NULL); | |
| 1413 | |
| 1414 conn = connection_create(sip, newfd); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1415 |
| 11181 | 1416 conn->inputhandler = gaim_input_add(newfd, GAIM_INPUT_READ, simple_input_cb, gc); |
| 1417 } | |
| 1418 | |
| 1419 static void login_cb(gpointer data, gint source, GaimInputCondition cond) { | |
| 1420 GaimConnection *gc = data; | |
| 1421 struct simple_account_data *sip = gc->proto_data; | |
| 1422 struct sip_connection *conn; | |
| 1423 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1424 if(source < 0) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1425 gaim_connection_error(gc, _("Could not connect")); |
| 11181 | 1426 return; |
| 1427 } | |
| 1428 | |
| 1429 sip->fd = source; | |
| 1430 | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1431 conn = connection_create(sip, source); |
|
13092
edef744647ff
[gaim-migrate @ 15454]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13088
diff
changeset
|
1432 |
| 12768 | 1433 sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip); |
| 11181 | 1434 |
| 11194 | 1435 do_register(sip); |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1436 |
| 11181 | 1437 conn->inputhandler = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_input_cb, gc); |
| 1438 } | |
| 1439 | |
| 1440 static guint simple_ht_hash_nick(const char *nick) { | |
| 1441 char *lc = g_utf8_strdown(nick, -1); | |
| 1442 guint bucket = g_str_hash(lc); | |
| 1443 g_free(lc); | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1444 |
| 11181 | 1445 return bucket; |
| 1446 } | |
| 1447 | |
| 1448 static gboolean simple_ht_equals_nick(const char *nick1, const char *nick2) { | |
| 1449 return (gaim_utf8_strcasecmp(nick1, nick2) == 0); | |
| 1450 } | |
| 1451 | |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1452 static void simple_udp_host_resolved_listen_cb(int listenfd, gpointer data) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1453 struct simple_account_data *sip = (struct simple_account_data*) data; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1454 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1455 if(listenfd == -1) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1456 gaim_connection_error(sip->gc, _("Could not create listen socket")); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1457 return; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1458 } |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1459 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1460 sip->fd = listenfd; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1461 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1462 sip->listenport = gaim_network_get_port_from_fd(sip->fd); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1463 sip->listenfd = sip->fd; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1464 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1465 sip->listenpa = gaim_input_add(sip->fd, GAIM_INPUT_READ, simple_udp_process, sip->gc); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1466 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1467 sip->resendtimeout = gaim_timeout_add(2500, (GSourceFunc) resend_timeout, sip); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1468 sip->registertimeout = gaim_timeout_add((rand()%100)+10*1000, (GSourceFunc)subscribe_timeout, sip); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1469 do_register(sip); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1470 } |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1471 |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1472 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
|
1473 struct simple_account_data *sip = (struct simple_account_data*) data; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1474 int addr_size; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1475 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1476 if (!hosts || !hosts->data) { |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1477 gaim_connection_error(sip->gc, _("Couldn't resolve host")); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1478 return; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1479 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1480 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1481 addr_size = GPOINTER_TO_INT(hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1482 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1483 memcpy(&(sip->serveraddr), hosts->data, addr_size); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1484 g_free(hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1485 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1486 while(hosts) { |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1487 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1488 g_free(hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1489 hosts = g_slist_remove(hosts, hosts->data); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1490 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1491 |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1492 /* create socket for incoming connections */ |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1493 if(!gaim_network_listen_range(5060, 5160, SOCK_DGRAM, |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1494 simple_udp_host_resolved_listen_cb, sip)) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1495 gaim_connection_error(sip->gc, _("Could not create listen socket")); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1496 return; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1497 } |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1498 } |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1499 |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1500 static void |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1501 simple_tcp_connect_listen_cb(int listenfd, gpointer data) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1502 struct simple_account_data *sip = (struct simple_account_data*) data; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1503 int error = 0; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1504 |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1505 sip->listenfd = listenfd; |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1506 if(sip->listenfd == -1) { |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1507 gaim_connection_error(sip->gc, _("Could not create listen socket")); |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1508 return; |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1509 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1510 |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1511 gaim_debug_info("simple", "listenfd: %d\n", sip->listenfd); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1512 sip->listenport = gaim_network_get_port_from_fd(sip->listenfd); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1513 sip->listenpa = gaim_input_add(sip->listenfd, GAIM_INPUT_READ, |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1514 simple_newconn_cb, sip->gc); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1515 gaim_debug_info("simple", "connecting to %s port %d\n", |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1516 sip->realhostname, sip->realport); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1517 /* open tcp connection to the server */ |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1518 error = gaim_proxy_connect(sip->account, sip->realhostname, |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1519 sip->realport, login_cb, sip->gc); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1520 if(error) { |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1521 gaim_connection_error(sip->gc, _("Couldn't create socket")); |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1522 } |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1523 } |
|
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1524 |
|
12686
5f65a0cca87c
[gaim-migrate @ 15029]
Richard Laager <rlaager@wiktel.com>
parents:
12657
diff
changeset
|
1525 static void srvresolved(GaimSrvResponse *resp, int results, gpointer data) { |
| 13580 | 1526 GaimConnection *gc; |
| 1527 struct simple_account_data *sip; | |
| 1528 gchar *hostname; | |
| 1529 int port; | |
| 11383 | 1530 |
| 13580 | 1531 gc = data; |
| 1532 if (!g_list_find(gaim_connections_get_all(), gc)) | |
| 1533 { | |
| 1534 /* This connection has been closed */ | |
| 1535 g_free(resp); | |
| 1536 return; | |
| 1537 } | |
| 1538 | |
| 1539 sip = gc->proto_data; | |
| 1540 port = gaim_account_get_int(sip->account, "port", 0); | |
| 11383 | 1541 |
| 1542 /* find the host to connect to */ | |
| 1543 if(results) { | |
| 1544 hostname = g_strdup(resp->hostname); | |
| 12769 | 1545 if(!port) |
| 1546 port = resp->port; | |
| 11383 | 1547 g_free(resp); |
| 1548 } else { | |
| 1549 if(!gaim_account_get_bool(sip->account, "useproxy", FALSE)) { | |
| 1550 hostname = g_strdup(sip->servername); | |
| 1551 } else { | |
| 1552 hostname = g_strdup(gaim_account_get_string(sip->account, "proxy", sip->servername)); | |
| 1553 } | |
| 1554 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1555 |
| 11383 | 1556 sip->realhostname = hostname; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1557 sip->realport = port; |
| 12769 | 1558 if(!sip->realport) sip->realport = 5060; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1559 |
| 11383 | 1560 /* TCP case */ |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1561 if(!sip->udp) { |
| 11409 | 1562 /* create socket for incoming connections */ |
|
12909
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1563 if(!gaim_network_listen_range(5060, 5160, SOCK_STREAM, |
|
8e3b85fe4a55
[gaim-migrate @ 15262]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12770
diff
changeset
|
1564 simple_tcp_connect_listen_cb, sip)) { |
| 11409 | 1565 gaim_connection_error(sip->gc, _("Could not create listen socket")); |
| 1566 return; | |
| 1567 } | |
| 11383 | 1568 } else { /* UDP */ |
| 1569 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
|
1570 |
|
12767
53218d758ba9
[gaim-migrate @ 15114]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12760
diff
changeset
|
1571 gaim_gethostbyname_async(hostname, port, simple_udp_host_resolved, sip); |
| 11383 | 1572 } |
| 1573 } | |
| 1574 | |
| 11837 | 1575 static void simple_login(GaimAccount *account) |
| 11181 | 1576 { |
| 1577 GaimConnection *gc; | |
| 1578 struct simple_account_data *sip; | |
| 1579 gchar **userserver; | |
| 11210 | 1580 gchar *hosttoconnect; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1581 |
| 11181 | 1582 const char *username = gaim_account_get_username(account); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1583 gc = gaim_account_get_connection(account); |
| 11181 | 1584 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1585 if (strpbrk(username, " \t\v\r\n") != NULL) { |
| 13678 | 1586 gc->wants_to_die = TRUE; |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1587 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
|
1588 return; |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1589 } |
| 11181 | 1590 |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1591 gc->proto_data = sip = g_new0(struct simple_account_data, 1); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1592 sip->gc = gc; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1593 sip->account = account; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1594 sip->registerexpire = 900; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1595 sip->udp = gaim_account_get_bool(account, "udp", FALSE); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1596 /* TODO: is there a good default grow size? */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1597 if(!sip->udp) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1598 sip->txbuf = gaim_circ_buffer_new(0); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1599 |
| 11181 | 1600 userserver = g_strsplit(username, "@", 2); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1601 gaim_connection_set_display_name(gc, userserver[0]); |
| 11181 | 1602 sip->username = g_strdup(userserver[0]); |
| 1603 sip->servername = g_strdup(userserver[1]); | |
| 1604 sip->password = g_strdup(gaim_connection_get_password(gc)); | |
| 1605 g_strfreev(userserver); | |
| 1606 | |
| 1607 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
|
1608 |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1609 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); |
| 11181 | 1610 |
| 11837 | 1611 /* TODO: Set the status correctly. */ |
| 11181 | 1612 sip->status = g_strdup("available"); |
| 11189 | 1613 |
| 11210 | 1614 if(!gaim_account_get_bool(account, "useproxy", FALSE)) { |
| 1615 hosttoconnect = g_strdup(sip->servername); | |
| 1616 } else { | |
| 1617 hosttoconnect = g_strdup(gaim_account_get_string(account, "proxy", sip->servername)); | |
| 1618 } | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1619 |
| 11341 | 1620 /* TCP case */ |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1621 if(!sip->udp) { |
| 13580 | 1622 gaim_srv_resolve("sip", "tcp", hosttoconnect, srvresolved, gc); |
| 11341 | 1623 } else { /* UDP */ |
| 13580 | 1624 gaim_srv_resolve("sip", "udp", hosttoconnect, srvresolved, gc); |
| 11181 | 1625 } |
| 11210 | 1626 g_free(hosttoconnect); |
| 11181 | 1627 } |
| 1628 | |
| 1629 static void simple_close(GaimConnection *gc) | |
| 1630 { | |
| 1631 struct simple_account_data *sip = gc->proto_data; | |
| 11194 | 1632 |
| 11341 | 1633 if(sip) { |
|
13398
bddf037063bd
[gaim-migrate @ 15772]
Richard Laager <rlaager@wiktel.com>
parents:
13347
diff
changeset
|
1634 /* unregister */ |
|
bddf037063bd
[gaim-migrate @ 15772]
Richard Laager <rlaager@wiktel.com>
parents:
13347
diff
changeset
|
1635 do_register_exp(sip, 0); |
|
bddf037063bd
[gaim-migrate @ 15772]
Richard Laager <rlaager@wiktel.com>
parents:
13347
diff
changeset
|
1636 connection_free_all(sip); |
|
bddf037063bd
[gaim-migrate @ 15772]
Richard Laager <rlaager@wiktel.com>
parents:
13347
diff
changeset
|
1637 |
| 11650 | 1638 g_free(sip->servername); |
| 1639 g_free(sip->username); | |
| 1640 g_free(sip->password); | |
| 1641 g_free(sip->registrar.nonce); | |
| 13084 | 1642 g_free(sip->registrar.opaque); |
| 1643 g_free(sip->registrar.target); | |
| 11650 | 1644 g_free(sip->registrar.realm); |
| 13084 | 1645 g_free(sip->registrar.digest_session_key); |
| 11650 | 1646 g_free(sip->proxy.nonce); |
| 13084 | 1647 g_free(sip->proxy.opaque); |
| 1648 g_free(sip->proxy.target); | |
| 11650 | 1649 g_free(sip->proxy.realm); |
| 13084 | 1650 g_free(sip->proxy.digest_session_key); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1651 if(sip->txbuf) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1652 gaim_circ_buffer_destroy(sip->txbuf); |
| 11650 | 1653 g_free(sip->realhostname); |
| 11409 | 1654 if(sip->listenpa) gaim_input_remove(sip->listenpa); |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13184
diff
changeset
|
1655 if(sip->tx_handler) gaim_input_remove(sip->tx_handler); |
|
12571
2c73e08032a1
[gaim-migrate @ 14890]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12570
diff
changeset
|
1656 if(sip->resendtimeout) gaim_timeout_remove(sip->resendtimeout); |
| 11346 | 1657 if(sip->registertimeout) gaim_timeout_remove(sip->registertimeout); |
| 11181 | 1658 } |
| 11650 | 1659 g_free(gc->proto_data); |
|
12571
2c73e08032a1
[gaim-migrate @ 14890]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12570
diff
changeset
|
1660 gc->proto_data = NULL; |
| 11181 | 1661 } |
| 1662 | |
| 11345 | 1663 /* not needed since privacy is checked for every subscribe */ |
| 1664 static void dummy_add_deny(GaimConnection *gc, const char *name) { | |
| 1665 } | |
| 1666 | |
| 1667 static void dummy_permit_deny(GaimConnection *gc) { | |
| 1668 } | |
| 1669 | |
| 11181 | 1670 static GaimPluginProtocolInfo prpl_info = |
| 1671 { | |
| 1672 0, | |
| 1673 NULL, /* user_splits */ | |
| 1674 NULL, /* protocol_options */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1675 NO_BUDDY_ICONS, /* icon_spec */ |
| 11181 | 1676 simple_list_icon, /* list_icon */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1677 NULL, /* list_emblems */ |
| 11181 | 1678 NULL, /* status_text */ |
| 1679 NULL, /* tooltip_text */ | |
| 1680 simple_status_types, /* away_states */ | |
| 1681 NULL, /* blist_node_menu */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1682 NULL, /* chat_info */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1683 NULL, /* chat_info_defaults */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1684 simple_login, /* login */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1685 simple_close, /* close */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1686 simple_im_send, /* send_im */ |
| 11181 | 1687 NULL, /* set_info */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1688 simple_typing, /* send_typing */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1689 NULL, /* get_info */ |
| 11181 | 1690 simple_set_status, /* set_status */ |
| 1691 NULL, /* set_idle */ | |
| 1692 NULL, /* change_passwd */ | |
| 1693 simple_add_buddy, /* add_buddy */ | |
| 1694 NULL, /* add_buddies */ | |
| 1695 simple_remove_buddy, /* remove_buddy */ | |
| 1696 NULL, /* remove_buddies */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1697 dummy_add_deny, /* add_permit */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1698 dummy_add_deny, /* add_deny */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1699 dummy_add_deny, /* rem_permit */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1700 dummy_add_deny, /* rem_deny */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1701 dummy_permit_deny, /* set_permit_deny */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1702 NULL, /* join_chat */ |
| 11181 | 1703 NULL, /* reject_chat */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1704 NULL, /* get_chat_name */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1705 NULL, /* chat_invite */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1706 NULL, /* chat_leave */ |
| 11181 | 1707 NULL, /* chat_whisper */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1708 NULL, /* chat_send */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1709 simple_keep_alive, /* keepalive */ |
| 11181 | 1710 NULL, /* register_user */ |
| 1711 NULL, /* get_cb_info */ | |
| 1712 NULL, /* get_cb_away */ | |
| 1713 NULL, /* alias_buddy */ | |
| 1714 NULL, /* group_buddy */ | |
| 1715 NULL, /* rename_group */ | |
| 1716 NULL, /* buddy_free */ | |
| 1717 NULL, /* convo_closed */ | |
| 1718 NULL, /* normalize */ | |
| 1719 NULL, /* set_buddy_icon */ | |
| 1720 NULL, /* remove_group */ | |
| 1721 NULL, /* get_cb_real_name */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1722 NULL, /* set_chat_topic */ |
| 11181 | 1723 NULL, /* find_blist_chat */ |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1724 NULL, /* roomlist_get_list */ |
|
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1725 NULL, /* roomlist_cancel */ |
| 11181 | 1726 NULL, /* roomlist_expand_category */ |
| 1727 NULL, /* can_receive_file */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
1728 NULL, /* send_file */ |
|
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
1729 NULL, /* new_xfer */ |
|
12645
fc28451f5d96
[gaim-migrate @ 14983]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
1730 NULL, /* offline_message */ |
|
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
1731 NULL, /* whiteboard_prpl_ops */ |
| 11181 | 1732 }; |
| 1733 | |
| 1734 | |
| 1735 static GaimPluginInfo info = | |
| 1736 { | |
| 1737 GAIM_PLUGIN_MAGIC, | |
| 1738 GAIM_MAJOR_VERSION, | |
| 1739 GAIM_MINOR_VERSION, | |
| 1740 GAIM_PLUGIN_PROTOCOL, /**< type */ | |
| 1741 NULL, /**< ui_requirement */ | |
| 1742 0, /**< flags */ | |
| 1743 NULL, /**< dependencies */ | |
| 1744 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
| 1745 | |
| 12489 | 1746 "prpl-simple", /**< id */ |
| 1747 "SIMPLE", /**< name */ | |
| 11181 | 1748 VERSION, /**< version */ |
| 12489 | 1749 N_("SIP/SIMPLE Protocol Plugin"), /** summary */ |
| 1750 N_("The SIP/SIMPLE Protocol Plugin"), /** description */ | |
| 1751 "Thomas Butter <butter@uni-mannheim.de>", /**< author */ | |
| 11181 | 1752 GAIM_WEBSITE, /**< homepage */ |
| 1753 | |
| 1754 NULL, /**< load */ | |
| 1755 NULL, /**< unload */ | |
| 1756 NULL, /**< destroy */ | |
| 1757 | |
| 1758 NULL, /**< ui_info */ | |
| 1759 &prpl_info, /**< extra_info */ | |
| 1760 NULL, | |
| 1761 NULL | |
| 1762 }; | |
| 1763 | |
| 1764 static void _init_plugin(GaimPlugin *plugin) | |
| 1765 { | |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1766 GaimAccountUserSplit *split; |
| 11189 | 1767 GaimAccountOption *option; |
| 11181 | 1768 |
|
11396
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1769 split = gaim_account_user_split_new(_("Server"), "", '@'); |
|
be776f9b1818
[gaim-migrate @ 13627]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11383
diff
changeset
|
1770 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); |
| 11181 | 1771 |
| 12489 | 1772 option = gaim_account_option_bool_new(_("Publish status (note: everyone may watch you)"), "dopublish", TRUE); |
| 11345 | 1773 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
| 1774 | |
| 12769 | 1775 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
|
1776 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
|
1777 |
| 11189 | 1778 option = gaim_account_option_bool_new(_("Use UDP"), "udp", FALSE); |
| 1779 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 12489 | 1780 option = gaim_account_option_bool_new(_("Use proxy"), "useproxy", FALSE); |
| 11210 | 1781 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
| 1782 option = gaim_account_option_string_new(_("Proxy"), "proxy", ""); | |
| 1783 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 13084 | 1784 option = gaim_account_option_string_new(_("Auth User"), "authuser", ""); |
| 1785 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 1786 option = gaim_account_option_string_new(_("Auth Domain"), "authdomain", ""); | |
| 1787 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 11181 | 1788 } |
| 1789 | |
| 1790 GAIM_INIT_PLUGIN(simple, _init_plugin, info); |
