Mercurial > pidgin.yaz
annotate src/protocols/novell/novell.c @ 8746:dbe23964ff2b
[gaim-migrate @ 9501]
(17:07:06) Luke: Hello Luke,
Sean has added 2 newlines in src/protocols/novell/novell.c.
Unfortunately this breaks the string freeze. If Sean's patch will not
be reverted, please commit my German translation update (file
i18n55.patch). If Sean's patch will be reverted, please do nothing.
Regards, Bj?rn
(17:09:28) Sean: oh, yeah, I did. I did that yesterady, didn't I?
(17:09:34) Luke: *nods*
(17:10:16) Sean: ok, revert it.
(17:10:24) Sean: please
(17:10:27) Luke: willdo
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Wed, 21 Apr 2004 21:14:21 +0000 |
parents | 0f73e8204529 |
children | d7b8eb1f0a18 |
rev | line source |
---|---|
8675 | 1 /* |
2 * novell.c | |
3 * | |
4 * Copyright © 2004 Unpublished Work of Novell, Inc. All Rights Reserved. | |
5 * | |
6 * THIS WORK IS AN UNPUBLISHED WORK OF NOVELL, INC. NO PART OF THIS WORK MAY BE | |
7 * USED, PRACTICED, PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, | |
8 * TRANSLATED, ABRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, | |
9 * RECAST, TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, | |
10 * INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT | |
11 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
12 * |
8675 | 13 * AS BETWEEN [GAIM] AND NOVELL, NOVELL GRANTS [GAIM] THE RIGHT TO REPUBLISH |
14 * THIS WORK UNDER THE GPL (GNU GENERAL PUBLIC LICENSE) WITH ALL RIGHTS AND | |
15 * LICENSES THEREUNDER. IF YOU HAVE RECEIVED THIS WORK DIRECTLY OR INDIRECTLY | |
16 * FROM [GAIM] AS PART OF SUCH A REPUBLICATION, YOU HAVE ALL RIGHTS AND LICENSES | |
17 * GRANTED BY [GAIM] UNDER THE GPL. IN CONNECTION WITH SUCH A REPUBLICATION, IF | |
18 * ANYTHING IN THIS NOTICE CONFLICTS WITH THE TERMS OF THE GPL, SUCH TERMS | |
19 * PREVAIL. | |
20 * | |
21 */ | |
22 | |
23 #include "internal.h" | |
24 #include "accountopt.h" | |
25 #include "debug.h" | |
26 #include "prpl.h" | |
27 #include "server.h" | |
28 #include "nmuser.h" | |
29 #include "notify.h" | |
30 #include "util.h" | |
31 #include "sslconn.h" | |
32 #include "request.h" | |
33 #include "network.h" | |
34 | |
35 #define DEFAULT_PORT 8300 | |
36 #define NOVELL_CONNECT_STEPS 4 | |
37 | |
38 static GaimPlugin *my_protocol = NULL; | |
39 | |
40 static gboolean | |
41 _is_disconnect_error(NMERR_T err); | |
42 | |
43 static gboolean | |
44 _check_for_disconnect(NMUser * user, NMERR_T err); | |
45 | |
46 static void | |
47 _send_message(NMUser * user, NMMessage * message); | |
48 | |
49 static void | |
50 _update_buddy_status(GaimBuddy * buddy, int status, int gmt); | |
51 | |
52 static void | |
53 _remove_gaim_buddies(NMUser * user); | |
54 | |
55 static void | |
56 _add_contacts_to_gaim_blist(NMUser * user, NMFolder * folder); | |
57 | |
58 static void | |
59 _add_gaim_buddies(NMUser * user); | |
60 | |
61 static void | |
62 _show_info(GaimConnection * gc, NMUserRecord * user_record); | |
63 | |
64 /******************************************************************************* | |
65 * Response callbacks | |
66 *******************************************************************************/ | |
67 | |
68 /* Handle login response */ | |
69 static void | |
70 _login_resp_cb(NMUser * user, NMERR_T ret_code, | |
71 gpointer resp_data, gpointer user_data) | |
72 { | |
73 GaimConnection *gc; | |
74 const char *alias; | |
75 NMERR_T rc; | |
76 | |
77 if (user == NULL) | |
78 return; | |
79 | |
80 gc = gaim_account_get_connection(user->client_data); | |
81 if (gc == NULL) | |
82 return; | |
83 | |
84 if (ret_code == NM_OK) { | |
85 | |
86 /* Set alias for user if not set (use Full Name) */ | |
87 alias = gaim_account_get_alias(user->client_data); | |
88 if (alias == NULL || *alias == '\0') { | |
89 alias = nm_user_record_get_full_name(user->user_record); | |
90 | |
91 if (alias) | |
92 gaim_account_set_alias(user->client_data, alias); | |
93 } | |
94 | |
95 /* Tell Gaim that we are connected */ | |
96 gaim_connection_set_state(gc, GAIM_CONNECTED); | |
97 serv_finish_login(gc); | |
98 | |
99 /* Sync the contact list. This is pretty simplistic right now, | |
100 * we just remove all of the GaimBuddy from the client side list | |
101 * for this account and then add in all of the contacts from the | |
102 * server side list. | |
103 */ | |
104 _remove_gaim_buddies(user); | |
105 _add_gaim_buddies(user); | |
106 | |
107 rc = nm_send_set_status(user, NM_STATUS_AVAILABLE, NULL, NULL, NULL, | |
108 NULL); | |
109 _check_for_disconnect(user, rc); | |
110 | |
111 } else { | |
112 | |
113 char *err = g_strdup_printf(_("Login failed (0x%X)."), ret_code); | |
114 | |
115 gaim_connection_error(gc, err); | |
116 g_free(err); | |
117 | |
118 } | |
119 } | |
120 | |
121 /* Handle getstatus response*/ | |
122 static void | |
123 _get_status_resp_cb(NMUser * user, NMERR_T ret_code, | |
124 gpointer resp_data, gpointer user_data) | |
125 { | |
126 GaimBuddy *buddy; | |
127 GSList *buddies; | |
128 GSList *bnode; | |
129 NMUserRecord *user_record = (NMUserRecord *) resp_data; | |
130 int status; | |
131 | |
132 if (user == NULL || user_record == NULL) | |
133 return; | |
134 | |
135 if (ret_code == NM_OK) { | |
136 | |
137 /* Find all Gaim buddies and update their statuses */ | |
138 const char *name = nm_user_record_get_display_id(user_record); | |
139 | |
140 if (name) { | |
141 buddies = gaim_find_buddies((GaimAccount *) user->client_data, name); | |
142 for (bnode = buddies; bnode; bnode = bnode->next) { | |
143 buddy = (GaimBuddy *) bnode->data; | |
144 if (buddy) { | |
145 status = nm_user_record_get_status(user_record); | |
146 _update_buddy_status(buddy, status, time(0)); | |
147 } | |
148 } | |
149 } | |
150 | |
151 } else { | |
152 | |
153 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
154 "_get_status_resp_cb(): rc = 0x%X\n", ret_code); | |
155 | |
156 } | |
157 } | |
158 | |
159 /* Show an error if the rename failed */ | |
160 static void | |
161 _rename_contact_resp_cb(NMUser * user, NMERR_T ret_code, | |
162 gpointer resp_data, gpointer user_data) | |
163 { | |
164 if (ret_code != NM_OK) { | |
165 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
166 "_rename_contact_resp_cb(): rc = 0x%X\n", ret_code); | |
167 } | |
168 } | |
169 | |
170 /* Handle the getdetails response and send the message */ | |
171 static void | |
172 _get_details_resp_send_msg(NMUser * user, NMERR_T ret_code, | |
173 gpointer resp_data, gpointer user_data) | |
174 { | |
175 GaimConversation *gconv; | |
176 GaimConnection *gc; | |
177 NMUserRecord *user_record = NULL; | |
178 NMContact *cntct = NULL; | |
179 NMConference *conf; | |
180 NMMessage *msg = user_data; | |
181 const char *dn = NULL; | |
182 const char *name; | |
183 | |
184 if (user == NULL || msg == NULL) | |
185 return; | |
186 | |
187 if (ret_code == NM_OK) { | |
188 user_record = (NMUserRecord *) resp_data; | |
189 if (user_record) { | |
190 | |
191 /* Set the title for the conversation */ | |
192 gconv = gaim_find_conversation_with_account(nm_user_record_get_display_id(user_record), | |
193 (GaimAccount *) user->client_data); | |
194 if (gconv) { | |
195 | |
196 dn = nm_user_record_get_dn(user_record); | |
197 if (dn) { | |
198 cntct = nm_find_contact(user, dn); | |
199 } | |
200 | |
201 if (cntct) { | |
202 gaim_conversation_set_title(gconv, | |
203 nm_contact_get_display_name(cntct)); | |
204 } else { | |
205 | |
206 /* Not in the contact list, try to user full name */ | |
207 name = (char *) nm_user_record_get_full_name(user_record); | |
208 if (name) | |
209 gaim_conversation_set_title(gconv, name); | |
210 } | |
211 } | |
212 | |
213 /* Add the user record to particpant list */ | |
214 conf = nm_message_get_conference(msg); | |
215 if (conf) { | |
216 nm_conference_add_participant(conf, user_record); | |
217 _send_message(user, msg); | |
218 } | |
219 } | |
220 | |
221 } else { | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
222 |
8675 | 223 gc = gaim_account_get_connection(user->client_data); |
224 if (gc != NULL) { | |
225 char *err = g_strdup_printf(_("Unable to send message." | |
226 " Could not get details for user (0x%X)."), | |
227 ret_code); | |
228 | |
229 gaim_notify_error(gc, NULL, err, NULL); | |
230 g_free(err); | |
231 } | |
232 | |
233 if (msg) | |
234 nm_release_message(msg); | |
235 } | |
236 } | |
237 | |
238 /* Set up the new GaimBuddy based on the response from getdetails */ | |
239 static void | |
240 _get_details_resp_setup_buddy(NMUser * user, NMERR_T ret_code, | |
241 gpointer resp_data, gpointer user_data) | |
242 { | |
243 NMUserRecord *user_record; | |
244 NMContact *contact; | |
245 GaimBuddy *buddy; | |
246 const char *alias; | |
247 NMERR_T rc = NM_OK; | |
248 | |
249 if (user == NULL || resp_data == NULL || user_data == NULL) | |
250 return; | |
251 | |
252 contact = user_data; | |
253 | |
254 if (ret_code == NM_OK) { | |
255 user_record = resp_data; | |
256 | |
257 buddy = nm_contact_get_data(contact); | |
258 | |
259 nm_contact_set_user_record(contact, user_record); | |
260 | |
261 /* Set the display id */ | |
262 gaim_blist_rename_buddy(buddy, | |
263 nm_user_record_get_display_id(user_record)); | |
264 | |
265 alias = gaim_get_buddy_alias(buddy); | |
266 if (alias == NULL || (strcmp(alias, buddy->name) == 0)) { | |
267 gaim_blist_alias_buddy(buddy, | |
268 nm_user_record_get_full_name(user_record)); | |
269 | |
270 /* Tell the server about the new display name */ | |
271 rc = nm_send_rename_contact(user, contact, | |
272 nm_user_record_get_full_name(user_record), | |
273 NULL, NULL); | |
274 _check_for_disconnect(user, rc); | |
275 | |
276 } | |
277 | |
278 | |
279 /* Get initial status for the buddy */ | |
280 rc = nm_send_get_status(user, resp_data, _get_status_resp_cb, NULL); | |
281 _check_for_disconnect(user, rc); | |
282 | |
283 /* nm_release_contact(contact);*/ | |
284 | |
285 } | |
286 | |
287 if (contact) | |
288 nm_release_contact(contact); | |
289 } | |
290 | |
291 /* Add the new contact into the GaimBuddy list */ | |
292 static void | |
293 _create_contact_resp_cb(NMUser * user, NMERR_T ret_code, | |
294 gpointer resp_data, gpointer user_data) | |
295 { | |
296 NMContact *tmp_contact = (NMContact *) user_data; | |
297 NMContact *new_contact = NULL; | |
298 NMFolder *folder = NULL; | |
299 GaimGroup *group; | |
300 GaimBuddy *buddy; | |
301 const char *folder_name = NULL; | |
302 NMERR_T rc = NM_OK; | |
303 | |
304 if (user == NULL) | |
305 return; | |
306 | |
307 if (ret_code == NM_OK) { | |
308 | |
309 new_contact = (NMContact *) resp_data; | |
310 if (new_contact == NULL || tmp_contact == NULL) | |
311 return; | |
312 | |
313 /* Get the userid and folder name for the new contact */ | |
314 folder = nm_find_folder_by_id(user, | |
315 nm_contact_get_parent_id(new_contact)); | |
316 if (folder) { | |
317 folder_name = nm_folder_get_name(folder); | |
318 } | |
319 | |
320 /* Re-add the buddy now that we got the okay from the server */ | |
321 if (folder_name && (group = gaim_find_group(folder_name))) { | |
322 | |
323 const char *alias = nm_contact_get_display_name(tmp_contact); | |
324 const char *display_id = nm_contact_get_display_id(new_contact); | |
325 | |
326 if (display_id == NULL) | |
327 display_id = nm_contact_get_dn(new_contact); | |
328 | |
329 if (alias && strcmp(alias, display_id)) { | |
330 | |
331 /* The user requested an alias, tell the server about it. */ | |
332 rc = nm_send_rename_contact(user, new_contact, alias, | |
333 _rename_contact_resp_cb, NULL); | |
334 _check_for_disconnect(user, rc); | |
335 | |
336 } else { | |
337 | |
338 alias = ""; | |
339 | |
340 } | |
341 | |
342 /* Add it to the gaim buddy list if it is not there */ | |
343 buddy = gaim_find_buddy_in_group(user->client_data, display_id, group); | |
344 if (buddy == NULL) { | |
345 buddy = gaim_buddy_new(user->client_data, display_id, alias); | |
346 gaim_blist_add_buddy(buddy, NULL, group, NULL); | |
347 } | |
348 | |
349 /* Save the new buddy as part of the contact object */ | |
350 nm_contact_set_data(new_contact, (gpointer) buddy); | |
351 | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
352 /* We need details for the user before we can setup the |
8675 | 353 * new Gaim buddy. We always call this because the |
354 * 'createcontact' response fields do not always contain | |
355 * everything that we need. | |
356 */ | |
357 nm_contact_add_ref(new_contact); | |
358 | |
359 rc = nm_send_get_details(user, nm_contact_get_dn(new_contact), | |
360 _get_details_resp_setup_buddy, new_contact); | |
361 _check_for_disconnect(user, rc); | |
362 | |
363 } | |
364 | |
365 } else { | |
366 GaimConnection *gc = gaim_account_get_connection(user->client_data); | |
367 const char *name = nm_contact_get_dn(tmp_contact); | |
368 char *err; | |
369 | |
370 err = | |
371 g_strdup_printf(_("Unable to add %s to your buddy list (0x%X)."), | |
372 name, ret_code); | |
373 gaim_notify_error(gc, NULL, err, NULL); | |
374 g_free(err); | |
375 | |
376 } | |
377 | |
378 if (tmp_contact) | |
379 nm_release_contact(tmp_contact); | |
380 } | |
381 | |
382 /* Show an error if we failed to send the message */ | |
383 static void | |
384 _send_message_resp_cb(NMUser * user, NMERR_T ret_code, | |
385 gpointer resp_data, gpointer user_data) | |
386 { | |
387 GaimConnection *gc; | |
388 char *err = NULL; | |
389 | |
390 if (user == NULL) | |
391 return; | |
392 | |
393 if (ret_code != NM_OK) { | |
394 gc = gaim_account_get_connection(user->client_data); | |
395 | |
396 /* TODO: Improve this! message to who or for what conference? */ | |
397 err = g_strdup_printf(_("Unable to send message (0x%X)."), | |
398 ret_code); | |
399 gaim_notify_error(gc, NULL, err, NULL); | |
400 g_free(err); | |
401 } | |
402 } | |
403 | |
404 /* Show an error if the remove failed */ | |
405 static void | |
406 _remove_contact_resp_cb(NMUser * user, NMERR_T ret_code, | |
407 gpointer resp_data, gpointer user_data) | |
408 { | |
409 if (ret_code != NM_OK) { | |
410 /* TODO: Display an error? */ | |
411 | |
412 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
413 "_remove_contact_resp_cb(): rc = 0x%x\n", ret_code); | |
414 } | |
415 } | |
416 | |
417 /* Show an error if the remove failed */ | |
418 static void | |
419 _remove_folder_resp_cb(NMUser * user, NMERR_T ret_code, | |
420 gpointer resp_data, gpointer user_data) | |
421 { | |
422 if (ret_code != NM_OK) { | |
423 /* TODO: Display an error? */ | |
424 | |
425 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
426 "_remove_folder_resp_cb(): rc = 0x%x\n", ret_code); | |
427 } | |
428 } | |
429 | |
430 /* Show an error if the move failed */ | |
431 static void | |
432 _move_contact_resp_cb(NMUser * user, NMERR_T ret_code, | |
433 gpointer resp_data, gpointer user_data) | |
434 { | |
435 if (ret_code != NM_OK) { | |
436 /* TODO: Display an error? */ | |
437 | |
438 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
439 "_move_contact_resp_cb(): rc = 0x%x\n", ret_code); | |
440 } | |
441 } | |
442 | |
443 /* Show an error if the rename failed */ | |
444 static void | |
445 _rename_folder_resp_cb(NMUser * user, NMERR_T ret_code, | |
446 gpointer resp_data, gpointer user_data) | |
447 { | |
448 if (ret_code != NM_OK) { | |
449 /* TODO: Display an error? */ | |
450 | |
451 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
452 "_rename_folder_resp_cb(): rc = 0x%x\n", ret_code); | |
453 } | |
454 } | |
455 | |
456 /* If the createconf was successful attempt to send the message, | |
457 * otherwise display an error message to the user. | |
458 */ | |
459 static void | |
460 _createconf_resp_send_msg(NMUser * user, NMERR_T ret_code, | |
461 gpointer resp_data, gpointer user_data) | |
462 { | |
463 NMConference *conf; | |
464 NMMessage *msg = user_data; | |
465 | |
466 if (user == NULL || msg == NULL) | |
467 return; | |
468 | |
469 if (ret_code == NM_OK) { | |
470 _send_message(user, msg); | |
471 } else { | |
472 | |
473 if ((conf = nm_message_get_conference(msg))) { | |
474 | |
475 GaimConnection *gc = gaim_account_get_connection(user->client_data); | |
476 const char *name = NULL; | |
477 char *err; | |
478 NMUserRecord *ur; | |
479 | |
480 ur = nm_conference_get_participant(conf, 0); | |
481 if (ur) | |
482 name = nm_user_record_get_userid(ur); | |
483 | |
484 if (name) | |
485 err = g_strdup_printf(_("Unable to send message to %s." | |
486 " Could not create the conference (0x%X)."), | |
487 name, ret_code); | |
488 else | |
489 err = g_strdup_printf(_("Unable to send message." | |
490 " Could not create the conference (0x%X)."), | |
491 ret_code); | |
492 | |
493 gaim_notify_error(gc, NULL, err, NULL); | |
494 g_free(err); | |
495 } | |
496 | |
497 if (msg) | |
498 nm_release_message(msg); | |
499 } | |
500 } | |
501 | |
502 /* Move contact to newly created folder */ | |
503 static void | |
504 _create_folder_resp_move_contact(NMUser * user, NMERR_T ret_code, | |
505 gpointer resp_data, gpointer user_data) | |
506 { | |
507 NMContact *contact = user_data; | |
508 NMFolder *new_folder; | |
509 char *folder_name = resp_data; | |
510 NMERR_T rc = NM_OK; | |
511 | |
512 if (user == NULL || folder_name == NULL || contact == NULL) { | |
513 | |
514 if (folder_name) | |
515 g_free(folder_name); | |
516 | |
517 return; | |
518 } | |
519 | |
520 if (ret_code == NM_OK || ret_code == 0xD126) { | |
521 new_folder = nm_find_folder(user, folder_name); | |
522 if (new_folder) { | |
523 | |
524 /* Tell the server to move the contact to the new folder */ | |
525 /* rc = nm_send_move_contact(user, contact, new_folder, | |
526 _move_contact_resp_cb, NULL); */ | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
527 |
8675 | 528 rc = nm_send_create_contact(user, new_folder, contact, |
529 NULL, NULL); | |
530 | |
531 _check_for_disconnect(user, rc); | |
532 | |
533 } | |
534 } else { | |
535 GaimConnection *gc = gaim_account_get_connection(user->client_data); | |
536 char *err = g_strdup_printf(_("Unable to move user %s" | |
537 " to folder %s in the server side list." | |
538 " Error while creating folder (0x%X)."), | |
539 nm_contact_get_dn(contact), | |
540 folder_name, | |
541 ret_code); | |
542 | |
543 gaim_notify_error(gc, NULL, err, NULL); | |
544 g_free(err); | |
545 } | |
546 | |
547 if (folder_name) | |
548 g_free(folder_name); | |
549 } | |
550 | |
551 /* Add contact to newly create folder */ | |
552 static void | |
553 _create_folder_resp_add_contact(NMUser * user, NMERR_T ret_code, | |
554 gpointer resp_data, gpointer user_data) | |
555 { | |
556 NMContact *contact = (NMContact *) user_data; | |
557 NMFolder *folder; | |
558 char *folder_name = (char *) resp_data; | |
559 NMERR_T rc = NM_OK; | |
560 | |
561 if (user == NULL || folder_name == NULL || contact == NULL) { | |
562 | |
563 if (contact) | |
564 nm_release_contact(contact); | |
565 | |
566 if (folder_name) | |
567 g_free(folder_name); | |
568 | |
569 return; | |
570 } | |
571 | |
572 if (ret_code == NM_OK || ret_code == 0xD126) { | |
573 folder = nm_find_folder(user, folder_name); | |
574 if (folder) { | |
575 | |
576 rc = nm_send_create_contact(user, folder, contact, | |
577 _create_contact_resp_cb, contact); | |
578 _check_for_disconnect(user, rc); | |
579 } | |
580 } else { | |
581 GaimConnection *gc = gaim_account_get_connection(user->client_data); | |
582 const char *name = nm_contact_get_dn(contact); | |
583 char *err = | |
584 g_strdup_printf(_("Unable to add %s to your buddy list." | |
585 " Error creating folder in server side list (0x%X)."), | |
586 name, ret_code); | |
587 | |
588 gaim_notify_error(gc, NULL, err, NULL); | |
589 | |
590 nm_release_contact(contact); | |
591 g_free(err); | |
592 } | |
593 | |
594 g_free(folder_name); | |
595 } | |
596 | |
597 static void | |
598 _join_conf_resp_cb(NMUser * user, NMERR_T ret_code, | |
599 gpointer resp_data, gpointer user_data) | |
600 { | |
601 GaimConversation *chat; | |
602 GaimConnection *gc; | |
603 NMUserRecord *ur; | |
604 NMConference *conference = user_data; | |
605 const char *name; | |
606 char *conf_name; | |
607 int i, count; | |
608 | |
609 if (user == NULL || conference == NULL) | |
610 return; | |
611 | |
612 gc = gaim_account_get_connection(user->client_data); | |
613 | |
614 if (ret_code == NM_OK) { | |
615 conf_name = g_strdup_printf(_("GroupWise Conference %d"), | |
616 ++user->conference_count); | |
617 chat = serv_got_joined_chat(gc, user->conference_count, conf_name); | |
618 if (chat) { | |
619 | |
620 nm_conference_set_data(conference, (gpointer) chat); | |
621 | |
622 count = nm_conference_get_participant_count(conference); | |
623 for (i = 0; i < count; i++) { | |
624 ur = nm_conference_get_participant(conference, i); | |
625 if (ur) { | |
626 name = nm_user_record_get_display_id(ur); | |
627 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); | |
628 } | |
629 } | |
630 } | |
631 g_free(conf_name); | |
632 } | |
633 } | |
634 | |
635 /* Show info returned by getdetails */ | |
636 static void | |
637 _get_details_resp_show_info(NMUser * user, NMERR_T ret_code, | |
638 gpointer resp_data, gpointer user_data) | |
639 { | |
640 GaimConnection *gc; | |
641 NMUserRecord *user_record; | |
642 char *name; | |
643 char *err; | |
644 | |
645 if (user == NULL) | |
646 return; | |
647 | |
648 name = user_data; | |
649 | |
650 if (ret_code == NM_OK) { | |
651 user_record = (NMUserRecord *) resp_data; | |
652 if (user_record) { | |
653 _show_info(gaim_account_get_connection(user->client_data), | |
654 user_record); | |
655 } | |
656 } else { | |
657 gc = gaim_account_get_connection(user->client_data); | |
658 err = | |
659 g_strdup_printf(_("Could not get details for user %s (0x%X)."), name, | |
660 ret_code); | |
661 gaim_notify_error(gc, NULL, err, NULL); | |
662 g_free(err); | |
663 } | |
664 | |
665 if (name) | |
666 g_free(name); | |
667 } | |
668 | |
669 /******************************************************************************* | |
670 * Helper functions | |
671 ******************************************************************************/ | |
672 | |
673 static char * | |
674 _user_agent_string() | |
675 { | |
676 | |
677 #if !defined(_WIN32) | |
678 | |
679 const char *sysname = ""; | |
680 const char *release = ""; | |
681 const char *template = "Gaim/%s (%s; %s)"; | |
682 struct utsname u; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
683 |
8675 | 684 if (uname(&u) == 0) { |
685 sysname = u.sysname; | |
686 release = u.release; | |
687 } else { | |
688 sysname = "Linux"; | |
689 release = "Unknown"; | |
690 } | |
691 | |
692 return g_strdup_printf(template, VERSION, sysname, release); | |
693 | |
694 #else | |
695 | |
696 const char *sysname = ""; | |
697 const char *template = "Gaim/%s (%s; %d.%d)"; | |
698 OSVERSIONINFO os_info; | |
699 SYSTEM_INFO sys_info; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
700 |
8675 | 701 os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
702 GetVersionEx(&os_info); | |
703 GetSystemInfo(&sys_info); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
704 |
8675 | 705 if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) { |
706 switch (os_info.dwMajorVersion) { | |
707 case 3: | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
708 case 4: |
8675 | 709 sysname = "Windows NT"; |
710 break; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
711 case 5: |
8675 | 712 switch (os_info.dwMinorVersion) { |
713 case 0: | |
714 sysname = "Windows 2000"; | |
715 break; | |
716 case 1: | |
717 sysname = "Windows XP"; | |
718 break; | |
719 case 2: | |
720 sysname = "Windows Server 2003"; | |
721 break; | |
722 default: | |
723 sysname = "Windows"; | |
724 break; | |
725 } | |
726 break; | |
727 default: | |
728 sysname = "Windows"; | |
729 break; | |
730 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
731 |
8675 | 732 } else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { |
733 switch (os_info.dwMinorVersion) { | |
734 case 0: | |
735 sysname = "Windows 95"; | |
736 break; | |
737 case 10: | |
738 sysname = "Windows 98"; | |
739 break; | |
740 case 90: | |
741 sysname = "Windows ME"; | |
742 break; | |
743 default: | |
744 sysname = "Windows"; | |
745 break; | |
746 } | |
747 } else { | |
748 sysname = "Windows"; | |
749 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
750 |
8675 | 751 return g_strdup_printf(template, VERSION, sysname, |
752 os_info.dwMajorVersion, os_info.dwMinorVersion); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
753 |
8675 | 754 #endif |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
755 |
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
756 |
8675 | 757 } |
758 | |
759 static gboolean | |
760 _is_disconnect_error(NMERR_T err) | |
761 { | |
762 return (err == NMERR_TCP_WRITE || | |
763 err == NMERR_TCP_READ || err == NMERR_PROTOCOL); | |
764 } | |
765 | |
766 static gboolean | |
767 _check_for_disconnect(NMUser * user, NMERR_T err) | |
768 { | |
769 GaimConnection *gc = gaim_account_get_connection(user->client_data); | |
770 | |
771 if (_is_disconnect_error(err)) { | |
772 | |
773 gaim_connection_error(gc, _("Error communicating with server." | |
774 " Closing connection.")); | |
775 return TRUE; | |
776 | |
777 } | |
778 | |
779 return FALSE; | |
780 } | |
781 | |
782 /* Check to see if the conference is instantiated, if so send the message. | |
783 * If not send the create conference -- the response handler for the createconf | |
784 * will call this function again. | |
785 */ | |
786 static void | |
787 _send_message(NMUser * user, NMMessage * message) | |
788 { | |
789 NMConference *conf; | |
790 NMERR_T rc = NM_OK; | |
791 | |
792 conf = nm_message_get_conference(message); | |
793 if (conf) { | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
794 /* We have a conference make sure that the |
8675 | 795 server knows about it already. */ |
796 if (nm_conference_is_instantiated(conf)) { | |
797 | |
798 /* We have everything that we need...finally! */ | |
799 rc = nm_send_message(user, message, _send_message_resp_cb); | |
800 _check_for_disconnect(user, rc); | |
801 | |
802 nm_release_message(message); | |
803 | |
804 } else { | |
805 rc = nm_send_create_conference(user, conf, | |
806 _createconf_resp_send_msg, message); | |
807 _check_for_disconnect(user, rc); | |
808 } | |
809 } | |
810 } | |
811 | |
812 /* Update the status of the given buddy in the Gaim buddy list */ | |
813 static void | |
814 _update_buddy_status(GaimBuddy * buddy, int status, int gmt) | |
815 { | |
816 GaimConnection *gc = gaim_account_get_connection(buddy->account); | |
817 int gstatus = status << 1; | |
818 int idle = 0; | |
819 int loggedin = 1; | |
820 | |
821 switch (status) { | |
822 case NM_STATUS_AVAILABLE: | |
823 /*nothing to do */ | |
824 break; | |
825 case NM_STATUS_AWAY: | |
826 case NM_STATUS_BUSY: | |
827 gstatus |= UC_UNAVAILABLE; | |
828 break; | |
829 case NM_STATUS_OFFLINE: | |
830 loggedin = 0; | |
831 gstatus |= UC_UNAVAILABLE; | |
832 break; | |
833 case NM_STATUS_AWAY_IDLE: | |
834 idle = gmt; | |
835 gstatus |= UC_UNAVAILABLE; | |
836 break; | |
837 default: | |
838 gstatus |= UC_UNAVAILABLE; | |
839 loggedin = 0; | |
840 break; | |
841 } | |
842 | |
843 serv_got_update(gc, buddy->name, loggedin, 0, 0, idle, gstatus); | |
844 } | |
845 | |
846 /* Iterate through the cached Gaim buddy list and remove all buddies | |
847 * for this account. | |
848 */ | |
849 static void | |
850 _remove_gaim_buddies(NMUser * user) | |
851 { | |
852 GaimBlistNode *gnode; | |
853 GaimBlistNode *cnode; | |
854 GaimBlistNode *bnode; | |
855 GaimGroup *group; | |
856 GaimBuddy *buddy; | |
857 GaimBuddyList *blist; | |
858 GSList *rem_list = NULL; | |
859 GSList *l; | |
860 | |
861 if ((blist = gaim_get_blist())) { | |
862 for (gnode = blist->root; gnode; gnode = gnode->next) { | |
863 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
864 continue; | |
865 group = (GaimGroup *) gnode; | |
866 for (cnode = gnode->child; cnode; cnode = cnode->next) { | |
867 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
868 continue; | |
869 for (bnode = cnode->child; bnode; bnode = bnode->next) { | |
870 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
871 continue; | |
872 buddy = (GaimBuddy *) bnode; | |
873 if (buddy->account == user->client_data) { | |
874 rem_list = g_slist_append(rem_list, buddy); | |
875 } | |
876 } | |
877 } | |
878 } | |
879 | |
880 if (rem_list) { | |
881 for (l = rem_list; l; l = l->next) { | |
882 gaim_blist_remove_buddy(l->data); | |
883 } | |
884 g_slist_free(rem_list); | |
885 } | |
886 } | |
887 } | |
888 | |
889 /* Add all of the contacts in the given folder to the Gaim buddy list */ | |
890 static void | |
891 _add_contacts_to_gaim_blist(NMUser * user, NMFolder * folder) | |
892 { | |
893 NMUserRecord *user_record = NULL; | |
894 NMContact *contact = NULL; | |
895 GaimBuddy *buddy = NULL; | |
896 NMERR_T cnt = 0, i; | |
897 const char *text = NULL; | |
898 const char *name = NULL; | |
899 int status = 0; | |
900 | |
901 /* Get each contact for this folder */ | |
902 cnt = nm_folder_get_contact_count(folder); | |
903 for (i = 0; i < cnt; i++) { | |
904 contact = nm_folder_get_contact(folder, i); | |
905 if (contact) { | |
906 | |
907 name = nm_contact_get_display_id(contact); | |
908 if (name) { | |
909 /* Add it to the gaim buddy list */ | |
910 buddy = gaim_buddy_new(user->client_data, | |
911 name, | |
912 nm_contact_get_display_name(contact)); | |
913 | |
914 /* Does the Gaim group exist already? */ | |
915 GaimGroup *group = gaim_find_group(nm_folder_get_name(folder)); | |
916 | |
917 if (group == NULL) { | |
918 group = gaim_group_new(nm_folder_get_name(folder)); | |
919 gaim_blist_add_group(group, NULL); | |
920 } | |
921 | |
922 /* Set the initial status for the buddy */ | |
923 user_record = nm_contact_get_user_record(contact); | |
924 if (user_record) { | |
925 status = nm_user_record_get_status(user_record); | |
926 text = nm_user_record_get_status_text(user_record); | |
927 } | |
928 | |
929 gaim_blist_add_buddy(buddy, NULL, group, NULL); | |
930 _update_buddy_status(buddy, status, time(0)); | |
931 | |
932 /* Save the new buddy as part of the contact object */ | |
933 nm_contact_set_data(contact, (gpointer) buddy); | |
934 } | |
935 | |
936 } else { | |
937 /* NULL contact. This should not happen, but | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
938 * let's break out of the loop. |
8675 | 939 */ |
940 break; | |
941 } | |
942 } | |
943 | |
944 } | |
945 | |
946 /* Add all of the server side contacts to the Gaim buddy list. */ | |
947 static void | |
948 _add_gaim_buddies(NMUser * user) | |
949 { | |
950 NMERR_T cnt = 0, i; | |
951 NMFolder *root_folder = NULL; | |
952 NMFolder *folder = NULL; | |
953 | |
954 root_folder = nm_get_root_folder(user); | |
955 if (root_folder) { | |
956 | |
957 /* Add contacts for the sub folders */ | |
958 cnt = nm_folder_get_subfolder_count(root_folder); | |
959 for (i = 0; i < cnt; i++) { | |
960 folder = nm_folder_get_subfolder(root_folder, i); | |
961 if (folder) { | |
962 _add_contacts_to_gaim_blist(user, folder); | |
963 } | |
964 } | |
965 | |
966 /* Add contacts for the root folder */ | |
967 _add_contacts_to_gaim_blist(user, root_folder); | |
968 } | |
969 } | |
970 | |
971 /* Display a dialog box showing the properties for the given user record */ | |
972 static void | |
973 _show_info(GaimConnection * gc, NMUserRecord * user_record) | |
974 { | |
975 GString *info_text; | |
976 int count, i; | |
977 NMProperty *property; | |
978 const char *tag, *value; | |
979 | |
980 info_text = g_string_new(""); | |
981 | |
982 tag = _("Userid"); | |
983 value = nm_user_record_get_userid(user_record); | |
984 if (value) { | |
985 g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n", tag, value); | |
986 } | |
987 | |
988 /* tag = _("DN"); | |
989 value = nm_user_record_get_dn(user_record); | |
990 if (value) { | |
991 g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n", | |
992 tag, value); | |
993 } | |
994 */ | |
995 | |
996 tag = _("Full name"); | |
997 value = nm_user_record_get_full_name(user_record); | |
998 if (value) { | |
999 g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n", tag, value); | |
1000 } | |
1001 | |
1002 count = nm_user_record_get_property_count(user_record); | |
1003 for (i = 0; i < count; i++) { | |
1004 property = nm_user_record_get_property(user_record, i); | |
1005 if (property) { | |
1006 tag = nm_property_get_tag(property); | |
1007 value = nm_property_get_value(property); | |
1008 if (tag && value) { | |
1009 g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n", | |
1010 tag, value); | |
1011 } | |
1012 nm_release_property(property); | |
1013 } | |
1014 } | |
1015 | |
8744 | 1016 gaim_notify_formatted(NULL, NULL, _("User Properties"), |
8675 | 1017 NULL, info_text->str, NULL, NULL); |
1018 | |
1019 g_string_free(info_text, TRUE); | |
1020 } | |
1021 | |
1022 /* Send a join conference, the first item in the parms list is the | |
1023 * NMUser object and the second item is the conference to join. | |
1024 * This callback is passed to gaim_request_action when we ask the | |
1025 * user if they want to join the conference. | |
1026 */ | |
1027 static void | |
1028 _join_conference_cb(GSList * parms) | |
1029 { | |
1030 NMUser *user; | |
1031 NMConference *conference; | |
1032 NMERR_T rc = NM_OK; | |
1033 | |
1034 if (parms == NULL || g_slist_length(parms) != 2) | |
1035 return; | |
1036 | |
1037 user = g_slist_nth_data(parms, 0); | |
1038 conference = g_slist_nth_data(parms, 1); | |
1039 | |
1040 if (user && conference) { | |
1041 rc = nm_send_join_conference(user, conference, | |
1042 _join_conf_resp_cb, conference); | |
1043 _check_for_disconnect(user, rc); | |
1044 } | |
1045 | |
1046 g_slist_free(parms); | |
1047 } | |
1048 | |
1049 /* Send a reject conference, the first item in the parms list is the | |
1050 * NMUser object and the second item is the conference to reject. | |
1051 * This callback is passed to gaim_request_action when we ask the | |
1052 * user if they want to joing the conference. | |
1053 */ | |
1054 static void | |
1055 _reject_conference_cb(GSList * parms) | |
1056 { | |
1057 NMUser *user; | |
1058 NMConference *conference; | |
1059 NMERR_T rc = NM_OK; | |
1060 | |
1061 if (parms == NULL || g_slist_length(parms) != 2) | |
1062 return; | |
1063 | |
1064 user = g_slist_nth_data(parms, 0); | |
1065 conference = g_slist_nth_data(parms, 1); | |
1066 | |
1067 if (user && conference) { | |
1068 rc = nm_send_reject_conference(user, conference, NULL, NULL); | |
1069 _check_for_disconnect(user, rc); | |
1070 } | |
1071 | |
1072 g_slist_free(parms); | |
1073 } | |
1074 | |
1075 /******************************************************************************* | |
1076 * Connect and recv callbacks | |
1077 ******************************************************************************/ | |
1078 | |
1079 static void | |
1080 novell_ssl_connect_error(GaimSslConnection * gsc, | |
1081 GaimSslErrorType error, gpointer data) | |
1082 { | |
1083 gaim_connection_error((GaimConnection *)data, | |
1084 _("Unable to make SSL connection to server.")); | |
1085 } | |
1086 | |
1087 static void | |
1088 novell_ssl_recv_cb(gpointer data, GaimSslConnection * gsc, | |
1089 GaimInputCondition condition) | |
1090 { | |
1091 GaimConnection *gc = data; | |
1092 NMUser *user; | |
1093 NMERR_T rc; | |
1094 | |
1095 if (gc == NULL) | |
1096 return; | |
1097 | |
1098 user = gc->proto_data; | |
1099 if (user == NULL) | |
1100 return; | |
1101 | |
1102 rc = nm_process_new_data(user); | |
1103 if (rc != NM_OK) { | |
1104 | |
1105 if (_is_disconnect_error(rc)) { | |
1106 gaim_connection_error(gc, | |
1107 _("Error communicating with server." | |
1108 " Closing connection.")); | |
1109 } else { | |
1110 | |
1111 char *error; | |
1112 | |
1113 error = g_strdup_printf(_("Error processing event or response." | |
1114 " (0x%X)"), rc); | |
1115 gaim_notify_error(gc, NULL, error, NULL); | |
1116 g_free(error); | |
1117 | |
1118 } | |
1119 | |
1120 } | |
1121 } | |
1122 | |
1123 static void | |
1124 novell_ssl_connected_cb(gpointer data, GaimSslConnection * gsc, | |
1125 GaimInputCondition cond) | |
1126 { | |
1127 GaimConnection *gc = data; | |
1128 NMUser *user; | |
1129 NMConn *conn; | |
1130 NMERR_T rc = 0; | |
1131 const char *pwd = NULL; | |
1132 const char *my_addr = NULL; | |
1133 char *ua = NULL; | |
1134 | |
1135 if (gc == NULL || gsc == NULL) | |
1136 return; | |
1137 | |
1138 user = gc->proto_data; | |
1139 if ((user == NULL) || (conn = user->conn) == NULL) | |
1140 return; | |
1141 | |
1142 conn->ssl_conn = g_new0(NMSSLConn, 1); | |
1143 conn->ssl_conn->data = gsc; | |
1144 conn->ssl_conn->read = (nm_ssl_read_cb) gaim_ssl_read; | |
1145 conn->ssl_conn->write = (nm_ssl_write_cb) gaim_ssl_write; | |
1146 | |
1147 gaim_connection_update_progress(gc, _("Authenticating..."), | |
1148 2, NOVELL_CONNECT_STEPS); | |
1149 | |
1150 my_addr = gaim_network_get_ip_for_account(user->client_data, gsc->fd); | |
1151 pwd = gaim_account_get_password(user->client_data); | |
1152 ua = _user_agent_string(); | |
1153 | |
1154 rc = nm_send_login(user, pwd, my_addr, ua, _login_resp_cb, NULL); | |
1155 if (rc == NM_OK) { | |
1156 conn->connected = TRUE; | |
1157 gaim_ssl_input_add(gsc, novell_ssl_recv_cb, gc); | |
1158 } else { | |
1159 gaim_connection_error(gc, _("Unable to connect to server.")); | |
1160 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1161 |
8675 | 1162 gaim_connection_update_progress(gc, _("Waiting for response..."), |
1163 3, NOVELL_CONNECT_STEPS); | |
1164 | |
1165 g_free(ua); | |
1166 } | |
1167 | |
1168 /******************************************************************************* | |
1169 * Event callback and event handlers | |
1170 ******************************************************************************/ | |
1171 | |
1172 static void | |
1173 _evt_receive_message(NMUser * user, NMEvent * event) | |
1174 { | |
1175 NMUserRecord *user_record = NULL; | |
1176 NMContact *contact = NULL; | |
1177 GaimConversation *gconv; | |
1178 NMConference *conference; | |
1179 GaimConvImFlags imflags; | |
1180 | |
1181 conference = nm_event_get_conference(event); | |
1182 if (conference) { | |
1183 | |
1184 GaimConversation *chat = nm_conference_get_data(conference); | |
1185 | |
1186 /* Is this a single person 'conversation' or a conference? */ | |
1187 if (chat == NULL && nm_conference_get_participant_count(conference) == 1) { | |
1188 | |
1189 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
1190 if (user_record) { | |
1191 | |
1192 imflags = 0; | |
1193 if (nm_event_get_type(event) == NMEVT_RECEIVE_AUTOREPLY) | |
1194 imflags |= GAIM_CONV_IM_AUTO_RESP; | |
1195 | |
1196 serv_got_im(gaim_account_get_connection(user->client_data), | |
1197 nm_user_record_get_display_id(user_record), | |
1198 nm_event_get_text(event), imflags, | |
1199 nm_event_get_gmt(event)); | |
1200 | |
1201 gconv = gaim_find_conversation_with_account( | |
1202 nm_user_record_get_display_id(user_record), | |
1203 (GaimAccount *) user->client_data); | |
1204 if (gconv) { | |
1205 | |
1206 contact = nm_find_contact(user, nm_event_get_source(event)); | |
1207 if (contact) { | |
1208 | |
1209 gaim_conversation_set_title( | |
1210 gconv, | |
1211 nm_contact_get_display_name(contact)); | |
1212 | |
1213 | |
1214 } else { | |
1215 | |
1216 const char *name = | |
1217 nm_user_record_get_full_name(user_record); | |
1218 | |
1219 if (name == NULL) | |
1220 name = nm_user_record_get_userid(user_record); | |
1221 | |
1222 gaim_conversation_set_title(gconv, name); | |
1223 } | |
1224 | |
1225 } | |
1226 | |
1227 } else { | |
1228 /* this should not happen, see the event code. | |
1229 * the event code will get the contact details from | |
1230 * the server if it does not have them before calling | |
1231 * the event callback. | |
1232 */ | |
1233 } | |
1234 | |
1235 } else if (chat) { | |
1236 | |
1237 /* get the contact for send if we have one */ | |
1238 NMContact *contact = nm_find_contact(user, | |
1239 nm_event_get_source(event)); | |
1240 | |
1241 /* get the user record for the sender */ | |
1242 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
1243 if (user_record) { | |
1244 const char *name = nm_contact_get_display_name(contact); | |
1245 | |
1246 if (name == NULL) { | |
1247 name = nm_user_record_get_full_name(user_record); | |
1248 if (name == NULL) | |
1249 name = nm_user_record_get_display_id(user_record); | |
1250 } | |
1251 | |
1252 serv_got_chat_in(gaim_account_get_connection(user->client_data), | |
1253 gaim_conv_chat_get_id(GAIM_CONV_CHAT(chat)), | |
1254 name, | |
1255 0, nm_event_get_text(event), | |
1256 nm_event_get_gmt(event)); | |
1257 } | |
1258 } | |
1259 } | |
1260 } | |
1261 | |
1262 static void | |
1263 _evt_conference_left(NMUser * user, NMEvent * event) | |
1264 { | |
1265 GaimConversation *chat; | |
1266 NMConference *conference; | |
1267 | |
1268 conference = nm_event_get_conference(event); | |
1269 if (conference) { | |
1270 chat = nm_conference_get_data(conference); | |
1271 if (chat) { | |
1272 NMUserRecord *ur = nm_find_user_record(user, | |
1273 nm_event_get_source(event)); | |
1274 | |
1275 if (ur) | |
1276 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(chat), | |
1277 nm_user_record_get_display_id(ur), | |
1278 NULL); | |
1279 } | |
1280 } | |
1281 } | |
1282 | |
1283 static void | |
1284 _evt_conference_invite(NMUser * user, NMEvent * event) | |
1285 { | |
1286 NMUserRecord *ur; | |
1287 GSList *parms = NULL; | |
1288 const char *title = NULL; | |
1289 const char *secondary = NULL; | |
1290 const char *name = NULL; | |
1291 char *primary = NULL; | |
1292 time_t gmt; | |
1293 | |
1294 ur = nm_find_user_record(user, nm_event_get_source(event)); | |
1295 if (ur) | |
1296 name = nm_user_record_get_full_name(ur); | |
1297 | |
1298 if (name == NULL) | |
1299 name = nm_event_get_source(event); | |
1300 | |
1301 gmt = nm_event_get_gmt(event); | |
1302 title = _("Invitation to Conversation"); | |
1303 primary = g_strdup_printf(_("Invitation from: %s\n\nSent: %s"), | |
1304 name, asctime(localtime(&gmt))); | |
1305 secondary = _("Would you like to join the conversation?"); | |
1306 | |
1307 /* Set up parms list for the callbacks | |
1308 * We need to send the NMUser object and | |
1309 * the NMConference object to the callbacks | |
1310 */ | |
1311 parms = NULL; | |
1312 parms = g_slist_append(parms, user); | |
1313 parms = g_slist_append(parms, nm_event_get_conference(event)); | |
1314 | |
1315 /* Prompt the user */ | |
1316 gaim_request_action(NULL, title, primary, secondary, -1, parms, 2, | |
1317 _("Yes"), G_CALLBACK(_join_conference_cb), | |
1318 _("No"), G_CALLBACK(_reject_conference_cb)); | |
1319 | |
1320 g_free(primary); | |
1321 } | |
1322 | |
1323 | |
1324 static void | |
1325 _evt_conference_joined(NMUser * user, NMEvent * event) | |
1326 { | |
1327 GaimConversation *chat = NULL; | |
1328 GaimConnection *gc; | |
1329 NMConference *conference = NULL; | |
1330 NMUserRecord *ur = NULL; | |
1331 const char *name; | |
1332 char *conf_name; | |
1333 | |
1334 gc = gaim_account_get_connection(user->client_data); | |
1335 if (gc == NULL) | |
1336 return; | |
1337 | |
1338 conference = nm_event_get_conference(event); | |
1339 if (conference) { | |
1340 chat = nm_conference_get_data(conference); | |
1341 if (nm_conference_get_participant_count(conference) == 2 && chat == NULL) { | |
1342 ur = nm_conference_get_participant(conference, 0); | |
1343 if (ur) { | |
1344 conf_name = g_strdup_printf(_("GroupWise Conference %d"), | |
1345 ++user->conference_count); | |
1346 chat = | |
1347 serv_got_joined_chat(gc, user->conference_count, conf_name); | |
1348 g_free(conf_name); | |
1349 if (chat) { | |
1350 | |
1351 nm_conference_set_data(conference, (gpointer) chat); | |
1352 | |
1353 name = nm_user_record_get_display_id(ur); | |
1354 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); | |
1355 | |
1356 } | |
1357 } | |
1358 } | |
1359 | |
1360 if (chat != NULL) { | |
1361 ur = nm_find_user_record(user, nm_event_get_source(event)); | |
1362 if (ur) { | |
1363 name = nm_user_record_get_display_id(ur); | |
1364 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); | |
1365 } | |
1366 } | |
1367 } | |
1368 } | |
1369 | |
1370 static void | |
1371 _evt_status_change(NMUser * user, NMEvent * event) | |
1372 { | |
1373 GaimBuddy *buddy = NULL; | |
1374 GSList *buddies; | |
1375 GSList *bnode; | |
1376 NMUserRecord *user_record; | |
1377 const char *display_id; | |
1378 int status; | |
1379 | |
1380 user_record = nm_event_get_user_record(event); | |
1381 if (user_record) { | |
1382 | |
1383 /* Retrieve new status */ | |
1384 status = nm_user_record_get_status(user_record); | |
1385 | |
1386 /* Update status for buddy in all folders */ | |
1387 display_id = nm_user_record_get_display_id(user_record); | |
1388 buddies = gaim_find_buddies(user->client_data, display_id); | |
1389 for (bnode = buddies; bnode; bnode = bnode->next) { | |
1390 buddy = (GaimBuddy *) bnode->data; | |
1391 if (buddy) { | |
1392 _update_buddy_status(buddy, status, nm_event_get_gmt(event)); | |
1393 } | |
1394 } | |
1395 | |
1396 g_slist_free(buddies); | |
1397 | |
1398 } | |
1399 } | |
1400 | |
1401 static void | |
1402 _evt_user_disconnect(NMUser * user, NMEvent * event) | |
1403 { | |
1404 GaimConnection *gc; | |
1405 | |
1406 gc = gaim_account_get_connection((GaimAccount *) user->client_data); | |
1407 if (gc) | |
1408 gaim_connection_error(gc, _("You have been logged out because you" | |
1409 " logged in at another workstation.")); | |
1410 } | |
1411 | |
1412 static void | |
1413 _evt_user_typing(NMUser * user, NMEvent * event) | |
1414 { | |
1415 GaimConnection *gc; | |
1416 NMUserRecord *user_record = NULL; | |
1417 | |
1418 gc = gaim_account_get_connection((GaimAccount *) user->client_data); | |
1419 if (gc) { | |
1420 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
1421 if (user_record) { | |
1422 serv_got_typing(gc, nm_user_record_get_display_id(user_record), | |
1423 30, GAIM_TYPING); | |
1424 } | |
1425 } | |
1426 } | |
1427 | |
1428 static void | |
1429 _evt_user_not_typing(NMUser * user, NMEvent * event) | |
1430 { | |
1431 GaimConnection *gc; | |
1432 NMUserRecord *user_record; | |
1433 | |
1434 gc = gaim_account_get_connection((GaimAccount *) user->client_data); | |
1435 if (gc) { | |
1436 user_record = nm_find_user_record(user, nm_event_get_source(event)); | |
1437 if (user_record) { | |
1438 serv_got_typing_stopped(gc, | |
1439 nm_user_record_get_display_id(user_record)); | |
1440 } | |
1441 } | |
1442 } | |
1443 | |
1444 static void | |
1445 _evt_undeliverable_status(NMUser * user, NMEvent * event) | |
1446 { | |
1447 NMUserRecord *ur; | |
1448 GaimConversation *gconv; | |
1449 char *str; | |
1450 | |
1451 ur = nm_find_user_record(user, nm_event_get_source(event)); | |
1452 if (ur) { | |
1453 gconv = | |
1454 gaim_find_conversation_with_account(nm_user_record_get_display_id(ur), | |
1455 user->client_data); | |
1456 if (gconv) { | |
1457 const char *name = nm_user_record_get_full_name(ur); | |
1458 | |
1459 if (name == NULL) { | |
1460 name = nm_user_record_get_display_id(ur); | |
1461 } | |
1462 str = g_strdup_printf(_("%s appears to be offline and did not receive" | |
1463 " the message that you just sent."), name); | |
1464 gaim_conversation_write(gconv, NULL, str, | |
1465 GAIM_MESSAGE_SYSTEM, time(NULL)); | |
1466 g_free(str); | |
1467 } | |
1468 } | |
1469 } | |
1470 | |
1471 static void | |
1472 _event_callback(NMUser * user, NMEvent * event) | |
1473 { | |
1474 if (user == NULL || event == NULL) | |
1475 return; | |
1476 | |
1477 switch (nm_event_get_type(event)) { | |
1478 case NMEVT_STATUS_CHANGE: | |
1479 _evt_status_change(user, event); | |
1480 break; | |
1481 case NMEVT_RECEIVE_AUTOREPLY: | |
1482 case NMEVT_RECEIVE_MESSAGE: | |
1483 _evt_receive_message(user, event); | |
1484 break; | |
1485 case NMEVT_USER_DISCONNECT: | |
1486 _evt_user_disconnect(user, event); | |
1487 break; | |
1488 case NMEVT_USER_TYPING: | |
1489 _evt_user_typing(user, event); | |
1490 break; | |
1491 case NMEVT_USER_NOT_TYPING: | |
1492 _evt_user_not_typing(user, event); | |
1493 break; | |
1494 case NMEVT_SERVER_DISCONNECT: | |
1495 /* Nothing to do? */ | |
1496 break; | |
1497 case NMEVT_INVALID_RECIPIENT: | |
1498 break; | |
1499 case NMEVT_UNDELIVERABLE_STATUS: | |
1500 _evt_undeliverable_status(user, event); | |
1501 break; | |
1502 case NMEVT_CONFERENCE_INVITE_NOTIFY: | |
1503 /* Someone else has been invited to join a | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1504 * conference that we are currently a part of |
8675 | 1505 */ |
1506 /* TODO: show the invite notify in chat window */ | |
1507 break; | |
1508 case NMEVT_CONFERENCE_INVITE: | |
1509 /* We have been invited to join a conference */ | |
1510 _evt_conference_invite(user, event); | |
1511 break; | |
1512 case NMEVT_CONFERENCE_JOINED: | |
1513 /* Some one has joined a conference that we | |
1514 * are a part of | |
1515 */ | |
1516 _evt_conference_joined(user, event); | |
1517 break; | |
1518 case NMEVT_CONFERENCE_LEFT: | |
1519 /* Someone else has left a conference that we | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1520 * are currently a part of |
8675 | 1521 */ |
1522 _evt_conference_left(user, event); | |
1523 break; | |
1524 default: | |
1525 gaim_debug(GAIM_DEBUG_INFO, "novell", | |
1526 "_event_callback(): unhandled event, %d\n", | |
1527 nm_event_get_type(event)); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1528 break; |
8675 | 1529 } |
1530 } | |
1531 | |
1532 /******************************************************************************* | |
1533 * Prpl Ops | |
1534 ******************************************************************************/ | |
1535 | |
1536 static void | |
1537 novell_login(GaimAccount * account) | |
1538 { | |
1539 GaimConnection *gc; | |
1540 NMUser *user = NULL; | |
1541 const char *server; | |
1542 const char *name; | |
1543 int port; | |
1544 | |
1545 if (account == NULL) | |
1546 return; | |
1547 | |
1548 gc = gaim_account_get_connection(account); | |
1549 if (gc == NULL) | |
1550 return; | |
1551 | |
1552 server = gaim_account_get_string(account, "server", NULL); | |
1553 if (server == NULL || *server == '\0') { | |
1554 | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1555 /* TODO: Would be nice to prompt if not set! |
8675 | 1556 * gaim_request_fields(gc, _("Server Address"),...); |
1557 */ | |
1558 | |
1559 /* ...but for now just error out with a nice message. */ | |
1560 gaim_connection_error(gc, _("Unable to connect to server." | |
1561 " Please enter the address of the server" | |
1562 " you wish to connect to.")); | |
1563 return; | |
1564 } | |
1565 | |
1566 port = gaim_account_get_int(account, "port", DEFAULT_PORT); | |
1567 name = gaim_account_get_username(account); | |
1568 | |
1569 user = nm_initialize_user(name, server, port, account, _event_callback); | |
1570 if (user) { | |
1571 /* save user */ | |
1572 gc->proto_data = user; | |
1573 | |
1574 /* connect to the server */ | |
1575 gaim_connection_update_progress(gc, _("Connecting"), | |
1576 1, NOVELL_CONNECT_STEPS); | |
1577 | |
1578 user->conn->use_ssl = TRUE; | |
1579 if (gaim_ssl_connect(user->client_data, user->conn->addr, | |
1580 user->conn->port, novell_ssl_connected_cb, | |
1581 novell_ssl_connect_error, gc) == NULL) { | |
1582 gaim_connection_error(gc, _("Error." | |
1583 " SSL support is not installed.")); | |
1584 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1585 } |
8675 | 1586 } |
1587 | |
1588 static void | |
1589 novell_close(GaimConnection * gc) | |
1590 { | |
1591 NMUser *user; | |
1592 NMConn *conn; | |
1593 | |
1594 if (gc == NULL) | |
1595 return; | |
1596 | |
1597 user = gc->proto_data; | |
1598 if (user) { | |
1599 conn = user->conn; | |
1600 if (conn) { | |
1601 if (conn->use_ssl && user->conn->ssl_conn) { | |
1602 gaim_ssl_close(user->conn->ssl_conn->data); | |
1603 } else { | |
1604 gaim_input_remove(gc->inpa); | |
1605 close(conn->fd); | |
1606 } | |
1607 } | |
1608 nm_deinitialize_user(user); | |
1609 } | |
1610 gc->proto_data = NULL; | |
1611 } | |
1612 | |
1613 static int | |
1614 novell_send_im(GaimConnection * gc, const char *name, | |
1615 const char *message_body, GaimConvImFlags flags) | |
1616 { | |
1617 NMUserRecord *user_record = NULL; | |
1618 NMConference *conf = NULL; | |
1619 NMMessage *message; | |
1620 NMUser *user; | |
1621 const char *dn = NULL; | |
1622 gboolean done = TRUE, created_conf = FALSE; | |
1623 NMERR_T rc = NM_OK; | |
1624 | |
1625 if (gc == NULL || name == NULL || | |
1626 message_body == NULL || *message_body == '\0') | |
1627 return 0; | |
1628 | |
1629 user = gc->proto_data; | |
1630 if (user == NULL) | |
1631 return 0; | |
1632 | |
1633 /* Create a new message */ | |
1634 message = nm_create_message(gaim_markup_strip_html(message_body)); | |
1635 | |
1636 /* Need to get the DN for the buddy so we can look up the convo */ | |
1637 dn = nm_lookup_dn(user, name); | |
1638 | |
1639 /* Do we already know about the sender? */ | |
1640 user_record = nm_find_user_record(user, dn); | |
1641 if (user_record) { | |
1642 | |
1643 /* Do we already have an instantiated conference? */ | |
1644 conf = nm_find_conversation(user, dn); | |
1645 if (conf == NULL) { | |
1646 | |
1647 /* If not, create a blank conference */ | |
1648 conf = nm_create_conference(NULL); | |
1649 created_conf = TRUE; | |
1650 | |
1651 nm_conference_add_participant(conf, user_record); | |
1652 } | |
1653 | |
1654 nm_message_set_conference(message, conf); | |
1655 | |
1656 /* Make sure conference is instatiated */ | |
1657 if (!nm_conference_is_instantiated(conf)) { | |
1658 | |
1659 /* It is not, so send the createconf. We will | |
1660 * have to finish sending the message when we | |
1661 * get the response with the new conference guid. | |
1662 */ | |
1663 rc = nm_send_create_conference(user, conf, | |
1664 _createconf_resp_send_msg, message); | |
1665 _check_for_disconnect(user, rc); | |
1666 | |
1667 done = FALSE; | |
1668 } | |
1669 | |
1670 } else { | |
1671 | |
1672 /* If we don't have details for the user, then we don't have | |
1673 * a conference yet. So create one and send the getdetails | |
1674 * to the server. We will have to finish sending the message | |
1675 * when we get the response from the server. | |
1676 */ | |
1677 conf = nm_create_conference(NULL); | |
1678 created_conf = TRUE; | |
1679 | |
1680 nm_message_set_conference(message, conf); | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1681 |
8675 | 1682 rc = nm_send_get_details(user, name, _get_details_resp_send_msg, message); |
1683 _check_for_disconnect(user, rc); | |
1684 | |
1685 done = FALSE; | |
1686 } | |
1687 | |
1688 if (done) { | |
1689 | |
1690 /* Did we find everything we needed? */ | |
1691 rc = nm_send_message(user, message, _send_message_resp_cb); | |
1692 _check_for_disconnect(user, rc); | |
1693 | |
1694 nm_release_message(message); | |
1695 } | |
1696 | |
1697 if (created_conf && conf) | |
1698 nm_release_conference(conf); | |
1699 | |
1700 return 1; | |
1701 } | |
1702 | |
1703 static int | |
1704 novell_send_typing(GaimConnection * gc, const char *name, int typing) | |
1705 { | |
1706 NMConference *conf = NULL; | |
1707 NMUser *user; | |
1708 const char *dn = NULL; | |
1709 NMERR_T rc = NM_OK; | |
1710 | |
1711 if (gc == NULL || name == NULL) | |
1712 return -1; | |
1713 | |
1714 user = gc->proto_data; | |
1715 if (user == NULL) | |
1716 return -1; | |
1717 | |
1718 /* Need to get the DN for the buddy so we can look up the convo */ | |
1719 dn = nm_lookup_dn(user, name); | |
1720 if (dn) { | |
1721 | |
1722 /* Now find the conference in our list */ | |
1723 conf = nm_find_conversation(user, dn); | |
1724 if (conf) { | |
1725 | |
1726 rc = nm_send_typing(user, conf, | |
1727 ((typing == GAIM_TYPING) ? TRUE : FALSE), NULL); | |
1728 _check_for_disconnect(user, rc); | |
1729 | |
1730 } | |
1731 | |
1732 } | |
1733 | |
1734 return 0; | |
1735 } | |
1736 | |
1737 static void | |
1738 novell_convo_closed(GaimConnection * gc, const char *who) | |
1739 { | |
1740 NMUser *user; | |
1741 NMConference *conf; | |
1742 const char *dn; | |
1743 NMERR_T rc = NM_OK; | |
1744 | |
1745 if (gc == NULL || who == NULL) | |
1746 return; | |
1747 | |
1748 user = gc->proto_data; | |
1749 if (user && (dn = nm_lookup_dn(user, who))) { | |
1750 conf = nm_find_conversation(user, dn); | |
1751 if (conf) { | |
1752 rc = nm_send_leave_conference(user, conf, NULL, NULL); | |
1753 _check_for_disconnect(user, rc); | |
1754 } | |
1755 } | |
1756 } | |
1757 | |
1758 static void | |
1759 novell_chat_leave(GaimConnection * gc, int id) | |
1760 { | |
1761 NMConference *conference; | |
1762 NMUser *user; | |
1763 GaimConversation *chat; | |
1764 GSList *cnode; | |
1765 NMERR_T rc = NM_OK; | |
1766 | |
1767 if (gc == NULL) | |
1768 return; | |
1769 | |
1770 user = gc->proto_data; | |
1771 if (user == NULL) | |
1772 return; | |
1773 | |
1774 for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) { | |
1775 conference = cnode->data; | |
1776 if (conference && (chat = nm_conference_get_data(conference))) { | |
1777 if (gaim_conv_chat_get_id(GAIM_CONV_CHAT(chat)) == id) { | |
1778 rc = nm_send_leave_conference(user, conference, NULL, NULL); | |
1779 _check_for_disconnect(user, rc); | |
1780 break; | |
1781 } | |
1782 } | |
1783 } | |
1784 | |
1785 serv_got_chat_left(gc, id); | |
1786 } | |
1787 | |
1788 static int | |
1789 novell_chat_send(GaimConnection * gc, int id, const char *text) | |
1790 { | |
1791 NMConference *conference; | |
1792 GaimConversation *chat; | |
1793 GSList *cnode; | |
1794 NMMessage *message; | |
1795 NMUser *user; | |
1796 NMERR_T rc = NM_OK; | |
1797 const char *name; | |
1798 char *str; | |
1799 | |
1800 if (gc == NULL || text == NULL) | |
1801 return -1; | |
1802 | |
1803 user = gc->proto_data; | |
1804 if (user == NULL) | |
1805 return -1; | |
1806 | |
1807 message = nm_create_message(gaim_markup_strip_html(text)); | |
1808 | |
1809 for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) { | |
1810 conference = cnode->data; | |
1811 if (conference && (chat = nm_conference_get_data(conference))) { | |
1812 if (gaim_conv_chat_get_id(GAIM_CONV_CHAT(chat)) == id) { | |
1813 | |
1814 nm_message_set_conference(message, conference); | |
1815 | |
1816 rc = nm_send_message(user, message, _send_message_resp_cb); | |
1817 nm_release_message(message); | |
1818 | |
1819 if (!_check_for_disconnect(user, rc)) { | |
1820 | |
1821 /* Use the account alias if it is set */ | |
1822 name = gaim_account_get_alias(user->client_data); | |
1823 if (name == NULL || *name == '\0') { | |
1824 | |
1825 /* If there is no account alias, try full name */ | |
1826 name = nm_user_record_get_full_name(user->user_record); | |
1827 if (name == NULL || *name == '\0') { | |
1828 | |
1829 /* Fall back to the username that we are signed in with */ | |
1830 name = gaim_account_get_username(user->client_data); | |
1831 } | |
1832 } | |
1833 | |
1834 serv_got_chat_in(gc, id, name, 0, text, time(NULL)); | |
1835 return 0; | |
1836 } else | |
1837 return -1; | |
1838 | |
1839 } | |
1840 } | |
1841 } | |
1842 | |
1843 /* The conference was not found, must be closed */ | |
1844 chat = gaim_find_chat(gc, id); | |
1845 if (chat) { | |
1846 str = g_strdup_printf(_("This conference has been closed." | |
1847 " No more messages can be sent.")); | |
1848 gaim_conversation_write(chat, NULL, str, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
1849 g_free(str); | |
1850 } | |
1851 | |
8744 | 1852 if (message) |
1853 nm_release_message(message); | |
1854 | |
8675 | 1855 return -1; |
1856 } | |
1857 | |
1858 static void | |
1859 novell_add_buddy(GaimConnection * gc, const char *name, GaimGroup * group) | |
1860 { | |
1861 GaimBuddy *buddy; | |
1862 NMFolder *folder = NULL; | |
1863 NMContact *contact; | |
1864 NMUser *user; | |
1865 NMERR_T rc = NM_OK; | |
1866 | |
1867 if (gc == NULL || name == NULL || group == NULL) | |
1868 return; | |
1869 | |
1870 user = (NMUser *) gc->proto_data; | |
1871 if (user == NULL) | |
1872 return; | |
1873 | |
1874 contact = nm_create_contact(); | |
1875 nm_contact_set_dn(contact, name); | |
1876 | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1877 /* Remove the GaimBuddy (we will add it back after adding it |
8675 | 1878 * to the server side list). Save the alias if there is one. |
1879 */ | |
1880 buddy = gaim_find_buddy_in_group(user->client_data, name, group); | |
1881 if (buddy) { | |
1882 const char *alias = gaim_get_buddy_alias(buddy); | |
1883 | |
1884 if (alias && strcmp(alias, name)) | |
1885 nm_contact_set_display_name(contact, gaim_get_buddy_alias(buddy)); | |
1886 gaim_blist_remove_buddy(buddy); | |
1887 buddy = NULL; | |
1888 } | |
1889 | |
1890 | |
1891 folder = nm_find_folder(user, group->name); | |
1892 if (folder) { | |
1893 | |
1894 /* We have everything that we need, so send the createcontact */ | |
1895 rc = nm_send_create_contact(user, folder, contact, | |
1896 _create_contact_resp_cb, contact); | |
1897 | |
1898 } else { | |
1899 | |
1900 /* Need to create the folder before we can add the contact */ | |
1901 rc = nm_send_create_folder(user, group->name, | |
1902 _create_folder_resp_add_contact, contact); | |
1903 } | |
1904 | |
1905 _check_for_disconnect(user, rc); | |
1906 | |
1907 } | |
1908 | |
1909 static void | |
1910 novell_remove_buddy(GaimConnection * gc, const char *name, const char *group_name) | |
1911 { | |
1912 NMContact *contact; | |
1913 NMFolder *folder; | |
1914 NMUser *user; | |
1915 const char *dn; | |
1916 NMERR_T rc = NM_OK; | |
1917 | |
1918 if (gc == NULL || name == NULL || group_name == NULL) | |
1919 return; | |
1920 | |
1921 user = (NMUser *) gc->proto_data; | |
1922 if (user && (dn = nm_lookup_dn(user, name))) { | |
1923 | |
1924 folder = nm_find_folder(user, group_name); | |
1925 if (folder) { | |
1926 contact = nm_folder_find_contact(folder, dn); | |
1927 if (contact) { | |
1928 | |
1929 /* Remove the buddy from the contact */ | |
1930 nm_contact_set_data(contact, NULL); | |
1931 | |
1932 /* Tell the server to remove the contact */ | |
1933 rc = nm_send_remove_contact(user, folder, contact, | |
1934 _remove_contact_resp_cb, NULL); | |
1935 _check_for_disconnect(user, rc); | |
1936 } | |
1937 } | |
1938 } | |
1939 } | |
1940 | |
1941 static void | |
1942 novell_remove_group(GaimConnection * gc, const char *name) | |
1943 { | |
1944 NMUser *user; | |
1945 NMERR_T rc = NM_OK; | |
1946 | |
1947 if (gc == NULL || name == NULL) | |
1948 return; | |
1949 | |
1950 user = (NMUser *) gc->proto_data; | |
1951 if (user) { | |
1952 NMFolder *folder = nm_find_folder(user, name); | |
1953 | |
1954 if (folder) { | |
1955 rc = nm_send_remove_folder(user, folder, | |
1956 _remove_folder_resp_cb, NULL); | |
1957 _check_for_disconnect(user, rc); | |
1958 } | |
1959 } | |
1960 } | |
1961 | |
1962 static void | |
1963 novell_alias_buddy(GaimConnection * gc, const char *name, const char *alias) | |
1964 { | |
1965 NMContact *contact; | |
1966 NMUser *user; | |
1967 GList *contacts = NULL; | |
1968 GList *cnode = NULL; | |
1969 const char *dn = NULL; | |
1970 NMERR_T rc = NM_OK; | |
1971 | |
1972 if (gc == NULL || name == NULL || alias == NULL) | |
1973 return; | |
1974 | |
1975 user = (NMUser *) gc->proto_data; | |
1976 if (user && (dn = nm_lookup_dn(user, name))) { | |
1977 | |
1978 /* Alias all of instances of the contact */ | |
1979 contacts = nm_find_contacts(user, dn); | |
1980 for (cnode = contacts; cnode != NULL; cnode = cnode->next) { | |
1981 contact = (NMContact *) cnode->data; | |
1982 if (contact) { | |
1983 GaimGroup *group; | |
1984 GaimBuddy *buddy; | |
1985 NMFolder *folder; | |
1986 | |
1987 /* Alias the Gaim buddy? */ | |
1988 folder = nm_find_folder_by_id(user, | |
1989 nm_contact_get_parent_id(contact)); | |
1990 if (folder && | |
1991 (group = gaim_find_group(nm_folder_get_name(folder)))) { | |
1992 buddy = gaim_find_buddy_in_group(user->client_data, | |
1993 name, group); | |
1994 if (buddy && strcmp(buddy->alias, alias)) | |
1995 gaim_blist_alias_buddy(buddy, alias); | |
1996 | |
1997 } | |
1998 /* Tell the server to alias the contact */ | |
1999 rc = nm_send_rename_contact(user, contact, alias, | |
2000 _rename_contact_resp_cb, NULL); | |
2001 _check_for_disconnect(user, rc); | |
2002 } | |
2003 } | |
2004 if (contacts) | |
2005 g_list_free(contacts); | |
2006 } | |
2007 } | |
2008 | |
2009 static void | |
2010 novell_group_buddy(GaimConnection * gc, | |
2011 const char *name, const char *old_group_name, | |
2012 const char *new_group_name) | |
2013 { | |
2014 NMFolder *old_folder; | |
2015 NMFolder *new_folder; | |
2016 NMContact *contact; | |
2017 NMUser *user; | |
2018 const char *dn; | |
2019 NMERR_T rc = NM_OK; | |
2020 | |
2021 if (gc == NULL || name == NULL || | |
2022 old_group_name == NULL || new_group_name == NULL) | |
2023 return; | |
2024 | |
2025 user = (NMUser *) gc->proto_data; | |
2026 if (user && (dn = nm_lookup_dn(user, name))) { | |
2027 | |
2028 /* Find the old folder */ | |
2029 old_folder = nm_find_folder(user, old_group_name); | |
2030 if (old_folder && (contact = nm_folder_find_contact(old_folder, dn))) { | |
2031 | |
2032 /* Find the new folder */ | |
2033 new_folder = nm_find_folder(user, new_group_name); | |
2034 if (new_folder) { | |
2035 | |
2036 /* Tell the server to move the contact to the new folder */ | |
2037 rc = nm_send_move_contact(user, contact, new_folder, | |
2038 _move_contact_resp_cb, NULL); | |
2039 | |
2040 } else { | |
2041 | |
2042 nm_contact_add_ref(contact); | |
2043 | |
2044 /* Remove the old contact first */ | |
2045 nm_send_remove_contact(user, old_folder, contact, | |
2046 _remove_contact_resp_cb, NULL); | |
2047 | |
2048 /* New folder does not exist yet, so create it */ | |
2049 rc = nm_send_create_folder(user, new_group_name, | |
2050 _create_folder_resp_move_contact, | |
2051 contact); | |
2052 } | |
2053 | |
2054 _check_for_disconnect(user, rc); | |
2055 } | |
2056 } | |
2057 } | |
2058 | |
2059 static void | |
2060 novell_rename_group(GaimConnection * gc, const char *old_name, | |
2061 const char *new_name, GList * tobemoved) | |
2062 { | |
2063 NMERR_T rc = NM_OK; | |
2064 NMUser *user; | |
2065 | |
2066 if (gc == NULL || old_name == NULL || new_name == NULL || tobemoved == NULL) { | |
2067 return; | |
2068 } | |
2069 | |
2070 user = gc->proto_data; | |
2071 if (user) { | |
2072 /* Does new folder exist already? */ | |
2073 if (nm_find_folder(user, new_name)) { | |
2074 /* Gaim currently calls novell_group_buddy() for | |
2075 * for all buddies in the group, so we don't | |
2076 * need to worry about this situation. | |
2077 */ | |
2078 return; | |
2079 } | |
2080 | |
2081 NMFolder *folder = nm_find_folder(user, old_name); | |
2082 | |
2083 if (folder) { | |
2084 rc = nm_send_rename_folder(user, folder, new_name, | |
2085 _rename_folder_resp_cb, NULL); | |
2086 _check_for_disconnect(user, rc); | |
2087 } | |
2088 } | |
2089 } | |
2090 | |
2091 static void | |
2092 novell_list_emblems(GaimBuddy * buddy, char **se, char **sw, char **nw, char **ne) | |
2093 { | |
2094 int status = buddy->uc >> 1; | |
2095 | |
2096 switch (status) { | |
2097 case NM_STATUS_AVAILABLE: | |
2098 *se = ""; | |
2099 break; | |
2100 case NM_STATUS_AWAY: | |
2101 *se = "away"; | |
2102 break; | |
2103 case NM_STATUS_BUSY: | |
2104 *se = "occupied"; | |
2105 break; | |
2106 case NM_STATUS_UNKNOWN: | |
2107 *se = "error"; | |
2108 break; | |
2109 } | |
2110 } | |
2111 | |
2112 static const char * | |
2113 novell_list_icon(GaimAccount * account, GaimBuddy * buddy) | |
2114 { | |
2115 return "novell"; | |
2116 } | |
2117 | |
2118 static char * | |
2119 novell_tooltip_text(GaimBuddy * buddy) | |
2120 { | |
2121 NMUserRecord *user_record = NULL; | |
2122 GaimConnection *gc; | |
2123 NMUser *user; | |
2124 int status = 0; | |
2125 char *ret_text = NULL; | |
2126 const char *status_str = NULL; | |
2127 const char *text = NULL; | |
2128 | |
2129 if (buddy == NULL) | |
2130 return ""; | |
2131 | |
2132 gc = gaim_account_get_connection(buddy->account); | |
2133 if (gc == NULL || (user = gc->proto_data) == NULL) | |
2134 return ""; | |
2135 | |
2136 if (GAIM_BUDDY_IS_ONLINE(buddy)) { | |
2137 user_record = nm_find_user_record(user, buddy->name); | |
2138 if (user_record) { | |
2139 status = nm_user_record_get_status(user_record); | |
2140 text = nm_user_record_get_status_text(user_record); | |
2141 /* No custom text, so default it ... */ | |
2142 switch (status) { | |
2143 case NM_STATUS_AVAILABLE: | |
2144 status_str = _("Available"); | |
2145 break; | |
2146 case NM_STATUS_AWAY: | |
2147 status_str = _("Away"); | |
2148 break; | |
2149 case NM_STATUS_BUSY: | |
2150 status_str = _("Busy"); | |
2151 break; | |
2152 case NM_STATUS_AWAY_IDLE: | |
2153 status_str = _("Idle"); | |
2154 break; | |
2155 case NM_STATUS_OFFLINE: | |
2156 status_str = _("Offline"); | |
2157 break; | |
2158 default: | |
2159 status_str = _("Unknown"); | |
2160 break; | |
2161 } | |
2162 | |
2163 if (text) | |
8746 | 2164 ret_text = g_strdup_printf(_("<b>Status:</b> %s\n" |
8675 | 2165 "<b>Message:</b> %s"), |
2166 status_str, text); | |
2167 else | |
8746 | 2168 ret_text = g_strdup_printf(_("<b>Status:</b> %s"), status_str); |
8675 | 2169 } |
2170 } | |
2171 | |
2172 return ret_text; | |
2173 } | |
2174 | |
2175 static void | |
2176 novell_set_idle(GaimConnection * gc, int time) | |
2177 { | |
2178 NMUser *user; | |
2179 NMERR_T rc = NM_OK; | |
2180 | |
2181 if (gc == NULL) | |
2182 return; | |
2183 | |
2184 user = gc->proto_data; | |
2185 if (user == NULL) | |
2186 return; | |
2187 | |
2188 if (time > 0) | |
2189 rc = nm_send_set_status(user, NM_STATUS_AWAY_IDLE, NULL, NULL, NULL, | |
2190 NULL); | |
2191 else | |
2192 rc = nm_send_set_status(user, NM_STATUS_AVAILABLE, NULL, NULL, NULL, | |
2193 NULL); | |
2194 | |
2195 _check_for_disconnect(user, rc); | |
2196 } | |
2197 | |
2198 static void | |
2199 novell_get_info(GaimConnection * gc, const char *name) | |
2200 { | |
2201 NMUserRecord *user_record; | |
2202 NMUser *user; | |
2203 NMERR_T rc; | |
2204 | |
2205 if (gc == NULL || name == NULL) | |
2206 return; | |
2207 | |
2208 user = (NMUser *) gc->proto_data; | |
2209 if (user) { | |
2210 | |
2211 user_record = nm_find_user_record(user, name); | |
2212 if (user_record) { | |
2213 | |
2214 _show_info(gc, user_record); | |
2215 | |
2216 } else { | |
2217 | |
2218 rc = nm_send_get_details(user, name, | |
2219 _get_details_resp_show_info, g_strdup(name)); | |
2220 | |
2221 _check_for_disconnect(user, rc); | |
2222 | |
2223 } | |
2224 | |
2225 } | |
2226 } | |
2227 | |
2228 static char * | |
2229 novell_status_text(GaimBuddy * buddy) | |
2230 { | |
2231 const char *text = NULL; | |
2232 const char *dn = NULL; | |
2233 | |
2234 if (buddy && buddy->account) { | |
2235 GaimConnection *gc = gaim_account_get_connection(buddy->account); | |
2236 | |
2237 if (gc && gc->proto_data) { | |
2238 NMUser *user = gc->proto_data; | |
2239 | |
2240 dn = nm_lookup_dn(user, buddy->name); | |
2241 if (dn) { | |
2242 NMUserRecord *user_record = nm_find_user_record(user, dn); | |
2243 | |
2244 if (user_record) { | |
2245 text = nm_user_record_get_status_text(user_record); | |
2246 if (text) | |
2247 return g_strdup(text); | |
2248 } | |
2249 } | |
2250 } | |
2251 } | |
2252 | |
2253 return NULL; | |
2254 } | |
2255 | |
2256 static GList * | |
2257 novell_away_states(GaimConnection * gc) | |
2258 { | |
2259 GList *m = NULL; | |
2260 | |
2261 m = g_list_append(m, _("Available")); | |
2262 m = g_list_append(m, _("Away")); | |
2263 m = g_list_append(m, _("Busy")); | |
2264 m = g_list_append(m, _("Appear Offline")); | |
2265 m = g_list_append(m, GAIM_AWAY_CUSTOM); | |
2266 | |
2267 return m; | |
2268 } | |
2269 | |
2270 static void | |
2271 novell_set_away(GaimConnection * gc, const char *state, const char *msg) | |
2272 { | |
2273 NMUser *user; | |
2274 NMSTATUS_T status = NM_STATUS_AVAILABLE; | |
2275 NMERR_T rc = NM_OK; | |
2276 char *text = NULL; | |
2277 char *tmp = NULL; | |
2278 char *p = NULL; | |
2279 | |
2280 if (gc == NULL) | |
2281 return; | |
2282 | |
2283 user = gc->proto_data; | |
2284 if (user == NULL) | |
2285 return; | |
2286 | |
2287 if (gc->away) { | |
2288 g_free(gc->away); | |
2289 gc->away = NULL; | |
2290 } | |
2291 | |
2292 if (msg != NULL) { | |
2293 status = NM_STATUS_AWAY; | |
2294 gc->away = g_strdup(""); | |
2295 | |
2296 /* Don't want newlines in status text */ | |
2297 tmp = g_strdup(msg); | |
2298 if ((p = strchr(tmp, '\n'))) { | |
2299 *p = '\0'; | |
2300 } | |
2301 | |
2302 /* Truncate the status text if necessary */ | |
2303 text = g_strdup(tmp); | |
2304 if (g_utf8_strlen(tmp, -1) > 60) { | |
2305 g_utf8_strncpy(text, tmp, 60); | |
2306 strcat(text, "..."); | |
2307 } | |
2308 | |
2309 g_free(tmp); | |
2310 | |
2311 } else if (state) { | |
2312 if (!strcmp(state, _("Available"))) { | |
2313 status = NM_STATUS_AVAILABLE; | |
2314 } else if (!strcmp(state, _("Away"))) { | |
2315 status = NM_STATUS_AWAY; | |
2316 gc->away = g_strdup(""); | |
2317 } else if (!strcmp(state, _("Busy"))) { | |
2318 status = NM_STATUS_BUSY; | |
2319 gc->away = g_strdup(""); | |
2320 } else if (!strcmp(state, _("Appear Offline"))) { | |
2321 status = NM_STATUS_OFFLINE; | |
2322 gc->away = g_strdup(""); | |
2323 } else { | |
2324 status = NM_STATUS_AVAILABLE; | |
2325 g_free(gc->away); | |
2326 gc->away = NULL; | |
2327 } | |
2328 } else if (gc->is_idle) { | |
2329 status = NM_STATUS_AWAY_IDLE; | |
2330 } else { | |
2331 status = NM_STATUS_AVAILABLE; | |
2332 } | |
2333 | |
2334 rc = nm_send_set_status(user, status, text, msg, NULL, NULL); | |
2335 _check_for_disconnect(user, rc); | |
2336 | |
2337 if (text) | |
2338 g_free(text); | |
2339 } | |
2340 | |
2341 static GaimPluginProtocolInfo prpl_info = { | |
2342 0, | |
2343 NULL, | |
2344 NULL, | |
2345 novell_list_icon, | |
2346 novell_list_emblems, | |
2347 novell_status_text, | |
2348 novell_tooltip_text, | |
2349 novell_away_states, | |
2350 NULL, /* prpl_actions */ | |
2351 NULL, /* buddy_menu */ | |
2352 NULL, /* chat_info */ | |
2353 novell_login, | |
2354 novell_close, | |
2355 novell_send_im, | |
2356 NULL, /* set_info */ | |
2357 novell_send_typing, | |
2358 novell_get_info, | |
2359 novell_set_away, | |
2360 NULL, /* set_dir */ | |
2361 NULL, /* get_dir */ | |
2362 NULL, /* dir_search */ | |
2363 novell_set_idle, | |
2364 NULL, /* change pwd */ | |
2365 novell_add_buddy, | |
2366 NULL, /* add_buddies */ | |
2367 novell_remove_buddy, | |
2368 NULL, /* remove_buddies */ | |
2369 NULL, /* add_permit */ | |
2370 NULL, /* add_deny */ | |
2371 NULL, /* rem_permit */ | |
2372 NULL, /* rem_deny */ | |
2373 NULL, /* set_permit_deny */ | |
2374 NULL, /* warn */ | |
2375 NULL, /* join_chat */ | |
2376 NULL, /* reject_chat ?? */ | |
2377 NULL, /* chat_invite */ | |
2378 novell_chat_leave, | |
2379 NULL, /* chat_whisper */ | |
2380 novell_chat_send, | |
2381 NULL, /* keepalive */ | |
2382 NULL, /* register_user */ | |
2383 NULL, /* get_cb_info */ | |
2384 NULL, /* get_cb_away_msg */ | |
2385 novell_alias_buddy, | |
2386 novell_group_buddy, | |
2387 novell_rename_group, | |
2388 NULL, /* buddy_free */ | |
2389 novell_convo_closed, | |
2390 NULL, /* normalize */ | |
2391 NULL, /* set_buddy_icon */ | |
2392 novell_remove_group, | |
2393 NULL | |
2394 }; | |
2395 | |
2396 static GaimPluginInfo info = { | |
2397 2, /**< api_version */ | |
2398 GAIM_PLUGIN_PROTOCOL, /**< type */ | |
2399 NULL, /**< ui_requirement */ | |
2400 0, /**< flags */ | |
2401 NULL, /**< dependencies */ | |
2402 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
2403 | |
2404 "prpl-novell", /**< id */ | |
8676 | 2405 "GroupWise", /**< name */ |
8675 | 2406 VERSION, /**< version */ |
2407 /** summary */ | |
2408 N_("Novell GroupWise Messenger Protocol Plugin"), | |
2409 /** description */ | |
2410 N_("Novell GroupWise Messenger Protocol Plugin"), | |
2411 NULL, /**< author */ | |
2412 GAIM_WEBSITE, /**< homepage */ | |
2413 | |
2414 NULL, /**< load */ | |
2415 NULL, /**< unload */ | |
2416 NULL, /**< destroy */ | |
2417 | |
2418 NULL, /**< ui_info */ | |
2419 &prpl_info /**< extra_info */ | |
2420 }; | |
2421 | |
2422 static void | |
2423 init_plugin(GaimPlugin * plugin) | |
2424 { | |
2425 GaimAccountOption *option; | |
2426 | |
2427 option = gaim_account_option_string_new(_("Server address"), "server", NULL); | |
2428 prpl_info.protocol_options = | |
2429 g_list_append(prpl_info.protocol_options, option); | |
2430 | |
2431 option = gaim_account_option_int_new(_("Server port"), "port", DEFAULT_PORT); | |
2432 prpl_info.protocol_options = | |
2433 g_list_append(prpl_info.protocol_options, option); | |
2434 | |
2435 my_protocol = plugin; | |
2436 } | |
2437 | |
2438 GAIM_INIT_PLUGIN(novell, init_plugin, info); |