comparison libpurple/protocols/msnp9/user.c @ 21312:a07cfce78345

Add MSNP9 back as an alternative alongside the existing MSN prpl. Cowardly old fools like me who prefer the stability of our MSNP9 code over the features of MSNP14 can enable this using the --disable-msnp14 ./configure option. If we want to release from i.p.p and MSN stability is the only blocker, we can trivially flick the default to use MSNP9 in configure.ac
author Stu Tomlinson <stu@nosnilmot.com>
date Sun, 11 Nov 2007 12:57:52 +0000
parents
children af5de2b08fe0
comparison
equal deleted inserted replaced
21311:7d031cec5ba2 21312:a07cfce78345
1 /**
2 * @file user.c User functions
3 *
4 * purple
5 *
6 * Purple 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 */
24 #include "msn.h"
25 #include "user.h"
26 #include "slp.h"
27
28 MsnUser *
29 msn_user_new(MsnUserList *userlist, const char *passport,
30 const char *store_name)
31 {
32 MsnUser *user;
33
34 user = g_new0(MsnUser, 1);
35
36 user->userlist = userlist;
37
38 msn_user_set_passport(user, passport);
39 msn_user_set_store_name(user, store_name);
40
41 /*
42 * XXX This seems to reset the friendly name from what it should be
43 * to the passport when moving users. So, screw it :)
44 */
45 #if 0
46 if (name != NULL)
47 msn_user_set_name(user, name);
48 #endif
49
50 return user;
51 }
52
53 void
54 msn_user_destroy(MsnUser *user)
55 {
56 g_return_if_fail(user != NULL);
57
58 if (user->clientcaps != NULL)
59 g_hash_table_destroy(user->clientcaps);
60
61 if (user->group_ids != NULL)
62 g_list_free(user->group_ids);
63
64 if (user->msnobj != NULL)
65 msn_object_destroy(user->msnobj);
66
67 g_free(user->passport);
68 g_free(user->friendly_name);
69 g_free(user->store_name);
70 g_free(user->phone.home);
71 g_free(user->phone.work);
72 g_free(user->phone.mobile);
73
74 g_free(user);
75 }
76
77 void
78 msn_user_update(MsnUser *user)
79 {
80 PurpleAccount *account;
81
82 account = user->userlist->session->account;
83
84 if (user->status != NULL) {
85 if (!strcmp(user->status, "offline") && user->mobile) {
86 purple_prpl_got_user_status(account, user->passport, "offline", NULL);
87 purple_prpl_got_user_status(account, user->passport, "mobile", NULL);
88 } else {
89 purple_prpl_got_user_status(account, user->passport, user->status, NULL);
90 purple_prpl_got_user_status_deactive(account, user->passport, "mobile");
91 }
92 }
93
94 if (user->idle)
95 purple_prpl_got_user_idle(account, user->passport, TRUE, -1);
96 else
97 purple_prpl_got_user_idle(account, user->passport, FALSE, 0);
98 }
99
100 void
101 msn_user_set_state(MsnUser *user, const char *state)
102 {
103 const char *status;
104
105 if (!g_ascii_strcasecmp(state, "BSY"))
106 status = "busy";
107 else if (!g_ascii_strcasecmp(state, "BRB"))
108 status = "brb";
109 else if (!g_ascii_strcasecmp(state, "AWY"))
110 status = "away";
111 else if (!g_ascii_strcasecmp(state, "PHN"))
112 status = "phone";
113 else if (!g_ascii_strcasecmp(state, "LUN"))
114 status = "lunch";
115 else
116 status = "available";
117
118 if (!g_ascii_strcasecmp(state, "IDL"))
119 user->idle = TRUE;
120 else
121 user->idle = FALSE;
122
123 user->status = status;
124 }
125
126 void
127 msn_user_set_passport(MsnUser *user, const char *passport)
128 {
129 g_return_if_fail(user != NULL);
130
131 g_free(user->passport);
132 user->passport = g_strdup(passport);
133 }
134
135 void
136 msn_user_set_friendly_name(MsnUser *user, const char *name)
137 {
138 g_return_if_fail(user != NULL);
139
140 g_free(user->friendly_name);
141 user->friendly_name = g_strdup(name);
142 }
143
144 void
145 msn_user_set_store_name(MsnUser *user, const char *name)
146 {
147 g_return_if_fail(user != NULL);
148
149 g_free(user->store_name);
150 user->store_name = g_strdup(name);
151 }
152
153 void
154 msn_user_set_buddy_icon(MsnUser *user, PurpleStoredImage *img)
155 {
156 MsnObject *msnobj = msn_user_get_object(user);
157
158 g_return_if_fail(user != NULL);
159
160 if (img == NULL)
161 msn_user_set_object(user, NULL);
162 else
163 {
164 PurpleCipherContext *ctx;
165 char *buf;
166 gconstpointer data = purple_imgstore_get_data(img);
167 size_t size = purple_imgstore_get_size(img);
168 char *base64;
169 unsigned char digest[20];
170
171 if (msnobj == NULL)
172 {
173 msnobj = msn_object_new();
174 msn_object_set_local(msnobj);
175 msn_object_set_type(msnobj, MSN_OBJECT_USERTILE);
176 msn_object_set_location(msnobj, "TFR2C2.tmp");
177 msn_object_set_creator(msnobj, msn_user_get_passport(user));
178
179 msn_user_set_object(user, msnobj);
180 }
181
182 msn_object_set_image(msnobj, img);
183
184 /* Compute the SHA1D field. */
185 memset(digest, 0, sizeof(digest));
186
187 ctx = purple_cipher_context_new_by_name("sha1", NULL);
188 purple_cipher_context_append(ctx, data, size);
189 purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
190
191 base64 = purple_base64_encode(digest, sizeof(digest));
192 msn_object_set_sha1d(msnobj, base64);
193 g_free(base64);
194
195 msn_object_set_size(msnobj, size);
196
197 /* Compute the SHA1C field. */
198 buf = g_strdup_printf(
199 "Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s",
200 msn_object_get_creator(msnobj),
201 msn_object_get_size(msnobj),
202 msn_object_get_type(msnobj),
203 msn_object_get_location(msnobj),
204 msn_object_get_friendly(msnobj),
205 msn_object_get_sha1d(msnobj));
206
207 memset(digest, 0, sizeof(digest));
208
209 purple_cipher_context_reset(ctx, NULL);
210 purple_cipher_context_append(ctx, (const guchar *)buf, strlen(buf));
211 purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
212 purple_cipher_context_destroy(ctx);
213 g_free(buf);
214
215 base64 = purple_base64_encode(digest, sizeof(digest));
216 msn_object_set_sha1c(msnobj, base64);
217 g_free(base64);
218 }
219 }
220
221 void
222 msn_user_add_group_id(MsnUser *user, int id)
223 {
224 MsnUserList *userlist;
225 PurpleAccount *account;
226 PurpleBuddy *b;
227 PurpleGroup *g;
228 const char *passport;
229 const char *group_name;
230
231 g_return_if_fail(user != NULL);
232 g_return_if_fail(id >= 0);
233
234 user->group_ids = g_list_append(user->group_ids, GINT_TO_POINTER(id));
235
236 userlist = user->userlist;
237 account = userlist->session->account;
238 passport = msn_user_get_passport(user);
239
240 group_name = msn_userlist_find_group_name(userlist, id);
241
242 g = purple_find_group(group_name);
243
244 if ((id == 0) && (g == NULL))
245 {
246 g = purple_group_new(group_name);
247 purple_blist_add_group(g, NULL);
248 }
249
250 b = purple_find_buddy_in_group(account, passport, g);
251
252 if (b == NULL)
253 {
254 b = purple_buddy_new(account, passport, NULL);
255
256 purple_blist_add_buddy(b, NULL, g, NULL);
257 }
258
259 b->proto_data = user;
260 }
261
262 void
263 msn_user_remove_group_id(MsnUser *user, int id)
264 {
265 g_return_if_fail(user != NULL);
266 g_return_if_fail(id >= 0);
267
268 user->group_ids = g_list_remove(user->group_ids, GINT_TO_POINTER(id));
269 }
270
271 void
272 msn_user_set_home_phone(MsnUser *user, const char *number)
273 {
274 g_return_if_fail(user != NULL);
275
276 if (user->phone.home != NULL)
277 g_free(user->phone.home);
278
279 user->phone.home = (number == NULL ? NULL : g_strdup(number));
280 }
281
282 void
283 msn_user_set_work_phone(MsnUser *user, const char *number)
284 {
285 g_return_if_fail(user != NULL);
286
287 if (user->phone.work != NULL)
288 g_free(user->phone.work);
289
290 user->phone.work = (number == NULL ? NULL : g_strdup(number));
291 }
292
293 void
294 msn_user_set_mobile_phone(MsnUser *user, const char *number)
295 {
296 g_return_if_fail(user != NULL);
297
298 if (user->phone.mobile != NULL)
299 g_free(user->phone.mobile);
300
301 user->phone.mobile = (number == NULL ? NULL : g_strdup(number));
302 }
303
304 void
305 msn_user_set_object(MsnUser *user, MsnObject *obj)
306 {
307 g_return_if_fail(user != NULL);
308
309 if (user->msnobj != NULL)
310 msn_object_destroy(user->msnobj);
311
312 user->msnobj = obj;
313
314 if (user->list_op & MSN_LIST_FL_OP)
315 msn_queue_buddy_icon_request(user);
316 }
317
318 void
319 msn_user_set_client_caps(MsnUser *user, GHashTable *info)
320 {
321 g_return_if_fail(user != NULL);
322 g_return_if_fail(info != NULL);
323
324 if (user->clientcaps != NULL)
325 g_hash_table_destroy(user->clientcaps);
326
327 user->clientcaps = info;
328 }
329
330 const char *
331 msn_user_get_passport(const MsnUser *user)
332 {
333 g_return_val_if_fail(user != NULL, NULL);
334
335 return user->passport;
336 }
337
338 const char *
339 msn_user_get_friendly_name(const MsnUser *user)
340 {
341 g_return_val_if_fail(user != NULL, NULL);
342
343 return user->friendly_name;
344 }
345
346 const char *
347 msn_user_get_store_name(const MsnUser *user)
348 {
349 g_return_val_if_fail(user != NULL, NULL);
350
351 return user->store_name;
352 }
353
354 const char *
355 msn_user_get_home_phone(const MsnUser *user)
356 {
357 g_return_val_if_fail(user != NULL, NULL);
358
359 return user->phone.home;
360 }
361
362 const char *
363 msn_user_get_work_phone(const MsnUser *user)
364 {
365 g_return_val_if_fail(user != NULL, NULL);
366
367 return user->phone.work;
368 }
369
370 const char *
371 msn_user_get_mobile_phone(const MsnUser *user)
372 {
373 g_return_val_if_fail(user != NULL, NULL);
374
375 return user->phone.mobile;
376 }
377
378 MsnObject *
379 msn_user_get_object(const MsnUser *user)
380 {
381 g_return_val_if_fail(user != NULL, NULL);
382
383 return user->msnobj;
384 }
385
386 GHashTable *
387 msn_user_get_client_caps(const MsnUser *user)
388 {
389 g_return_val_if_fail(user != NULL, NULL);
390
391 return user->clientcaps;
392 }