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