Mercurial > pidgin
annotate src/protocols/novell/novell.c @ 8713:7024b595b6ae
[gaim-migrate @ 9467]
" Expansion from my original protocol prefs to plugin prefs.
Things are handled a bit different in this iteration of
it, but I have already modified msn and jabber to use
it, and included an example plugin to show how to use
it. It will also generate pages with doxygen. The
example plugin doesn't not contain any translatable
strings seeing as we're in the string freeze. And it's
an example, whats the point of translating it..?
Also, I tweaked the documentation for 2 functions in
gtkprefs, gaim_gtk_prefs_dropdown and
gaim_gtk_prefs_dropdown_from_list. Nothing major in
that, just made it say that the list should be a list
of pairs label/value.
Also there's 5 new files that will need to be added to cvs:
src/pluginpref.h
src/pluginpref.c
src/gtkpluginpref.h
src/gtkpluginpref.c
plugins/pluginpref_example.c
the tarball already has them structured correctly and
contains the diff" --Gary Kramlich - amc_grim
and the german translator pointed out that sean missed the novell file for POTFILES.in
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Mon, 19 Apr 2004 21:12:45 +0000 |
parents | 046dd8ef2920 |
children | ee04a6089cbf |
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 | |
1016 gaim_notify_formatted(NULL, "Title", _("User Properties"), | |
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 | |
1852 return -1; | |
1853 } | |
1854 | |
1855 static void | |
1856 novell_add_buddy(GaimConnection * gc, const char *name, GaimGroup * group) | |
1857 { | |
1858 GaimBuddy *buddy; | |
1859 NMFolder *folder = NULL; | |
1860 NMContact *contact; | |
1861 NMUser *user; | |
1862 NMERR_T rc = NM_OK; | |
1863 | |
1864 if (gc == NULL || name == NULL || group == NULL) | |
1865 return; | |
1866 | |
1867 user = (NMUser *) gc->proto_data; | |
1868 if (user == NULL) | |
1869 return; | |
1870 | |
1871 contact = nm_create_contact(); | |
1872 nm_contact_set_dn(contact, name); | |
1873 | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8676
diff
changeset
|
1874 /* Remove the GaimBuddy (we will add it back after adding it |
8675 | 1875 * to the server side list). Save the alias if there is one. |
1876 */ | |
1877 buddy = gaim_find_buddy_in_group(user->client_data, name, group); | |
1878 if (buddy) { | |
1879 const char *alias = gaim_get_buddy_alias(buddy); | |
1880 | |
1881 if (alias && strcmp(alias, name)) | |
1882 nm_contact_set_display_name(contact, gaim_get_buddy_alias(buddy)); | |
1883 gaim_blist_remove_buddy(buddy); | |
1884 buddy = NULL; | |
1885 } | |
1886 | |
1887 | |
1888 folder = nm_find_folder(user, group->name); | |
1889 if (folder) { | |
1890 | |
1891 /* We have everything that we need, so send the createcontact */ | |
1892 rc = nm_send_create_contact(user, folder, contact, | |
1893 _create_contact_resp_cb, contact); | |
1894 | |
1895 } else { | |
1896 | |
1897 /* Need to create the folder before we can add the contact */ | |
1898 rc = nm_send_create_folder(user, group->name, | |
1899 _create_folder_resp_add_contact, contact); | |
1900 } | |
1901 | |
1902 _check_for_disconnect(user, rc); | |
1903 | |
1904 } | |
1905 | |
1906 static void | |
1907 novell_remove_buddy(GaimConnection * gc, const char *name, const char *group_name) | |
1908 { | |
1909 NMContact *contact; | |
1910 NMFolder *folder; | |
1911 NMUser *user; | |
1912 const char *dn; | |
1913 NMERR_T rc = NM_OK; | |
1914 | |
1915 if (gc == NULL || name == NULL || group_name == NULL) | |
1916 return; | |
1917 | |
1918 user = (NMUser *) gc->proto_data; | |
1919 if (user && (dn = nm_lookup_dn(user, name))) { | |
1920 | |
1921 folder = nm_find_folder(user, group_name); | |
1922 if (folder) { | |
1923 contact = nm_folder_find_contact(folder, dn); | |
1924 if (contact) { | |
1925 | |
1926 /* Remove the buddy from the contact */ | |
1927 nm_contact_set_data(contact, NULL); | |
1928 | |
1929 /* Tell the server to remove the contact */ | |
1930 rc = nm_send_remove_contact(user, folder, contact, | |
1931 _remove_contact_resp_cb, NULL); | |
1932 _check_for_disconnect(user, rc); | |
1933 } | |
1934 } | |
1935 } | |
1936 } | |
1937 | |
1938 static void | |
1939 novell_remove_group(GaimConnection * gc, const char *name) | |
1940 { | |
1941 NMUser *user; | |
1942 NMERR_T rc = NM_OK; | |
1943 | |
1944 if (gc == NULL || name == NULL) | |
1945 return; | |
1946 | |
1947 user = (NMUser *) gc->proto_data; | |
1948 if (user) { | |
1949 NMFolder *folder = nm_find_folder(user, name); | |
1950 | |
1951 if (folder) { | |
1952 rc = nm_send_remove_folder(user, folder, | |
1953 _remove_folder_resp_cb, NULL); | |
1954 _check_for_disconnect(user, rc); | |
1955 } | |
1956 } | |
1957 } | |
1958 | |
1959 static void | |
1960 novell_alias_buddy(GaimConnection * gc, const char *name, const char *alias) | |
1961 { | |
1962 NMContact *contact; | |
1963 NMUser *user; | |
1964 GList *contacts = NULL; | |
1965 GList *cnode = NULL; | |
1966 const char *dn = NULL; | |
1967 NMERR_T rc = NM_OK; | |
1968 | |
1969 if (gc == NULL || name == NULL || alias == NULL) | |
1970 return; | |
1971 | |
1972 user = (NMUser *) gc->proto_data; | |
1973 if (user && (dn = nm_lookup_dn(user, name))) { | |
1974 | |
1975 /* Alias all of instances of the contact */ | |
1976 contacts = nm_find_contacts(user, dn); | |
1977 for (cnode = contacts; cnode != NULL; cnode = cnode->next) { | |
1978 contact = (NMContact *) cnode->data; | |
1979 if (contact) { | |
1980 GaimGroup *group; | |
1981 GaimBuddy *buddy; | |
1982 NMFolder *folder; | |
1983 | |
1984 /* Alias the Gaim buddy? */ | |
1985 folder = nm_find_folder_by_id(user, | |
1986 nm_contact_get_parent_id(contact)); | |
1987 if (folder && | |
1988 (group = gaim_find_group(nm_folder_get_name(folder)))) { | |
1989 buddy = gaim_find_buddy_in_group(user->client_data, | |
1990 name, group); | |
1991 if (buddy && strcmp(buddy->alias, alias)) | |
1992 gaim_blist_alias_buddy(buddy, alias); | |
1993 | |
1994 } | |
1995 /* Tell the server to alias the contact */ | |
1996 rc = nm_send_rename_contact(user, contact, alias, | |
1997 _rename_contact_resp_cb, NULL); | |
1998 _check_for_disconnect(user, rc); | |
1999 } | |
2000 } | |
2001 if (contacts) | |
2002 g_list_free(contacts); | |
2003 } | |
2004 } | |
2005 | |
2006 static void | |
2007 novell_group_buddy(GaimConnection * gc, | |
2008 const char *name, const char *old_group_name, | |
2009 const char *new_group_name) | |
2010 { | |
2011 NMFolder *old_folder; | |
2012 NMFolder *new_folder; | |
2013 NMContact *contact; | |
2014 NMUser *user; | |
2015 const char *dn; | |
2016 NMERR_T rc = NM_OK; | |
2017 | |
2018 if (gc == NULL || name == NULL || | |
2019 old_group_name == NULL || new_group_name == NULL) | |
2020 return; | |
2021 | |
2022 user = (NMUser *) gc->proto_data; | |
2023 if (user && (dn = nm_lookup_dn(user, name))) { | |
2024 | |
2025 /* Find the old folder */ | |
2026 old_folder = nm_find_folder(user, old_group_name); | |
2027 if (old_folder && (contact = nm_folder_find_contact(old_folder, dn))) { | |
2028 | |
2029 /* Find the new folder */ | |
2030 new_folder = nm_find_folder(user, new_group_name); | |
2031 if (new_folder) { | |
2032 | |
2033 /* Tell the server to move the contact to the new folder */ | |
2034 rc = nm_send_move_contact(user, contact, new_folder, | |
2035 _move_contact_resp_cb, NULL); | |
2036 | |
2037 } else { | |
2038 | |
2039 nm_contact_add_ref(contact); | |
2040 | |
2041 /* Remove the old contact first */ | |
2042 nm_send_remove_contact(user, old_folder, contact, | |
2043 _remove_contact_resp_cb, NULL); | |
2044 | |
2045 /* New folder does not exist yet, so create it */ | |
2046 rc = nm_send_create_folder(user, new_group_name, | |
2047 _create_folder_resp_move_contact, | |
2048 contact); | |
2049 } | |
2050 | |
2051 _check_for_disconnect(user, rc); | |
2052 } | |
2053 } | |
2054 } | |
2055 | |
2056 static void | |
2057 novell_rename_group(GaimConnection * gc, const char *old_name, | |
2058 const char *new_name, GList * tobemoved) | |
2059 { | |
2060 NMERR_T rc = NM_OK; | |
2061 NMUser *user; | |
2062 | |
2063 if (gc == NULL || old_name == NULL || new_name == NULL || tobemoved == NULL) { | |
2064 return; | |
2065 } | |
2066 | |
2067 user = gc->proto_data; | |
2068 if (user) { | |
2069 /* Does new folder exist already? */ | |
2070 if (nm_find_folder(user, new_name)) { | |
2071 /* Gaim currently calls novell_group_buddy() for | |
2072 * for all buddies in the group, so we don't | |
2073 * need to worry about this situation. | |
2074 */ | |
2075 return; | |
2076 } | |
2077 | |
2078 NMFolder *folder = nm_find_folder(user, old_name); | |
2079 | |
2080 if (folder) { | |
2081 rc = nm_send_rename_folder(user, folder, new_name, | |
2082 _rename_folder_resp_cb, NULL); | |
2083 _check_for_disconnect(user, rc); | |
2084 } | |
2085 } | |
2086 } | |
2087 | |
2088 static void | |
2089 novell_list_emblems(GaimBuddy * buddy, char **se, char **sw, char **nw, char **ne) | |
2090 { | |
2091 int status = buddy->uc >> 1; | |
2092 | |
2093 switch (status) { | |
2094 case NM_STATUS_AVAILABLE: | |
2095 *se = ""; | |
2096 break; | |
2097 case NM_STATUS_AWAY: | |
2098 *se = "away"; | |
2099 break; | |
2100 case NM_STATUS_BUSY: | |
2101 *se = "occupied"; | |
2102 break; | |
2103 case NM_STATUS_UNKNOWN: | |
2104 *se = "error"; | |
2105 break; | |
2106 } | |
2107 } | |
2108 | |
2109 static const char * | |
2110 novell_list_icon(GaimAccount * account, GaimBuddy * buddy) | |
2111 { | |
2112 return "novell"; | |
2113 } | |
2114 | |
2115 static char * | |
2116 novell_tooltip_text(GaimBuddy * buddy) | |
2117 { | |
2118 NMUserRecord *user_record = NULL; | |
2119 GaimConnection *gc; | |
2120 NMUser *user; | |
2121 int status = 0; | |
2122 char *ret_text = NULL; | |
2123 const char *status_str = NULL; | |
2124 const char *text = NULL; | |
2125 | |
2126 if (buddy == NULL) | |
2127 return ""; | |
2128 | |
2129 gc = gaim_account_get_connection(buddy->account); | |
2130 if (gc == NULL || (user = gc->proto_data) == NULL) | |
2131 return ""; | |
2132 | |
2133 if (GAIM_BUDDY_IS_ONLINE(buddy)) { | |
2134 user_record = nm_find_user_record(user, buddy->name); | |
2135 if (user_record) { | |
2136 status = nm_user_record_get_status(user_record); | |
2137 text = nm_user_record_get_status_text(user_record); | |
2138 /* No custom text, so default it ... */ | |
2139 switch (status) { | |
2140 case NM_STATUS_AVAILABLE: | |
2141 status_str = _("Available"); | |
2142 break; | |
2143 case NM_STATUS_AWAY: | |
2144 status_str = _("Away"); | |
2145 break; | |
2146 case NM_STATUS_BUSY: | |
2147 status_str = _("Busy"); | |
2148 break; | |
2149 case NM_STATUS_AWAY_IDLE: | |
2150 status_str = _("Idle"); | |
2151 break; | |
2152 case NM_STATUS_OFFLINE: | |
2153 status_str = _("Offline"); | |
2154 break; | |
2155 default: | |
2156 status_str = _("Unknown"); | |
2157 break; | |
2158 } | |
2159 | |
2160 if (text) | |
2161 ret_text = g_strdup_printf(_("<b>Status:</b> %s\n" | |
2162 "<b>Message:</b> %s"), | |
2163 status_str, text); | |
2164 else | |
2165 ret_text = g_strdup_printf(_("<b>Status:</b> %s"), status_str); | |
2166 } | |
2167 } | |
2168 | |
2169 return ret_text; | |
2170 } | |
2171 | |
2172 static void | |
2173 novell_set_idle(GaimConnection * gc, int time) | |
2174 { | |
2175 NMUser *user; | |
2176 NMERR_T rc = NM_OK; | |
2177 | |
2178 if (gc == NULL) | |
2179 return; | |
2180 | |
2181 user = gc->proto_data; | |
2182 if (user == NULL) | |
2183 return; | |
2184 | |
2185 if (time > 0) | |
2186 rc = nm_send_set_status(user, NM_STATUS_AWAY_IDLE, NULL, NULL, NULL, | |
2187 NULL); | |
2188 else | |
2189 rc = nm_send_set_status(user, NM_STATUS_AVAILABLE, NULL, NULL, NULL, | |
2190 NULL); | |
2191 | |
2192 _check_for_disconnect(user, rc); | |
2193 } | |
2194 | |
2195 static void | |
2196 novell_get_info(GaimConnection * gc, const char *name) | |
2197 { | |
2198 NMUserRecord *user_record; | |
2199 NMUser *user; | |
2200 NMERR_T rc; | |
2201 | |
2202 if (gc == NULL || name == NULL) | |
2203 return; | |
2204 | |
2205 user = (NMUser *) gc->proto_data; | |
2206 if (user) { | |
2207 | |
2208 user_record = nm_find_user_record(user, name); | |
2209 if (user_record) { | |
2210 | |
2211 _show_info(gc, user_record); | |
2212 | |
2213 } else { | |
2214 | |
2215 rc = nm_send_get_details(user, name, | |
2216 _get_details_resp_show_info, g_strdup(name)); | |
2217 | |
2218 _check_for_disconnect(user, rc); | |
2219 | |
2220 } | |
2221 | |
2222 } | |
2223 } | |
2224 | |
2225 static char * | |
2226 novell_status_text(GaimBuddy * buddy) | |
2227 { | |
2228 const char *text = NULL; | |
2229 const char *dn = NULL; | |
2230 | |
2231 if (buddy && buddy->account) { | |
2232 GaimConnection *gc = gaim_account_get_connection(buddy->account); | |
2233 | |
2234 if (gc && gc->proto_data) { | |
2235 NMUser *user = gc->proto_data; | |
2236 | |
2237 dn = nm_lookup_dn(user, buddy->name); | |
2238 if (dn) { | |
2239 NMUserRecord *user_record = nm_find_user_record(user, dn); | |
2240 | |
2241 if (user_record) { | |
2242 text = nm_user_record_get_status_text(user_record); | |
2243 if (text) | |
2244 return g_strdup(text); | |
2245 } | |
2246 } | |
2247 } | |
2248 } | |
2249 | |
2250 return NULL; | |
2251 } | |
2252 | |
2253 static GList * | |
2254 novell_away_states(GaimConnection * gc) | |
2255 { | |
2256 GList *m = NULL; | |
2257 | |
2258 m = g_list_append(m, _("Available")); | |
2259 m = g_list_append(m, _("Away")); | |
2260 m = g_list_append(m, _("Busy")); | |
2261 m = g_list_append(m, _("Appear Offline")); | |
2262 m = g_list_append(m, GAIM_AWAY_CUSTOM); | |
2263 | |
2264 return m; | |
2265 } | |
2266 | |
2267 static void | |
2268 novell_set_away(GaimConnection * gc, const char *state, const char *msg) | |
2269 { | |
2270 NMUser *user; | |
2271 NMSTATUS_T status = NM_STATUS_AVAILABLE; | |
2272 NMERR_T rc = NM_OK; | |
2273 char *text = NULL; | |
2274 char *tmp = NULL; | |
2275 char *p = NULL; | |
2276 | |
2277 if (gc == NULL) | |
2278 return; | |
2279 | |
2280 user = gc->proto_data; | |
2281 if (user == NULL) | |
2282 return; | |
2283 | |
2284 if (gc->away) { | |
2285 g_free(gc->away); | |
2286 gc->away = NULL; | |
2287 } | |
2288 | |
2289 if (msg != NULL) { | |
2290 status = NM_STATUS_AWAY; | |
2291 gc->away = g_strdup(""); | |
2292 | |
2293 /* Don't want newlines in status text */ | |
2294 tmp = g_strdup(msg); | |
2295 if ((p = strchr(tmp, '\n'))) { | |
2296 *p = '\0'; | |
2297 } | |
2298 | |
2299 /* Truncate the status text if necessary */ | |
2300 text = g_strdup(tmp); | |
2301 if (g_utf8_strlen(tmp, -1) > 60) { | |
2302 g_utf8_strncpy(text, tmp, 60); | |
2303 strcat(text, "..."); | |
2304 } | |
2305 | |
2306 g_free(tmp); | |
2307 | |
2308 } else if (state) { | |
2309 if (!strcmp(state, _("Available"))) { | |
2310 status = NM_STATUS_AVAILABLE; | |
2311 } else if (!strcmp(state, _("Away"))) { | |
2312 status = NM_STATUS_AWAY; | |
2313 gc->away = g_strdup(""); | |
2314 } else if (!strcmp(state, _("Busy"))) { | |
2315 status = NM_STATUS_BUSY; | |
2316 gc->away = g_strdup(""); | |
2317 } else if (!strcmp(state, _("Appear Offline"))) { | |
2318 status = NM_STATUS_OFFLINE; | |
2319 gc->away = g_strdup(""); | |
2320 } else { | |
2321 status = NM_STATUS_AVAILABLE; | |
2322 g_free(gc->away); | |
2323 gc->away = NULL; | |
2324 } | |
2325 } else if (gc->is_idle) { | |
2326 status = NM_STATUS_AWAY_IDLE; | |
2327 } else { | |
2328 status = NM_STATUS_AVAILABLE; | |
2329 } | |
2330 | |
2331 rc = nm_send_set_status(user, status, text, msg, NULL, NULL); | |
2332 _check_for_disconnect(user, rc); | |
2333 | |
2334 if (text) | |
2335 g_free(text); | |
2336 } | |
2337 | |
2338 static GaimPluginProtocolInfo prpl_info = { | |
2339 0, | |
2340 NULL, | |
2341 NULL, | |
2342 novell_list_icon, | |
2343 novell_list_emblems, | |
2344 novell_status_text, | |
2345 novell_tooltip_text, | |
2346 novell_away_states, | |
2347 NULL, /* prpl_actions */ | |
2348 NULL, /* buddy_menu */ | |
2349 NULL, /* chat_info */ | |
2350 novell_login, | |
2351 novell_close, | |
2352 novell_send_im, | |
2353 NULL, /* set_info */ | |
2354 novell_send_typing, | |
2355 novell_get_info, | |
2356 novell_set_away, | |
2357 NULL, /* set_dir */ | |
2358 NULL, /* get_dir */ | |
2359 NULL, /* dir_search */ | |
2360 novell_set_idle, | |
2361 NULL, /* change pwd */ | |
2362 novell_add_buddy, | |
2363 NULL, /* add_buddies */ | |
2364 novell_remove_buddy, | |
2365 NULL, /* remove_buddies */ | |
2366 NULL, /* add_permit */ | |
2367 NULL, /* add_deny */ | |
2368 NULL, /* rem_permit */ | |
2369 NULL, /* rem_deny */ | |
2370 NULL, /* set_permit_deny */ | |
2371 NULL, /* warn */ | |
2372 NULL, /* join_chat */ | |
2373 NULL, /* reject_chat ?? */ | |
2374 NULL, /* chat_invite */ | |
2375 novell_chat_leave, | |
2376 NULL, /* chat_whisper */ | |
2377 novell_chat_send, | |
2378 NULL, /* keepalive */ | |
2379 NULL, /* register_user */ | |
2380 NULL, /* get_cb_info */ | |
2381 NULL, /* get_cb_away_msg */ | |
2382 novell_alias_buddy, | |
2383 novell_group_buddy, | |
2384 novell_rename_group, | |
2385 NULL, /* buddy_free */ | |
2386 novell_convo_closed, | |
2387 NULL, /* normalize */ | |
2388 NULL, /* set_buddy_icon */ | |
2389 novell_remove_group, | |
2390 NULL | |
2391 }; | |
2392 | |
2393 static GaimPluginInfo info = { | |
2394 2, /**< api_version */ | |
2395 GAIM_PLUGIN_PROTOCOL, /**< type */ | |
2396 NULL, /**< ui_requirement */ | |
2397 0, /**< flags */ | |
2398 NULL, /**< dependencies */ | |
2399 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
2400 | |
2401 "prpl-novell", /**< id */ | |
8676 | 2402 "GroupWise", /**< name */ |
8675 | 2403 VERSION, /**< version */ |
2404 /** summary */ | |
2405 N_("Novell GroupWise Messenger Protocol Plugin"), | |
2406 /** description */ | |
2407 N_("Novell GroupWise Messenger Protocol Plugin"), | |
2408 NULL, /**< author */ | |
2409 GAIM_WEBSITE, /**< homepage */ | |
2410 | |
2411 NULL, /**< load */ | |
2412 NULL, /**< unload */ | |
2413 NULL, /**< destroy */ | |
2414 | |
2415 NULL, /**< ui_info */ | |
2416 &prpl_info /**< extra_info */ | |
2417 }; | |
2418 | |
2419 static void | |
2420 init_plugin(GaimPlugin * plugin) | |
2421 { | |
2422 GaimAccountOption *option; | |
2423 | |
2424 option = gaim_account_option_string_new(_("Server address"), "server", NULL); | |
2425 prpl_info.protocol_options = | |
2426 g_list_append(prpl_info.protocol_options, option); | |
2427 | |
2428 option = gaim_account_option_int_new(_("Server port"), "port", DEFAULT_PORT); | |
2429 prpl_info.protocol_options = | |
2430 g_list_append(prpl_info.protocol_options, option); | |
2431 | |
2432 my_protocol = plugin; | |
2433 } | |
2434 | |
2435 GAIM_INIT_PLUGIN(novell, init_plugin, info); |