Mercurial > pidgin.yaz
annotate src/protocols/oscar/oscar.c @ 2141:1fc962350561
[gaim-migrate @ 2151]
because one time, at band camp, there was this guy, and no matter what he did, there was always something wrong with it, and other people had to keep correcting him, and at first it was really annoying but then it became really funny
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Thu, 09 Aug 2001 23:24:09 +0000 |
parents | 18722ae5b882 |
children | cff133e0ec0c |
rev | line source |
---|---|
2086 | 1 /* |
2 * gaim | |
3 * | |
4 * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
5 * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx> | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
24 #include <config.h> |
2086 | 25 #endif |
26 | |
27 | |
28 #include <netdb.h> | |
29 #include <gtk/gtk.h> | |
30 #include <unistd.h> | |
31 #include <errno.h> | |
32 #include <netinet/in.h> | |
33 #include <arpa/inet.h> | |
34 #include <string.h> | |
35 #include <stdlib.h> | |
36 #include <stdio.h> | |
37 #include <time.h> | |
38 #include <sys/socket.h> | |
39 #include <sys/stat.h> | |
40 #include "multi.h" | |
41 #include "prpl.h" | |
42 #include "gaim.h" | |
43 #include "aim.h" | |
44 #include "proxy.h" | |
45 | |
46 #if USE_PIXBUF | |
47 #include <gdk-pixbuf/gdk-pixbuf.h> | |
48 #include <gdk-pixbuf/gdk-pixbuf-loader.h> | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
49 #define SCALE 48 |
2086 | 50 #endif |
51 | |
52 /*#include "pixmaps/cancel.xpm"*/ | |
53 #include "pixmaps/admin_icon.xpm" | |
54 #include "pixmaps/aol_icon.xpm" | |
55 #include "pixmaps/away_icon.xpm" | |
56 #include "pixmaps/dt_icon.xpm" | |
57 #include "pixmaps/free_icon.xpm" | |
58 | |
59 /* constants to identify proto_opts */ | |
60 #define USEROPT_AUTH 0 | |
61 #define USEROPT_AUTHPORT 1 | |
62 | |
63 #define AIMHASHDATA "http://gaim.sourceforge.net/aim_data.php3" | |
64 | |
65 static int gaim_caps = AIM_CAPS_CHAT | | |
66 #if USE_PIXBUF | |
67 AIM_CAPS_BUDDYICON | | |
68 #endif | |
69 AIM_CAPS_GETFILE | | |
70 AIM_CAPS_IMIMAGE; | |
71 | |
72 static GtkWidget *join_chat_spin = NULL; | |
73 static GtkWidget *join_chat_entry = NULL; | |
74 | |
75 struct oscar_data { | |
76 struct aim_session_t *sess; | |
77 struct aim_conn_t *conn; | |
78 | |
79 guint cnpa; | |
80 guint paspa; | |
81 | |
82 int create_exchange; | |
83 char *create_name; | |
84 | |
85 gboolean conf; | |
86 gboolean reqemail; | |
87 gboolean chpass; | |
88 char *oldp; | |
89 char *newp; | |
90 | |
91 GSList *oscar_chats; | |
92 GSList *direct_ims; | |
93 GSList *getfiles; | |
94 GSList *hasicons; | |
95 | |
96 gboolean killme; | |
97 }; | |
98 | |
99 struct chat_connection { | |
100 char *name; | |
101 char *show; /* AOL did something funny to us */ | |
102 int exchange; | |
103 int fd; /* this is redundant since we have the conn below */ | |
104 struct aim_conn_t *conn; | |
105 int inpa; | |
106 int id; | |
107 struct gaim_connection *gc; /* i hate this. */ | |
108 struct conversation *cnv; /* bah. */ | |
109 }; | |
110 | |
111 struct direct_im { | |
112 struct gaim_connection *gc; | |
113 char name[80]; | |
114 struct conversation *cnv; | |
115 int watcher; | |
116 struct aim_conn_t *conn; | |
117 }; | |
118 | |
119 struct ask_direct { | |
120 struct gaim_connection *gc; | |
121 char *sn; | |
122 struct aim_directim_priv *priv; | |
123 }; | |
124 | |
125 struct ask_getfile { | |
126 struct gaim_connection *gc; | |
127 char *sn; | |
128 char *cookie; | |
129 char *ip; | |
130 }; | |
131 | |
132 struct getfile_transfer { | |
133 struct gaim_connection *gc; | |
134 char *receiver; | |
135 char *filename; | |
136 struct aim_conn_t *conn; | |
137 struct aim_fileheader_t *fh; | |
138 int gip; | |
139 int gop; | |
140 FILE *listing; | |
141 FILE *file; | |
142 GtkWidget *window; | |
143 GtkWidget *meter; | |
144 GtkWidget *label; | |
145 long pos; | |
146 long size; | |
147 }; | |
148 | |
149 #if USE_PIXBUF | |
150 struct icon_req { | |
151 char *user; | |
152 time_t timestamp; | |
153 unsigned long length; | |
154 gpointer data; | |
155 gboolean request; | |
156 GdkPixbufAnimation *anim; | |
157 GdkPixbuf *unanim; | |
158 struct conversation *cnv; | |
159 GtkWidget *pix; | |
160 int curframe; | |
161 int timer; | |
162 }; | |
163 #endif | |
164 | |
165 static struct direct_im *find_direct_im(struct oscar_data *od, char *who) { | |
166 GSList *d = od->direct_ims; | |
167 char *n = g_strdup(normalize(who)); | |
168 struct direct_im *m = NULL; | |
169 | |
170 while (d) { | |
171 m = (struct direct_im *)d->data; | |
172 if (!strcmp(n, normalize(m->name))) | |
173 break; | |
174 m = NULL; | |
175 d = d->next; | |
176 } | |
177 | |
178 g_free(n); | |
179 return m; | |
180 } | |
181 | |
182 /* | |
183 static struct getfile_transfer *find_getfile_transfer(struct oscar_data *od, struct aim_conn_t *conn) { | |
184 GSList *g = od->getfiles; | |
185 struct getfile_transfer *n = NULL; | |
186 | |
187 while (g) { | |
188 n = (struct getfile_transfer *)g->data; | |
189 if (n->conn == conn) | |
190 return n; | |
191 n = NULL; | |
192 g = g->next; | |
193 } | |
194 | |
195 return n; | |
196 } | |
197 */ | |
198 | |
199 static char *extract_name(char *name) { | |
200 char *tmp; | |
201 int i, j; | |
202 char *x = strchr(name, '-'); | |
203 if (!x) return NULL; | |
204 x = strchr(++x, '-'); | |
205 if (!x) return NULL; | |
206 tmp = g_strdup(++x); | |
207 | |
208 for (i = 0, j = 0; x[i]; i++) { | |
209 if (x[i] != '%') | |
210 tmp[j++] = x[i]; | |
211 else { | |
212 char hex[3]; | |
213 hex[0] = x[++i]; | |
214 hex[1] = x[++i]; | |
215 hex[2] = 0; | |
216 sscanf(hex, "%x", (int *)&tmp[j++]); | |
217 } | |
218 } | |
219 | |
220 tmp[j] = 0; | |
221 return tmp; | |
222 } | |
223 | |
224 static struct chat_connection *find_oscar_chat(struct gaim_connection *gc, int id) { | |
225 GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats; | |
226 struct chat_connection *c = NULL; | |
227 if (gc->protocol != PROTO_OSCAR) return NULL; | |
228 | |
229 while (g) { | |
230 c = (struct chat_connection *)g->data; | |
231 if (c->id == id) | |
232 break; | |
233 g = g->next; | |
234 c = NULL; | |
235 } | |
236 | |
237 return c; | |
238 } | |
239 | |
240 static struct chat_connection *find_oscar_chat_by_conn(struct gaim_connection *gc, | |
241 struct aim_conn_t *conn) { | |
242 GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats; | |
243 struct chat_connection *c = NULL; | |
244 | |
245 while (g) { | |
246 c = (struct chat_connection *)g->data; | |
247 if (c->conn == conn) | |
248 break; | |
249 g = g->next; | |
250 c = NULL; | |
251 } | |
252 | |
253 return c; | |
254 } | |
255 | |
256 static int gaim_parse_auth_resp (struct aim_session_t *, struct command_rx_struct *, ...); | |
257 static int gaim_parse_login (struct aim_session_t *, struct command_rx_struct *, ...); | |
258 static int gaim_server_ready (struct aim_session_t *, struct command_rx_struct *, ...); | |
259 static int gaim_handle_redirect (struct aim_session_t *, struct command_rx_struct *, ...); | |
260 static int gaim_info_change (struct aim_session_t *, struct command_rx_struct *, ...); | |
261 static int gaim_account_confirm (struct aim_session_t *, struct command_rx_struct *, ...); | |
262 static int gaim_parse_oncoming (struct aim_session_t *, struct command_rx_struct *, ...); | |
263 static int gaim_parse_offgoing (struct aim_session_t *, struct command_rx_struct *, ...); | |
264 static int gaim_parse_incoming_im(struct aim_session_t *, struct command_rx_struct *, ...); | |
265 static int gaim_parse_misses (struct aim_session_t *, struct command_rx_struct *, ...); | |
266 static int gaim_parse_user_info (struct aim_session_t *, struct command_rx_struct *, ...); | |
267 static int gaim_parse_motd (struct aim_session_t *, struct command_rx_struct *, ...); | |
268 static int gaim_chatnav_info (struct aim_session_t *, struct command_rx_struct *, ...); | |
269 static int gaim_chat_join (struct aim_session_t *, struct command_rx_struct *, ...); | |
270 static int gaim_chat_leave (struct aim_session_t *, struct command_rx_struct *, ...); | |
271 static int gaim_chat_info_update (struct aim_session_t *, struct command_rx_struct *, ...); | |
272 static int gaim_chat_incoming_msg(struct aim_session_t *, struct command_rx_struct *, ...); | |
273 static int gaim_parse_msgack (struct aim_session_t *, struct command_rx_struct *, ...); | |
274 static int gaim_parse_ratechange (struct aim_session_t *, struct command_rx_struct *, ...); | |
275 static int gaim_parse_evilnotify (struct aim_session_t *, struct command_rx_struct *, ...); | |
276 static int gaim_parse_searcherror(struct aim_session_t *, struct command_rx_struct *, ...); | |
277 static int gaim_parse_searchreply(struct aim_session_t *, struct command_rx_struct *, ...); | |
278 static int gaim_bosrights (struct aim_session_t *, struct command_rx_struct *, ...); | |
279 static int gaim_rateresp (struct aim_session_t *, struct command_rx_struct *, ...); | |
280 static int gaim_reportinterval (struct aim_session_t *, struct command_rx_struct *, ...); | |
281 static int gaim_parse_msgerr (struct aim_session_t *, struct command_rx_struct *, ...); | |
282 static int gaim_parse_buddyrights(struct aim_session_t *, struct command_rx_struct *, ...); | |
283 static int gaim_parse_locerr (struct aim_session_t *, struct command_rx_struct *, ...); | |
284 static int gaim_parse_genericerr (struct aim_session_t *, struct command_rx_struct *, ...); | |
285 static int gaim_memrequest (struct aim_session_t *, struct command_rx_struct *, ...); | |
286 | |
287 static int gaim_directim_initiate (struct aim_session_t *, struct command_rx_struct *, ...); | |
288 static int gaim_directim_incoming (struct aim_session_t *, struct command_rx_struct *, ...); | |
289 static int gaim_directim_disconnect(struct aim_session_t *, struct command_rx_struct *, ...); | |
290 static int gaim_directim_typing (struct aim_session_t *, struct command_rx_struct *, ...); | |
291 | |
292 static char *msgerrreason[] = { | |
293 "Invalid error", | |
294 "Invalid SNAC", | |
295 "Rate to host", | |
296 "Rate to client", | |
297 "Not logged in", | |
298 "Service unavailable", | |
299 "Service not defined", | |
300 "Obsolete SNAC", | |
301 "Not supported by host", | |
302 "Not supported by client", | |
303 "Refused by client", | |
304 "Reply too big", | |
305 "Responses lost", | |
306 "Request denied", | |
307 "Busted SNAC payload", | |
308 "Insufficient rights", | |
309 "In local permit/deny", | |
310 "Too evil (sender)", | |
311 "Too evil (receiver)", | |
312 "User temporarily unavailable", | |
313 "No match", | |
314 "List overflow", | |
315 "Request ambiguous", | |
316 "Queue full", | |
317 "Not while on AOL" | |
318 }; | |
319 static int msgerrreasonlen = 25; | |
320 | |
321 static void oscar_callback(gpointer data, gint source, | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
322 GaimInputCondition condition) { |
2086 | 323 struct aim_conn_t *conn = (struct aim_conn_t *)data; |
324 struct aim_session_t *sess = aim_conn_getsess(conn); | |
325 struct gaim_connection *gc = sess ? sess->aux_data : NULL; | |
326 struct oscar_data *odata; | |
327 | |
328 if (!gc) { | |
329 /* gc is null. we return, else we seg SIGSEG on next line. */ | |
330 debug_printf("oscar callback for closed connection (1).\n"); | |
331 return; | |
332 } | |
333 | |
334 odata = (struct oscar_data *)gc->proto_data; | |
335 | |
336 if (!g_slist_find(connections, gc)) { | |
337 /* oh boy. this is probably bad. i guess the only thing we | |
338 * can really do is return? */ | |
339 debug_printf("oscar callback for closed connection (2).\n"); | |
340 return; | |
341 } | |
342 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
343 if (condition & GAIM_INPUT_READ) { |
2086 | 344 if (conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) { |
345 debug_printf("got information on rendezvous\n"); | |
346 if (aim_handlerendconnect(odata->sess, conn) < 0) { | |
347 debug_printf(_("connection error (rend)\n")); | |
348 } | |
349 } else { | |
350 if (aim_get_command(odata->sess, conn) >= 0) { | |
351 aim_rxdispatch(odata->sess); | |
352 if (odata->killme) | |
353 signoff(gc); | |
354 } else { | |
355 if ((conn->type == AIM_CONN_TYPE_BOS) || | |
356 !(aim_getconn_type(odata->sess, AIM_CONN_TYPE_BOS))) { | |
357 debug_printf(_("major connection error\n")); | |
358 hide_login_progress(gc, _("Disconnected.")); | |
359 signoff(gc); | |
360 } else if (conn->type == AIM_CONN_TYPE_CHAT) { | |
361 struct chat_connection *c = find_oscar_chat_by_conn(gc, conn); | |
362 char buf[BUF_LONG]; | |
363 debug_printf("disconnected from chat room %s\n", c->name); | |
364 c->conn = NULL; | |
365 if (c->inpa > 0) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
366 gaim_input_remove(c->inpa); |
2086 | 367 c->inpa = 0; |
368 c->fd = -1; | |
369 aim_conn_kill(odata->sess, &conn); | |
370 sprintf(buf, _("You have been disconnected from chat room %s."), c->name); | |
371 do_error_dialog(buf, _("Chat Error!")); | |
372 } else if (conn->type == AIM_CONN_TYPE_CHATNAV) { | |
373 if (odata->cnpa > 0) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
374 gaim_input_remove(odata->cnpa); |
2086 | 375 odata->cnpa = 0; |
376 debug_printf("removing chatnav input watcher\n"); | |
377 if (odata->create_exchange) { | |
378 odata->create_exchange = 0; | |
379 g_free(odata->create_name); | |
380 odata->create_name = NULL; | |
381 do_error_dialog(_("Chat is currently unavailable"), | |
382 _("Gaim - Chat")); | |
383 } | |
384 aim_conn_kill(odata->sess, &conn); | |
385 } else if (conn->type == AIM_CONN_TYPE_AUTH) { | |
386 if (odata->paspa > 0) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
387 gaim_input_remove(odata->paspa); |
2086 | 388 odata->paspa = 0; |
389 debug_printf("removing authconn input watcher\n"); | |
390 aim_conn_kill(odata->sess, &conn); | |
391 } else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) { | |
392 debug_printf("No handler for rendezvous disconnect (%d).\n", | |
393 source); | |
394 aim_conn_kill(odata->sess, &conn); | |
395 } else { | |
396 debug_printf("holy crap! generic connection error! %d\n", | |
397 conn->type); | |
398 aim_conn_kill(odata->sess, &conn); | |
399 } | |
400 } | |
401 } | |
402 } | |
403 } | |
404 | |
405 static void oscar_debug(struct aim_session_t *sess, int level, const char *format, va_list va) { | |
406 char *s = g_strdup_vprintf(format, va); | |
407 char buf[256]; | |
408 char *t; | |
409 struct gaim_connection *gc = sess->aux_data; | |
410 | |
411 g_snprintf(buf, sizeof(buf), "%s %d: ", gc->username, level); | |
412 t = g_strconcat(buf, s, NULL); | |
413 debug_printf(t); | |
414 if (t[strlen(t)-1] != '\n') | |
415 debug_printf("\n"); | |
416 g_free(t); | |
417 g_free(s); | |
418 } | |
419 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
420 static void oscar_login_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 421 { |
422 struct gaim_connection *gc = data; | |
423 struct oscar_data *odata; | |
424 struct aim_session_t *sess; | |
425 struct aim_conn_t *conn; | |
426 | |
427 if (!g_slist_find(connections, gc)) { | |
428 close(source); | |
429 return; | |
430 } | |
431 | |
432 odata = gc->proto_data; | |
433 sess = odata->sess; | |
434 conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH); | |
435 | |
436 if (source < 0) { | |
437 hide_login_progress(gc, _("Couldn't connect to host")); | |
438 signoff(gc); | |
439 return; | |
440 } | |
441 | |
442 aim_conn_completeconnect(sess, conn); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
443 gc->inpa = gaim_input_add(conn->fd, GAIM_INPUT_READ, |
2086 | 444 oscar_callback, conn); |
445 debug_printf(_("Password sent, waiting for response\n")); | |
446 } | |
447 | |
448 static void oscar_login(struct aim_user *user) { | |
449 struct aim_session_t *sess; | |
450 struct aim_conn_t *conn; | |
451 char buf[256]; | |
452 struct gaim_connection *gc = new_gaim_conn(user); | |
453 struct oscar_data *odata = gc->proto_data = g_new0(struct oscar_data, 1); | |
454 odata->create_exchange = 0; | |
455 | |
456 debug_printf(_("Logging in %s\n"), user->username); | |
457 | |
458 sess = g_new0(struct aim_session_t, 1); | |
459 | |
460 aim_session_init(sess, AIM_SESS_FLAGS_NONBLOCKCONNECT, 0); | |
461 aim_setdebuggingcb(sess, oscar_debug); | |
462 | |
463 /* we need an immediate queue because we don't use a while-loop to | |
464 * see if things need to be sent. */ | |
465 aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL); | |
466 odata->sess = sess; | |
467 sess->aux_data = gc; | |
468 | |
469 conn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL); | |
470 if (conn == NULL) { | |
471 debug_printf(_("internal connection error\n")); | |
472 hide_login_progress(gc, _("Unable to login to AIM")); | |
473 signoff(gc); | |
474 return; | |
475 } | |
476 | |
477 g_snprintf(buf, sizeof(buf), _("Signon: %s"), gc->username); | |
478 set_login_progress(gc, 2, buf); | |
479 | |
480 aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0); | |
481 aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); | |
482 | |
483 conn->status |= AIM_CONN_STATUS_INPROGRESS; | |
484 conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ? | |
485 user->proto_opt[USEROPT_AUTH] : FAIM_LOGIN_SERVER, | |
486 user->proto_opt[USEROPT_AUTHPORT][0] ? | |
487 atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT, | |
488 oscar_login_connect, gc); | |
489 if (conn->fd < 0) { | |
490 hide_login_progress(gc, _("Couldn't connect to host")); | |
491 signoff(gc); | |
492 return; | |
493 } | |
494 aim_request_login(sess, conn, gc->username); | |
495 } | |
496 | |
497 static void oscar_close(struct gaim_connection *gc) { | |
498 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; | |
499 if (gc->protocol != PROTO_OSCAR) return; | |
500 | |
501 while (odata->oscar_chats) { | |
502 struct chat_connection *n = odata->oscar_chats->data; | |
503 if (n->inpa > 0) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
504 gaim_input_remove(n->inpa); |
2086 | 505 g_free(n->name); |
506 g_free(n->show); | |
507 odata->oscar_chats = g_slist_remove(odata->oscar_chats, n); | |
508 g_free(n); | |
509 } | |
510 while (odata->direct_ims) { | |
511 struct direct_im *n = odata->direct_ims->data; | |
512 if (n->watcher > 0) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
513 gaim_input_remove(n->watcher); |
2086 | 514 odata->direct_ims = g_slist_remove(odata->direct_ims, n); |
515 g_free(n); | |
516 } | |
517 #if USE_PIXBUF | |
518 while (odata->hasicons) { | |
519 struct icon_req *n = odata->hasicons->data; | |
520 if (n->anim) | |
521 gdk_pixbuf_animation_unref(n->anim); | |
522 if (n->unanim) | |
523 gdk_pixbuf_unref(n->unanim); | |
524 if (n->timer) | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2127
diff
changeset
|
525 g_source_remove(n->timer); |
2086 | 526 if (n->cnv && n->pix) |
527 gtk_container_remove(GTK_CONTAINER(n->cnv->bbox), n->pix); | |
528 g_free(n->user); | |
529 if (n->data) | |
530 g_free(n->data); | |
531 odata->hasicons = g_slist_remove(odata->hasicons, n); | |
532 g_free(n); | |
533 } | |
534 #endif | |
535 if (gc->inpa > 0) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
536 gaim_input_remove(gc->inpa); |
2086 | 537 if (odata->cnpa > 0) |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
538 gaim_input_remove(odata->cnpa); |
2086 | 539 if (odata->paspa > 0) |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
540 gaim_input_remove(odata->paspa); |
2086 | 541 aim_session_kill(odata->sess); |
542 g_free(odata->sess); | |
543 odata->sess = NULL; | |
544 g_free(gc->proto_data); | |
545 gc->proto_data = NULL; | |
546 debug_printf(_("Signed off.\n")); | |
547 } | |
548 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
549 static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition cond) { |
2086 | 550 struct gaim_connection *gc = data; |
551 struct oscar_data *odata; | |
552 struct aim_session_t *sess; | |
553 struct aim_conn_t *bosconn; | |
554 | |
555 if (!g_slist_find(connections, gc)) { | |
556 close(source); | |
557 return; | |
558 } | |
559 | |
560 odata = gc->proto_data; | |
561 sess = odata->sess; | |
562 bosconn = odata->conn; | |
563 | |
564 if (source < 0) { | |
565 hide_login_progress(gc, _("Could Not Connect")); | |
566 signoff(gc); | |
567 return; | |
568 } | |
569 | |
570 aim_conn_completeconnect(sess, bosconn); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
571 gc->inpa = gaim_input_add(bosconn->fd, GAIM_INPUT_READ, |
2086 | 572 oscar_callback, bosconn); |
573 set_login_progress(gc, 4, _("Connection established, cookie sent")); | |
574 } | |
575 | |
576 int gaim_parse_auth_resp(struct aim_session_t *sess, | |
577 struct command_rx_struct *command, ...) { | |
578 va_list ap; | |
579 struct aim_conn_t *bosconn = NULL; | |
580 char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL; | |
581 unsigned char *cookie = NULL; | |
582 int errorcode = 0, regstatus = 0; | |
583 int latestbuild = 0, latestbetabuild = 0; | |
584 char *latestrelease = NULL, *latestbeta = NULL; | |
585 char *latestreleaseurl = NULL, *latestbetaurl = NULL; | |
586 char *latestreleaseinfo = NULL, *latestbetainfo = NULL; | |
587 int i; char *host; int port; | |
588 struct aim_user *user; | |
589 | |
590 struct gaim_connection *gc = sess->aux_data; | |
591 struct oscar_data *od = gc->proto_data; | |
592 user = gc->user; | |
593 port = user->proto_opt[USEROPT_AUTHPORT][0] ? | |
594 atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT, | |
595 | |
596 va_start(ap, command); | |
597 sn = va_arg(ap, char *); | |
598 errorcode = va_arg(ap, int); | |
599 errurl = va_arg(ap, char *); | |
600 regstatus = va_arg(ap, int); | |
601 email = va_arg(ap, char *); | |
602 bosip = va_arg(ap, char *); | |
603 cookie = va_arg(ap, unsigned char *); | |
604 | |
605 latestrelease = va_arg(ap, char *); | |
606 latestbuild = va_arg(ap, int); | |
607 latestreleaseurl = va_arg(ap, char *); | |
608 latestreleaseinfo = va_arg(ap, char *); | |
609 | |
610 latestbeta = va_arg(ap, char *); | |
611 latestbetabuild = va_arg(ap, int); | |
612 latestbetaurl = va_arg(ap, char *); | |
613 latestbetainfo = va_arg(ap, char *); | |
614 | |
615 va_end(ap); | |
616 | |
617 debug_printf("inside auth_resp (Screen name: %s)\n", sn); | |
618 | |
619 if (errorcode || !bosip || !cookie) { | |
620 switch (errorcode) { | |
621 case 0x05: | |
622 /* Incorrect nick/password */ | |
623 hide_login_progress(gc, _("Incorrect nickname or password.")); | |
624 plugin_event(event_error, (void *)980, 0, 0, 0); | |
625 break; | |
626 case 0x11: | |
627 /* Suspended account */ | |
628 hide_login_progress(gc, _("Your account is currently suspended.")); | |
629 break; | |
630 case 0x18: | |
631 /* connecting too frequently */ | |
632 hide_login_progress(gc, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); | |
633 plugin_event(event_error, (void *)983, 0, 0, 0); | |
634 break; | |
635 case 0x1c: | |
636 /* client too old */ | |
637 hide_login_progress(gc, _("The client version you are using is too old. Please upgrade at " WEBSITE)); | |
638 plugin_event(event_error, (void *)989, 0, 0, 0); | |
639 break; | |
640 default: | |
641 hide_login_progress(gc, _("Authentication Failed")); | |
642 break; | |
643 } | |
644 debug_printf("Login Error Code 0x%04x\n", errorcode); | |
645 debug_printf("Error URL: %s\n", errurl); | |
646 od->killme = TRUE; | |
647 return 1; | |
648 } | |
649 | |
650 | |
651 debug_printf("Reg status: %2d\n", regstatus); | |
652 if (email) { | |
653 debug_printf("Email: %s\n", email); | |
654 } else { | |
655 debug_printf("Email is NULL\n"); | |
656 } | |
657 debug_printf("BOSIP: %s\n", bosip); | |
658 if (latestbeta) | |
659 debug_printf("Latest WinAIM beta version %s, build %d, at %s (%s)\n", | |
660 latestbeta, latestbetabuild, latestbetaurl, latestbetainfo); | |
661 if (latestrelease) | |
662 debug_printf("Latest WinAIM released version %s, build %d, at %s (%s)\n", | |
663 latestrelease, latestbuild, latestreleaseurl, latestreleaseinfo); | |
664 debug_printf("Closing auth connection...\n"); | |
665 aim_conn_kill(sess, &command->conn); | |
666 | |
667 bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, NULL); | |
668 if (bosconn == NULL) { | |
669 hide_login_progress(gc, _("Internal Error")); | |
670 od->killme = TRUE; | |
671 return 0; | |
672 } | |
673 | |
674 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, gaim_bosrights, 0); | |
675 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0007, gaim_rateresp, 0); /* rate info */ | |
676 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0); | |
677 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, gaim_server_ready, 0); | |
678 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATEINFO, NULL, 0); | |
679 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, gaim_handle_redirect, 0); | |
680 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL, gaim_reportinterval, 0); | |
681 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, gaim_parse_buddyrights, 0); | |
682 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, gaim_parse_oncoming, 0); | |
683 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, gaim_parse_offgoing, 0); | |
684 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, gaim_parse_incoming_im, 0); | |
685 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, gaim_parse_locerr, 0); | |
686 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, gaim_parse_misses, 0); | |
687 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, gaim_parse_ratechange, 0); | |
688 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, gaim_parse_evilnotify, 0); | |
689 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, gaim_parse_searcherror, 0); | |
690 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, 0x0003, gaim_parse_searchreply, 0); | |
691 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, gaim_parse_msgerr, 0); | |
692 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parse_user_info, 0); | |
693 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, gaim_parse_msgack, 0); | |
694 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0); | |
695 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0001, gaim_parse_genericerr, 0); | |
696 aim_conn_addhandler(sess, bosconn, 0x0003, 0x0001, gaim_parse_genericerr, 0); | |
697 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0001, gaim_parse_genericerr, 0); | |
698 aim_conn_addhandler(sess, bosconn, 0x0001, 0x001f, gaim_memrequest, 0); | |
699 | |
700 ((struct oscar_data *)gc->proto_data)->conn = bosconn; | |
701 for (i = 0; i < (int)strlen(bosip); i++) { | |
702 if (bosip[i] == ':') { | |
703 port = atoi(&(bosip[i+1])); | |
704 break; | |
705 } | |
706 } | |
707 host = g_strndup(bosip, i); | |
708 bosconn->status |= AIM_CONN_STATUS_INPROGRESS; | |
709 bosconn->fd = proxy_connect(host, port, oscar_bos_connect, gc); | |
710 g_free(host); | |
711 if (bosconn->fd < 0) { | |
712 hide_login_progress(gc, _("Could Not Connect")); | |
713 od->killme = TRUE; | |
714 return 0; | |
715 } | |
716 aim_auth_sendcookie(sess, bosconn, cookie); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
717 gaim_input_remove(gc->inpa); |
2086 | 718 return 1; |
719 } | |
720 | |
721 struct pieceofcrap { | |
722 struct gaim_connection *gc; | |
723 unsigned long offset; | |
724 unsigned long len; | |
725 char *modname; | |
726 int fd; | |
727 struct aim_conn_t *conn; | |
728 unsigned int inpa; | |
729 }; | |
730 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
731 static void damn_you(gpointer data, gint source, GaimInputCondition c) |
2086 | 732 { |
733 struct pieceofcrap *pos = data; | |
734 struct oscar_data *od = pos->gc->proto_data; | |
735 char in = '\0'; | |
736 int x = 0; | |
737 unsigned char m[17]; | |
738 | |
739 while (read(pos->fd, &in, 1) == 1) { | |
740 if (in == '\n') | |
741 x++; | |
742 else if (in != '\r') | |
743 x = 0; | |
744 if (x == 2) | |
745 break; | |
746 in = '\0'; | |
747 } | |
748 if (in != '\n') { | |
749 do_error_dialog("Gaim was unable to get a valid hash for logging into AIM." | |
750 " You may be disconnected shortly.", "Login Error"); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
751 gaim_input_remove(pos->inpa); |
2086 | 752 close(pos->fd); |
753 g_free(pos); | |
754 return; | |
755 } | |
756 read(pos->fd, m, 16); | |
757 m[16] = '\0'; | |
758 debug_printf("Sending hash: "); | |
759 for (x = 0; x < 16; x++) | |
760 debug_printf("%02x ", (unsigned char)m[x]); | |
761 debug_printf("\n"); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
762 gaim_input_remove(pos->inpa); |
2086 | 763 close(pos->fd); |
764 aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH); | |
765 g_free(pos); | |
766 } | |
767 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
768 static void straight_to_hell(gpointer data, gint source, GaimInputCondition cond) { |
2086 | 769 struct pieceofcrap *pos = data; |
770 char buf[BUF_LONG]; | |
771 | |
772 if (source < 0) { | |
773 do_error_dialog("Gaim was unable to get a valid hash for logging into AIM." | |
774 " You may be disconnected shortly.", "Login Error"); | |
775 if (pos->modname) | |
776 g_free(pos->modname); | |
777 g_free(pos); | |
778 return; | |
779 } | |
780 | |
781 g_snprintf(buf, sizeof(buf), "GET " AIMHASHDATA | |
782 "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n", | |
783 pos->offset, pos->len, pos->modname ? pos->modname : ""); | |
784 write(pos->fd, buf, strlen(buf)); | |
785 if (pos->modname) | |
786 g_free(pos->modname); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
787 pos->inpa = gaim_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos); |
2086 | 788 return; |
789 } | |
790 | |
791 /* size of icbmui.ocm, the largest module in AIM 3.5 */ | |
792 #define AIM_MAX_FILE_SIZE 98304 | |
793 | |
794 int gaim_memrequest(struct aim_session_t *sess, | |
795 struct command_rx_struct *command, ...) { | |
796 va_list ap; | |
797 struct pieceofcrap *pos; | |
798 unsigned long offset, len; | |
799 char *modname; | |
800 int fd; | |
801 | |
802 va_start(ap, command); | |
803 offset = va_arg(ap, unsigned long); | |
804 len = va_arg(ap, unsigned long); | |
805 modname = va_arg(ap, char *); | |
806 va_end(ap); | |
807 | |
808 debug_printf("offset: %d, len: %d, file: %s\n", offset, len, modname ? modname : "aim.exe"); | |
809 if (len == 0) { | |
810 debug_printf("len is 0, hashing NULL\n"); | |
811 aim_sendmemblock(sess, command->conn, offset, len, NULL, | |
812 AIM_SENDMEMBLOCK_FLAG_ISREQUEST); | |
813 return 1; | |
814 } | |
815 /* uncomment this when you're convinced it's right. remember, it's been wrong before. | |
816 if (offset > AIM_MAX_FILE_SIZE || len > AIM_MAX_FILE_SIZE) { | |
817 char *buf; | |
818 int i = 8; | |
819 if (modname) | |
820 i += strlen(modname); | |
821 buf = g_malloc(i); | |
822 i = 0; | |
823 if (modname) { | |
824 memcpy(buf, modname, strlen(modname)); | |
825 i += strlen(modname); | |
826 } | |
827 buf[i++] = offset & 0xff; | |
828 buf[i++] = (offset >> 8) & 0xff; | |
829 buf[i++] = (offset >> 16) & 0xff; | |
830 buf[i++] = (offset >> 24) & 0xff; | |
831 buf[i++] = len & 0xff; | |
832 buf[i++] = (len >> 8) & 0xff; | |
833 buf[i++] = (len >> 16) & 0xff; | |
834 buf[i++] = (len >> 24) & 0xff; | |
835 debug_printf("len + offset is invalid, hashing request\n"); | |
836 aim_sendmemblock(sess, command->conn, offset, i, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST); | |
837 g_free(buf); | |
838 return 1; | |
839 } | |
840 */ | |
841 | |
842 pos = g_new0(struct pieceofcrap, 1); | |
843 pos->gc = sess->aux_data; | |
844 pos->conn = command->conn; | |
845 | |
846 pos->offset = offset; | |
847 pos->len = len; | |
848 pos->modname = modname ? g_strdup(modname) : NULL; | |
849 | |
850 fd = proxy_connect("gaim.sourceforge.net", 80, straight_to_hell, pos); | |
851 if (fd < 0) { | |
852 if (pos->modname) | |
853 g_free(pos->modname); | |
854 g_free(pos); | |
855 do_error_dialog("Gaim was unable to get a valid hash for logging into AIM." | |
856 " You may be disconnected shortly.", "Login Error"); | |
857 } | |
858 pos->fd = fd; | |
859 | |
860 return 1; | |
861 } | |
862 | |
863 int gaim_parse_login(struct aim_session_t *sess, | |
864 struct command_rx_struct *command, ...) { | |
865 #if 0 | |
866 struct client_info_s info = {"gaim", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x04b}; | |
867 #else | |
868 struct client_info_s info = AIM_CLIENTINFO_KNOWNGOOD; | |
869 #endif | |
870 char *key; | |
871 va_list ap; | |
872 struct gaim_connection *gc = sess->aux_data; | |
873 | |
874 va_start(ap, command); | |
875 key = va_arg(ap, char *); | |
876 va_end(ap); | |
877 | |
878 aim_send_login(sess, command->conn, gc->username, gc->password, &info, key); | |
879 return 1; | |
880 } | |
881 | |
882 int gaim_server_ready(struct aim_session_t *sess, | |
883 struct command_rx_struct *command, ...) { | |
884 static int id = 1; | |
885 struct gaim_connection *gc = sess->aux_data; | |
886 struct oscar_data *od = gc->proto_data; | |
887 struct chat_connection *chatcon; | |
888 switch (command->conn->type) { | |
889 case AIM_CONN_TYPE_AUTH: | |
890 aim_auth_setversions(sess, command->conn); | |
891 aim_bos_reqrate(sess, command->conn); | |
892 debug_printf("done with AUTH ServerReady\n"); | |
893 if (od->chpass) { | |
894 debug_printf("changing password\n"); | |
895 aim_auth_changepasswd(sess, command->conn, od->newp, od->oldp); | |
896 g_free(od->oldp); | |
897 g_free(od->newp); | |
898 od->chpass = FALSE; | |
899 } | |
900 if (od->conf) { | |
901 debug_printf("confirming account\n"); | |
902 aim_auth_reqconfirm(sess, command->conn); | |
903 od->conf = FALSE; | |
904 } | |
905 if (od->reqemail) { | |
906 debug_printf("requesting email\n"); | |
907 aim_auth_getinfo(sess, command->conn, 0x0011); | |
908 od->reqemail = FALSE; | |
909 } | |
910 break; | |
911 case AIM_CONN_TYPE_BOS: | |
912 aim_setversions(sess, command->conn); | |
913 aim_bos_reqrate(sess, command->conn); /* request rate info */ | |
914 debug_printf("done with BOS ServerReady\n"); | |
915 break; | |
916 case AIM_CONN_TYPE_CHATNAV: | |
917 debug_printf("chatnav: got server ready\n"); | |
918 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CTN, AIM_CB_CTN_INFO, gaim_chatnav_info, 0); | |
919 aim_bos_reqrate(sess, command->conn); | |
920 aim_bos_ackrateresp(sess, command->conn); | |
921 aim_chatnav_clientready(sess, command->conn); | |
922 aim_chatnav_reqrights(sess, command->conn); | |
923 break; | |
924 case AIM_CONN_TYPE_CHAT: | |
925 debug_printf("chat: got server ready\n"); | |
926 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, gaim_chat_join, 0); | |
927 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, gaim_chat_leave, 0); | |
928 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, gaim_chat_info_update, 0); | |
929 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, gaim_chat_incoming_msg, 0); | |
930 aim_bos_reqrate(sess, command->conn); | |
931 aim_bos_ackrateresp(sess, command->conn); | |
932 aim_chat_clientready(sess, command->conn); | |
933 chatcon = find_oscar_chat_by_conn(gc, command->conn); | |
934 chatcon->id = id; | |
935 chatcon->cnv = serv_got_joined_chat(gc, id++, chatcon->show); | |
936 break; | |
937 case AIM_CONN_TYPE_RENDEZVOUS: | |
938 break; | |
939 default: /* huh? */ | |
940 debug_printf("server ready: got unexpected connection type %04x\n", command->conn->type); | |
941 break; | |
942 } | |
943 return 1; | |
944 } | |
945 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
946 static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 947 { |
948 struct gaim_connection *gc = data; | |
949 struct oscar_data *odata; | |
950 struct aim_session_t *sess; | |
951 struct aim_conn_t *tstconn; | |
952 | |
953 if (!g_slist_find(connections, gc)) { | |
954 close(source); | |
955 return; | |
956 } | |
957 | |
958 odata = gc->proto_data; | |
959 sess = odata->sess; | |
960 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_CHATNAV); | |
961 | |
962 if (source < 0) { | |
963 aim_conn_kill(sess, &tstconn); | |
964 debug_printf("unable to connect to chatnav server\n"); | |
965 return; | |
966 } | |
967 | |
968 aim_conn_completeconnect(sess, tstconn); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
969 odata->cnpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, |
2086 | 970 oscar_callback, tstconn); |
971 debug_printf("chatnav: connected\n"); | |
972 } | |
973 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
974 static void oscar_auth_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 975 { |
976 struct gaim_connection *gc = data; | |
977 struct oscar_data *odata; | |
978 struct aim_session_t *sess; | |
979 struct aim_conn_t *tstconn; | |
980 | |
981 if (!g_slist_find(connections, gc)) { | |
982 close(source); | |
983 return; | |
984 } | |
985 | |
986 odata = gc->proto_data; | |
987 sess = odata->sess; | |
988 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH); | |
989 | |
990 if (source < 0) { | |
991 aim_conn_kill(sess, &tstconn); | |
992 debug_printf("unable to connect to authorizer\n"); | |
993 return; | |
994 } | |
995 | |
996 aim_conn_completeconnect(sess, tstconn); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
997 odata->paspa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, |
2086 | 998 oscar_callback, tstconn); |
999 debug_printf("chatnav: connected\n"); | |
1000 } | |
1001 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1002 static void oscar_chat_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 1003 { |
1004 struct chat_connection *ccon = data; | |
1005 struct gaim_connection *gc = ccon->gc; | |
1006 struct oscar_data *odata; | |
1007 struct aim_session_t *sess; | |
1008 struct aim_conn_t *tstconn; | |
1009 | |
1010 if (!g_slist_find(connections, gc)) { | |
1011 close(source); | |
1012 g_free(ccon->show); | |
1013 g_free(ccon->name); | |
1014 g_free(ccon); | |
1015 return; | |
1016 } | |
1017 | |
1018 odata = gc->proto_data; | |
1019 sess = odata->sess; | |
1020 tstconn = ccon->conn; | |
1021 | |
1022 if (source < 0) { | |
1023 aim_conn_kill(sess, &tstconn); | |
1024 g_free(ccon->show); | |
1025 g_free(ccon->name); | |
1026 g_free(ccon); | |
1027 return; | |
1028 } | |
1029 | |
1030 aim_conn_completeconnect(sess, ccon->conn); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1031 ccon->inpa = gaim_input_add(tstconn->fd, |
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1032 GAIM_INPUT_READ, |
2086 | 1033 oscar_callback, tstconn); |
1034 odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon); | |
1035 aim_chat_attachname(tstconn, ccon->name); | |
1036 } | |
1037 | |
1038 int gaim_handle_redirect(struct aim_session_t *sess, | |
1039 struct command_rx_struct *command, ...) { | |
1040 va_list ap; | |
1041 int serviceid; | |
1042 char *ip; | |
1043 unsigned char *cookie; | |
1044 struct gaim_connection *gc = sess->aux_data; | |
1045 struct aim_user *user = gc->user; | |
1046 struct aim_conn_t *tstconn; | |
1047 int i; | |
1048 char *host; | |
1049 int port; | |
1050 | |
1051 port = user->proto_opt[USEROPT_AUTHPORT][0] ? | |
1052 atoi(user->proto_opt[USEROPT_AUTHPORT]) : FAIM_LOGIN_PORT, | |
1053 | |
1054 va_start(ap, command); | |
1055 serviceid = va_arg(ap, int); | |
1056 ip = va_arg(ap, char *); | |
1057 cookie = va_arg(ap, unsigned char *); | |
1058 | |
1059 for (i = 0; i < (int)strlen(ip); i++) { | |
1060 if (ip[i] == ':') { | |
1061 port = atoi(&(ip[i+1])); | |
1062 break; | |
1063 } | |
1064 } | |
1065 host = g_strndup(ip, i); | |
1066 | |
1067 switch(serviceid) { | |
1068 case 0x7: /* Authorizer */ | |
1069 debug_printf("Reconnecting with authorizor...\n"); | |
1070 tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL); | |
1071 if (tstconn == NULL) { | |
1072 debug_printf("unable to reconnect with authorizer\n"); | |
1073 g_free(host); | |
1074 return 1; | |
1075 } | |
1076 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0); | |
1077 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, gaim_rateresp, 0); | |
1078 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, gaim_info_change, 0); | |
1079 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, gaim_info_change, 0); | |
1080 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, gaim_account_confirm, 0); | |
1081 | |
1082 tstconn->status |= AIM_CONN_STATUS_INPROGRESS; | |
1083 tstconn->fd = proxy_connect(host, port, oscar_auth_connect, gc); | |
1084 if (tstconn->fd < 0) { | |
1085 aim_conn_kill(sess, &tstconn); | |
1086 debug_printf("unable to reconnect with authorizer\n"); | |
1087 g_free(host); | |
1088 return 1; | |
1089 } | |
1090 aim_auth_sendcookie(sess, tstconn, cookie); | |
1091 break; | |
1092 case 0xd: /* ChatNav */ | |
1093 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, NULL); | |
1094 if (tstconn == NULL) { | |
1095 debug_printf("unable to connect to chatnav server\n"); | |
1096 g_free(host); | |
1097 return 1; | |
1098 } | |
1099 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0); | |
1100 | |
1101 tstconn->status |= AIM_CONN_STATUS_INPROGRESS; | |
1102 tstconn->fd = proxy_connect(host, port, oscar_chatnav_connect, gc); | |
1103 if (tstconn->fd < 0) { | |
1104 aim_conn_kill(sess, &tstconn); | |
1105 debug_printf("unable to connect to chatnav server\n"); | |
1106 g_free(host); | |
1107 return 1; | |
1108 } | |
1109 aim_auth_sendcookie(sess, tstconn, cookie); | |
1110 break; | |
1111 case 0xe: /* Chat */ | |
1112 { | |
1113 char *roomname = va_arg(ap, char *); | |
1114 int exchange = va_arg(ap, int); | |
1115 struct chat_connection *ccon; | |
1116 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, NULL); | |
1117 if (tstconn == NULL) { | |
1118 debug_printf("unable to connect to chat server\n"); | |
1119 g_free(host); | |
1120 return 1; | |
1121 } | |
1122 | |
1123 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, gaim_server_ready, 0); | |
1124 ccon = g_new0(struct chat_connection, 1); | |
1125 ccon->conn = tstconn; | |
1126 ccon->gc = gc; | |
1127 ccon->fd = -1; | |
1128 ccon->name = g_strdup(roomname); | |
1129 ccon->exchange = exchange; | |
1130 ccon->show = extract_name(roomname); | |
1131 | |
1132 ccon->conn->status |= AIM_CONN_STATUS_INPROGRESS; | |
1133 ccon->conn->fd = proxy_connect(host, port, oscar_chat_connect, ccon); | |
1134 if (ccon->conn->fd < 0) { | |
1135 aim_conn_kill(sess, &tstconn); | |
1136 debug_printf("unable to connect to chat server\n"); | |
1137 g_free(host); | |
1138 g_free(ccon->show); | |
1139 g_free(ccon->name); | |
1140 g_free(ccon); | |
1141 return 1; | |
1142 } | |
1143 aim_auth_sendcookie(sess, tstconn, cookie); | |
1144 debug_printf("Connected to chat room %s exchange %d\n", roomname, exchange); | |
1145 } | |
1146 break; | |
1147 default: /* huh? */ | |
1148 debug_printf("got redirect for unknown service 0x%04x\n", serviceid); | |
1149 break; | |
1150 } | |
1151 | |
1152 va_end(ap); | |
1153 | |
1154 g_free(host); | |
1155 return 1; | |
1156 } | |
1157 | |
1158 int gaim_parse_oncoming(struct aim_session_t *sess, | |
1159 struct command_rx_struct *command, ...) { | |
1160 struct aim_userinfo_s *info; | |
1161 time_t time_idle; | |
1162 int type = 0; | |
1163 struct gaim_connection *gc = sess->aux_data; | |
1164 | |
1165 va_list ap; | |
1166 va_start(ap, command); | |
1167 info = va_arg(ap, struct aim_userinfo_s *); | |
1168 va_end(ap); | |
1169 | |
1170 if (info->flags & AIM_FLAG_UNCONFIRMED) | |
1171 type |= UC_UNCONFIRMED; | |
1172 else if (info->flags & AIM_FLAG_ADMINISTRATOR) | |
1173 type |= UC_ADMIN; | |
1174 else if (info->flags & AIM_FLAG_AOL) | |
1175 type |= UC_AOL; | |
1176 else if (info->flags & AIM_FLAG_FREE) | |
1177 type |= UC_NORMAL; | |
1178 if (info->flags & AIM_FLAG_AWAY) | |
1179 type |= UC_UNAVAILABLE; | |
1180 | |
1181 if (info->idletime) { | |
1182 time(&time_idle); | |
1183 time_idle -= info->idletime*60; | |
1184 } else | |
1185 time_idle = 0; | |
1186 | |
1187 serv_got_update(gc, info->sn, 1, info->warnlevel/10, info->onlinesince, | |
1188 time_idle, type, info->capabilities); | |
1189 | |
1190 return 1; | |
1191 } | |
1192 | |
1193 int gaim_parse_offgoing(struct aim_session_t *sess, | |
1194 struct command_rx_struct *command, ...) { | |
1195 struct aim_userinfo_s *info; | |
1196 va_list ap; | |
1197 struct gaim_connection *gc = sess->aux_data; | |
1198 | |
1199 va_start(ap, command); | |
1200 info = va_arg(ap, struct aim_userinfo_s *); | |
1201 va_end(ap); | |
1202 | |
1203 serv_got_update(gc, info->sn, 0, 0, 0, 0, 0, 0); | |
1204 | |
1205 return 1; | |
1206 } | |
1207 | |
1208 static void cancel_direct_im(gpointer w, struct ask_direct *d) { | |
1209 debug_printf("Freeing DirectIM prompts.\n"); | |
1210 | |
1211 g_free(d->sn); | |
1212 g_free(d); | |
1213 } | |
1214 | |
1215 static void delete_direct_im(gpointer w, struct direct_im *d) { | |
1216 struct oscar_data *od = (struct oscar_data *)d->gc->proto_data; | |
1217 | |
1218 od->direct_ims = g_slist_remove(od->direct_ims, d); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1219 gaim_input_remove(d->watcher); |
2086 | 1220 aim_conn_kill(od->sess, &d->conn); |
1221 g_free(d); | |
1222 } | |
1223 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1224 static void oscar_directim_callback(gpointer data, gint source, GaimInputCondition condition) { |
2086 | 1225 struct direct_im *dim = data; |
1226 struct gaim_connection *gc = dim->gc; | |
1227 struct oscar_data *od = gc->proto_data; | |
1228 char buf[256]; | |
1229 | |
1230 if (!g_slist_find(connections, gc)) { | |
1231 g_free(dim); | |
1232 return; | |
1233 } | |
1234 | |
1235 if (source < 0) { | |
1236 g_free(dim); | |
1237 return; | |
1238 } | |
1239 | |
1240 aim_conn_completeconnect(od->sess, dim->conn); | |
1241 if (!(dim->cnv = find_conversation(dim->name))) dim->cnv = new_conversation(dim->name); | |
1242 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), dim->name); | |
1243 write_to_conv(dim->cnv, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL)); | |
1244 | |
1245 od->direct_ims = g_slist_append(od->direct_ims, dim); | |
1246 | |
1247 gtk_signal_connect(GTK_OBJECT(dim->cnv->window), "destroy", | |
1248 GTK_SIGNAL_FUNC(delete_direct_im), dim); | |
1249 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1250 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, |
2086 | 1251 oscar_callback, dim->conn); |
1252 } | |
1253 | |
1254 static int accept_direct_im(gpointer w, struct ask_direct *d) { | |
1255 struct gaim_connection *gc = d->gc; | |
1256 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1257 struct direct_im *dim; | |
1258 char *host; int port = FAIM_LOGIN_PORT; | |
1259 int i; | |
1260 | |
1261 debug_printf("Accepted DirectIM.\n"); | |
1262 | |
1263 dim = find_direct_im(od, d->sn); | |
1264 if (dim) { | |
1265 cancel_direct_im(w, d); /* 40 */ | |
1266 return TRUE; | |
1267 } | |
1268 dim = g_new0(struct direct_im, 1); | |
1269 dim->gc = d->gc; | |
1270 g_snprintf(dim->name, sizeof dim->name, "%s", d->sn); | |
1271 | |
1272 if ((dim->conn = aim_newconn(od->sess, AIM_CONN_TYPE_RENDEZVOUS, NULL)) == NULL) { | |
1273 g_free(dim); | |
1274 cancel_direct_im(w, d); | |
1275 return TRUE; | |
1276 } | |
1277 dim->conn->subtype = AIM_CONN_SUBTYPE_OFT_DIRECTIM; | |
1278 dim->conn->priv = d->priv; | |
1279 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, | |
1280 gaim_directim_incoming, 0); | |
1281 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, | |
1282 gaim_directim_disconnect, 0); | |
1283 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, | |
1284 gaim_directim_typing, 0); | |
1285 | |
1286 for (i = 0; i < (int)strlen(d->priv->ip); i++) { | |
1287 if (d->priv->ip[i] == ':') { | |
1288 port = atoi(&(d->priv->ip[i+1])); | |
1289 break; | |
1290 } | |
1291 } | |
1292 host = g_strndup(d->priv->ip, i); | |
1293 dim->conn->status |= AIM_CONN_STATUS_INPROGRESS; | |
1294 dim->conn->fd = proxy_connect(host, port, oscar_directim_callback, dim); | |
1295 g_free(host); | |
1296 if (dim->conn->fd < 0) { | |
1297 aim_conn_kill(od->sess, &dim->conn); | |
1298 g_free(dim); | |
1299 cancel_direct_im(w, d); | |
1300 return TRUE; | |
1301 } | |
1302 | |
1303 cancel_direct_im(w, d); | |
1304 | |
1305 return TRUE; | |
1306 } | |
1307 | |
1308 /* | |
1309 static void cancel_getfile(gpointer w, struct ask_getfile *g) { | |
1310 g_free(g->ip); | |
1311 g_free(g->cookie); | |
1312 g_free(g->sn); | |
1313 g_free(g); | |
1314 } | |
1315 | |
1316 static void cancel_getfile_file(GtkObject *obj, struct ask_getfile *g) { | |
1317 GtkWidget *w = gtk_object_get_user_data(obj); | |
1318 gtk_widget_destroy(w); | |
1319 cancel_getfile(w, g); | |
1320 } | |
1321 | |
1322 static void cancel_getfile_cancel(GtkObject *obj, struct ask_getfile *g) { | |
1323 GtkWidget *w = gtk_object_get_user_data(obj); | |
1324 gtk_widget_destroy(w); | |
1325 } | |
1326 | |
1327 static void interrupt_getfile(GtkObject *obj, struct getfile_transfer *gt) { | |
1328 struct gaim_connection *gc = gt->gc; | |
1329 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1330 | |
1331 gtk_widget_destroy(gt->window); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1332 gaim_input_remove(gt->gip); |
2086 | 1333 if (gt->gop > 0) |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1334 gaim_input_remove(gt->gop); |
2086 | 1335 aim_conn_kill(od->sess, >->conn); |
1336 od->getfiles = g_slist_remove(od->getfiles, gt); | |
1337 g_free(gt->receiver); | |
1338 g_free(gt->filename); | |
1339 fclose(gt->listing); | |
1340 g_free(gt); | |
1341 } | |
1342 | |
1343 static int gaim_getfile_filereq(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1344 struct gaim_connection *gc = sess->aux_data; | |
1345 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1346 struct getfile_transfer *gt; | |
1347 char buf[2048]; | |
1348 GtkWidget *label; | |
1349 GtkWidget *button; | |
1350 | |
1351 va_list ap; | |
1352 struct aim_conn_t *oftconn; | |
1353 struct aim_fileheader_t *fh; | |
1354 char *cookie; | |
1355 | |
1356 va_start(ap, command); | |
1357 oftconn = va_arg(ap, struct aim_conn_t *); | |
1358 fh = va_arg(ap, struct aim_fileheader_t *); | |
1359 cookie = va_arg(ap, char *); | |
1360 va_end(ap); | |
1361 | |
1362 gt = find_getfile_transfer(od, oftconn); | |
1363 | |
1364 if (gt->window) | |
1365 return 1; | |
1366 | |
1367 gt->window = gtk_dialog_new(); | |
1368 gtk_window_set_title(GTK_WINDOW(gt->window), _("Gaim - File Transfer")); | |
1369 gtk_widget_realize(gt->window); | |
1370 aol_icon(gt->window->window); | |
1371 | |
1372 g_snprintf(buf, sizeof buf, _("Sending %s to %s"), fh->name, gt->receiver); | |
1373 label = gtk_label_new(buf); | |
1374 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(gt->window)->vbox), label, FALSE, FALSE, 5); | |
1375 gtk_widget_show(label); | |
1376 | |
1377 gt->meter = gtk_progress_bar_new(); | |
1378 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(gt->window)->action_area), gt->meter, FALSE, FALSE, 5); | |
1379 gtk_widget_show(gt->meter); | |
1380 | |
1381 gt->label = gtk_label_new("0 %"); | |
1382 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(gt->window)->action_area), gt->label, FALSE, FALSE, 5); | |
1383 gtk_widget_show(gt->label); | |
1384 | |
1385 button = picture_button(gt->window, _("Cancel"), cancel_xpm); | |
1386 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(gt->window)->action_area), button, FALSE, FALSE, 5); | |
1387 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(interrupt_getfile), gt); | |
1388 | |
1389 gtk_widget_show(gt->window); | |
1390 | |
1391 return 1; | |
1392 } | |
1393 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1394 static void getfile_send_callback(gpointer data, gint source, GaimInputCondition condition) { |
2086 | 1395 struct getfile_transfer *gt = (struct getfile_transfer *)data; |
1396 int result; | |
1397 | |
1398 result = aim_getfile_send_chunk(gt->conn, gt->file, gt->fh, -1, 1024); | |
1399 gt->pos += result; | |
1400 if (result == 0) { | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1401 gaim_input_remove(gt->gop); gt->gop = 0; |
2086 | 1402 } else if (result == -1) { |
1403 do_error_dialog(_("Error in transfer"), "Gaim"); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1404 gaim_input_remove(gt->gop); gt->gop = 0; |
2086 | 1405 interrupt_getfile(NULL, gt); |
1406 } | |
1407 } | |
1408 | |
1409 static int gaim_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1410 struct gaim_connection *gc = sess->aux_data; | |
1411 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1412 struct getfile_transfer *gt; | |
1413 | |
1414 va_list ap; | |
1415 struct aim_conn_t *oftconn; | |
1416 struct aim_fileheader_t *fh; | |
1417 char *cookie; | |
1418 | |
1419 va_start(ap, command); | |
1420 oftconn = va_arg(ap, struct aim_conn_t *); | |
1421 fh = va_arg(ap, struct aim_fileheader_t *); | |
1422 cookie = va_arg(ap, char *); | |
1423 va_end(ap); | |
1424 | |
1425 gt = find_getfile_transfer(od, oftconn); | |
1426 | |
1427 if (gt->gop > 0) { | |
1428 debug_printf("already have output watcher?\n"); | |
1429 return 1; | |
1430 } | |
1431 | |
1432 if ((gt->file = fopen(gt->filename, "r")) == NULL) { | |
1433 interrupt_getfile(NULL, gt); | |
1434 return 1; | |
1435 } | |
1436 gt->pos = 0; | |
1437 gt->fh = g_memdup(fh, sizeof(struct aim_fileheader_t)); | |
1438 fseek(gt->file, 0, SEEK_SET); | |
1439 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1440 gt->gop = gaim_input_add(gt->conn->fd, GAIM_INPUT_WRITE, getfile_send_callback, gt); |
2086 | 1441 |
1442 return 1; | |
1443 } | |
1444 | |
1445 static int gaim_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1446 struct gaim_connection *gc = sess->aux_data; | |
1447 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1448 struct getfile_transfer *gt; | |
1449 | |
1450 va_list ap; | |
1451 struct aim_conn_t *conn; | |
1452 struct aim_fileheader_t *fh; | |
1453 | |
1454 va_start(ap, command); | |
1455 conn = va_arg(ap, struct aim_conn_t *); | |
1456 fh = va_arg(ap, struct aim_fileheader_t *); | |
1457 va_end(ap); | |
1458 | |
1459 gt = find_getfile_transfer(od, conn); | |
1460 | |
1461 gtk_widget_destroy(gt->window); | |
1462 gt->window = NULL; | |
1463 do_error_dialog(_("Transfer complete."), "Gaim"); | |
1464 | |
1465 return 1; | |
1466 } | |
1467 | |
1468 static int gaim_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1469 struct gaim_connection *gc = sess->aux_data; | |
1470 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1471 struct getfile_transfer *gt; | |
1472 | |
1473 va_list ap; | |
1474 struct aim_conn_t *conn; | |
1475 char *sn; | |
1476 | |
1477 va_start(ap, command); | |
1478 conn = va_arg(ap, struct aim_conn_t *); | |
1479 sn = va_arg(ap, char *); | |
1480 va_end(ap); | |
1481 | |
1482 gt = find_getfile_transfer(od, conn); | |
1483 od->getfiles = g_slist_remove(od->getfiles, gt); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1484 gaim_input_remove(gt->gip); |
2086 | 1485 if (gt->gop > 0) |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1486 gaim_input_remove(gt->gop); |
2086 | 1487 g_free(gt->receiver); |
1488 g_free(gt->filename); | |
1489 aim_conn_kill(sess, &conn); | |
1490 fclose(gt->listing); | |
1491 g_free(gt); | |
1492 | |
1493 debug_printf("getfile disconnect\n"); | |
1494 | |
1495 return 1; | |
1496 } | |
1497 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1498 static void oscar_getfile_callback(gpointer data, gint source, GaimInputCondition condition) { |
2086 | 1499 struct getfile_transfer *gf = data; |
1500 struct gaim_connection *gc = gf->gc; | |
1501 struct oscar_data *od = gc->proto_data; | |
1502 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1503 gaim_input_remove(gf->gip); |
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1504 gf->gip = gaim_input_add(source, GAIM_INPUT_READ, oscar_callback, gf->conn); |
2086 | 1505 |
1506 aim_conn_addhandler(od->sess, gf->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, gaim_getfile_filereq, 0); | |
1507 aim_conn_addhandler(od->sess, gf->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, gaim_getfile_filesend, 0); | |
1508 aim_conn_addhandler(od->sess, gf->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, gaim_getfile_complete, 0); | |
1509 aim_conn_addhandler(od->sess, gf->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, gaim_getfile_disconnect, 0); | |
1510 } | |
1511 | |
1512 static void do_getfile(GtkObject *obj, struct ask_getfile *g) { | |
1513 GtkWidget *w = gtk_object_get_user_data(obj); | |
1514 char *filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(w)); | |
1515 struct gaim_connection *gc = g->gc; | |
1516 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1517 struct getfile_transfer *gf; | |
1518 struct stat st; | |
1519 struct tm *ft; | |
1520 char tmppath[256]; | |
1521 FILE *file; | |
1522 static int current = 0; | |
1523 struct aim_conn_t *newconn; | |
1524 | |
1525 if (file_is_dir(filename, w)) | |
1526 return; | |
1527 | |
1528 if (stat(filename, &st) != 0) { | |
1529 gtk_widget_destroy(w); | |
1530 do_error_dialog(_("Error examining file"), _("GetFile Error")); | |
1531 cancel_getfile(w, g); | |
1532 return; | |
1533 } | |
1534 | |
1535 g_snprintf(tmppath, sizeof tmppath, "/%s/gaim%d%d", g_get_tmp_dir(), getpid(), current++); | |
1536 if ((file = fopen(tmppath, "w+")) == NULL) { | |
1537 gtk_widget_destroy(w); | |
1538 do_error_dialog(_("Could not open temporary file, aborting"), _("GetFile Error")); | |
1539 cancel_getfile(w, g); | |
1540 return; | |
1541 } | |
1542 | |
1543 gf = g_new0(struct getfile_transfer, 1); | |
1544 gf->gc = gc; | |
1545 gf->filename = g_strdup(filename); | |
1546 gf->listing = file; | |
1547 gf->receiver = g_strdup(g->sn); | |
1548 gf->size = st.st_size; | |
1549 | |
1550 ft = localtime(&st.st_ctime); | |
1551 fprintf(file, "%2d/%2d/%4d %2d:%2d %8ld ", | |
1552 ft->tm_mon + 1, ft->tm_mday, ft->tm_year + 1900, | |
1553 ft->tm_hour + 1, ft->tm_min + 1, (long)st.st_size); | |
1554 fprintf(file, "%s\r\n", g_basename(filename)); | |
1555 rewind(file); | |
1556 | |
1557 aim_oft_registerlisting(od->sess, file, ""); | |
1558 if ((newconn = aim_accepttransfer(od->sess, od->conn, g->sn, g->cookie, g->ip, file, AIM_CAPS_GETFILE)) == NULL) { | |
1559 od->sess->flags ^= AIM_SESS_FLAGS_NONBLOCKCONNECT; | |
1560 do_error_dialog(_("Error connecting for transfer"), _("GetFile Error")); | |
1561 g_free(gf->filename); | |
1562 fclose(file); | |
1563 g_free(gf); | |
1564 gtk_widget_destroy(w); | |
1565 return; | |
1566 } | |
1567 | |
1568 gtk_widget_destroy(w); | |
1569 | |
1570 od->getfiles = g_slist_append(od->getfiles, gf); | |
1571 gf->conn = newconn; | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1572 gf->gip = gaim_input_add(newconn->fd, GAIM_INPUT_WRITE, oscar_getfile_callback, gf); |
2086 | 1573 } |
1574 | |
1575 static int accept_getfile(gpointer w, struct ask_getfile *g) { | |
1576 GtkWidget *window; | |
1577 window = gtk_file_selection_new(_("Gaim - Send File...")); | |
1578 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(window)); | |
1579 gtk_object_set_user_data(GTK_OBJECT(window), window); | |
1580 gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
1581 GTK_SIGNAL_FUNC(cancel_getfile_file), g); | |
1582 gtk_object_set_user_data(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), window); | |
1583 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", | |
1584 GTK_SIGNAL_FUNC(do_getfile), g); | |
1585 gtk_object_set_user_data(GTK_OBJECT(GTK_FILE_SELECTION(window)->cancel_button), window); | |
1586 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->cancel_button), "clicked", | |
1587 GTK_SIGNAL_FUNC(cancel_getfile_cancel), g); | |
1588 gtk_widget_show(window); | |
1589 | |
1590 return TRUE; | |
1591 } | |
1592 */ | |
1593 | |
1594 #if USE_PIXBUF | |
1595 static gboolean redraw_anim(gpointer data) | |
1596 { | |
1597 int delay; | |
1598 struct icon_req *ir = data; | |
1599 GList *frames; | |
1600 GdkPixbufFrame *frame; | |
1601 GdkPixbuf *buf; | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1602 GdkPixbuf *scale; |
2086 | 1603 GdkPixmap *pm; GdkBitmap *bm; |
1604 GdkPixmap *src; | |
1605 GdkGC *gc; | |
1606 | |
1607 if (!ir->cnv || !g_list_find(conversations, ir->cnv)) { | |
1608 debug_printf("I think this is a bug.\n"); | |
1609 return FALSE; | |
1610 } | |
1611 | |
1612 frames = gdk_pixbuf_animation_get_frames(ir->anim); | |
1613 frame = g_list_nth_data(frames, ir->curframe); | |
1614 switch (gdk_pixbuf_frame_get_action(frame)) { | |
1615 case GDK_PIXBUF_FRAME_RETAIN: | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1616 buf = gdk_pixbuf_frame_get_pixbuf(frame); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1617 scale = gdk_pixbuf_scale_simple(buf, |
2141
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1618 MAX(gdk_pixbuf_get_width(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1619 gdk_pixbuf_animation_get_width(ir->anim), 1), |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1620 MAX(gdk_pixbuf_get_height(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1621 gdk_pixbuf_animation_get_height(ir->anim), 1), |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1622 GDK_INTERP_NEAREST); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1623 gdk_pixbuf_render_pixmap_and_mask(scale, &src, NULL, 0); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1624 gdk_pixbuf_unref(scale); |
2086 | 1625 gtk_pixmap_get(GTK_PIXMAP(ir->pix), &pm, &bm); |
1626 gc = gdk_gc_new(pm); | |
1627 gdk_draw_pixmap(pm, gc, src, 0, 0, | |
2141
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1628 MAX(gdk_pixbuf_frame_get_x_offset(frame) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1629 gdk_pixbuf_animation_get_width(ir->anim), 1), |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1630 MAX(gdk_pixbuf_frame_get_y_offset(frame) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1631 gdk_pixbuf_animation_get_height(ir->anim), 1), |
2086 | 1632 -1, -1); |
1633 gdk_pixmap_unref(src); | |
1634 gtk_widget_queue_draw(ir->pix); | |
1635 gdk_gc_unref(gc); | |
1636 break; | |
1637 case GDK_PIXBUF_FRAME_DISPOSE: | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1638 buf = gdk_pixbuf_frame_get_pixbuf(frame); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1639 scale = gdk_pixbuf_scale_simple(buf, |
2141
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1640 MAX(gdk_pixbuf_get_width(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1641 gdk_pixbuf_animation_get_width(ir->anim), 1), |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1642 MAX(gdk_pixbuf_get_height(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1643 gdk_pixbuf_animation_get_height(ir->anim), 1), |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1644 GDK_INTERP_NEAREST); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1645 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1646 gdk_pixbuf_unref(scale); |
2086 | 1647 gtk_pixmap_set(GTK_PIXMAP(ir->pix), pm, bm); |
1648 gdk_pixmap_unref(pm); | |
1649 if (bm) | |
1650 gdk_bitmap_unref(bm); | |
1651 break; | |
1652 case GDK_PIXBUF_FRAME_REVERT: | |
1653 frame = frames->data; | |
1654 buf = gdk_pixbuf_frame_get_pixbuf(frame); | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1655 scale = gdk_pixbuf_scale_simple(buf, |
2141
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1656 MAX(gdk_pixbuf_get_width(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1657 gdk_pixbuf_animation_get_width(ir->anim), 1), |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1658 MAX(gdk_pixbuf_get_height(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1659 gdk_pixbuf_animation_get_height(ir->anim), 1), |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1660 GDK_INTERP_NEAREST); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1661 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1662 gdk_pixbuf_unref(scale); |
2086 | 1663 gtk_pixmap_set(GTK_PIXMAP(ir->pix), pm, bm); |
1664 gdk_pixmap_unref(pm); | |
1665 if (bm) | |
1666 gdk_bitmap_unref(bm); | |
1667 break; | |
1668 } | |
1669 ir->curframe = (ir->curframe + 1) % g_list_length(frames); | |
1670 delay = MAX(gdk_pixbuf_frame_get_delay_time(frame), 13); | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2127
diff
changeset
|
1671 ir->timer = g_timeout_add(delay * 10, redraw_anim, ir); |
2086 | 1672 return FALSE; |
1673 } | |
1674 #endif | |
1675 | |
1676 int gaim_parse_incoming_im(struct aim_session_t *sess, | |
1677 struct command_rx_struct *command, ...) { | |
1678 int channel; | |
1679 struct aim_userinfo_s *userinfo; | |
1680 va_list ap; | |
1681 struct gaim_connection *gc = sess->aux_data; | |
1682 | |
1683 va_start(ap, command); | |
1684 channel = va_arg(ap, int); | |
1685 userinfo = va_arg(ap, struct aim_userinfo_s *); | |
1686 | |
1687 /* channel 1: standard message */ | |
1688 if (channel == 1) { | |
1689 char *tmp = g_malloc(BUF_LONG); | |
1690 struct aim_incomingim_ch1_args *args; | |
1691 | |
1692 args = va_arg(ap, struct aim_incomingim_ch1_args *); | |
1693 va_end(ap); | |
1694 | |
1695 #if USE_PIXBUF | |
1696 if (args->icbmflags & AIM_IMFLAGS_HASICON) { | |
1697 struct oscar_data *od = gc->proto_data; | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
1698 struct icon_req *ir = NULL; |
2086 | 1699 GSList *h = od->hasicons; |
1700 char *who = normalize(userinfo->sn); | |
1701 debug_printf("%s has an icon\n", userinfo->sn); | |
1702 while (h) { | |
1703 ir = h->data; | |
1704 if (!strcmp(ir->user, who)) | |
1705 break; | |
1706 h = h->next; | |
1707 } | |
1708 if (!h) { | |
1709 ir = g_new0(struct icon_req, 1); | |
1710 ir->user = g_strdup(who); | |
1711 od->hasicons = g_slist_append(od->hasicons, ir); | |
1712 } | |
1713 if (args->iconstamp > ir->timestamp) | |
1714 ir->request = TRUE; | |
1715 ir->timestamp = args->iconstamp; | |
1716 } | |
1717 #endif | |
1718 | |
1719 /* | |
1720 * Quickly convert it to eight bit format, replacing | |
1721 * non-ASCII UNICODE characters with their equivelent | |
1722 * HTML entity. | |
1723 */ | |
1724 if (args->icbmflags & AIM_IMFLAGS_UNICODE) { | |
1725 int i; | |
1726 | |
1727 for (i = 0, tmp[0] = '\0'; i < args->msglen; i += 2) { | |
1728 unsigned short uni; | |
1729 | |
1730 uni = ((args->msg[i] & 0xff) << 8) | (args->msg[i+1] & 0xff); | |
1731 | |
1732 if ((uni < 128) || ((uni >= 160) && (uni <= 255))) { /* ISO 8859-1 */ | |
1733 | |
1734 g_snprintf(tmp+strlen(tmp), BUF_LONG-strlen(tmp), "%c", uni); | |
1735 | |
1736 } else { /* something else, do UNICODE entity */ | |
1737 g_snprintf(tmp+strlen(tmp), BUF_LONG-strlen(tmp), "&#%04x;", uni); | |
1738 } | |
1739 } | |
1740 } else | |
1741 g_snprintf(tmp, BUF_LONG, "%s", args->msg); | |
1742 | |
1743 serv_got_im(gc, userinfo->sn, tmp, args->icbmflags & AIM_IMFLAGS_AWAY, time(NULL)); | |
1744 g_free(tmp); | |
1745 } else if (channel == 2) { | |
1746 struct aim_incomingim_ch2_args *args; | |
1747 args = va_arg(ap, struct aim_incomingim_ch2_args *); | |
1748 va_end(ap); | |
1749 if (args->reqclass & AIM_CAPS_CHAT) { | |
1750 char *name = extract_name(args->info.chat.roominfo.name); | |
1751 serv_got_chat_invite(gc, | |
1752 name ? name : args->info.chat.roominfo.name, | |
1753 args->info.chat.roominfo.exchange, | |
1754 userinfo->sn, | |
1755 args->info.chat.msg); | |
1756 if (name) | |
1757 g_free(name); | |
1758 } else if (args->reqclass & AIM_CAPS_SENDFILE) { | |
1759 } else if (args->reqclass & AIM_CAPS_GETFILE) { | |
1760 /* | |
1761 char *ip, *cookie; | |
1762 struct ask_getfile *g = g_new0(struct ask_getfile, 1); | |
1763 char buf[256]; | |
1764 | |
1765 userinfo = va_arg(ap, struct aim_userinfo_s *); | |
1766 ip = va_arg(ap, char *); | |
1767 cookie = va_arg(ap, char *); | |
1768 va_end(ap); | |
1769 | |
1770 debug_printf("%s received getfile request from %s (%s), cookie = %s\n", | |
1771 gc->username, userinfo->sn, ip, cookie); | |
1772 | |
1773 g->gc = gc; | |
1774 g->sn = g_strdup(userinfo->sn); | |
1775 g->cookie = g_strdup(cookie); | |
1776 g->ip = g_strdup(ip); | |
1777 g_snprintf(buf, sizeof buf, "%s has just asked to get a file from %s.", | |
1778 userinfo->sn, gc->username); | |
1779 do_ask_dialog(buf, g, accept_getfile, cancel_getfile); | |
1780 */ | |
1781 } else if (args->reqclass & AIM_CAPS_VOICE) { | |
1782 } else if (args->reqclass & AIM_CAPS_BUDDYICON) { | |
1783 #if USE_PIXBUF | |
1784 struct oscar_data *od = gc->proto_data; | |
1785 GSList *h = od->hasicons; | |
1786 struct icon_req *ir = NULL; | |
1787 char *who; | |
1788 struct conversation *c; | |
1789 | |
1790 GdkPixbufLoader *load; | |
1791 GList *frames; | |
1792 GdkPixbuf *buf; | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1793 GdkPixbuf *scale; |
2086 | 1794 GdkPixmap *pm; |
1795 GdkBitmap *bm; | |
1796 | |
1797 who = normalize(userinfo->sn); | |
1798 | |
1799 while (h) { | |
1800 ir = h->data; | |
1801 if (!strcmp(who, ir->user)) | |
1802 break; | |
1803 h = h->next; | |
1804 | |
1805 } | |
1806 | |
1807 if (!h || ((c = find_conversation(userinfo->sn)) == NULL) || (c->gc != gc)) { | |
1808 debug_printf("got buddy icon for %s but didn't want it\n", userinfo->sn); | |
1809 return 1; | |
1810 } | |
1811 | |
1812 if (ir->pix && ir->cnv) | |
1813 gtk_container_remove(GTK_CONTAINER(ir->cnv->bbox), ir->pix); | |
1814 ir->pix = NULL; | |
1815 ir->cnv = NULL; | |
1816 if (ir->data) | |
1817 g_free(ir->data); | |
1818 if (ir->anim) | |
1819 gdk_pixbuf_animation_unref(ir->anim); | |
1820 ir->anim = NULL; | |
1821 if (ir->unanim) | |
1822 gdk_pixbuf_unref(ir->unanim); | |
1823 ir->unanim = NULL; | |
1824 if (ir->timer) | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2127
diff
changeset
|
1825 g_source_remove(ir->timer); |
2086 | 1826 ir->timer = 0; |
1827 | |
1828 ir->length = args->info.icon.length; | |
1829 | |
1830 if (!ir->length) | |
1831 return 1; | |
1832 | |
1833 ir->data = g_memdup(args->info.icon.icon, args->info.icon.length); | |
1834 | |
1835 load = gdk_pixbuf_loader_new(); | |
1836 gdk_pixbuf_loader_write(load, ir->data, ir->length); | |
1837 ir->anim = gdk_pixbuf_loader_get_animation(load); | |
1838 | |
1839 if (ir->anim) { | |
1840 frames = gdk_pixbuf_animation_get_frames(ir->anim); | |
1841 buf = gdk_pixbuf_frame_get_pixbuf(frames->data); | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1842 scale = gdk_pixbuf_scale_simple(buf, |
2141
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1843 MAX(gdk_pixbuf_get_width(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1844 gdk_pixbuf_animation_get_width(ir->anim), 1), |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1845 MAX(gdk_pixbuf_get_height(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
1846 gdk_pixbuf_animation_get_height(ir->anim), 1), |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1847 GDK_INTERP_NEAREST); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1848 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1849 gdk_pixbuf_unref(scale); |
2086 | 1850 |
1851 if (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1) { | |
1852 int delay = | |
1853 MAX(gdk_pixbuf_frame_get_delay_time(frames->data), 13); | |
1854 ir->curframe = 1; | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2127
diff
changeset
|
1855 ir->timer = g_timeout_add(delay * 10, redraw_anim, ir); |
2086 | 1856 } |
1857 } else { | |
1858 ir->unanim = gdk_pixbuf_loader_get_pixbuf(load); | |
1859 if (!ir->unanim) { | |
1860 gdk_pixbuf_loader_close(load); | |
1861 return 1; | |
1862 } | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1863 scale = gdk_pixbuf_scale_simple(ir->unanim, SCALE, SCALE, |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1864 GDK_INTERP_NEAREST); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1865 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); |
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1866 gdk_pixbuf_unref(scale); |
2086 | 1867 } |
1868 | |
1869 ir->cnv = c; | |
1870 ir->pix = gtk_pixmap_new(pm, bm); | |
1871 gtk_box_pack_start(GTK_BOX(c->bbox), ir->pix, FALSE, FALSE, 5); | |
1872 if (ir->anim && (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1)) | |
2126
b935eca131be
[gaim-migrate @ 2136]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1873 gtk_widget_set_usize(ir->pix, SCALE, SCALE); |
2086 | 1874 gtk_widget_show(ir->pix); |
1875 gdk_pixmap_unref(pm); | |
1876 if (bm) | |
1877 gdk_bitmap_unref(bm); | |
1878 | |
1879 gdk_pixbuf_loader_close(load); | |
1880 | |
1881 #endif | |
1882 } else if (args->reqclass & AIM_CAPS_IMIMAGE) { | |
1883 struct ask_direct *d = g_new0(struct ask_direct, 1); | |
1884 char buf[256]; | |
1885 | |
1886 debug_printf("%s received direct im request from %s (%s)\n", | |
1887 gc->username, userinfo->sn, args->info.directim->ip); | |
1888 | |
1889 d->gc = gc; | |
1890 d->sn = g_strdup(userinfo->sn); | |
1891 d->priv = args->info.directim; | |
1892 g_snprintf(buf, sizeof buf, "%s has just asked to directly connect to %s.", | |
1893 userinfo->sn, gc->username); | |
1894 do_ask_dialog(buf, d, accept_direct_im, cancel_direct_im); | |
1895 } else { | |
1896 debug_printf("Unknown reqclass %d\n", args->reqclass); | |
1897 } | |
1898 } | |
1899 | |
1900 return 1; | |
1901 } | |
1902 | |
1903 int gaim_parse_misses(struct aim_session_t *sess, | |
1904 struct command_rx_struct *command, ...) { | |
1905 va_list ap; | |
1906 unsigned short chan, nummissed, reason; | |
1907 struct aim_userinfo_s *userinfo; | |
1908 char buf[1024]; | |
1909 | |
1910 va_start(ap, command); | |
1911 chan = (unsigned short)va_arg(ap, unsigned int); | |
1912 userinfo = va_arg(ap, struct aim_userinfo_s *); | |
1913 nummissed = (unsigned short)va_arg(ap, unsigned int); | |
1914 reason = (unsigned short)va_arg(ap, unsigned int); | |
1915 va_end(ap); | |
1916 | |
1917 switch(reason) { | |
1918 case 1: | |
1919 /* message too large */ | |
1920 sprintf(buf, _("You missed a message from %s because it was too large."), userinfo->sn); | |
1921 do_error_dialog(buf, _("Gaim - Error")); | |
1922 plugin_event(event_error, (void *)961, 0, 0, 0); | |
1923 break; | |
1924 default: | |
1925 sprintf(buf, _("You missed a message from %s for unknown reasons."), userinfo->sn); | |
1926 do_error_dialog(buf, _("Gaim - Error")); | |
1927 plugin_event(event_error, (void *)970, 0, 0, 0); | |
1928 break; | |
1929 } | |
1930 | |
1931 return 1; | |
1932 } | |
1933 | |
1934 int gaim_parse_genericerr(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1935 va_list ap; | |
1936 unsigned short reason; | |
1937 | |
1938 va_start(ap, command); | |
1939 reason = va_arg(ap, int); | |
1940 va_end(ap); | |
1941 | |
1942 debug_printf("snac threw error (reason 0x%04x: %s\n", reason, | |
1943 (reason < msgerrreasonlen) ? msgerrreason[reason] : "unknown"); | |
1944 | |
1945 return 1; | |
1946 } | |
1947 | |
1948 int gaim_parse_msgerr(struct aim_session_t *sess, | |
1949 struct command_rx_struct *command, ...) { | |
1950 va_list ap; | |
1951 char *destn; | |
1952 unsigned short reason; | |
1953 char buf[1024]; | |
1954 | |
1955 va_start(ap, command); | |
1956 reason = (unsigned short)va_arg(ap, unsigned int); | |
1957 destn = va_arg(ap, char *); | |
1958 va_end(ap); | |
1959 | |
1960 sprintf(buf, _("Your message to %s did not get sent: %s"), destn, | |
1961 (reason < msgerrreasonlen) ? msgerrreason[reason] : _("Reason unknown")); | |
1962 do_error_dialog(buf, _("Gaim - Error")); | |
1963 | |
1964 return 1; | |
1965 } | |
1966 | |
1967 int gaim_parse_locerr(struct aim_session_t *sess, | |
1968 struct command_rx_struct *command, ...) { | |
1969 va_list ap; | |
1970 char *destn; | |
1971 unsigned short reason; | |
1972 char buf[1024]; | |
1973 | |
1974 va_start(ap, command); | |
1975 reason = (unsigned short)va_arg(ap, unsigned int); | |
1976 destn = va_arg(ap, char *); | |
1977 va_end(ap); | |
1978 | |
1979 sprintf(buf, _("User information for %s unavailable: %s"), destn, | |
1980 (reason < msgerrreasonlen) ? msgerrreason[reason] : _("Reason unknown")); | |
1981 do_error_dialog(buf, _("Gaim - Error")); | |
1982 | |
1983 return 1; | |
1984 } | |
1985 | |
1986 static char *images(int flags) { | |
1987 static char buf[1024]; | |
1988 g_snprintf(buf, sizeof(buf), "%s%s%s%s", | |
1989 (flags & AIM_FLAG_UNCONFIRMED) ? "<IMG SRC=\"dt_icon.gif\">" : "", | |
1990 (flags & AIM_FLAG_AOL) ? "<IMG SRC=\"aol_icon.gif\">" : "", | |
1991 (flags & AIM_FLAG_ADMINISTRATOR) ? "<IMG SRC=\"admin_icon.gif\">" : "", | |
1992 (flags & AIM_FLAG_FREE) ? "<IMG SRC=\"free_icon.gif\">" : ""); | |
1993 return buf; | |
1994 } | |
1995 | |
1996 int gaim_parse_user_info(struct aim_session_t *sess, | |
1997 struct command_rx_struct *command, ...) { | |
1998 struct aim_userinfo_s *info; | |
1999 char *prof_enc = NULL, *prof = NULL; | |
2000 unsigned short infotype; | |
2001 char buf[BUF_LONG]; | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2002 char legend[BUF_LONG]; |
2086 | 2003 struct gaim_connection *gc = sess->aux_data; |
2004 va_list ap; | |
2005 char *asc; | |
2006 | |
2007 va_start(ap, command); | |
2008 info = va_arg(ap, struct aim_userinfo_s *); | |
2009 prof_enc = va_arg(ap, char *); | |
2010 prof = va_arg(ap, char *); | |
2011 infotype = (unsigned short)va_arg(ap, unsigned int); | |
2012 va_end(ap); | |
2013 | |
2014 if (info->membersince) | |
2015 asc = g_strdup_printf("Member Since : <B>%s</B><BR>\n", | |
2016 asctime(localtime(&info->membersince))); | |
2017 else | |
2018 asc = g_strdup(""); | |
2019 | |
2020 g_snprintf(buf, sizeof buf, | |
2021 _("Username : <B>%s</B> %s <BR>\n" | |
2022 "%s" | |
2023 "Warning Level : <B>%d %%</B><BR>\n" | |
2024 "Online Since : <B>%s</B><BR>\n" | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2025 "Idle Minutes : <B>%d</B>\n<BR>\n<HR><BR>\n"), |
2086 | 2026 info->sn, images(info->flags), |
2027 asc, | |
2028 info->warnlevel/10, | |
2029 asctime(localtime(&info->onlinesince)), | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2030 info->idletime); |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2031 g_snprintf(legend, sizeof legend, |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2032 _("<br><BODY BGCOLOR=WHITE><hr><I>Legend:</I><br><br>" |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2033 "<IMG SRC=\"free_icon.gif\"> : Normal AIM User<br>" |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2034 "<IMG SRC=\"aol_icon.gif\"> : AOL User <br>" |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2035 "<IMG SRC=\"dt_icon.gif\"> : Trial AIM User <br>" |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2036 "<IMG SRC=\"admin_icon.gif\"> : Administrator")); |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2037 g_show_info_text(buf, |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2038 (prof && strlen(prof)) ? |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2039 away_subs(prof, gc->username) |
2086 | 2040 : |
2041 (infotype == AIM_GETINFO_GENERALINFO ? | |
2042 _("<i>No Information Provided</i>") : | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2043 _("<i>User has no away message</i>")), |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2044 legend, |
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2045 NULL); |
2086 | 2046 |
2047 g_free(asc); | |
2048 | |
2049 return 1; | |
2050 } | |
2051 | |
2052 int gaim_parse_motd(struct aim_session_t *sess, | |
2053 struct command_rx_struct *command, ...) { | |
2054 char *msg; | |
2055 unsigned short id; | |
2056 va_list ap; | |
2057 char buildbuf[150]; | |
2058 | |
2059 va_start(ap, command); | |
2060 id = (unsigned short)va_arg(ap, unsigned int); | |
2061 msg = va_arg(ap, char *); | |
2062 va_end(ap); | |
2063 | |
2064 aim_getbuildstring(buildbuf, sizeof(buildbuf)); | |
2065 | |
2066 debug_printf("MOTD: %s (%d)\n", msg ? msg : "Unknown", id); | |
2067 debug_printf("Gaim %s / Libfaim %s\n", VERSION, buildbuf); | |
2092
59b0377d18aa
[gaim-migrate @ 2102]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
2068 if (id < 4) |
2086 | 2069 do_error_dialog(_("Your connection may be lost."), |
2070 _("AOL error")); | |
2071 | |
2072 return 1; | |
2073 } | |
2074 | |
2075 int gaim_chatnav_info(struct aim_session_t *sess, | |
2076 struct command_rx_struct *command, ...) { | |
2077 va_list ap; | |
2078 unsigned short type; | |
2079 struct gaim_connection *gc = sess->aux_data; | |
2080 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; | |
2081 | |
2082 va_start(ap, command); | |
2083 type = (unsigned short)va_arg(ap, unsigned int); | |
2084 | |
2085 switch(type) { | |
2086 case 0x0002: { | |
2087 int maxrooms; | |
2088 struct aim_chat_exchangeinfo *exchanges; | |
2089 int exchangecount, i = 0; | |
2090 | |
2091 maxrooms = (unsigned char)va_arg(ap, unsigned int); | |
2092 exchangecount = va_arg(ap, int); | |
2093 exchanges = va_arg(ap, struct aim_chat_exchangeinfo *); | |
2094 va_end(ap); | |
2095 | |
2096 debug_printf("chat info: Chat Rights:\n"); | |
2097 debug_printf("chat info: \tMax Concurrent Rooms: %d\n", maxrooms); | |
2098 debug_printf("chat info: \tExchange List: (%d total)\n", exchangecount); | |
2099 while (i < exchangecount) | |
2100 debug_printf("chat info: \t\t%d\n", exchanges[i++].number); | |
2101 if (odata->create_exchange) { | |
2102 debug_printf("creating room %s\n", odata->create_name); | |
2103 aim_chatnav_createroom(sess, command->conn, odata->create_name, | |
2104 odata->create_exchange); | |
2105 odata->create_exchange = 0; | |
2106 g_free(odata->create_name); | |
2107 odata->create_name = NULL; | |
2108 } | |
2109 } | |
2110 break; | |
2111 case 0x0008: { | |
2112 char *fqcn, *name, *ck; | |
2113 unsigned short instance, flags, maxmsglen, maxoccupancy, unknown, exchange; | |
2114 unsigned char createperms; | |
2115 unsigned long createtime; | |
2116 | |
2117 fqcn = va_arg(ap, char *); | |
2118 instance = (unsigned short)va_arg(ap, unsigned int); | |
2119 exchange = (unsigned short)va_arg(ap, unsigned int); | |
2120 flags = (unsigned short)va_arg(ap, unsigned int); | |
2121 createtime = va_arg(ap, unsigned long); | |
2122 maxmsglen = (unsigned short)va_arg(ap, unsigned int); | |
2123 maxoccupancy = (unsigned short)va_arg(ap, unsigned int); | |
2124 createperms = (unsigned char)va_arg(ap, int); | |
2125 unknown = (unsigned short)va_arg(ap, unsigned int); | |
2126 name = va_arg(ap, char *); | |
2127 ck = va_arg(ap, char *); | |
2128 va_end(ap); | |
2129 | |
2130 debug_printf("created room: %s %d %d %d %lu %d %d %d %d %s %s\n", | |
2131 fqcn, | |
2132 exchange, instance, flags, | |
2133 createtime, | |
2134 maxmsglen, maxoccupancy, createperms, unknown, | |
2135 name, ck); | |
2136 aim_chat_join(odata->sess, odata->conn, exchange, ck); | |
2137 } | |
2138 break; | |
2139 default: | |
2140 va_end(ap); | |
2141 debug_printf("chatnav info: unknown type (%04x)\n", type); | |
2142 break; | |
2143 } | |
2144 return 1; | |
2145 } | |
2146 | |
2147 int gaim_chat_join(struct aim_session_t *sess, | |
2148 struct command_rx_struct *command, ...) { | |
2149 va_list ap; | |
2150 int count, i = 0; | |
2151 struct aim_userinfo_s *info; | |
2152 struct gaim_connection *g = sess->aux_data; | |
2153 | |
2154 struct chat_connection *c = NULL; | |
2155 | |
2156 va_start(ap, command); | |
2157 count = va_arg(ap, int); | |
2158 info = va_arg(ap, struct aim_userinfo_s *); | |
2159 va_end(ap); | |
2160 | |
2161 c = find_oscar_chat_by_conn(g, command->conn); | |
2162 if (!c) | |
2163 return 1; | |
2164 | |
2165 while (i < count) | |
2166 add_chat_buddy(c->cnv, info[i++].sn); | |
2167 | |
2168 return 1; | |
2169 } | |
2170 | |
2171 int gaim_chat_leave(struct aim_session_t *sess, | |
2172 struct command_rx_struct *command, ...) { | |
2173 va_list ap; | |
2174 int count, i = 0; | |
2175 struct aim_userinfo_s *info; | |
2176 struct gaim_connection *g = sess->aux_data; | |
2177 | |
2178 struct chat_connection *c = NULL; | |
2179 | |
2180 va_start(ap, command); | |
2181 count = va_arg(ap, int); | |
2182 info = va_arg(ap, struct aim_userinfo_s *); | |
2183 va_end(ap); | |
2184 | |
2185 c = find_oscar_chat_by_conn(g, command->conn); | |
2186 if (!c) | |
2187 return 1; | |
2188 | |
2189 while (i < count) | |
2190 remove_chat_buddy(c->cnv, info[i++].sn); | |
2191 | |
2192 return 1; | |
2193 } | |
2194 | |
2195 int gaim_chat_info_update(struct aim_session_t *sess, | |
2196 struct command_rx_struct *command, ...) { | |
2197 debug_printf("inside chat_info_update\n"); | |
2198 return 1; | |
2199 } | |
2200 | |
2201 int gaim_chat_incoming_msg(struct aim_session_t *sess, | |
2202 struct command_rx_struct *command, ...) { | |
2203 va_list ap; | |
2204 struct aim_userinfo_s *info; | |
2205 char *msg; | |
2206 struct gaim_connection *gc = sess->aux_data; | |
2207 struct chat_connection *ccon = find_oscar_chat_by_conn(gc, command->conn); | |
2208 char *tmp; | |
2209 | |
2210 va_start(ap, command); | |
2211 info = va_arg(ap, struct aim_userinfo_s *); | |
2212 msg = va_arg(ap, char *); | |
2213 | |
2214 tmp = g_malloc(BUF_LONG); | |
2215 g_snprintf(tmp, BUF_LONG, "%s", msg); | |
2216 serv_got_chat_in(gc, ccon->id, info->sn, 0, tmp, time((time_t)NULL)); | |
2217 g_free(tmp); | |
2218 | |
2219 return 1; | |
2220 } | |
2221 | |
2222 /* | |
2223 * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option. | |
2224 */ | |
2225 int gaim_parse_msgack(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2226 va_list ap; | |
2227 unsigned short type; | |
2228 char *sn = NULL; | |
2229 | |
2230 va_start(ap, command); | |
2231 type = (unsigned short)va_arg(ap, unsigned int); | |
2232 sn = va_arg(ap, char *); | |
2233 va_end(ap); | |
2234 | |
2235 debug_printf("Sent message to %s.\n", sn); | |
2236 | |
2237 return 1; | |
2238 } | |
2239 | |
2240 int gaim_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2241 static char *codes[5] = {"invalid", | |
2242 "change", | |
2243 "warning", | |
2244 "limit", | |
2245 "limit cleared"}; | |
2246 va_list ap; | |
2247 int code; | |
2248 unsigned long rateclass, windowsize, clear, alert, limit, disconnect; | |
2249 unsigned long currentavg, maxavg; | |
2250 | |
2251 va_start(ap, command); | |
2252 code = va_arg(ap, int); | |
2253 rateclass= va_arg(ap, int); | |
2254 windowsize = va_arg(ap, unsigned long); | |
2255 clear = va_arg(ap, unsigned long); | |
2256 alert = va_arg(ap, unsigned long); | |
2257 limit = va_arg(ap, unsigned long); | |
2258 disconnect = va_arg(ap, unsigned long); | |
2259 currentavg = va_arg(ap, unsigned long); | |
2260 maxavg = va_arg(ap, unsigned long); | |
2261 va_end(ap); | |
2262 | |
2263 debug_printf("rate %s (paramid 0x%04lx): curavg = %ld, maxavg = %ld, alert at %ld, " | |
2264 "clear warning at %ld, limit at %ld, disconnect at %ld (window size = %ld)\n", | |
2265 (code < 5) ? codes[code] : codes[0], | |
2266 rateclass, | |
2267 currentavg, maxavg, | |
2268 alert, clear, | |
2269 limit, disconnect, | |
2270 windowsize); | |
2271 | |
2272 if (code == AIM_RATE_CODE_CHANGE) { | |
2273 if (currentavg >= clear) | |
2274 aim_conn_setlatency(command->conn, 0); | |
2275 } else if (code == AIM_RATE_CODE_WARNING) { | |
2276 aim_conn_setlatency(command->conn, windowsize/4); | |
2277 } else if (code == AIM_RATE_CODE_LIMIT) { | |
2278 aim_conn_setlatency(command->conn, windowsize/2); | |
2279 } else if (code == AIM_RATE_CODE_CLEARLIMIT) { | |
2280 aim_conn_setlatency(command->conn, 0); | |
2281 } | |
2282 | |
2283 return 1; | |
2284 } | |
2285 | |
2286 int gaim_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2287 va_list ap; | |
2288 int newevil; | |
2289 struct aim_userinfo_s *userinfo; | |
2290 struct gaim_connection *gc = sess->aux_data; | |
2291 | |
2292 va_start(ap, command); | |
2293 newevil = va_arg(ap, int); | |
2294 userinfo = va_arg(ap, struct aim_userinfo_s *); | |
2295 va_end(ap); | |
2296 | |
2297 serv_got_eviled(gc, (userinfo && userinfo->sn[0]) ? userinfo->sn : NULL, newevil / 10); | |
2298 | |
2299 return 1; | |
2300 } | |
2301 | |
2302 int gaim_rateresp(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2303 struct gaim_connection *gc = sess->aux_data; | |
2304 switch (command->conn->type) { | |
2305 case AIM_CONN_TYPE_BOS: | |
2306 aim_bos_ackrateresp(sess, command->conn); | |
2307 aim_bos_reqpersonalinfo(sess, command->conn); | |
2308 aim_bos_reqlocaterights(sess, command->conn); | |
2309 aim_bos_setprofile(sess, command->conn, gc->user->user_info, NULL, gaim_caps); | |
2310 aim_bos_reqbuddyrights(sess, command->conn); | |
2311 | |
2312 account_online(gc); | |
2313 serv_finish_login(gc); | |
2314 | |
2315 if (bud_list_cache_exists(gc)) | |
2316 do_import(NULL, gc); | |
2317 | |
2318 debug_printf("buddy list loaded\n"); | |
2319 | |
2320 aim_addicbmparam(sess, command->conn); | |
2321 aim_bos_reqicbmparaminfo(sess, command->conn); | |
2322 | |
2323 aim_bos_reqrights(sess, command->conn); | |
2324 aim_bos_setgroupperm(sess, command->conn, AIM_FLAG_ALLUSERS); | |
2325 aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE | | |
2326 AIM_PRIVFLAGS_ALLOWMEMBERSINCE); | |
2327 | |
2328 break; | |
2329 case AIM_CONN_TYPE_AUTH: | |
2330 aim_bos_ackrateresp(sess, command->conn); | |
2331 aim_auth_clientready(sess, command->conn); | |
2332 debug_printf("connected to auth (admin)\n"); | |
2333 break; | |
2334 default: | |
2335 debug_printf("got rate response for unhandled connection type %04x\n", | |
2336 command->conn->type); | |
2337 break; | |
2338 } | |
2339 | |
2340 return 1; | |
2341 } | |
2342 | |
2343 int gaim_reportinterval(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2344 if (command->data) { | |
2345 debug_printf("minimum report interval: %d (seconds?)\n", aimutil_get16(command->data+10)); | |
2346 } else | |
2347 debug_printf("NULL minimum report interval!\n"); | |
2348 return 1; | |
2349 } | |
2350 | |
2351 int gaim_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2352 va_list ap; | |
2353 unsigned short maxbuddies, maxwatchers; | |
2354 | |
2355 va_start(ap, command); | |
2356 maxbuddies = (unsigned short)va_arg(ap, unsigned int); | |
2357 maxwatchers = (unsigned short)va_arg(ap, unsigned int); | |
2358 va_end(ap); | |
2359 | |
2360 debug_printf("buddy list rights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers); | |
2361 | |
2362 return 1; | |
2363 } | |
2364 | |
2365 int gaim_bosrights(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2366 unsigned short maxpermits, maxdenies; | |
2367 va_list ap; | |
2368 | |
2369 va_start(ap, command); | |
2370 maxpermits = (unsigned short)va_arg(ap, unsigned int); | |
2371 maxdenies = (unsigned short)va_arg(ap, unsigned int); | |
2372 va_end(ap); | |
2373 | |
2374 debug_printf("BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies); | |
2375 | |
2376 aim_bos_clientready(sess, command->conn); | |
2377 | |
2378 aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV); | |
2379 | |
2380 return 1; | |
2381 } | |
2382 | |
2383 int gaim_parse_searchreply(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2384 va_list ap; | |
2385 char *address, *SNs; | |
2386 int i, num; | |
2387 char *buf; | |
2388 int at = 0, len; | |
2389 | |
2390 va_start(ap, command); | |
2391 address = va_arg(ap, char *); | |
2392 num = va_arg(ap, int); | |
2393 SNs = va_arg(ap, char *); | |
2394 va_end(ap); | |
2395 | |
2396 len = num * (MAXSNLEN + 1) + 1024; | |
2397 buf = g_malloc(len); | |
2398 at += g_snprintf(buf + at, len - at, "<B>%s has the following screen names:</B><BR>", address); | |
2399 for (i = 0; i < num; i++) | |
2400 at += g_snprintf(buf + at, len - at, "%s<BR>", &SNs[i * (MAXSNLEN + 1)]); | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2401 g_show_info_text(buf, NULL); |
2086 | 2402 g_free(buf); |
2403 | |
2404 return 1; | |
2405 } | |
2406 | |
2407 int gaim_parse_searcherror(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2408 va_list ap; | |
2409 char *address; | |
2410 char buf[BUF_LONG]; | |
2411 | |
2412 va_start(ap, command); | |
2413 address = va_arg(ap, char *); | |
2414 va_end(ap); | |
2415 | |
2416 g_snprintf(buf, sizeof(buf), "No results found for email address %s", address); | |
2417 do_error_dialog(buf, _("Error")); | |
2418 | |
2419 return 1; | |
2420 } | |
2421 | |
2422 int gaim_account_confirm(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2423 int status; | |
2424 va_list ap; | |
2425 char msg[256]; | |
2426 struct gaim_connection *gc = sess->aux_data; | |
2427 | |
2428 va_start(ap, command); | |
2429 status = va_arg(ap, int); /* status code of confirmation request */ | |
2430 va_end(ap); | |
2431 | |
2432 debug_printf("account confirmation returned status 0x%04x (%s)\n", status, | |
2433 status ? "email sent" : "unknown"); | |
2434 if (status) { | |
2435 g_snprintf(msg, sizeof(msg), "You should receive an email asking to confirm %s.", | |
2436 gc->username); | |
2437 do_error_dialog(msg, "Confirm"); | |
2438 } | |
2439 | |
2440 return 1; | |
2441 } | |
2442 | |
2443 int gaim_info_change(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2444 unsigned short change = 0; | |
2445 int perms, type, length, str; | |
2446 char *val; | |
2447 va_list ap; | |
2448 char buf[BUF_LONG]; | |
2449 struct gaim_connection *gc = sess->aux_data; | |
2450 | |
2451 va_start(ap, command); | |
2452 perms = va_arg(ap, int); | |
2453 type = va_arg(ap, int); | |
2454 length = va_arg(ap, int); | |
2455 val = va_arg(ap, char *); | |
2456 str = va_arg(ap, int); | |
2457 va_end(ap); | |
2458 | |
2459 if (aimutil_get16(command->data+2) == 0x0005) | |
2460 change = 1; | |
2461 | |
2462 debug_printf("info%s: perms = %d, type = %x, length = %d, val = %s\n", | |
2463 change ? " change" : "", perms, type, length, str ? val : "(not string)"); | |
2464 | |
2465 if ((type == 0x0011) && str) { | |
2466 g_snprintf(buf, sizeof(buf), "The email address for %s is %s", gc->username, val); | |
2467 do_error_dialog(buf, "Email"); | |
2468 } | |
2469 | |
2470 return 1; | |
2471 } | |
2472 | |
2473 static void oscar_keepalive(struct gaim_connection *gc) { | |
2474 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; | |
2475 aim_flap_nop(odata->sess, odata->conn); | |
2476 } | |
2477 | |
2478 static char *oscar_name() { | |
2479 return "Oscar"; | |
2480 } | |
2481 | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2113
diff
changeset
|
2482 static int oscar_send_im(struct gaim_connection *gc, char *name, char *message, int away) { |
2086 | 2483 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; |
2484 struct direct_im *dim = find_direct_im(odata, name); | |
2485 if (dim) { | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2113
diff
changeset
|
2486 return aim_send_im_direct(odata->sess, dim->conn, message); |
2086 | 2487 } else { |
2488 if (away) | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2113
diff
changeset
|
2489 return aim_send_im(odata->sess, odata->conn, name, AIM_IMFLAGS_AWAY, message); |
2086 | 2490 else { |
2491 int flags = AIM_IMFLAGS_ACK; | |
2492 #if USE_PIXBUF | |
2493 GSList *h = odata->hasicons; | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
2494 struct icon_req *ir = NULL; |
2086 | 2495 char *who = normalize(name); |
2496 while (h) { | |
2497 ir = h->data; | |
2498 if (ir->request && !strcmp(who, ir->user)) | |
2499 break; | |
2500 h = h->next; | |
2501 } | |
2502 if (h) { | |
2503 ir->request = FALSE; | |
2504 flags |= AIM_IMFLAGS_BUDDYREQ; | |
2505 debug_printf("sending buddy icon request with message\n"); | |
2506 } | |
2507 #endif | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2113
diff
changeset
|
2508 return aim_send_im(odata->sess, odata->conn, name, flags, message); |
2086 | 2509 } |
2510 } | |
2511 } | |
2512 | |
2513 static void oscar_get_info(struct gaim_connection *g, char *name) { | |
2514 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2515 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_GENERALINFO); | |
2516 } | |
2517 | |
2518 static void oscar_get_away_msg(struct gaim_connection *g, char *name) { | |
2519 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2520 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_AWAYMESSAGE); | |
2521 } | |
2522 | |
2523 static void oscar_set_dir(struct gaim_connection *g, char *first, char *middle, char *last, | |
2524 char *maiden, char *city, char *state, char *country, int web) { | |
2525 /* FIXME : some of these things are wrong, but i'm lazy */ | |
2526 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2527 aim_setdirectoryinfo(odata->sess, odata->conn, first, middle, last, | |
2528 maiden, NULL, NULL, city, state, NULL, 0, web); | |
2529 } | |
2530 | |
2531 | |
2532 static void oscar_set_idle(struct gaim_connection *g, int time) { | |
2533 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2534 aim_bos_setidle(odata->sess, odata->conn, time); | |
2535 } | |
2536 | |
2537 static void oscar_set_info(struct gaim_connection *g, char *info) { | |
2538 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2539 char inforeal[1025], away[1025]; | |
2540 g_snprintf(inforeal, sizeof(inforeal), "%s", info); | |
2541 if (g->away) | |
2542 g_snprintf(away, sizeof(away), "%s", g->away); | |
2543 if (strlen(info) > 1024) | |
2544 do_error_dialog("Maximum info length (1024) exceeded, truncating", "Info Too Long"); | |
2545 aim_bos_setprofile(odata->sess, odata->conn, inforeal, g->away ? NULL : "", gaim_caps); | |
2546 } | |
2547 | |
2548 static void oscar_set_away(struct gaim_connection *g, char *state, char *message) { | |
2549 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2550 char info[1025], away[1025]; | |
2551 g_snprintf(info, sizeof(info), "%s", g->user->user_info); | |
2552 if (message) | |
2553 g_snprintf(away, sizeof(away), "%s", message); | |
2554 aim_bos_setprofile(odata->sess, odata->conn, NULL, message ? away : "", gaim_caps); | |
2555 if (g->away) | |
2556 g_free (g->away); | |
2557 g->away = NULL; | |
2558 if (message) { | |
2559 if (strlen(message) > 1024) | |
2560 do_error_dialog("Maximum away length (1024) exceeded, truncating", | |
2561 "Info Too Long"); | |
2562 g->away = g_strdup (message); | |
2563 } | |
2564 } | |
2565 | |
2566 static void oscar_warn(struct gaim_connection *g, char *name, int anon) { | |
2567 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2113 | 2568 aim_send_warning(odata->sess, odata->conn, name, anon ? AIM_WARN_ANON : 0); |
2086 | 2569 } |
2570 | |
2571 static void oscar_dir_search(struct gaim_connection *g, char *first, char *middle, char *last, | |
2572 char *maiden, char *city, char *state, char *country, char *email) { | |
2573 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2574 if (strlen(email)) | |
2575 aim_usersearch_address(odata->sess, odata->conn, email); | |
2576 } | |
2577 | |
2578 static void oscar_add_buddy(struct gaim_connection *g, char *name) { | |
2579 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2580 aim_add_buddy(odata->sess, odata->conn, name); | |
2581 } | |
2582 | |
2583 static void oscar_add_buddies(struct gaim_connection *g, GList *buddies) { | |
2584 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2585 char buf[MSG_LEN]; | |
2586 int n = 0; | |
2587 while (buddies) { | |
2588 if (n > MSG_LEN - 18) { | |
2589 aim_bos_setbuddylist(odata->sess, odata->conn, buf); | |
2590 n = 0; | |
2591 } | |
2592 n += g_snprintf(buf + n, sizeof(buf) - n, "%s&", (char *)buddies->data); | |
2593 buddies = buddies->next; | |
2594 } | |
2595 aim_bos_setbuddylist(odata->sess, odata->conn, buf); | |
2596 } | |
2597 | |
2598 static void oscar_remove_buddy(struct gaim_connection *g, char *name) { | |
2599 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2600 aim_remove_buddy(odata->sess, odata->conn, name); | |
2601 } | |
2602 | |
2603 static void oscar_join_chat(struct gaim_connection *g, int exchange, char *name) { | |
2604 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2605 struct aim_conn_t *cur = NULL; | |
2606 if (!name) { | |
2607 if (!join_chat_entry || !join_chat_spin) | |
2608 return; | |
2609 name = gtk_entry_get_text(GTK_ENTRY(join_chat_entry)); | |
2610 exchange = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(join_chat_spin)); | |
2611 if (!name || !strlen(name)) | |
2612 return; | |
2613 } | |
2614 debug_printf("Attempting to join chat room %s.\n", name); | |
2615 if ((cur = aim_getconn_type(odata->sess, AIM_CONN_TYPE_CHATNAV))) { | |
2616 debug_printf("chatnav exists, creating room\n"); | |
2617 aim_chatnav_createroom(odata->sess, cur, name, exchange); | |
2618 } else { | |
2619 /* this gets tricky */ | |
2620 debug_printf("chatnav does not exist, opening chatnav\n"); | |
2621 odata->create_exchange = exchange; | |
2622 odata->create_name = g_strdup(name); | |
2623 aim_bos_reqservice(odata->sess, odata->conn, AIM_CONN_TYPE_CHATNAV); | |
2624 } | |
2625 } | |
2626 | |
2627 static void des_jc() | |
2628 { | |
2629 join_chat_entry = NULL; | |
2630 join_chat_spin = NULL; | |
2631 } | |
2632 | |
2633 static void oscar_draw_join_chat(struct gaim_connection *gc, GtkWidget *fbox) { | |
2634 GtkWidget *label; | |
2635 GtkWidget *rowbox; | |
2636 GtkObject *adjust; | |
2637 | |
2638 rowbox = gtk_hbox_new(FALSE, 5); | |
2639 gtk_box_pack_start(GTK_BOX(fbox), rowbox, TRUE, TRUE, 0); | |
2640 gtk_widget_show(rowbox); | |
2641 | |
2642 label = gtk_label_new(_("Join what group:")); | |
2643 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
2644 gtk_signal_connect(GTK_OBJECT(label), "destroy", GTK_SIGNAL_FUNC(des_jc), NULL); | |
2645 gtk_widget_show(label); | |
2646 | |
2647 join_chat_entry = gtk_entry_new(); | |
2648 gtk_box_pack_start(GTK_BOX(rowbox), join_chat_entry, TRUE, TRUE, 0); | |
2649 gtk_widget_grab_focus(join_chat_entry); | |
2650 gtk_signal_connect(GTK_OBJECT(join_chat_entry), "activate", GTK_SIGNAL_FUNC(do_join_chat), NULL); | |
2651 gtk_widget_show(join_chat_entry); | |
2652 | |
2653 rowbox = gtk_hbox_new(FALSE, 5); | |
2654 gtk_box_pack_start(GTK_BOX(fbox), rowbox, TRUE, TRUE, 0); | |
2655 gtk_widget_show(rowbox); | |
2656 | |
2657 label = gtk_label_new(_("Exchange:")); | |
2658 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
2659 gtk_widget_show(label); | |
2660 | |
2661 adjust = gtk_adjustment_new(4, 4, 20, 1, 10, 10); | |
2662 join_chat_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); | |
2663 gtk_widget_set_usize(join_chat_spin, 50, -1); | |
2664 gtk_box_pack_start(GTK_BOX(rowbox), join_chat_spin, FALSE, FALSE, 0); | |
2665 gtk_widget_show(join_chat_spin); | |
2666 } | |
2667 | |
2668 static void oscar_chat_invite(struct gaim_connection *g, int id, char *message, char *name) { | |
2669 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2670 struct chat_connection *ccon = find_oscar_chat(g, id); | |
2671 | |
2672 if (!ccon) | |
2673 return; | |
2674 | |
2675 aim_chat_invite(odata->sess, odata->conn, name, message ? message : "", | |
2676 ccon->exchange, ccon->name, 0x0); | |
2677 } | |
2678 | |
2679 static void oscar_chat_leave(struct gaim_connection *g, int id) { | |
2680 struct oscar_data *odata = g ? (struct oscar_data *)g->proto_data : NULL; | |
2681 GSList *bcs = g->buddy_chats; | |
2682 struct conversation *b = NULL; | |
2683 struct chat_connection *c = NULL; | |
2684 int count = 0; | |
2685 | |
2686 while (bcs) { | |
2687 count++; | |
2688 b = (struct conversation *)bcs->data; | |
2689 if (id == b->id) | |
2690 break; | |
2691 bcs = bcs->next; | |
2692 b = NULL; | |
2693 } | |
2694 | |
2695 if (!b) | |
2696 return; | |
2697 | |
2698 debug_printf("Attempting to leave room %s (currently in %d rooms)\n", b->name, count); | |
2699 | |
2700 c = find_oscar_chat(g, b->id); | |
2701 if (c != NULL) { | |
2702 if (odata) | |
2703 odata->oscar_chats = g_slist_remove(odata->oscar_chats, c); | |
2704 if (c->inpa > 0) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
2705 gaim_input_remove(c->inpa); |
2086 | 2706 if (g && odata->sess) |
2707 aim_conn_kill(odata->sess, &c->conn); | |
2708 g_free(c->name); | |
2709 g_free(c->show); | |
2710 g_free(c); | |
2711 } | |
2712 /* we do this because with Oscar it doesn't tell us we left */ | |
2713 serv_got_chat_left(g, b->id); | |
2714 } | |
2715 | |
2716 static void oscar_chat_send(struct gaim_connection *g, int id, char *message) { | |
2717 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | |
2718 GSList *bcs = g->buddy_chats; | |
2719 struct conversation *b = NULL; | |
2720 struct chat_connection *c = NULL; | |
2721 char *buf; | |
2722 int i, j; | |
2723 | |
2724 while (bcs) { | |
2725 b = (struct conversation *)bcs->data; | |
2726 if (id == b->id) | |
2727 break; | |
2728 bcs = bcs->next; | |
2729 b = NULL; | |
2730 } | |
2731 if (!b) | |
2732 return; | |
2733 | |
2734 bcs = odata->oscar_chats; | |
2735 while (bcs) { | |
2736 c = (struct chat_connection *)bcs->data; | |
2737 if (b == c->cnv) | |
2738 break; | |
2739 bcs = bcs->next; | |
2740 c = NULL; | |
2741 } | |
2742 if (!c) | |
2743 return; | |
2744 | |
2745 buf = g_malloc(strlen(message) * 4 + 1); | |
2746 for (i = 0, j = 0; i < strlen(message); i++) { | |
2747 if (message[i] == '\n') { | |
2748 buf[j++] = '<'; | |
2749 buf[j++] = 'B'; | |
2750 buf[j++] = 'R'; | |
2751 buf[j++] = '>'; | |
2752 } else { | |
2753 buf[j++] = message[i]; | |
2754 } | |
2755 } | |
2756 buf[j] = '\0'; | |
2757 aim_chat_send_im(odata->sess, c->conn, 0, buf, strlen(buf)); | |
2758 g_free(buf); | |
2759 } | |
2760 | |
2761 static char **oscar_list_icon(int uc) { | |
2762 if (uc & UC_UNAVAILABLE) | |
2763 return (char **)away_icon_xpm; | |
2764 if (uc & UC_AOL) | |
2765 return (char **)aol_icon_xpm; | |
2766 if (uc & UC_NORMAL) | |
2767 return (char **)free_icon_xpm; | |
2768 if (uc & UC_ADMIN) | |
2769 return (char **)admin_icon_xpm; | |
2770 if (uc & UC_UNCONFIRMED) | |
2771 return (char **)dt_icon_xpm; | |
2772 return NULL; | |
2773 } | |
2774 | |
2775 static void oscar_info(GtkObject *obj, char *who) { | |
2776 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(obj); | |
2777 serv_get_info(gc, who); | |
2778 } | |
2779 | |
2780 static void oscar_away_msg(GtkObject *obj, char *who) { | |
2781 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(obj); | |
2782 serv_get_away_msg(gc, who); | |
2783 } | |
2784 | |
2785 static int gaim_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2786 va_list ap; | |
2787 struct gaim_connection *gc = sess->aux_data; | |
2788 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
2789 struct aim_directim_priv *priv; | |
2790 struct aim_conn_t *newconn; | |
2791 struct direct_im *dim; | |
2792 char buf[256]; | |
2793 | |
2794 va_start(ap, command); | |
2795 newconn = va_arg(ap, struct aim_conn_t *); | |
2796 va_end(ap); | |
2797 | |
2798 priv = (struct aim_directim_priv *)newconn->priv; | |
2799 | |
2800 debug_printf("DirectIM: initiate success to %s\n", priv->sn); | |
2801 dim = find_direct_im(od, priv->sn); | |
2802 | |
2803 dim->cnv = find_conversation(priv->sn); | |
2804 if (!dim->cnv) dim->cnv = new_conversation(priv->sn); | |
2805 gtk_signal_connect(GTK_OBJECT(dim->cnv->window), "destroy", | |
2806 GTK_SIGNAL_FUNC(delete_direct_im), dim); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
2807 gaim_input_remove(dim->watcher); |
2086 | 2808 dim->conn = newconn; |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
2809 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, |
2086 | 2810 oscar_callback, dim->conn); |
2811 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), priv->sn); | |
2812 write_to_conv(dim->cnv, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL)); | |
2813 | |
2814 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, | |
2815 gaim_directim_incoming, 0); | |
2816 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, | |
2817 gaim_directim_disconnect, 0); | |
2818 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, | |
2819 gaim_directim_typing, 0); | |
2820 | |
2821 return 1; | |
2822 } | |
2823 | |
2824 static int gaim_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2825 va_list ap; | |
2826 char *msg = NULL; | |
2827 struct aim_conn_t *conn; | |
2828 struct aim_directim_priv *priv; | |
2829 struct gaim_connection *gc = sess->aux_data; | |
2830 | |
2831 va_start(ap, command); | |
2832 conn = va_arg(ap, struct aim_conn_t *); | |
2833 msg = va_arg(ap, char *); | |
2834 va_end(ap); | |
2835 | |
2836 if (!(priv = conn->priv)) { | |
2837 return -1; | |
2838 } | |
2839 | |
2840 debug_printf("Got DirectIM message from %s\n", priv->sn); | |
2841 | |
2842 serv_got_im(gc, priv->sn, msg, 0, time((time_t)NULL)); | |
2843 | |
2844 return 1; | |
2845 } | |
2846 | |
2847 static int gaim_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2848 va_list ap; | |
2849 struct aim_conn_t *conn; | |
2850 char *sn; | |
2851 struct gaim_connection *gc = sess->aux_data; | |
2852 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
2853 struct direct_im *dim; | |
2854 char buf[256]; | |
2855 | |
2856 va_start(ap, command); | |
2857 conn = va_arg(ap, struct aim_conn_t *); | |
2858 sn = va_arg(ap, char *); | |
2859 va_end(ap); | |
2860 | |
2861 debug_printf("%s disconnected Direct IM.\n", sn); | |
2862 | |
2863 dim = find_direct_im(od, sn); | |
2864 od->direct_ims = g_slist_remove(od->direct_ims, dim); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
2865 gaim_input_remove(dim->watcher); |
2086 | 2866 gtk_signal_disconnect_by_data(GTK_OBJECT(dim->cnv->window), dim); |
2867 | |
2868 g_snprintf(buf, sizeof buf, _("Direct IM with %s closed"), sn); | |
2869 if (dim->cnv) | |
2870 write_to_conv(dim->cnv, buf, WFLAG_SYSTEM, NULL, time((time_t)NULL)); | |
2871 | |
2872 aim_conn_kill(sess, &conn); | |
2873 | |
2874 return 1; | |
2875 } | |
2876 | |
2877 static int gaim_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
2878 va_list ap; | |
2879 struct aim_conn_t *conn; | |
2880 struct aim_directim_priv *priv; | |
2881 | |
2882 va_start(ap, command); | |
2883 conn = va_arg(ap, struct aim_conn_t *); | |
2884 va_end(ap); | |
2885 | |
2886 if (!(priv = conn->priv)) { | |
2887 return -1; | |
2888 } | |
2889 | |
2890 /* I had to leave this. It's just too funny. It reminds me of my sister. */ | |
2891 debug_printf("ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", priv->sn); | |
2892 | |
2893 return 1; | |
2894 } | |
2895 | |
2896 struct ask_do_dir_im { | |
2897 char *who; | |
2898 struct gaim_connection *gc; | |
2899 }; | |
2900 | |
2901 static void oscar_cancel_direct_im(GtkObject *obj, struct ask_do_dir_im *data) { | |
2902 g_free(data); | |
2903 } | |
2904 | |
2905 static void oscar_direct_im(GtkObject *obj, struct ask_do_dir_im *data) { | |
2906 struct gaim_connection *gc = data->gc; | |
2907 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
2908 struct direct_im *dim; | |
2909 | |
2910 dim = find_direct_im(od, data->who); | |
2911 if (dim) { | |
2912 do_error_dialog("Direct IM request already pending.", "Unable"); | |
2913 return; | |
2914 } | |
2915 dim = g_new0(struct direct_im, 1); | |
2916 dim->gc = gc; | |
2917 g_snprintf(dim->name, sizeof dim->name, "%s", data->who); | |
2918 | |
2919 dim->conn = aim_directim_initiate(od->sess, od->conn, NULL, data->who); | |
2920 if (dim->conn != NULL) { | |
2921 od->direct_ims = g_slist_append(od->direct_ims, dim); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
2922 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, |
2086 | 2923 oscar_callback, dim->conn); |
2924 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, | |
2925 gaim_directim_initiate, 0); | |
2926 } else { | |
2927 do_error_dialog(_("Unable to open Direct IM"), _("Error")); | |
2928 g_free(dim); | |
2929 } | |
2930 } | |
2931 | |
2932 static void oscar_ask_direct_im(GtkObject *m, gchar *who) { | |
2933 char buf[BUF_LONG]; | |
2934 struct ask_do_dir_im *data = g_new0(struct ask_do_dir_im, 1); | |
2935 data->who = who; | |
2936 data->gc = gtk_object_get_user_data(m); | |
2937 g_snprintf(buf, sizeof(buf), _("You have selected to open a Direct IM connection with %s." | |
2938 " Doing this will let them see your IP address, and may be" | |
2939 " a security risk. Do you wish to continue?"), who); | |
2940 do_ask_dialog(buf, data, oscar_direct_im, oscar_cancel_direct_im); | |
2941 } | |
2942 | |
2943 static void oscar_buddy_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) { | |
2944 GtkWidget *button; | |
2945 char *n = g_strdup(normalize(gc->username)); | |
2946 | |
2947 button = gtk_menu_item_new_with_label(_("Get Info")); | |
2948 gtk_signal_connect(GTK_OBJECT(button), "activate", | |
2949 GTK_SIGNAL_FUNC(oscar_info), who); | |
2950 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
2951 gtk_menu_append(GTK_MENU(menu), button); | |
2952 gtk_widget_show(button); | |
2953 | |
2954 button = gtk_menu_item_new_with_label(_("Get Away Msg")); | |
2955 gtk_signal_connect(GTK_OBJECT(button), "activate", | |
2956 GTK_SIGNAL_FUNC(oscar_away_msg), who); | |
2957 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
2958 gtk_menu_append(GTK_MENU(menu), button); | |
2959 gtk_widget_show(button); | |
2960 | |
2961 if (strcmp(n, normalize(who))) { | |
2962 button = gtk_menu_item_new_with_label(_("Direct IM")); | |
2963 gtk_signal_connect(GTK_OBJECT(button), "activate", | |
2964 GTK_SIGNAL_FUNC(oscar_ask_direct_im), who); | |
2965 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
2966 gtk_menu_append(GTK_MENU(menu), button); | |
2967 gtk_widget_show(button); | |
2968 } | |
2969 g_free(n); | |
2970 } | |
2971 | |
2972 | |
2973 /* weeee */ | |
2974 static void oscar_print_option(GtkEntry *entry, struct aim_user *user) | |
2975 { | |
2976 int entrynum; | |
2977 | |
2978 entrynum = (int)gtk_object_get_user_data(GTK_OBJECT(entry)); | |
2979 | |
2980 if (entrynum == USEROPT_AUTH) { | |
2981 g_snprintf(user->proto_opt[USEROPT_AUTH], | |
2982 sizeof(user->proto_opt[USEROPT_AUTH]), "%s", gtk_entry_get_text(entry)); | |
2983 } else if (entrynum == USEROPT_AUTHPORT) { | |
2984 g_snprintf(user->proto_opt[USEROPT_AUTHPORT], | |
2985 sizeof(user->proto_opt[USEROPT_AUTHPORT]), "%s", gtk_entry_get_text(entry)); | |
2986 } | |
2987 } | |
2988 | |
2989 static void oscar_user_opts(GtkWidget *book, struct aim_user *user) | |
2990 { | |
2991 /* so here, we create the new notebook page */ | |
2992 GtkWidget *vbox; | |
2993 GtkWidget *hbox; | |
2994 GtkWidget *label; | |
2995 GtkWidget *entry; | |
2996 | |
2997 vbox = gtk_vbox_new(FALSE, 5); | |
2998 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); | |
2999 gtk_notebook_append_page(GTK_NOTEBOOK(book), vbox, gtk_label_new("Oscar Options")); | |
3000 gtk_widget_show(vbox); | |
3001 | |
3002 hbox = gtk_hbox_new(FALSE, 5); | |
3003 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
3004 gtk_widget_show(hbox); | |
3005 | |
3006 label = gtk_label_new("Auth Host:"); | |
3007 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
3008 gtk_widget_show(label); | |
3009 | |
3010 entry = gtk_entry_new(); | |
3011 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
3012 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTH); | |
3013 gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(oscar_print_option), user); | |
3014 if (user->proto_opt[USEROPT_AUTH][0]) { | |
3015 debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTH]); | |
3016 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTH]); | |
3017 } else | |
3018 gtk_entry_set_text(GTK_ENTRY(entry), "login.oscar.aol.com"); | |
3019 gtk_widget_show(entry); | |
3020 | |
3021 hbox = gtk_hbox_new(FALSE, 0); | |
3022 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
3023 gtk_widget_show(hbox); | |
3024 | |
3025 label = gtk_label_new("Auth Port:"); | |
3026 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
3027 gtk_widget_show(label); | |
3028 | |
3029 entry = gtk_entry_new(); | |
3030 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
3031 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTHPORT); | |
3032 gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(oscar_print_option), user); | |
3033 if (user->proto_opt[USEROPT_AUTHPORT][0]) { | |
3034 debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTHPORT]); | |
3035 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHPORT]); | |
3036 } else | |
3037 gtk_entry_set_text(GTK_ENTRY(entry), "5190"); | |
3038 | |
3039 gtk_widget_show(entry); | |
3040 } | |
3041 | |
3042 static void oscar_set_permit_deny(struct gaim_connection *gc) { | |
3043 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
3044 GSList *list; | |
3045 char buf[MAXMSGLEN]; | |
3046 int at; | |
3047 | |
3048 switch(gc->permdeny) { | |
3049 case 1: | |
3050 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, gc->username); | |
3051 break; | |
3052 case 2: | |
3053 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, gc->username); | |
3054 break; | |
3055 case 3: | |
3056 list = gc->permit; | |
3057 at = 0; | |
3058 while (list) { | |
3059 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data); | |
3060 list = list->next; | |
3061 } | |
3062 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf); | |
3063 break; | |
3064 case 4: | |
3065 list = gc->deny; | |
3066 at = 0; | |
3067 while (list) { | |
3068 at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data); | |
3069 list = list->next; | |
3070 } | |
3071 aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, buf); | |
3072 break; | |
3073 default: | |
3074 break; | |
3075 } | |
3076 } | |
3077 | |
3078 static void oscar_add_permit(struct gaim_connection *gc, char *who) { | |
3079 if (gc->permdeny != 3) return; | |
3080 oscar_set_permit_deny(gc); | |
3081 } | |
3082 | |
3083 static void oscar_add_deny(struct gaim_connection *gc, char *who) { | |
3084 if (gc->permdeny != 4) return; | |
3085 oscar_set_permit_deny(gc); | |
3086 } | |
3087 | |
3088 static void oscar_rem_permit(struct gaim_connection *gc, char *who) { | |
3089 if (gc->permdeny != 3) return; | |
3090 oscar_set_permit_deny(gc); | |
3091 } | |
3092 | |
3093 static void oscar_rem_deny(struct gaim_connection *gc, char *who) { | |
3094 if (gc->permdeny != 4) return; | |
3095 oscar_set_permit_deny(gc); | |
3096 } | |
3097 | |
3098 static void oscar_draw_new_user(GtkWidget *box) | |
3099 { | |
3100 GtkWidget *label; | |
3101 | |
3102 label = gtk_label_new(_("Unfortunately, currently Oscar only allows new user registration by " | |
3103 "going to http://aim.aol.com/aimnew/Aim/register.adp?promo=106723&pageset=Aim&client=no" | |
3104 ". Clicking the Register button will open the URL for you.")); | |
3105 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
3106 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5); | |
3107 gtk_widget_show(label); | |
3108 } | |
3109 | |
3110 static void oscar_do_new_user() | |
3111 { | |
3112 open_url(NULL, "http://aim.aol.com/aimnew/Aim/register.adp?promo=106723&pageset=Aim&client=no"); | |
3113 } | |
3114 | |
3115 static GList *oscar_away_states() | |
3116 { | |
3117 return g_list_append(NULL, GAIM_AWAY_CUSTOM); | |
3118 } | |
3119 | |
3120 static void oscar_do_action(struct gaim_connection *gc, char *act) | |
3121 { | |
3122 struct oscar_data *od = gc->proto_data; | |
3123 struct aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH); | |
3124 | |
3125 if (!strcmp(act, "Set User Info")) { | |
3126 show_set_info(gc); | |
3127 } else if (!strcmp(act, "Change Password")) { | |
3128 show_change_passwd(gc); | |
3129 } else if (!strcmp(act, "Confirm Account")) { | |
3130 if (!conn) { | |
3131 od->conf = TRUE; | |
3132 aim_bos_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH); | |
3133 } else | |
3134 aim_auth_reqconfirm(od->sess, conn); | |
3135 } else if (!strcmp(act, "Change Email")) { | |
3136 } else if (!strcmp(act, "Display Current Registered Address")) { | |
3137 if (!conn) { | |
3138 od->reqemail = TRUE; | |
3139 aim_bos_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH); | |
3140 } else | |
3141 aim_auth_getinfo(od->sess, conn, 0x11); | |
3142 } else if (!strcmp(act, "Search for Buddy by Email")) { | |
3143 show_find_email(gc); | |
3144 } | |
3145 } | |
3146 | |
3147 static GList *oscar_actions() | |
3148 { | |
3149 GList *m = NULL; | |
3150 | |
3151 m = g_list_append(m, "Set User Info"); | |
3152 m = g_list_append(m, NULL); | |
3153 m = g_list_append(m, "Change Password"); | |
3154 m = g_list_append(m, "Confirm Account"); | |
3155 /* | |
3156 m = g_list_append(m, "Change Email"); | |
3157 */ | |
3158 m = g_list_append(m, "Display Current Registered Address"); | |
3159 m = g_list_append(m, NULL); | |
3160 m = g_list_append(m, "Search for Buddy by Email"); | |
3161 | |
3162 return m; | |
3163 } | |
3164 | |
3165 static void oscar_change_passwd(struct gaim_connection *gc, char *old, char *new) | |
3166 { | |
3167 struct oscar_data *od = gc->proto_data; | |
3168 if (!aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH)) { | |
3169 od->chpass = TRUE; | |
3170 od->oldp = g_strdup(old); | |
3171 od->newp = g_strdup(new); | |
3172 aim_bos_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH); | |
3173 } else { | |
3174 aim_auth_changepasswd(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH), | |
3175 new, old); | |
3176 } | |
3177 } | |
3178 | |
3179 static void oscar_insert_convo(struct gaim_connection *gc, struct conversation *c) | |
3180 { | |
3181 #if USE_PIXBUF | |
3182 struct oscar_data *od = gc->proto_data; | |
3183 GSList *h = od->hasicons; | |
3184 struct icon_req *ir = NULL; | |
3185 char *who = normalize(c->name); | |
3186 | |
3187 GdkPixbufLoader *load; | |
3188 GList *frames; | |
3189 GdkPixbuf *buf; | |
2127
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3190 GdkPixbuf *scale; |
2086 | 3191 GdkPixmap *pm; |
3192 GdkBitmap *bm; | |
3193 | |
3194 while (h) { | |
3195 ir = h->data; | |
3196 if (!strcmp(who, ir->user)) | |
3197 break; | |
3198 h = h->next; | |
3199 } | |
3200 if (!h || !ir->data) | |
3201 return; | |
3202 | |
3203 ir->cnv = c; | |
3204 | |
3205 load = gdk_pixbuf_loader_new(); | |
3206 gdk_pixbuf_loader_write(load, ir->data, ir->length); | |
3207 ir->anim = gdk_pixbuf_loader_get_animation(load); | |
3208 | |
3209 if (ir->anim) { | |
3210 frames = gdk_pixbuf_animation_get_frames(ir->anim); | |
3211 buf = gdk_pixbuf_frame_get_pixbuf(frames->data); | |
2127
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3212 scale = gdk_pixbuf_scale_simple(buf, |
2141
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
3213 MAX(gdk_pixbuf_get_width(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
3214 gdk_pixbuf_animation_get_width(ir->anim), 1), |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
3215 MAX(gdk_pixbuf_get_height(buf) * SCALE / |
1fc962350561
[gaim-migrate @ 2151]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
3216 gdk_pixbuf_animation_get_height(ir->anim), 1), |
2127
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3217 GDK_INTERP_NEAREST); |
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3218 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); |
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3219 gdk_pixbuf_unref(scale); |
2086 | 3220 |
3221 if (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1) { | |
3222 int delay = MAX(gdk_pixbuf_frame_get_delay_time(frames->data), 13); | |
3223 ir->curframe = 1; | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2127
diff
changeset
|
3224 ir->timer = g_timeout_add(delay * 10, redraw_anim, ir); |
2086 | 3225 } |
3226 } else { | |
3227 ir->unanim = gdk_pixbuf_loader_get_pixbuf(load); | |
3228 if (!ir->unanim) { | |
3229 gdk_pixbuf_loader_close(load); | |
3230 return; | |
3231 } | |
2127
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3232 scale = gdk_pixbuf_scale_simple(ir->unanim, SCALE, SCALE, |
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3233 GDK_INTERP_NEAREST); |
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3234 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 0); |
c305a43d60c7
[gaim-migrate @ 2137]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2126
diff
changeset
|
3235 gdk_pixbuf_unref(scale); |
2086 | 3236 } |
3237 | |
3238 ir->pix = gtk_pixmap_new(pm, bm); | |
3239 gtk_box_pack_start(GTK_BOX(c->bbox), ir->pix, FALSE, FALSE, 5); | |
3240 if (ir->anim && (gdk_pixbuf_animation_get_num_frames(ir->anim) > 1)) | |
3241 gtk_widget_set_usize(ir->pix, gdk_pixbuf_animation_get_width(ir->anim), | |
3242 gdk_pixbuf_animation_get_height(ir->anim)); | |
3243 gtk_widget_show(ir->pix); | |
3244 gdk_pixmap_unref(pm); | |
3245 if (bm) | |
3246 gdk_bitmap_unref(bm); | |
3247 | |
3248 gdk_pixbuf_loader_close(load); | |
3249 #endif | |
3250 } | |
3251 | |
3252 static void oscar_remove_convo(struct gaim_connection *gc, struct conversation *c) | |
3253 { | |
3254 #if USE_PIXBUF | |
3255 struct oscar_data *od = gc->proto_data; | |
3256 GSList *h = od->hasicons; | |
3257 struct icon_req *ir = NULL; | |
3258 char *who = normalize(c->name); | |
3259 | |
3260 while (h) { | |
3261 ir = h->data; | |
3262 if (!strcmp(who, ir->user)) | |
3263 break; | |
3264 h = h->next; | |
3265 } | |
3266 if (!h || !ir->data) | |
3267 return; | |
3268 | |
3269 if (ir->cnv && ir->pix) { | |
3270 gtk_container_remove(GTK_CONTAINER(ir->cnv->bbox), ir->pix); | |
3271 ir->pix = NULL; | |
3272 ir->cnv = NULL; | |
3273 } | |
3274 | |
3275 if (ir->anim) { | |
3276 gdk_pixbuf_animation_unref(ir->anim); | |
3277 ir->anim = NULL; | |
3278 } else if (ir->unanim) { | |
3279 gdk_pixbuf_unref(ir->unanim); | |
3280 ir->unanim = NULL; | |
3281 } | |
3282 | |
3283 ir->curframe = 0; | |
3284 | |
3285 if (ir->timer) | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2127
diff
changeset
|
3286 g_source_remove(ir->timer); |
2086 | 3287 ir->timer = 0; |
3288 #endif | |
3289 } | |
3290 | |
3291 static struct prpl *my_protocol = NULL; | |
3292 | |
3293 void oscar_init(struct prpl *ret) { | |
3294 ret->protocol = PROTO_OSCAR; | |
3295 ret->options = OPT_PROTO_HTML | OPT_PROTO_CORRECT_TIME; | |
3296 ret->name = oscar_name; | |
3297 ret->list_icon = oscar_list_icon; | |
3298 ret->away_states = oscar_away_states; | |
3299 ret->actions = oscar_actions; | |
3300 ret->do_action = oscar_do_action; | |
3301 ret->buddy_menu = oscar_buddy_menu; | |
3302 ret->user_opts = oscar_user_opts; | |
3303 ret->draw_new_user = oscar_draw_new_user; | |
3304 ret->do_new_user = oscar_do_new_user; | |
3305 ret->insert_convo = oscar_insert_convo; | |
3306 ret->remove_convo = oscar_remove_convo; | |
3307 ret->login = oscar_login; | |
3308 ret->close = oscar_close; | |
3309 ret->send_im = oscar_send_im; | |
3310 ret->set_info = oscar_set_info; | |
3311 ret->get_info = oscar_get_info; | |
3312 ret->set_away = oscar_set_away; | |
3313 ret->get_away_msg = oscar_get_away_msg; | |
3314 ret->set_dir = oscar_set_dir; | |
3315 ret->get_dir = NULL; /* Oscar really doesn't have this */ | |
3316 ret->dir_search = oscar_dir_search; | |
3317 ret->set_idle = oscar_set_idle; | |
3318 ret->change_passwd = oscar_change_passwd; | |
3319 ret->add_buddy = oscar_add_buddy; | |
3320 ret->add_buddies = oscar_add_buddies; | |
3321 ret->remove_buddy = oscar_remove_buddy; | |
3322 ret->add_permit = oscar_add_permit; | |
3323 ret->add_deny = oscar_add_deny; | |
3324 ret->rem_permit = oscar_rem_permit; | |
3325 ret->rem_deny = oscar_rem_deny; | |
3326 ret->set_permit_deny = oscar_set_permit_deny; | |
3327 ret->warn = oscar_warn; | |
3328 ret->accept_chat = NULL; /* oscar doesn't have accept, it just joins */ | |
3329 ret->join_chat = oscar_join_chat; | |
3330 ret->draw_join_chat = oscar_draw_join_chat; | |
3331 ret->chat_invite = oscar_chat_invite; | |
3332 ret->chat_leave = oscar_chat_leave; | |
3333 ret->chat_whisper = NULL; | |
3334 ret->chat_send = oscar_chat_send; | |
3335 ret->keepalive = oscar_keepalive; | |
3336 | |
3337 my_protocol = ret; | |
3338 } | |
3339 | |
3340 #ifndef STATIC | |
3341 | |
3342 char *gaim_plugin_init(GModule *handle) | |
3343 { | |
3344 load_protocol(oscar_init, sizeof(struct prpl)); | |
3345 return NULL; | |
3346 } | |
3347 | |
3348 void gaim_plugin_remove() | |
3349 { | |
3350 struct prpl *p = find_prpl(PROTO_OSCAR); | |
3351 if (p == my_protocol) | |
3352 unload_protocol(p); | |
3353 } | |
3354 | |
3355 char *name() | |
3356 { | |
3357 return "Oscar"; | |
3358 } | |
3359 | |
3360 char *description() | |
3361 { | |
3362 return "Allows gaim to use the Oscar protocol."; | |
3363 } | |
3364 | |
3365 #endif |