Mercurial > pidgin.yaz
annotate src/protocols/yahoo/yay.c @ 2145:91223be78b70
[gaim-migrate @ 2155]
thanks to Valdis Kletnieks for pointing this out.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Wed, 15 Aug 2001 19:23:03 +0000 |
parents | 56c4382f2909 |
children | 0befa2d2e540 |
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 | |
24 #include "config.h" | |
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 "yay.h" | |
44 #include "proxy.h" | |
45 | |
46 #include "pixmaps/status-away.xpm" | |
47 #include "pixmaps/status-here.xpm" | |
48 #include "pixmaps/status-idle.xpm" | |
49 | |
50 #include "pixmaps/cancel.xpm" | |
51 | |
52 #define USEROPT_MAIL 0 | |
53 | |
54 #define USEROPT_AUTHHOST 1 | |
55 #define USEROPT_AUTHPORT 2 | |
56 #define USEROPT_PAGERHOST 3 | |
57 #define USEROPT_PAGERPORT 4 | |
58 | |
59 struct conn { | |
60 int socket; | |
61 int type; | |
62 int inpa; | |
63 }; | |
64 | |
65 struct connect { | |
66 struct yahoo_session *sess; | |
67 gpointer data; | |
68 }; | |
69 | |
70 struct yahoo_data { | |
71 struct yahoo_session *sess; | |
72 int current_status; | |
73 GHashTable *hash; | |
74 GtkWidget *email_win; | |
75 GtkWidget *email_label; | |
76 char *active_id; | |
77 GList *conns; | |
78 gboolean logged_in; | |
79 GSList *offline; | |
80 }; | |
81 | |
82 static char *yahoo_name() { | |
83 return "Yahoo"; | |
84 } | |
85 | |
86 static int yahoo_status(struct yahoo_session *sess, ...) { | |
87 struct gaim_connection *gc = sess->user_data; | |
88 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
89 time_t tmptime; | |
90 struct buddy *b; | |
91 gboolean online; | |
92 | |
93 va_list ap; | |
94 char *who; | |
95 int status; | |
96 char *msg; | |
97 int in_pager, in_chat, in_game; | |
98 | |
99 va_start(ap, sess); | |
100 who = va_arg(ap, char *); | |
101 status = va_arg(ap, int); | |
102 msg = va_arg(ap, char *); | |
103 in_pager = va_arg(ap, int); | |
104 in_chat = va_arg(ap, int); | |
105 in_game = va_arg(ap, int); | |
106 va_end(ap); | |
107 | |
108 online = in_pager || in_chat || in_game; | |
109 | |
110 b = find_buddy(gc, who); | |
111 if (!b) return 0; | |
112 if (!online) | |
113 serv_got_update(gc, b->name, 0, 0, 0, 0, 0, 0); | |
114 else { | |
115 if (status == YAHOO_STATUS_AVAILABLE) | |
116 serv_got_update(gc, b->name, 1, 0, 0, 0, UC_NORMAL, 0); | |
117 else if (status == YAHOO_STATUS_IDLE) { | |
118 time(&tmptime); | |
119 serv_got_update(gc, b->name, 1, 0, 0, tmptime - 600, | |
120 (status << 5) | UC_NORMAL, 0); | |
121 } else | |
122 serv_got_update(gc, b->name, 1, 0, 0, 0, | |
123 (status << 5) | UC_UNAVAILABLE, 0); | |
124 if (status == YAHOO_STATUS_CUSTOM) { | |
125 gpointer val = g_hash_table_lookup(yd->hash, b->name); | |
126 if (val) | |
127 g_free(val); | |
128 g_hash_table_insert(yd->hash, g_strdup(b->name), g_strdup(msg)); | |
129 } | |
130 } | |
131 | |
132 return 1; | |
133 } | |
134 | |
135 static int yahoo_message(struct yahoo_session *sess, ...) { | |
136 struct gaim_connection *gc = sess->user_data; | |
137 char buf[BUF_LEN * 4]; | |
138 char *tmp, *c, *e; | |
139 time_t tm; | |
140 int at = 0; | |
141 | |
142 va_list ap; | |
143 char *id, *nick, *msg; | |
144 | |
145 va_start(ap, sess); | |
146 id = va_arg(ap, char *); | |
147 nick = va_arg(ap, char *); | |
148 tm = va_arg(ap, time_t); | |
149 msg = va_arg(ap, char *); | |
150 va_end(ap); | |
151 | |
152 if (msg) | |
153 e = tmp = g_strdup(msg); | |
154 else | |
155 return 1; | |
156 | |
157 while ((c = strchr(e, '\033')) != NULL) { | |
158 *c++ = '\0'; | |
159 at += g_snprintf(buf + at, sizeof(buf) - at, "%s", e); | |
160 e = ++c; | |
161 while (*e && (*e++ != 'm')); | |
162 } | |
163 | |
164 if (*e) | |
165 g_snprintf(buf + at, sizeof(buf) - at, "%s", e); | |
166 | |
167 g_free(tmp); | |
168 | |
169 serv_got_im(gc, nick, buf, 0, tm ? tm : time((time_t)NULL)); | |
170 | |
171 return 1; | |
172 } | |
173 | |
174 static int yahoo_bounce(struct yahoo_session *sess, ...) { | |
175 do_error_dialog(_("Your message did not get sent."), _("Gaim - Error")); | |
176 | |
177 return 1; | |
178 } | |
179 | |
180 static int yahoo_buddyadded(struct yahoo_session *sess, ...) { | |
181 va_list ap; | |
182 char *id; | |
183 char *who; | |
184 char *msg; | |
185 char buf[2048]; | |
186 | |
187 va_start(ap, sess); | |
188 id = va_arg(ap, char *); | |
189 who = va_arg(ap, char *); | |
190 msg = va_arg(ap, char *); | |
191 va_end(ap); | |
192 | |
193 g_snprintf(buf, sizeof(buf), _("%s has made %s their buddy%s%s"), who, id, | |
194 msg ? ": " : "", msg ? msg : ""); | |
195 do_error_dialog(buf, _("Gaim - Buddy")); | |
196 | |
197 return 1; | |
198 } | |
199 | |
200 static void des_win(GtkWidget *w, struct yahoo_data *yd) { | |
201 gtk_widget_destroy(yd->email_win); | |
202 if (yd->email_win == w) | |
203 yd->email_win = NULL; | |
204 yd->email_label = NULL; | |
205 } | |
206 | |
207 static int yahoo_newmail(struct yahoo_session *sess, ...) { | |
208 struct gaim_connection *gc = sess->user_data; | |
209 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
210 char buf[2048]; | |
211 | |
212 va_list ap; | |
213 int count; | |
214 | |
215 va_start(ap, sess); | |
216 count = va_arg(ap, int); | |
217 va_end(ap); | |
218 | |
219 if (gc->user->proto_opt[USEROPT_MAIL][0] != '1') | |
220 return 1; | |
221 | |
222 if (count) { | |
223 g_snprintf(buf, sizeof buf, "%s has %d new message%s on Yahoo Mail.", | |
224 gc->username, count, count == 1 ? "" : "s"); | |
225 if (!yd->email_win) { | |
226 GtkWidget *close; | |
227 | |
228 yd->email_win = gtk_dialog_new(); | |
229 gtk_window_set_policy(GTK_WINDOW(yd->email_win), 0, 0, 1); | |
230 gtk_container_set_border_width(GTK_CONTAINER(yd->email_win), 5); | |
231 gtk_window_set_title(GTK_WINDOW(yd->email_win), "New Mail"); | |
232 gtk_signal_connect(GTK_OBJECT(yd->email_win), "destroy", | |
233 GTK_SIGNAL_FUNC(des_win), yd); | |
234 gtk_widget_realize(yd->email_win); | |
235 aol_icon(yd->email_win->window); | |
236 | |
237 yd->email_label = gtk_label_new(buf); | |
238 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(yd->email_win)->vbox), | |
239 yd->email_label, 0, 0, 5); | |
240 gtk_widget_show(yd->email_label); | |
241 | |
242 close = picture_button(yd->email_win, _("Close"), cancel_xpm); | |
243 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(yd->email_win)->action_area), | |
244 close, 0, 0, 5); | |
245 gtk_signal_connect(GTK_OBJECT(close), "clicked", GTK_SIGNAL_FUNC(des_win), yd); | |
246 | |
247 gtk_widget_show(yd->email_win); | |
248 } | |
249 gtk_label_set_text(GTK_LABEL(yd->email_label), buf); | |
250 } else if (yd->email_win) | |
251 gtk_widget_destroy(yd->email_win); | |
252 | |
253 return 1; | |
254 } | |
255 | |
256 static int yahoo_disconn(struct yahoo_session *sess, ...) { | |
257 struct gaim_connection *gc = sess->user_data; | |
258 hide_login_progress(gc, "Disconnected"); | |
259 signoff(gc); | |
260 return 1; | |
261 } | |
262 | |
263 static int yahoo_authconnect(struct yahoo_session *sess, ...) { | |
264 struct gaim_connection *gc = sess->user_data; | |
265 | |
266 set_login_progress(gc, 2, "Connected to Auth"); | |
267 if (yahoo_send_login(sess, gc->username, gc->password) < 1) { | |
268 hide_login_progress(gc, "Authorizer error"); | |
269 signoff(gc); | |
2145
91223be78b70
[gaim-migrate @ 2155]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
270 return 0; |
2086 | 271 } |
272 | |
273 return 1; | |
274 } | |
275 | |
276 static int yahoo_badpassword(struct yahoo_session *sess, ...) { | |
277 struct gaim_connection *gc = sess->user_data; | |
278 hide_login_progress(gc, "Bad Password"); | |
279 signoff(gc); | |
280 return 1; | |
281 } | |
282 | |
283 static int yahoo_logincookie(struct yahoo_session *sess, ...) { | |
284 struct gaim_connection *gc = sess->user_data; | |
285 | |
286 set_login_progress(gc, 3, "Got login cookie"); | |
287 if (yahoo_major_connect(sess, gc->user->proto_opt[USEROPT_PAGERHOST], | |
288 atoi(gc->user->proto_opt[USEROPT_PAGERPORT])) < 1) { | |
289 hide_login_progress(gc, "Login error"); | |
290 signoff(gc); | |
291 } | |
292 | |
293 return 1; | |
294 } | |
295 | |
296 static int yahoo_mainconnect(struct yahoo_session *sess, ...) { | |
297 struct gaim_connection *gc = sess->user_data; | |
298 struct yahoo_data *yd = gc->proto_data; | |
299 GList *grps; | |
300 | |
301 set_login_progress(gc, 4, "Connected to service"); | |
302 if (yahoo_finish_logon(sess, YAHOO_STATUS_AVAILABLE) < 1) { | |
303 hide_login_progress(gc, "Login error"); | |
304 signoff(gc); | |
2145
91223be78b70
[gaim-migrate @ 2155]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
305 return 0; |
2086 | 306 } |
307 | |
308 if (bud_list_cache_exists(gc)) | |
309 do_import(NULL, gc); | |
310 | |
311 grps = yd->sess->groups; | |
312 while (grps) { | |
313 struct yahoo_group *grp = grps->data; | |
314 int i; | |
315 | |
316 for (i = 0; grp->buddies[i]; i++) | |
317 add_buddy(gc, grp->name, grp->buddies[i], NULL); | |
318 | |
319 grps = grps->next; | |
320 } | |
321 | |
322 return 1; | |
323 } | |
324 | |
325 static int yahoo_online(struct yahoo_session *sess, ...) { | |
326 struct gaim_connection *gc = sess->user_data; | |
327 struct yahoo_data *yd = gc->proto_data; | |
328 | |
329 account_online(gc); | |
330 serv_finish_login(gc); | |
331 yd->active_id = g_strdup(gc->username); | |
332 yd->logged_in = TRUE; | |
333 | |
334 return 1; | |
335 } | |
336 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
337 static void yahoo_pending(gpointer data, gint source, GaimInputCondition condition) { |
2086 | 338 struct gaim_connection *gc = (struct gaim_connection *)data; |
339 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
340 | |
341 yahoo_socket_handler(yd->sess, source, condition); | |
342 } | |
343 | |
344 static void yahoo_notify(struct yahoo_session *sess, int socket, int type, int cont) { | |
345 struct gaim_connection *gc = sess->user_data; | |
346 struct yahoo_data *yd = gc->proto_data; | |
347 | |
348 if (cont) { | |
349 struct conn *c = g_new0(struct conn, 1); | |
350 c->socket = socket; | |
351 c->type = type; | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
352 c->inpa = gaim_input_add(socket, type, yahoo_pending, gc); |
2086 | 353 yd->conns = g_list_append(yd->conns, c); |
354 } else { | |
355 GList *c = yd->conns; | |
356 while (c) { | |
357 struct conn *m = c->data; | |
358 if ((m->socket == socket) && (m->type == type)) { | |
359 yd->conns = g_list_remove(yd->conns, m); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
360 gaim_input_remove(m->inpa); |
2086 | 361 g_free(m); |
362 return; | |
363 } | |
364 c = g_list_next(c); | |
365 } | |
366 } | |
367 } | |
368 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
369 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) { |
2086 | 370 struct connect *con = data; |
371 | |
372 debug_printf("got connected (possibly)\n"); | |
373 yahoo_connected(con->sess, con->data, source); | |
374 | |
375 g_free(con); | |
376 } | |
377 | |
378 static int yahoo_connect_to(struct yahoo_session *sess, const char *host, int port, gpointer data) { | |
379 struct connect *con = g_new0(struct connect, 1); | |
380 int fd; | |
381 | |
382 con->sess = sess; | |
383 con->data = data; | |
384 fd = proxy_connect((char *)host, port, yahoo_got_connected, con); | |
385 if (fd < 0) { | |
386 g_free(con); | |
387 return -1; | |
388 } | |
389 | |
390 return fd; | |
391 } | |
392 | |
393 static void yahoo_debug(struct yahoo_session *sess, int level, const char *string) { | |
394 debug_printf("Level %d: %s\n", level, string); | |
395 } | |
396 | |
397 static void yahoo_login(struct aim_user *user) { | |
398 struct gaim_connection *gc = new_gaim_conn(user); | |
399 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); | |
400 | |
401 yd->sess = yahoo_new(); | |
402 yd->sess->user_data = gc; | |
403 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
404 yd->hash = g_hash_table_new(g_str_hash, g_str_equal); | |
405 | |
406 set_login_progress(gc, 1, "Connecting"); | |
407 | |
408 if (!yahoo_connect(yd->sess, user->proto_opt[USEROPT_AUTHHOST], | |
409 atoi(user->proto_opt[USEROPT_AUTHPORT]))) { | |
410 hide_login_progress(gc, "Connection problem"); | |
411 signoff(gc); | |
412 return; | |
413 } | |
414 | |
415 yahoo_add_handler(yd->sess, YAHOO_HANDLE_DISCONNECT, yahoo_disconn); | |
416 yahoo_add_handler(yd->sess, YAHOO_HANDLE_AUTHCONNECT, yahoo_authconnect); | |
417 yahoo_add_handler(yd->sess, YAHOO_HANDLE_BADPASSWORD, yahoo_badpassword); | |
418 yahoo_add_handler(yd->sess, YAHOO_HANDLE_LOGINCOOKIE, yahoo_logincookie); | |
419 yahoo_add_handler(yd->sess, YAHOO_HANDLE_MAINCONNECT, yahoo_mainconnect); | |
420 yahoo_add_handler(yd->sess, YAHOO_HANDLE_ONLINE, yahoo_online); | |
421 yahoo_add_handler(yd->sess, YAHOO_HANDLE_NEWMAIL, yahoo_newmail); | |
422 yahoo_add_handler(yd->sess, YAHOO_HANDLE_MESSAGE, yahoo_message); | |
423 yahoo_add_handler(yd->sess, YAHOO_HANDLE_BOUNCE, yahoo_bounce); | |
424 yahoo_add_handler(yd->sess, YAHOO_HANDLE_STATUS, yahoo_status); | |
425 yahoo_add_handler(yd->sess, YAHOO_HANDLE_BUDDYADDED, yahoo_buddyadded); | |
426 } | |
427 | |
428 static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) { | |
429 g_free(key); | |
430 g_free(val); | |
431 return TRUE; | |
432 } | |
433 | |
434 static void yahoo_close(struct gaim_connection *gc) { | |
435 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
436 while (yd->offline) { | |
437 g_free(yd->offline->data); | |
438 yd->offline = g_slist_remove(yd->offline, yd->offline->data); | |
439 } | |
440 g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); | |
441 g_hash_table_destroy(yd->hash); | |
442 yahoo_disconnect(yd->sess); | |
443 yahoo_delete(yd->sess); | |
444 g_free(yd); | |
445 } | |
446 | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
447 static int yahoo_send_im(struct gaim_connection *gc, char *who, char *message, int away) { |
2086 | 448 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; |
449 GSList *l = yd->offline; | |
450 | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
451 if (away || !strlen(message)) return 0; |
2086 | 452 |
453 while (l) { | |
454 if (!strcmp(who, l->data)) | |
455 break; | |
456 l = l->next; | |
457 } | |
458 | |
459 if (l) | |
460 yahoo_send_message(yd->sess, yd->active_id, who, message); | |
461 else | |
462 yahoo_send_message_offline(yd->sess, yd->active_id, who, message); | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
463 return 0; |
2086 | 464 } |
465 | |
466 static void yahoo_set_away(struct gaim_connection *gc, char *state, char *msg) { | |
467 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
468 | |
469 gc->away = NULL; | |
470 | |
471 if (msg) { | |
472 yahoo_away(yd->sess, YAHOO_STATUS_CUSTOM, msg); | |
473 yd->current_status = YAHOO_STATUS_CUSTOM; | |
474 gc->away = ""; | |
475 } else if (state) { | |
476 gc->away = ""; | |
477 if (!strcmp(state, "Available")) { | |
478 yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, msg); | |
479 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
480 } else if (!strcmp(state, "Be Right Back")) { | |
481 yahoo_away(yd->sess, YAHOO_STATUS_BRB, msg); | |
482 yd->current_status = YAHOO_STATUS_BRB; | |
483 } else if (!strcmp(state, "Busy")) { | |
484 yahoo_away(yd->sess, YAHOO_STATUS_BUSY, msg); | |
485 yd->current_status = YAHOO_STATUS_BUSY; | |
486 } else if (!strcmp(state, "Not At Home")) { | |
487 yahoo_away(yd->sess, YAHOO_STATUS_NOTATHOME, msg); | |
488 yd->current_status = YAHOO_STATUS_NOTATHOME; | |
489 } else if (!strcmp(state, "Not At Desk")) { | |
490 yahoo_away(yd->sess, YAHOO_STATUS_NOTATDESK, msg); | |
491 yd->current_status = YAHOO_STATUS_NOTATDESK; | |
492 } else if (!strcmp(state, "Not In Office")) { | |
493 yahoo_away(yd->sess, YAHOO_STATUS_NOTINOFFICE, msg); | |
494 yd->current_status = YAHOO_STATUS_NOTINOFFICE; | |
495 } else if (!strcmp(state, "On Phone")) { | |
496 yahoo_away(yd->sess, YAHOO_STATUS_ONPHONE, msg); | |
497 yd->current_status = YAHOO_STATUS_ONPHONE; | |
498 } else if (!strcmp(state, "On Vacation")) { | |
499 yahoo_away(yd->sess, YAHOO_STATUS_ONVACATION, msg); | |
500 yd->current_status = YAHOO_STATUS_ONVACATION; | |
501 } else if (!strcmp(state, "Out To Lunch")) { | |
502 yahoo_away(yd->sess, YAHOO_STATUS_OUTTOLUNCH, msg); | |
503 yd->current_status = YAHOO_STATUS_OUTTOLUNCH; | |
504 } else if (!strcmp(state, "Stepped Out")) { | |
505 yahoo_away(yd->sess, YAHOO_STATUS_STEPPEDOUT, msg); | |
506 yd->current_status = YAHOO_STATUS_STEPPEDOUT; | |
507 } else if (!strcmp(state, "Invisible")) { | |
508 yahoo_away(yd->sess, YAHOO_STATUS_INVISIBLE, msg); | |
509 yd->current_status = YAHOO_STATUS_INVISIBLE; | |
510 } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { | |
511 if (gc->is_idle) { | |
512 yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); | |
513 yd->current_status = YAHOO_STATUS_IDLE; | |
514 } else { | |
515 yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); | |
516 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
517 } | |
518 gc->away = NULL; | |
519 } | |
520 } else if (gc->is_idle) { | |
521 yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); | |
522 yd->current_status = YAHOO_STATUS_IDLE; | |
523 } else { | |
524 yahoo_away(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); | |
525 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
526 } | |
527 } | |
528 | |
529 static void yahoo_set_idle(struct gaim_connection *gc, int idle) { | |
530 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
531 | |
532 if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { | |
533 yahoo_away(yd->sess, YAHOO_STATUS_IDLE, NULL); | |
534 yd->current_status = YAHOO_STATUS_IDLE; | |
535 } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { | |
536 yahoo_back(yd->sess, YAHOO_STATUS_AVAILABLE, NULL); | |
537 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
538 } | |
539 } | |
540 | |
541 static void yahoo_keepalive(struct gaim_connection *gc) { | |
542 yahoo_ping(((struct yahoo_data *)gc->proto_data)->sess); | |
543 } | |
544 | |
545 static void gyahoo_add_buddy(struct gaim_connection *gc, char *name) { | |
546 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
547 struct yahoo_group *tmpgroup; | |
548 struct group *g = find_group_by_buddy(gc, name); | |
549 char *group = NULL; | |
550 | |
551 if (!yd->logged_in) | |
552 return; | |
553 | |
554 if (g) { | |
555 group = g->name; | |
556 } else if (yd->sess && yd->sess->groups) { | |
557 tmpgroup = yd->sess->groups->data; | |
558 group = tmpgroup->name; | |
559 } else { | |
560 group = "Buddies"; | |
561 } | |
562 | |
563 if (group) | |
564 yahoo_add_buddy(yd->sess, yd->active_id, group, name, ""); | |
565 } | |
566 | |
567 static void yahoo_add_buddies(struct gaim_connection *gc, GList *buddies) { | |
568 while (buddies) { | |
569 gyahoo_add_buddy(gc, buddies->data); | |
570 buddies = buddies->next; | |
571 } | |
572 } | |
573 | |
574 static void gyahoo_remove_buddy(struct gaim_connection *gc, char *name) { | |
575 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
576 struct group *g = find_group_by_buddy(gc, name); | |
577 char *group = NULL; | |
578 | |
579 if (g) { | |
580 group = g->name; | |
581 } else if (yd->sess && yd->sess->groups) { | |
582 GList *x = yd->sess->groups; | |
583 while (x) { | |
584 struct yahoo_group *tmpgroup = x->data; | |
585 char **bds = tmpgroup->buddies; | |
586 while (*bds) { | |
587 if (!strcmp(*bds, name)) | |
588 break; | |
589 bds++; | |
590 } | |
591 if (*bds) { | |
592 group = tmpgroup->name; | |
593 break; | |
594 } | |
595 x = x->next; | |
596 } | |
597 } else { | |
598 group = "Buddies"; | |
599 } | |
600 | |
601 if (group) | |
602 yahoo_remove_buddy(yd->sess, yd->active_id, group, name, ""); | |
603 } | |
604 | |
605 static char **yahoo_list_icon(int uc) { | |
606 if ((uc >> 5) == YAHOO_STATUS_IDLE) | |
607 return status_idle_xpm; | |
608 else if (uc == UC_NORMAL) | |
609 return status_here_xpm; | |
610 return status_away_xpm; | |
611 } | |
612 | |
613 static char *yahoo_get_status_string(enum yahoo_status a) { | |
614 switch (a) { | |
615 case YAHOO_STATUS_BRB: | |
616 return "Be Right Back"; | |
617 case YAHOO_STATUS_BUSY: | |
618 return "Busy"; | |
619 case YAHOO_STATUS_NOTATHOME: | |
620 return "Not At Home"; | |
621 case YAHOO_STATUS_NOTATDESK: | |
622 return "Not At Desk"; | |
623 case YAHOO_STATUS_NOTINOFFICE: | |
624 return "Not In Office"; | |
625 case YAHOO_STATUS_ONPHONE: | |
626 return "On Phone"; | |
627 case YAHOO_STATUS_ONVACATION: | |
628 return "On Vacation"; | |
629 case YAHOO_STATUS_OUTTOLUNCH: | |
630 return "Out To Lunch"; | |
631 case YAHOO_STATUS_STEPPEDOUT: | |
632 return "Stepped Out"; | |
633 default: | |
634 return NULL; | |
635 } | |
636 } | |
637 | |
638 static void yahoo_buddy_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) { | |
639 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
640 GtkWidget *button; | |
641 struct buddy *b = find_buddy(gc, who); /* this should never be null. if it is, | |
642 segfault and get the bug report. */ | |
643 char buf[1024]; | |
644 | |
645 if (b->uc & UC_NORMAL) | |
646 return; | |
647 | |
648 if ((b->uc >> 5) != YAHOO_STATUS_CUSTOM) | |
649 g_snprintf(buf, sizeof buf, "Status: %s", yahoo_get_status_string(b->uc >> 5)); | |
650 else | |
651 g_snprintf(buf, sizeof buf, "Custom Status: %s", | |
652 (char *)g_hash_table_lookup(yd->hash, b->name)); | |
653 button = gtk_menu_item_new_with_label(buf); | |
654 gtk_menu_append(GTK_MENU(menu), button); | |
655 gtk_widget_show(button); | |
656 } | |
657 | |
658 static GList *yahoo_away_states() { | |
659 GList *m = NULL; | |
660 | |
661 m = g_list_append(m, "Available"); | |
662 m = g_list_append(m, "Be Right Back"); | |
663 m = g_list_append(m, "Busy"); | |
664 m = g_list_append(m, "Not At Home"); | |
665 m = g_list_append(m, "Not At Desk"); | |
666 m = g_list_append(m, "Not In Office"); | |
667 m = g_list_append(m, "On Phone"); | |
668 m = g_list_append(m, "On Vacation"); | |
669 m = g_list_append(m, "Out To Lunch"); | |
670 m = g_list_append(m, "Stepped Out"); | |
671 m = g_list_append(m, "Invisible"); | |
672 m = g_list_append(m, GAIM_AWAY_CUSTOM); | |
673 | |
674 return m; | |
675 } | |
676 | |
677 static void yahoo_act_id(gpointer data, char *entry) { | |
678 struct gaim_connection *gc = data; | |
679 struct yahoo_data *yd = gc->proto_data; | |
680 | |
681 yahoo_activate_id(yd->sess, entry); | |
682 if (yd->active_id) | |
683 g_free(yd->active_id); | |
684 yd->active_id = g_strdup(entry); | |
685 } | |
686 | |
687 static void yahoo_do_action(struct gaim_connection *gc, char *act) { | |
688 if (!strcmp(act, "Activate ID")) { | |
689 do_prompt_dialog("Activate which ID:", gc, yahoo_act_id, NULL); | |
690 } | |
691 } | |
692 | |
693 static GList *yahoo_actions() { | |
694 GList *m = NULL; | |
695 | |
696 m = g_list_append(m, "Activate ID"); | |
697 | |
698 return m; | |
699 } | |
700 | |
701 struct mod_usr_opt { | |
702 struct aim_user *user; | |
703 int opt; | |
704 }; | |
705 | |
706 static void mod_opt(GtkWidget *b, struct mod_usr_opt *m) | |
707 { | |
708 if (m->user->proto_opt[m->opt][0] == '1') | |
709 m->user->proto_opt[m->opt][0] = '\0'; | |
710 else | |
711 strcpy(m->user->proto_opt[m->opt],"1"); | |
712 } | |
713 | |
714 static void free_muo(GtkWidget *b, struct mod_usr_opt *m) | |
715 { | |
716 g_free(m); | |
717 } | |
718 | |
719 static GtkWidget *yahoo_protoopt_button(const char *text, struct aim_user *u, int option, GtkWidget *box) | |
720 { | |
721 GtkWidget *button; | |
722 struct mod_usr_opt *muo = g_new0(struct mod_usr_opt, 1); | |
723 button = gtk_check_button_new_with_label(text); | |
724 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), (u->proto_opt[option][0] == '1')); | |
725 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); | |
726 muo->user = u; | |
727 muo->opt = option; | |
728 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(mod_opt), muo); | |
729 gtk_signal_connect(GTK_OBJECT(button), "destroy", GTK_SIGNAL_FUNC(free_muo), muo); | |
730 gtk_widget_show(button); | |
731 return button; | |
732 } | |
733 | |
734 static void yahoo_print_option(GtkEntry *entry, struct aim_user *user) { | |
735 int entrynum; | |
736 | |
737 entrynum = (int) gtk_object_get_user_data(GTK_OBJECT(entry)); | |
738 | |
739 if (entrynum == USEROPT_AUTHHOST) { | |
740 g_snprintf(user->proto_opt[USEROPT_AUTHHOST], | |
741 sizeof(user->proto_opt[USEROPT_AUTHHOST]), | |
742 "%s", gtk_entry_get_text(entry)); | |
743 } else if (entrynum == USEROPT_AUTHPORT) { | |
744 g_snprintf(user->proto_opt[USEROPT_AUTHPORT], | |
745 sizeof(user->proto_opt[USEROPT_AUTHPORT]), | |
746 "%s", gtk_entry_get_text(entry)); | |
747 } else if (entrynum == USEROPT_PAGERHOST) { | |
748 g_snprintf(user->proto_opt[USEROPT_PAGERHOST], | |
749 sizeof(user->proto_opt[USEROPT_PAGERHOST]), | |
750 "%s", gtk_entry_get_text(entry)); | |
751 } else if (entrynum == USEROPT_PAGERPORT) { | |
752 g_snprintf(user->proto_opt[USEROPT_PAGERPORT], | |
753 sizeof(user->proto_opt[USEROPT_PAGERPORT]), | |
754 "%s", gtk_entry_get_text(entry)); | |
755 } | |
756 } | |
757 | |
758 static void yahoo_user_opts(GtkWidget *book, struct aim_user *user) | |
759 { | |
760 GtkWidget *vbox; | |
761 GtkWidget *hbox; | |
762 GtkWidget *label; | |
763 GtkWidget *entry; | |
764 | |
765 vbox = gtk_vbox_new(FALSE, 5); | |
766 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); | |
767 gtk_notebook_append_page(GTK_NOTEBOOK(book), vbox, gtk_label_new("Yahoo Options")); | |
768 gtk_widget_show(vbox); | |
769 | |
770 yahoo_protoopt_button("Notify me of new Yahoo! Mail", user, USEROPT_MAIL, vbox); | |
771 hbox = gtk_hbox_new(FALSE, 5); | |
772 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
773 gtk_widget_show(hbox); | |
774 | |
775 label = gtk_label_new("Yahoo Auth Host:"); | |
776 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
777 gtk_widget_show(label); | |
778 | |
779 entry = gtk_entry_new(); | |
780 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
781 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTHHOST); | |
782 gtk_signal_connect(GTK_OBJECT(entry), "changed", | |
783 GTK_SIGNAL_FUNC(yahoo_print_option), user); | |
784 if (user->proto_opt[USEROPT_AUTHHOST][0]) { | |
785 debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTHHOST]); | |
786 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHHOST]); | |
787 } else { | |
788 gtk_entry_set_text(GTK_ENTRY(entry), YAHOO_AUTH_HOST); | |
789 } | |
790 gtk_widget_show(entry); | |
791 | |
792 hbox = gtk_hbox_new(FALSE, 5); | |
793 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
794 gtk_widget_show(hbox); | |
795 | |
796 label = gtk_label_new("Yahoo Auth Port:"); | |
797 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
798 gtk_widget_show(label); | |
799 | |
800 entry = gtk_entry_new(); | |
801 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
802 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_AUTHPORT); | |
803 gtk_signal_connect(GTK_OBJECT(entry), "changed", | |
804 GTK_SIGNAL_FUNC(yahoo_print_option), user); | |
805 if (user->proto_opt[USEROPT_AUTHPORT][0]) { | |
806 debug_printf("setting text %s\n", user->proto_opt[USEROPT_AUTHPORT]); | |
807 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHPORT]); | |
808 } else { | |
809 g_snprintf(user->proto_opt[USEROPT_AUTHPORT], sizeof(user->proto_opt[USEROPT_AUTHPORT]), | |
810 "%d", YAHOO_AUTH_PORT); | |
811 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_AUTHPORT]); | |
812 } | |
813 gtk_widget_show(entry); | |
814 | |
815 hbox = gtk_hbox_new(FALSE, 5); | |
816 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
817 gtk_widget_show(hbox); | |
818 | |
819 label = gtk_label_new("Yahoo Pager Host:"); | |
820 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
821 gtk_widget_show(label); | |
822 | |
823 entry = gtk_entry_new(); | |
824 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
825 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_PAGERHOST); | |
826 gtk_signal_connect(GTK_OBJECT(entry), "changed", | |
827 GTK_SIGNAL_FUNC(yahoo_print_option), user); | |
828 if (user->proto_opt[USEROPT_PAGERHOST][0]) { | |
829 debug_printf("setting text %s\n", user->proto_opt[USEROPT_PAGERHOST]); | |
830 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_PAGERHOST]); | |
831 } else { | |
832 gtk_entry_set_text(GTK_ENTRY(entry), YAHOO_PAGER_HOST); | |
833 } | |
834 gtk_widget_show(entry); | |
835 | |
836 hbox = gtk_hbox_new(FALSE, 5); | |
837 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
838 gtk_widget_show(hbox); | |
839 | |
840 label = gtk_label_new("Yahoo Pager Port:"); | |
841 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
842 gtk_widget_show(label); | |
843 | |
844 entry = gtk_entry_new(); | |
845 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
846 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_PAGERPORT); | |
847 gtk_signal_connect(GTK_OBJECT(entry), "changed", | |
848 GTK_SIGNAL_FUNC(yahoo_print_option), user); | |
849 if (user->proto_opt[USEROPT_PAGERPORT][0]) { | |
850 debug_printf("setting text %s\n", user->proto_opt[USEROPT_PAGERPORT]); | |
851 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_PAGERPORT]); | |
852 } else { | |
853 g_snprintf(user->proto_opt[USEROPT_PAGERPORT], sizeof(user->proto_opt[USEROPT_PAGERPORT]), | |
854 "%d", YAHOO_PAGER_PORT); | |
855 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_PAGERPORT]); | |
856 } | |
857 gtk_widget_show(entry); | |
858 } | |
859 | |
860 static void toggle_offline(GtkToggleButton *button, struct conversation *c) | |
861 { | |
862 struct gaim_connection *gc = gtk_object_get_user_data(GTK_OBJECT(button)); | |
863 struct yahoo_data *yd = gc->proto_data; | |
864 GSList *l = yd->offline; | |
865 | |
866 while (l) { | |
867 if (!strcmp(c->name, l->data)) | |
868 break; | |
869 l = l->next; | |
870 } | |
871 if (l) { | |
872 g_free(l->data); | |
873 yd->offline = g_slist_remove(yd->offline, l->data); | |
874 } else | |
875 yd->offline = g_slist_append(yd->offline, g_strdup(c->name)); | |
876 } | |
877 | |
878 static void yahoo_insert_convo(struct gaim_connection *gc, struct conversation *c) | |
879 { | |
880 GtkWidget *button; | |
881 struct yahoo_data *yd = gc->proto_data; | |
882 GSList *l = yd->offline; | |
883 struct buddy *b = find_buddy(gc, c->name); | |
884 | |
885 button = gtk_check_button_new_with_label("Send offline message"); | |
886 gtk_box_pack_start(GTK_BOX(c->lbox), button, FALSE, FALSE, 5); | |
887 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(toggle_offline), c); | |
888 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
889 while (l) { | |
890 if (!strcmp(c->name, l->data)) | |
891 break; | |
892 l = l->next; | |
893 } | |
894 if (l || (b && !b->present)) | |
895 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | |
896 gtk_widget_show(button); | |
897 } | |
898 | |
899 static void yahoo_remove_convo(struct gaim_connection *gc, struct conversation *c) | |
900 { | |
901 while (GTK_BOX(c->lbox)->children) | |
902 gtk_container_remove(GTK_CONTAINER(c->lbox), | |
903 ((GtkBoxChild *)GTK_BOX(c->lbox)->children->data)->widget); | |
904 } | |
905 | |
906 static struct prpl *my_protocol = NULL; | |
907 | |
908 void yahoo_init(struct prpl *ret) { | |
909 /* the NULL's aren't required but they're nice to have */ | |
910 ret->protocol = PROTO_YAHOO; | |
911 ret->name = yahoo_name; | |
912 ret->list_icon = yahoo_list_icon; | |
913 ret->away_states = yahoo_away_states; | |
914 ret->actions = yahoo_actions; | |
915 ret->do_action = yahoo_do_action; | |
916 ret->buddy_menu = yahoo_buddy_menu; | |
917 ret->user_opts = yahoo_user_opts; | |
918 ret->insert_convo = yahoo_insert_convo; | |
919 ret->remove_convo = yahoo_remove_convo; | |
920 ret->login = yahoo_login; | |
921 ret->close = yahoo_close; | |
922 ret->send_im = yahoo_send_im; | |
923 ret->set_info = NULL; | |
924 ret->get_info = NULL; | |
925 ret->set_away = yahoo_set_away; | |
926 ret->get_away_msg = NULL; | |
927 ret->set_dir = NULL; | |
928 ret->get_dir = NULL; | |
929 ret->dir_search = NULL; | |
930 ret->set_idle = yahoo_set_idle; | |
931 ret->change_passwd = NULL; | |
932 ret->add_buddy = gyahoo_add_buddy; | |
933 ret->add_buddies = yahoo_add_buddies; | |
934 ret->remove_buddy = gyahoo_remove_buddy; | |
935 ret->add_permit = NULL; | |
936 ret->add_deny = NULL; | |
937 ret->rem_permit = NULL; | |
938 ret->rem_deny = NULL; | |
939 ret->set_permit_deny = NULL; | |
940 ret->warn = NULL; | |
941 ret->accept_chat = NULL; | |
942 ret->join_chat = NULL; | |
943 ret->chat_invite = NULL; | |
944 ret->chat_leave = NULL; | |
945 ret->chat_whisper = NULL; | |
946 ret->chat_send = NULL; | |
947 ret->keepalive = yahoo_keepalive; | |
948 | |
949 my_protocol = ret; | |
950 | |
951 yahoo_socket_notify = yahoo_notify; | |
952 yahoo_print = yahoo_debug; | |
953 yahoo_connector = yahoo_connect_to; | |
954 } | |
955 | |
956 #ifndef STATIC | |
957 | |
958 char *gaim_plugin_init(GModule *handle) | |
959 { | |
960 load_protocol(yahoo_init, sizeof(struct prpl)); | |
961 return NULL; | |
962 } | |
963 | |
964 void gaim_plugin_remove() | |
965 { | |
966 struct prpl *p = find_prpl(PROTO_YAHOO); | |
967 if (p == my_protocol) | |
968 unload_protocol(p); | |
969 } | |
970 | |
971 char *name() | |
972 { | |
973 return "Yahoo"; | |
974 } | |
975 | |
976 char *description() | |
977 { | |
978 return "Allows gaim to use the Yahoo protocol"; | |
979 } | |
980 | |
981 #endif |