comparison libpurple/protocols/msn/session.c @ 15374:5fe8042783c1

Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author Sean Egan <seanegan@gmail.com>
date Sat, 20 Jan 2007 02:32:10 +0000
parents
children 32c366eeeb99
comparison
equal deleted inserted replaced
15373:f79e0f4df793 15374:5fe8042783c1
1 /**
2 * @file session.c MSN session functions
3 *
4 * gaim
5 *
6 * Gaim is the legal property of its developers, whose names are too numerous
7 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * source distribution.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 #include "msn.h"
25 #include "session.h"
26 #include "notification.h"
27
28 #include "dialog.h"
29
30 MsnSession *
31 msn_session_new(GaimAccount *account)
32 {
33 MsnSession *session;
34
35 g_return_val_if_fail(account != NULL, NULL);
36
37 session = g_new0(MsnSession, 1);
38
39 session->account = account;
40 session->notification = msn_notification_new(session);
41 session->userlist = msn_userlist_new(session);
42
43 session->user = msn_user_new(session->userlist,
44 gaim_account_get_username(account), NULL);
45
46 session->protocol_ver = 9;
47 session->conv_seq = 1;
48
49 return session;
50 }
51
52 void
53 msn_session_destroy(MsnSession *session)
54 {
55 g_return_if_fail(session != NULL);
56
57 session->destroying = TRUE;
58
59 if (session->connected)
60 msn_session_disconnect(session);
61
62 if (session->notification != NULL)
63 msn_notification_destroy(session->notification);
64
65 while (session->switches != NULL)
66 msn_switchboard_destroy(session->switches->data);
67
68 while (session->slplinks != NULL)
69 msn_slplink_destroy(session->slplinks->data);
70
71 msn_userlist_destroy(session->userlist);
72
73 g_free(session->passport_info.kv);
74 g_free(session->passport_info.sid);
75 g_free(session->passport_info.mspauth);
76 g_free(session->passport_info.client_ip);
77
78 if (session->passport_info.file != NULL)
79 {
80 g_unlink(session->passport_info.file);
81 g_free(session->passport_info.file);
82 }
83
84 if (session->sync != NULL)
85 msn_sync_destroy(session->sync);
86
87 if (session->nexus != NULL)
88 msn_nexus_destroy(session->nexus);
89
90 if (session->user != NULL)
91 msn_user_destroy(session->user);
92
93 g_free(session);
94 }
95
96 gboolean
97 msn_session_connect(MsnSession *session, const char *host, int port,
98 gboolean http_method)
99 {
100 g_return_val_if_fail(session != NULL, FALSE);
101 g_return_val_if_fail(!session->connected, TRUE);
102
103 session->connected = TRUE;
104 session->http_method = http_method;
105
106 if (session->notification == NULL)
107 {
108 gaim_debug_error("msn", "This shouldn't happen\n");
109 g_return_val_if_reached(FALSE);
110 }
111
112 if (msn_notification_connect(session->notification, host, port))
113 {
114 return TRUE;
115 }
116
117 return FALSE;
118 }
119
120 void
121 msn_session_disconnect(MsnSession *session)
122 {
123 g_return_if_fail(session != NULL);
124 g_return_if_fail(session->connected);
125
126 session->connected = FALSE;
127
128 while (session->switches != NULL)
129 msn_switchboard_close(session->switches->data);
130
131 if (session->notification != NULL)
132 msn_notification_close(session->notification);
133 }
134
135 /* TODO: This must go away when conversation is redesigned */
136 MsnSwitchBoard *
137 msn_session_find_swboard(MsnSession *session, const char *username)
138 {
139 GList *l;
140
141 g_return_val_if_fail(session != NULL, NULL);
142 g_return_val_if_fail(username != NULL, NULL);
143
144 for (l = session->switches; l != NULL; l = l->next)
145 {
146 MsnSwitchBoard *swboard;
147
148 swboard = l->data;
149
150 if ((swboard->im_user != NULL) && !strcmp(username, swboard->im_user))
151 return swboard;
152 }
153
154 return NULL;
155 }
156
157 MsnSwitchBoard *
158 msn_session_find_swboard_with_conv(MsnSession *session, GaimConversation *conv)
159 {
160 GList *l;
161
162 g_return_val_if_fail(session != NULL, NULL);
163 g_return_val_if_fail(conv != NULL, NULL);
164
165 for (l = session->switches; l != NULL; l = l->next)
166 {
167 MsnSwitchBoard *swboard;
168
169 swboard = l->data;
170
171 if (swboard->conv == conv)
172 return swboard;
173 }
174
175 return NULL;
176 }
177
178 MsnSwitchBoard *
179 msn_session_find_swboard_with_id(const MsnSession *session, int chat_id)
180 {
181 GList *l;
182
183 g_return_val_if_fail(session != NULL, NULL);
184 g_return_val_if_fail(chat_id >= 0, NULL);
185
186 for (l = session->switches; l != NULL; l = l->next)
187 {
188 MsnSwitchBoard *swboard;
189
190 swboard = l->data;
191
192 if (swboard->chat_id == chat_id)
193 return swboard;
194 }
195
196 return NULL;
197 }
198
199 MsnSwitchBoard *
200 msn_session_get_swboard(MsnSession *session, const char *username,
201 MsnSBFlag flag)
202 {
203 MsnSwitchBoard *swboard;
204
205 g_return_val_if_fail(session != NULL, NULL);
206
207 swboard = msn_session_find_swboard(session, username);
208
209 if (swboard == NULL)
210 {
211 swboard = msn_switchboard_new(session);
212 swboard->im_user = g_strdup(username);
213 msn_switchboard_request(swboard);
214 msn_switchboard_request_add_user(swboard, username);
215 }
216
217 swboard->flag |= flag;
218
219 return swboard;
220 }
221
222 static void
223 msn_session_sync_users(MsnSession *session)
224 {
225 GaimBlistNode *gnode, *cnode, *bnode;
226 GaimConnection *gc = gaim_account_get_connection(session->account);
227
228 g_return_if_fail(gc != NULL);
229
230 /* The core used to use msn_add_buddy to add all buddies before
231 * being logged in. This no longer happens, so we manually iterate
232 * over the whole buddy list to identify sync issues. */
233
234 for (gnode = gaim_blist_get_root(); gnode; gnode = gnode->next) {
235 GaimGroup *group = (GaimGroup *)gnode;
236 const char *group_name = group->name;
237 if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
238 continue;
239 for(cnode = gnode->child; cnode; cnode = cnode->next) {
240 if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
241 continue;
242 for(bnode = cnode->child; bnode; bnode = bnode->next) {
243 GaimBuddy *b;
244 if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
245 continue;
246 b = (GaimBuddy *)bnode;
247 if(gaim_buddy_get_account(b) == gaim_connection_get_account(gc)) {
248 MsnUser *remote_user;
249 gboolean found = FALSE;
250
251 remote_user = msn_userlist_find_user(session->userlist, gaim_buddy_get_name(b));
252
253 if ((remote_user != NULL) && (remote_user->list_op & MSN_LIST_FL_OP))
254 {
255 int group_id;
256 GList *l;
257
258 group_id = msn_userlist_find_group_id(remote_user->userlist,
259 group_name);
260
261 for (l = remote_user->group_ids; l != NULL; l = l->next)
262 {
263 if (group_id == GPOINTER_TO_INT(l->data))
264 {
265 found = TRUE;
266 break;
267 }
268 }
269
270 }
271
272 if (!found)
273 {
274 /* The user was not on the server list or not in that group
275 * on the server list */
276 msn_show_sync_issue(session, gaim_buddy_get_name(b), group_name);
277 }
278 }
279 }
280 }
281 }
282 }
283
284 void
285 msn_session_set_error(MsnSession *session, MsnErrorType error,
286 const char *info)
287 {
288 GaimConnection *gc;
289 char *msg;
290
291 gc = gaim_account_get_connection(session->account);
292
293 switch (error)
294 {
295 case MSN_ERROR_SERVCONN:
296 msg = g_strdup(info);
297 break;
298 case MSN_ERROR_UNSUPPORTED_PROTOCOL:
299 msg = g_strdup(_("Our protocol is not supported by the "
300 "server."));
301 break;
302 case MSN_ERROR_HTTP_MALFORMED:
303 msg = g_strdup(_("Error parsing HTTP."));
304 break;
305 case MSN_ERROR_SIGN_OTHER:
306 gc->wants_to_die = TRUE;
307 msg = g_strdup(_("You have signed on from another location."));
308 break;
309 case MSN_ERROR_SERV_UNAVAILABLE:
310 msg = g_strdup(_("The MSN servers are temporarily "
311 "unavailable. Please wait and try "
312 "again."));
313 break;
314 case MSN_ERROR_SERV_DOWN:
315 msg = g_strdup(_("The MSN servers are going down "
316 "temporarily."));
317 break;
318 case MSN_ERROR_AUTH:
319 msg = g_strdup_printf(_("Unable to authenticate: %s"),
320 (info == NULL ) ?
321 _("Unknown error") : info);
322 break;
323 case MSN_ERROR_BAD_BLIST:
324 msg = g_strdup(_("Your MSN buddy list is temporarily "
325 "unavailable. Please wait and try "
326 "again."));
327 break;
328 default:
329 msg = g_strdup(_("Unknown error."));
330 break;
331 }
332
333 msn_session_disconnect(session);
334
335 gaim_connection_error(gc, msg);
336
337 g_free(msg);
338 }
339
340 static const char *
341 get_login_step_text(MsnSession *session)
342 {
343 const char *steps_text[] = {
344 _("Connecting"),
345 _("Handshaking"),
346 _("Transferring"),
347 _("Handshaking"),
348 _("Starting authentication"),
349 _("Getting cookie"),
350 _("Authenticating"),
351 _("Sending cookie"),
352 _("Retrieving buddy list")
353 };
354
355 return steps_text[session->login_step];
356 }
357
358 void
359 msn_session_set_login_step(MsnSession *session, MsnLoginStep step)
360 {
361 GaimConnection *gc;
362
363 /* Prevent the connection progress going backwards, eg. if we get
364 * transferred several times during login */
365 if (session->login_step > step)
366 return;
367
368 /* If we're already logged in, we're probably here because of a
369 * mid-session XFR from the notification server, so we don't want to
370 * popup the connection progress dialog */
371 if (session->logged_in)
372 return;
373
374 gc = session->account->gc;
375
376 session->login_step = step;
377
378 gaim_connection_update_progress(gc, get_login_step_text(session), step,
379 MSN_LOGIN_STEPS);
380 }
381
382 void
383 msn_session_finish_login(MsnSession *session)
384 {
385 GaimAccount *account;
386 GaimConnection *gc;
387 char *icon;
388
389 if (session->logged_in)
390 return;
391
392 account = session->account;
393 gc = gaim_account_get_connection(account);
394
395 icon = gaim_buddy_icons_get_full_path(gaim_account_get_buddy_icon(session->account));
396 msn_user_set_buddy_icon(session->user, icon);
397 g_free(icon);
398
399 session->logged_in = TRUE;
400
401 msn_change_status(session);
402
403 gaim_connection_set_state(gc, GAIM_CONNECTED);
404
405 /* Sync users */
406 msn_session_sync_users(session);
407 }