4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
30 #include "purpleaccountoption.h"
38 #define DEFAULT_PORT 8300
39 #define NOVELL_CONNECT_STEPS 4
40 #define NM_ROOT_FOLDER_NAME "GroupWise Messenger"
42 #define NOVELL_STATUS_TYPE_AVAILABLE "available"
43 #define NOVELL_STATUS_TYPE_AWAY "away"
44 #define NOVELL_STATUS_TYPE_BUSY "busy"
45 #define NOVELL_STATUS_TYPE_OFFLINE "offline"
46 #define NOVELL_STATUS_TYPE_IDLE "idle"
47 #define NOVELL_STATUS_TYPE_APPEAR_OFFLINE "appearoffline"
49 static PurpleProtocol
*my_protocol
= NULL
;
52 _is_disconnect_error(NMERR_T err
);
55 _check_for_disconnect(NMUser
* user
, NMERR_T err
);
58 _send_message(NMUser
* user
, NMMessage
* message
);
61 _update_buddy_status(NMUser
*user
, PurpleBuddy
* buddy
, int status
, int gmt
);
64 _remove_purple_buddies(NMUser
* user
);
67 _add_contacts_to_purple_blist(NMUser
* user
, NMFolder
* folder
);
70 _add_purple_buddies(NMUser
* user
);
73 _sync_contact_list(NMUser
*user
);
76 _sync_privacy_lists(NMUser
*user
);
79 _show_info(PurpleConnection
* gc
, NMUserRecord
* user_record
, char * name
);
82 _get_conference_name(int id
);
84 /*******************************************************************************
86 *******************************************************************************/
88 /* Handle login response */
90 _login_resp_cb(NMUser
* user
, NMERR_T ret_code
,
91 gpointer resp_data
, gpointer user_data
)
100 gc
= purple_account_get_connection(user
->client_data
);
104 if (ret_code
== NM_OK
) {
106 /* Set alias for user if not set (use Full Name) */
107 alias
= purple_account_get_private_alias(user
->client_data
);
108 if (alias
== NULL
|| *alias
== '\0') {
109 alias
= nm_user_record_get_full_name(user
->user_record
);
112 purple_account_set_private_alias(user
->client_data
, alias
);
115 /* Tell Purple that we are connected */
116 purple_connection_set_state(gc
, PURPLE_CONNECTION_CONNECTED
);
118 _sync_contact_list(user
);
120 rc
= nm_send_set_status(user
, NM_STATUS_AVAILABLE
, NULL
, NULL
, NULL
,
122 _check_for_disconnect(user
, rc
);
125 PurpleConnectionError reason
;
126 char *err
= g_strdup_printf(_("Unable to login: %s"),
127 nm_error_to_string (ret_code
));
130 case NMERR_AUTHENTICATION_FAILED
:
131 case NMERR_CREDENTIALS_MISSING
:
132 case NMERR_PASSWORD_INVALID
:
133 /* Don't attempt to auto-reconnect if our
134 * password was invalid.
136 if (!purple_account_get_remember_password(purple_connection_get_account(gc
)))
137 purple_account_set_password(purple_connection_get_account(gc
), NULL
, NULL
, NULL
);
138 reason
= PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED
;
141 /* FIXME: There are other reasons login could fail */
142 reason
= PURPLE_CONNECTION_ERROR_NETWORK_ERROR
;
145 purple_connection_error(gc
, reason
, err
);
150 /* Handle getstatus response*/
152 _get_status_resp_cb(NMUser
* user
, NMERR_T ret_code
,
153 gpointer resp_data
, gpointer user_data
)
158 NMUserRecord
*user_record
= (NMUserRecord
*) resp_data
;
161 if (user
== NULL
|| user_record
== NULL
)
164 if (ret_code
== NM_OK
) {
166 /* Find all Purple buddies and update their statuses */
167 const char *name
= nm_user_record_get_display_id(user_record
);
170 buddies
= purple_blist_find_buddies((PurpleAccount
*) user
->client_data
, name
);
171 for (bnode
= buddies
; bnode
; bnode
= bnode
->next
) {
172 buddy
= (PurpleBuddy
*) bnode
->data
;
174 status
= nm_user_record_get_status(user_record
);
175 _update_buddy_status(user
, buddy
, status
, time(0));
178 g_slist_free(buddies
);
183 purple_debug(PURPLE_DEBUG_INFO
, "novell",
184 "_get_status_resp_cb(): rc = 0x%X\n", ret_code
);
189 /* Show an error if the rename failed */
191 _rename_contact_resp_cb(NMUser
* user
, NMERR_T ret_code
,
192 gpointer resp_data
, gpointer user_data
)
194 if (ret_code
!= NM_OK
) {
195 purple_debug(PURPLE_DEBUG_INFO
, "novell",
196 "_rename_contact_resp_cb(): rc = 0x%X\n", ret_code
);
200 /* Handle the getdetails response and send the message */
202 _get_details_resp_send_msg(NMUser
* user
, NMERR_T ret_code
,
203 gpointer resp_data
, gpointer user_data
)
205 PurpleConversation
*gconv
;
206 PurpleConnection
*gc
;
207 NMUserRecord
*user_record
= NULL
;
208 NMContact
*cntct
= NULL
;
210 NMMessage
*msg
= user_data
;
211 const char *dn
= NULL
;
214 if (user
== NULL
|| msg
== NULL
)
217 if (ret_code
== NM_OK
) {
218 user_record
= (NMUserRecord
*) resp_data
;
221 /* Set the title for the conversation */
222 /* XXX - Should this be find_im_with_account? */
223 gconv
= purple_conversations_find_with_account(nm_user_record_get_display_id(user_record
),
224 (PurpleAccount
*) user
->client_data
);
227 dn
= nm_user_record_get_dn(user_record
);
229 cntct
= nm_find_contact(user
, dn
);
233 purple_conversation_set_title(gconv
,
234 nm_contact_get_display_name(cntct
));
237 /* Not in the contact list, try to user full name */
238 name
= (char *) nm_user_record_get_full_name(user_record
);
240 purple_conversation_set_title(gconv
, name
);
244 /* Add the user record to particpant list */
245 conf
= nm_message_get_conference(msg
);
247 nm_conference_add_participant(conf
, user_record
);
248 _send_message(user
, msg
);
254 gc
= purple_account_get_connection(user
->client_data
);
256 char *err
= g_strdup_printf(_("Unable to send message."
257 " Could not get details for user (%s)."),
258 nm_error_to_string (ret_code
));
260 purple_notify_error(gc
, NULL
, err
, NULL
,
261 purple_request_cpar_from_connection(gc
));
265 nm_release_message(msg
);
269 /* Set up the new PurpleBuddy based on the response from getdetails */
271 _get_details_resp_setup_buddy(NMUser
* user
, NMERR_T ret_code
,
272 gpointer resp_data
, gpointer user_data
)
274 NMUserRecord
*user_record
;
280 if (user
== NULL
|| resp_data
== NULL
|| user_data
== NULL
)
285 if (ret_code
== NM_OK
) {
286 user_record
= resp_data
;
288 buddy
= nm_contact_get_data(contact
);
290 nm_contact_set_user_record(contact
, user_record
);
292 /* Set the display id */
293 purple_buddy_set_name(buddy
,
294 nm_user_record_get_display_id(user_record
));
296 alias
= purple_buddy_get_alias(buddy
);
297 if (alias
== NULL
|| *alias
== '\0' || purple_strequal(alias
, purple_buddy_get_name(buddy
))) {
298 purple_buddy_set_local_alias(buddy
,
299 nm_user_record_get_full_name(user_record
));
301 /* Tell the server about the new display name */
302 rc
= nm_send_rename_contact(user
, contact
,
303 nm_user_record_get_full_name(user_record
),
305 _check_for_disconnect(user
, rc
);
310 /* Get initial status for the buddy */
311 rc
= nm_send_get_status(user
, resp_data
, _get_status_resp_cb
, NULL
);
312 _check_for_disconnect(user
, rc
);
314 /* nm_release_contact(contact);*/
318 nm_release_contact(contact
);
321 /* Add the new contact into the PurpleBuddy list */
323 _create_contact_resp_cb(NMUser
* user
, NMERR_T ret_code
,
324 gpointer resp_data
, gpointer user_data
)
326 NMContact
*tmp_contact
= (NMContact
*) user_data
;
327 NMContact
*new_contact
= NULL
;
328 NMFolder
*folder
= NULL
;
331 const char *folder_name
= NULL
;
337 if (ret_code
== NM_OK
) {
339 new_contact
= (NMContact
*) resp_data
;
340 if (new_contact
== NULL
|| tmp_contact
== NULL
)
343 /* Get the userid and folder name for the new contact */
344 folder
= nm_find_folder_by_id(user
,
345 nm_contact_get_parent_id(new_contact
));
347 folder_name
= nm_folder_get_name(folder
);
350 if (folder_name
== NULL
|| *folder_name
== '\0')
351 folder_name
= NM_ROOT_FOLDER_NAME
;
353 /* Re-add the buddy now that we got the okay from the server */
354 group
= purple_blist_find_group(folder_name
);
356 const char *alias
= nm_contact_get_display_name(tmp_contact
);
357 const char *display_id
= nm_contact_get_display_id(new_contact
);
359 if (display_id
== NULL
)
360 display_id
= nm_contact_get_dn(new_contact
);
362 if (alias
&& !purple_strequal(alias
, display_id
)) {
364 /* The user requested an alias, tell the server about it. */
365 rc
= nm_send_rename_contact(user
, new_contact
, alias
,
366 _rename_contact_resp_cb
, NULL
);
367 _check_for_disconnect(user
, rc
);
375 /* Add it to the purple buddy list if it is not there */
376 buddy
= purple_blist_find_buddy_in_group(user
->client_data
, display_id
, group
);
378 buddy
= purple_buddy_new(user
->client_data
, display_id
, alias
);
379 purple_blist_add_buddy(buddy
, NULL
, group
, NULL
);
382 /* Save the new buddy as part of the contact object */
383 nm_contact_set_data(new_contact
, (gpointer
) buddy
);
385 /* We need details for the user before we can setup the
386 * new Purple buddy. We always call this because the
387 * 'createcontact' response fields do not always contain
388 * everything that we need.
390 nm_contact_add_ref(new_contact
);
392 rc
= nm_send_get_details(user
, nm_contact_get_dn(new_contact
),
393 _get_details_resp_setup_buddy
, new_contact
);
394 _check_for_disconnect(user
, rc
);
398 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
399 const char *name
= nm_contact_get_dn(tmp_contact
);
403 g_strdup_printf(_("Unable to add %s to your buddy list (%s)."),
404 name
, nm_error_to_string (ret_code
));
405 purple_notify_error(gc
, NULL
, err
, NULL
,
406 purple_request_cpar_from_connection(gc
));
412 nm_release_contact(tmp_contact
);
415 /* Show an error if we failed to send the message */
417 _send_message_resp_cb(NMUser
* user
, NMERR_T ret_code
,
418 gpointer resp_data
, gpointer user_data
)
420 PurpleConnection
*gc
;
426 if (ret_code
!= NM_OK
) {
427 gc
= purple_account_get_connection(user
->client_data
);
429 /* TODO: Improve this! message to who or for what conference? */
430 err
= g_strdup_printf(_("Unable to send message (%s)."),
431 nm_error_to_string (ret_code
));
432 purple_notify_error(gc
, NULL
, err
, NULL
,
433 purple_request_cpar_from_connection(gc
));
438 /* Show an error if the remove failed */
440 _remove_contact_resp_cb(NMUser
* user
, NMERR_T ret_code
,
441 gpointer resp_data
, gpointer user_data
)
443 if (ret_code
!= NM_OK
) {
444 /* TODO: Display an error? */
446 purple_debug(PURPLE_DEBUG_INFO
, "novell",
447 "_remove_contact_resp_cb(): rc = 0x%x\n", ret_code
);
451 /* Show an error if the remove failed */
453 _remove_folder_resp_cb(NMUser
* user
, NMERR_T ret_code
,
454 gpointer resp_data
, gpointer user_data
)
456 if (ret_code
!= NM_OK
) {
457 /* TODO: Display an error? */
459 purple_debug(PURPLE_DEBUG_INFO
, "novell",
460 "_remove_folder_resp_cb(): rc = 0x%x\n", ret_code
);
464 /* Show an error if the move failed */
466 _move_contact_resp_cb(NMUser
* user
, NMERR_T ret_code
,
467 gpointer resp_data
, gpointer user_data
)
469 if (ret_code
!= NM_OK
) {
470 /* TODO: Display an error? */
472 purple_debug(PURPLE_DEBUG_INFO
, "novell",
473 "_move_contact_resp_cb(): rc = 0x%x\n", ret_code
);
477 /* Show an error if the rename failed */
479 _rename_folder_resp_cb(NMUser
* user
, NMERR_T ret_code
,
480 gpointer resp_data
, gpointer user_data
)
482 if (ret_code
!= NM_OK
) {
483 /* TODO: Display an error? */
485 purple_debug(PURPLE_DEBUG_INFO
, "novell",
486 "_rename_folder_resp_cb(): rc = 0x%x\n", ret_code
);
491 _sendinvite_resp_cb(NMUser
*user
, NMERR_T ret_code
,
492 gpointer resp_data
, gpointer user_data
)
495 PurpleConnection
*gc
;
500 if (ret_code
!= NM_OK
) {
501 gc
= purple_account_get_connection(user
->client_data
);
502 err
= g_strdup_printf(_("Unable to invite user (%s)."), nm_error_to_string(ret_code
));
503 purple_notify_error(gc
, NULL
, err
, NULL
,
504 purple_request_cpar_from_connection(gc
));
507 purple_debug(PURPLE_DEBUG_INFO
, "novell",
508 "_sendinvite_resp_cb(): rc = 0x%x\n", ret_code
);
513 /* If the createconf was successful attempt to send the message,
514 * otherwise display an error message to the user.
517 _createconf_resp_send_msg(NMUser
* user
, NMERR_T ret_code
,
518 gpointer resp_data
, gpointer user_data
)
521 NMMessage
*msg
= user_data
;
523 if (user
== NULL
|| msg
== NULL
)
526 if (ret_code
== NM_OK
) {
527 _send_message(user
, msg
);
530 if ((conf
= nm_message_get_conference(msg
))) {
532 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
533 const char *name
= NULL
;
537 ur
= nm_conference_get_participant(conf
, 0);
539 name
= nm_user_record_get_userid(ur
);
542 err
= g_strdup_printf(_("Unable to send message to %s."
543 " Could not create the conference (%s)."),
545 nm_error_to_string (ret_code
));
547 err
= g_strdup_printf(_("Unable to send message."
548 " Could not create the conference (%s)."),
549 nm_error_to_string (ret_code
));
551 purple_notify_error(gc
, NULL
, err
, NULL
,
552 purple_request_cpar_from_connection(gc
));
556 nm_release_message(msg
);
560 /* Move contact to newly created folder */
562 _create_folder_resp_move_contact(NMUser
* user
, NMERR_T ret_code
,
563 gpointer resp_data
, gpointer user_data
)
565 NMContact
*contact
= user_data
;
566 NMFolder
*new_folder
;
567 char *folder_name
= resp_data
;
570 if (user
== NULL
|| folder_name
== NULL
|| contact
== NULL
) {
577 if (ret_code
== NM_OK
|| ret_code
== NMERR_DUPLICATE_FOLDER
) {
578 new_folder
= nm_find_folder(user
, folder_name
);
581 /* Tell the server to move the contact to the new folder */
582 /* rc = nm_send_move_contact(user, contact, new_folder,
583 _move_contact_resp_cb, NULL); */
585 rc
= nm_send_create_contact(user
, new_folder
, contact
,
588 _check_for_disconnect(user
, rc
);
592 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
593 char *err
= g_strdup_printf(_("Unable to move user %s"
594 " to folder %s in the server side list."
595 " Error while creating folder (%s)."),
596 nm_contact_get_dn(contact
),
598 nm_error_to_string (ret_code
));
600 purple_notify_error(gc
, NULL
, err
, NULL
,
601 purple_request_cpar_from_connection(gc
));
608 /* Add contact to newly create folder */
610 _create_folder_resp_add_contact(NMUser
* user
, NMERR_T ret_code
,
611 gpointer resp_data
, gpointer user_data
)
613 NMContact
*contact
= (NMContact
*) user_data
;
615 char *folder_name
= (char *) resp_data
;
618 if (user
== NULL
|| folder_name
== NULL
|| contact
== NULL
) {
621 nm_release_contact(contact
);
628 if (ret_code
== NM_OK
|| ret_code
== NMERR_DUPLICATE_FOLDER
) {
629 folder
= nm_find_folder(user
, folder_name
);
632 rc
= nm_send_create_contact(user
, folder
, contact
,
633 _create_contact_resp_cb
, contact
);
634 _check_for_disconnect(user
, rc
);
637 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
638 const char *name
= nm_contact_get_dn(contact
);
640 g_strdup_printf(_("Unable to add %s to your buddy list."
641 " Error creating folder in server side list (%s)."),
642 name
, nm_error_to_string (ret_code
));
644 purple_notify_error(gc
, NULL
, err
, NULL
,
645 purple_request_cpar_from_connection(gc
));
647 nm_release_contact(contact
);
655 _join_conf_resp_cb(NMUser
* user
, NMERR_T ret_code
,
656 gpointer resp_data
, gpointer user_data
)
658 PurpleChatConversation
*chat
;
659 PurpleConnection
*gc
;
661 NMConference
*conference
= user_data
;
662 const char *name
, *conf_name
;
665 if (user
== NULL
|| conference
== NULL
)
668 gc
= purple_account_get_connection(user
->client_data
);
670 if (ret_code
== NM_OK
) {
671 conf_name
= _get_conference_name(++user
->conference_count
);
672 chat
= purple_serv_got_joined_chat(gc
, user
->conference_count
, conf_name
);
675 nm_conference_set_data(conference
, (gpointer
) chat
);
677 count
= nm_conference_get_participant_count(conference
);
678 for (i
= 0; i
< count
; i
++) {
679 ur
= nm_conference_get_participant(conference
, i
);
681 name
= nm_user_record_get_display_id(ur
);
682 purple_chat_conversation_add_user(chat
, name
, NULL
,
683 PURPLE_CHAT_USER_NONE
, TRUE
);
690 /* Show info returned by getdetails */
692 _get_details_resp_show_info(NMUser
* user
, NMERR_T ret_code
,
693 gpointer resp_data
, gpointer user_data
)
695 PurpleConnection
*gc
;
696 NMUserRecord
*user_record
;
705 if (ret_code
== NM_OK
) {
706 user_record
= (NMUserRecord
*) resp_data
;
708 _show_info(purple_account_get_connection(user
->client_data
),
709 user_record
, g_strdup(name
));
712 gc
= purple_account_get_connection(user
->client_data
);
714 g_strdup_printf(_("Could not get details for user %s (%s)."),
715 name
, nm_error_to_string (ret_code
));
716 purple_notify_error(gc
, NULL
, err
, NULL
,
717 purple_request_cpar_from_connection(gc
));
724 /* Handle get details response add to privacy list */
726 _get_details_resp_add_privacy_item(NMUser
*user
, NMERR_T ret_code
,
727 gpointer resp_data
, gpointer user_data
)
729 PurpleConnection
*gc
;
730 PurpleAccount
*account
;
731 NMUserRecord
*user_record
= resp_data
;
733 gboolean allowed
= GPOINTER_TO_INT(user_data
);
734 const char *display_id
;
739 gc
= purple_account_get_connection(user
->client_data
);
740 display_id
= nm_user_record_get_display_id(user_record
);
741 account
= purple_connection_get_account(gc
);
743 if (ret_code
== NM_OK
) {
747 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
748 display_id
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
749 purple_account_privacy_permit_add(account
, display_id
, TRUE
);
754 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
755 display_id
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
756 purple_account_privacy_deny_add(account
, display_id
, TRUE
);
762 err
= g_strdup_printf(_("Unable to add user to privacy list (%s)."),
763 nm_error_to_string(ret_code
));
764 purple_notify_error(gc
, NULL
, err
, NULL
,
765 purple_request_cpar_from_connection(gc
));
771 /* Handle response to create privacy item request */
773 _create_privacy_item_deny_resp_cb(NMUser
*user
, NMERR_T ret_code
,
774 gpointer resp_data
, gpointer user_data
)
776 PurpleConnection
*gc
;
777 PurpleAccount
*account
;
778 NMUserRecord
*user_record
;
779 char *who
= user_data
;
782 const char *display_id
= NULL
;
787 gc
= purple_account_get_connection(user
->client_data
);
788 account
= purple_connection_get_account(gc
);
790 if (ret_code
== NM_OK
) {
792 user_record
= nm_find_user_record(user
, who
);
794 display_id
= nm_user_record_get_display_id(user_record
);
798 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
799 display_id
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
801 purple_account_privacy_deny_add(account
, display_id
, TRUE
);
805 rc
= nm_send_get_details(user
, who
,
806 _get_details_resp_add_privacy_item
,
807 GINT_TO_POINTER(FALSE
));
808 _check_for_disconnect(user
, rc
);
812 err
= g_strdup_printf(_("Unable to add %s to deny list (%s)."),
813 who
, nm_error_to_string(ret_code
));
814 purple_notify_error(gc
, NULL
, err
, NULL
,
815 purple_request_cpar_from_connection(gc
));
824 /* Handle response to create privacy item request */
826 _create_privacy_item_permit_resp_cb(NMUser
*user
, NMERR_T ret_code
,
827 gpointer resp_data
, gpointer user_data
)
829 PurpleConnection
*gc
;
830 PurpleAccount
*account
;
831 NMUserRecord
*user_record
;
832 char *who
= user_data
;
835 const char *display_id
= NULL
;
840 gc
= purple_account_get_connection(user
->client_data
);
841 account
= purple_connection_get_account(gc
);
843 if (ret_code
== NM_OK
) {
845 user_record
= nm_find_user_record(user
, who
);
847 display_id
= nm_user_record_get_display_id(user_record
);
851 if (!g_slist_find_custom(purple_account_privacy_get_permitted(account
),
853 (GCompareFunc
)purple_utf8_strcasecmp
)) {
855 purple_account_privacy_permit_add(account
, display_id
, TRUE
);
859 rc
= nm_send_get_details(user
, who
,
860 _get_details_resp_add_privacy_item
,
861 GINT_TO_POINTER(TRUE
));
862 _check_for_disconnect(user
, rc
);
867 err
= g_strdup_printf(_("Unable to add %s to permit list (%s)."), who
,
868 nm_error_to_string(ret_code
));
869 purple_notify_error(gc
, NULL
, err
, NULL
,
870 purple_request_cpar_from_connection(gc
));
879 _get_details_send_privacy_create(NMUser
*user
, NMERR_T ret_code
,
880 gpointer resp_data
, gpointer user_data
)
883 PurpleConnection
*gc
;
884 NMUserRecord
*user_record
= resp_data
;
886 gboolean allowed
= GPOINTER_TO_INT(user_data
);
887 const char *dn
, *display_id
;
892 gc
= purple_account_get_connection(user
->client_data
);
893 dn
= nm_user_record_get_dn(user_record
);
894 display_id
= nm_user_record_get_display_id(user_record
);
896 if (ret_code
== NM_OK
) {
899 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
900 _create_privacy_item_permit_resp_cb
,
901 g_strdup(display_id
));
902 _check_for_disconnect(user
, rc
);
905 rc
= nm_send_create_privacy_item(user
, dn
, FALSE
,
906 _create_privacy_item_deny_resp_cb
,
907 g_strdup(display_id
));
908 _check_for_disconnect(user
, rc
);
913 err
= g_strdup_printf(_("Unable to add user to privacy list (%s)."),
914 nm_error_to_string(ret_code
));
915 purple_notify_error(gc
, NULL
, err
, NULL
,
916 purple_request_cpar_from_connection(gc
));
923 _remove_privacy_item_resp_cb(NMUser
*user
, NMERR_T ret_code
,
924 gpointer resp_data
, gpointer user_data
)
926 PurpleConnection
*gc
;
927 char *who
= user_data
;
933 if (ret_code
!= NM_OK
) {
935 gc
= purple_account_get_connection(user
->client_data
);
936 err
= g_strdup_printf(_("Unable to remove %s from privacy list (%s)."), who
,
937 nm_error_to_string(ret_code
));
938 purple_notify_error(gc
, NULL
, err
, NULL
,
939 purple_request_cpar_from_connection(gc
));
947 _set_privacy_default_resp_cb(NMUser
*user
, NMERR_T ret_code
,
948 gpointer resp_data
, gpointer user_data
)
950 PurpleConnection
*gc
;
956 if (ret_code
!= NM_OK
) {
958 gc
= purple_account_get_connection(user
->client_data
);
959 err
= g_strdup_printf(_("Unable to change server side privacy settings (%s)."),
960 nm_error_to_string(ret_code
));
961 purple_notify_error(gc
, NULL
, err
, NULL
,
962 purple_request_cpar_from_connection(gc
));
968 /* Handle get details response add to privacy list */
970 _get_details_resp_send_invite(NMUser
*user
, NMERR_T ret_code
,
971 gpointer resp_data
, gpointer user_data
)
974 PurpleConnection
*gc
;
975 NMUserRecord
*user_record
= resp_data
;
978 NMConference
*conference
;
980 int id
= GPOINTER_TO_INT(user_data
);
985 gc
= purple_account_get_connection(user
->client_data
);
987 if (ret_code
== NM_OK
) {
989 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
990 conference
= cnode
->data
;
991 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
992 if (purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(chat
)) == id
) {
993 rc
= nm_send_conference_invite(user
, conference
, user_record
,
994 NULL
, _sendinvite_resp_cb
, NULL
);
995 _check_for_disconnect(user
, rc
);
1003 err
= g_strdup_printf(_("Unable to invite user (%s)."), nm_error_to_string(ret_code
));
1004 purple_notify_error(gc
, NULL
, err
, NULL
,
1005 purple_request_cpar_from_connection(gc
));
1012 _createconf_resp_send_invite(NMUser
* user
, NMERR_T ret_code
,
1013 gpointer resp_data
, gpointer user_data
)
1016 NMConference
*conference
= resp_data
;
1017 NMUserRecord
*user_record
= user_data
;
1018 PurpleConnection
*gc
;
1026 if (ret_code
== NM_OK
) {
1027 rc
= nm_send_conference_invite(user
, conference
, user_record
,
1028 NULL
, _sendinvite_resp_cb
, NULL
);
1029 _check_for_disconnect(user
, rc
);
1031 err
= g_strdup_printf(_("Unable to create conference (%s)."), nm_error_to_string(ret_code
));
1032 gc
= purple_account_get_connection(user
->client_data
);
1033 purple_notify_error(gc
, NULL
, err
, NULL
,
1034 purple_request_cpar_from_connection(gc
));
1039 /*******************************************************************************
1041 ******************************************************************************/
1044 _user_agent_string(void)
1047 #if !defined(_WIN32)
1049 const char *sysname
= "";
1050 const char *release
= "";
1053 if (uname(&u
) == 0) {
1054 sysname
= u
.sysname
;
1055 release
= u
.release
;
1058 release
= "Unknown";
1061 return g_strdup_printf("Purple/%s (%s; %s)", VERSION
, sysname
, release
);
1065 const char *sysname
= "";
1066 OSVERSIONINFO os_info
;
1067 SYSTEM_INFO sys_info
;
1069 os_info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1070 GetVersionEx(&os_info
);
1071 GetSystemInfo(&sys_info
);
1073 if (os_info
.dwPlatformId
== VER_PLATFORM_WIN32_NT
) {
1074 switch (os_info
.dwMajorVersion
) {
1077 sysname
= "Windows NT";
1080 switch (os_info
.dwMinorVersion
) {
1082 sysname
= "Windows 2000";
1085 sysname
= "Windows XP";
1088 sysname
= "Windows Server 2003";
1091 sysname
= "Windows";
1096 sysname
= "Windows";
1100 } else if (os_info
.dwPlatformId
== VER_PLATFORM_WIN32_WINDOWS
) {
1101 switch (os_info
.dwMinorVersion
) {
1103 sysname
= "Windows 95";
1106 sysname
= "Windows 98";
1109 sysname
= "Windows ME";
1112 sysname
= "Windows";
1116 sysname
= "Windows";
1119 return g_strdup_printf("Purple/%s (%s; %ld.%ld)", VERSION
, sysname
,
1120 os_info
.dwMajorVersion
, os_info
.dwMinorVersion
);
1128 _is_disconnect_error(NMERR_T err
)
1130 return (err
== NMERR_TCP_WRITE
||
1131 err
== NMERR_TCP_READ
|| err
== NMERR_PROTOCOL
);
1135 _check_for_disconnect(NMUser
* user
, NMERR_T err
)
1137 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
1139 if (_is_disconnect_error(err
)) {
1141 purple_connection_error(gc
,
1142 PURPLE_CONNECTION_ERROR_NETWORK_ERROR
,
1143 _("Error communicating with server. Closing connection."));
1151 /* Check to see if the conference is instantiated, if so send the message.
1152 * If not send the create conference -- the response handler for the createconf
1153 * will call this function again.
1156 _send_message(NMUser
* user
, NMMessage
* message
)
1161 conf
= nm_message_get_conference(message
);
1163 /* We have a conference make sure that the
1164 server knows about it already. */
1165 if (nm_conference_is_instantiated(conf
)) {
1167 /* We have everything that we need...finally! */
1168 rc
= nm_send_message(user
, message
, _send_message_resp_cb
);
1169 _check_for_disconnect(user
, rc
);
1171 nm_release_message(message
);
1174 rc
= nm_send_create_conference(user
, conf
, _createconf_resp_send_msg
, message
);
1175 _check_for_disconnect(user
, rc
);
1181 * Update the status of the given buddy in the Purple buddy list
1184 _update_buddy_status(NMUser
*user
, PurpleBuddy
* buddy
, int novellstatus
, int gmt
)
1186 PurpleAccount
*account
;
1187 const char *status_id
;
1188 const char *text
= NULL
;
1193 account
= purple_buddy_get_account(buddy
);
1194 name
= purple_buddy_get_name(buddy
);
1196 switch (novellstatus
) {
1197 case NM_STATUS_AVAILABLE
:
1198 status_id
= NOVELL_STATUS_TYPE_AVAILABLE
;
1200 case NM_STATUS_AWAY
:
1201 status_id
= NOVELL_STATUS_TYPE_AWAY
;
1203 case NM_STATUS_BUSY
:
1204 status_id
= NOVELL_STATUS_TYPE_BUSY
;
1206 case NM_STATUS_OFFLINE
:
1207 status_id
= NOVELL_STATUS_TYPE_OFFLINE
;
1209 case NM_STATUS_AWAY_IDLE
:
1210 status_id
= NOVELL_STATUS_TYPE_AWAY
;
1214 status_id
= NOVELL_STATUS_TYPE_OFFLINE
;
1218 /* Get status text for the user */
1219 dn
= nm_lookup_dn(user
, name
);
1221 NMUserRecord
*user_record
= nm_find_user_record(user
, dn
);
1223 text
= nm_user_record_get_status_text(user_record
);
1227 purple_protocol_got_user_status(account
, name
, status_id
,
1228 "message", text
, NULL
);
1229 purple_protocol_got_user_idle(account
, name
,
1230 (novellstatus
== NM_STATUS_AWAY_IDLE
), idle
);
1233 /* Iterate through the cached Purple buddy list and remove buddies
1234 * that are not in the server side list.
1237 _remove_purple_buddies(NMUser
*user
)
1239 PurpleBlistNode
*gnode
;
1240 PurpleBlistNode
*cnode
;
1241 PurpleBlistNode
*bnode
;
1244 GSList
*rem_list
= NULL
;
1245 NMFolder
*folder
= NULL
;
1246 const char *gname
= NULL
;
1248 for (gnode
= purple_blist_get_default_root(); gnode
;
1249 gnode
= purple_blist_node_get_sibling_next(gnode
)) {
1250 if (!PURPLE_IS_GROUP(gnode
))
1252 group
= (PurpleGroup
*) gnode
;
1253 gname
= purple_group_get_name(group
);
1254 for (cnode
= purple_blist_node_get_first_child(gnode
);
1256 cnode
= purple_blist_node_get_sibling_next(cnode
)) {
1257 if (!PURPLE_IS_CONTACT(cnode
))
1259 for (bnode
= purple_blist_node_get_first_child(cnode
);
1261 bnode
= purple_blist_node_get_sibling_next(bnode
)) {
1262 if (!PURPLE_IS_BUDDY(bnode
))
1264 buddy
= (PurpleBuddy
*) bnode
;
1265 if (purple_buddy_get_account(buddy
) == user
->client_data
) {
1266 if (purple_strequal(gname
, NM_ROOT_FOLDER_NAME
))
1268 folder
= nm_find_folder(user
, gname
);
1269 if (folder
== NULL
||
1270 !nm_folder_find_contact_by_display_id(folder
, purple_buddy_get_name(buddy
))) {
1271 rem_list
= g_slist_append(rem_list
, buddy
);
1278 g_slist_free_full(rem_list
, (GDestroyNotify
)purple_blist_remove_buddy
);
1281 /* Add all of the contacts in the given folder to the Purple buddy list */
1283 _add_contacts_to_purple_blist(NMUser
* user
, NMFolder
* folder
)
1285 NMUserRecord
*user_record
= NULL
;
1286 NMContact
*contact
= NULL
;
1287 PurpleBuddy
*buddy
= NULL
;
1290 const char *name
= NULL
;
1291 const char *fname
= NULL
;
1294 /* If this is the root folder give it a name. Purple does not have the concept of
1297 fname
= nm_folder_get_name(folder
);
1298 if (fname
== NULL
|| *fname
== '\0') {
1299 fname
= NM_ROOT_FOLDER_NAME
;
1302 /* Does the Purple group exist already? */
1303 group
= purple_blist_find_group(fname
);
1304 if (group
== NULL
) {
1305 group
= purple_group_new(fname
);
1306 purple_blist_add_group(group
, NULL
);
1309 /* Get each contact for this folder */
1310 cnt
= nm_folder_get_contact_count(folder
);
1311 for (i
= 0; i
< cnt
; i
++) {
1312 contact
= nm_folder_get_contact(folder
, i
);
1315 name
= nm_contact_get_display_id(contact
);
1318 buddy
= purple_blist_find_buddy_in_group(user
->client_data
, name
, group
);
1319 if (buddy
== NULL
) {
1320 /* Add it to the purple buddy list */
1321 buddy
= purple_buddy_new(user
->client_data
,
1323 nm_contact_get_display_name(contact
));
1325 purple_blist_add_buddy(buddy
, NULL
, group
, NULL
);
1328 /* Set the initial status for the buddy */
1329 user_record
= nm_contact_get_user_record(contact
);
1331 status
= nm_user_record_get_status(user_record
);
1333 _update_buddy_status(user
, buddy
, status
, time(0));
1335 /* Save the new buddy as part of the contact object */
1336 nm_contact_set_data(contact
, (gpointer
) buddy
);
1340 /* NULL contact. This should not happen, but
1341 * let's break out of the loop.
1348 /* Add all of the server side contacts to the Purple buddy list. */
1350 _add_purple_buddies(NMUser
* user
)
1353 NMFolder
*root_folder
= NULL
;
1354 NMFolder
*folder
= NULL
;
1356 root_folder
= nm_get_root_folder(user
);
1359 /* Add sub-folders and contacts to sub-folders...
1360 * iterate throught the sub-folders in reverse order
1361 * because Purple adds the folders to the front -- so we
1362 * want to add the first folder last
1364 cnt
= nm_folder_get_subfolder_count(root_folder
);
1365 for (i
= cnt
-1; i
>= 0; i
--) {
1366 folder
= nm_folder_get_subfolder(root_folder
, i
);
1368 _add_contacts_to_purple_blist(user
, folder
);
1372 /* Add contacts for the root folder */
1373 _add_contacts_to_purple_blist(user
, root_folder
);
1378 _sync_contact_list(NMUser
*user
)
1380 /* Remove all buddies from the local list that are
1381 * not in the server side list and add all buddies
1382 * from the server side list that are not in
1385 _remove_purple_buddies(user
);
1386 _add_purple_buddies(user
);
1387 user
->clist_synched
= TRUE
;
1391 _sync_privacy_lists(NMUser
*user
)
1393 GSList
*node
= NULL
, *rem_list
= NULL
;
1394 PurpleConnection
*gc
;
1395 PurpleAccount
*account
;
1396 const char *name
, *dn
;
1397 NMUserRecord
*user_record
;
1402 gc
= purple_account_get_connection(user
->client_data
);
1406 account
= purple_connection_get_account(gc
);
1408 /* Set the Purple privacy setting */
1409 if (user
->default_deny
) {
1410 if (user
->allow_list
== NULL
) {
1411 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_DENY_ALL
);
1413 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
);
1416 if (user
->deny_list
== NULL
) {
1417 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
);
1419 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_DENY_USERS
);
1424 for (node
= user
->allow_list
; node
; node
= node
->next
) {
1425 user_record
= nm_find_user_record(user
, (char *)node
->data
);
1427 name
= nm_user_record_get_display_id(user_record
);
1429 name
=(char *)node
->data
;
1431 if (!g_slist_find_custom(purple_account_privacy_get_permitted(account
),
1432 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1433 purple_account_privacy_permit_add(account
, name
, TRUE
);
1437 for (node
= user
->deny_list
; node
; node
= node
->next
) {
1438 user_record
= nm_find_user_record(user
, (char *)node
->data
);
1440 name
= nm_user_record_get_display_id(user_record
);
1442 name
=(char *)node
->data
;
1444 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
1445 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1446 purple_account_privacy_deny_add(account
, name
, TRUE
);
1452 for (node
= purple_account_privacy_get_permitted(account
); node
; node
= node
->next
) {
1453 dn
= nm_lookup_dn(user
, (char *)node
->data
);
1455 !g_slist_find_custom(user
->allow_list
,
1456 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1457 rem_list
= g_slist_append(rem_list
, node
->data
);
1462 for (node
= rem_list
; node
; node
= node
->next
) {
1463 purple_account_privacy_permit_remove(account
, (char *)node
->data
, TRUE
);
1465 g_slist_free(rem_list
);
1469 for (node
= purple_account_privacy_get_denied(account
); node
; node
= node
->next
) {
1470 dn
= nm_lookup_dn(user
, (char *)node
->data
);
1472 !g_slist_find_custom(user
->deny_list
,
1473 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1474 rem_list
= g_slist_append(rem_list
, node
->data
);
1479 for (node
= rem_list
; node
; node
= node
->next
) {
1480 purple_account_privacy_deny_remove(account
, (char *)node
->data
, TRUE
);
1482 g_slist_free(rem_list
);
1486 /* Map known property tags to user-friendly strings */
1488 _map_property_tag(const char *tag
)
1490 if (tag
== NULL
) return NULL
;
1492 if (purple_strequal(tag
, "telephoneNumber"))
1493 return _("Telephone Number");
1494 else if (purple_strequal(tag
, "L"))
1495 return _("Location");
1496 else if (purple_strequal(tag
, "OU"))
1497 return _("Department");
1498 else if (purple_strequal(tag
, "personalTitle"))
1499 return _("Personal Title");
1500 else if (purple_strequal(tag
, "Title"))
1501 return _("Job Title");
1502 else if (purple_strequal(tag
, "mailstop"))
1503 return _("Mailstop");
1504 else if (purple_strequal(tag
, "Internet EMail Address"))
1505 return _("Email Address");
1510 /* Display a dialog box showing the properties for the given user record */
1512 _show_info(PurpleConnection
* gc
, NMUserRecord
* user_record
, char * name
)
1514 PurpleNotifyUserInfo
*user_info
= purple_notify_user_info_new();
1516 NMProperty
*property
;
1517 const char *tag
, *value
;
1520 value
= nm_user_record_get_userid(user_record
);
1522 /* TODO: Check whether it's correct to call add_pair_html,
1523 or if we should be using add_pair_plaintext */
1524 purple_notify_user_info_add_pair_html(user_info
, tag
, value
);
1527 tag
= _("Full name");
1528 value
= nm_user_record_get_full_name(user_record
);
1530 /* TODO: Check whether it's correct to call add_pair_html,
1531 or if we should be using add_pair_plaintext */
1532 purple_notify_user_info_add_pair_html(user_info
, tag
, value
);
1535 count
= nm_user_record_get_property_count(user_record
);
1536 for (i
= 0; i
< count
; i
++) {
1537 property
= nm_user_record_get_property(user_record
, i
);
1539 tag
= _map_property_tag(nm_property_get_tag(property
));
1540 value
= nm_property_get_value(property
);
1542 /* TODO: Check whether it's correct to call add_pair_html,
1543 or if we should be using add_pair_plaintext */
1544 purple_notify_user_info_add_pair_html(user_info
, tag
, value
);
1546 nm_release_property(property
);
1550 purple_notify_userinfo(gc
, name
, user_info
, NULL
, NULL
);
1551 purple_notify_user_info_destroy(user_info
);
1556 /* Send a join conference, the first item in the parms list is the
1557 * NMUser object and the second item is the conference to join.
1558 * This callback is passed to purple_request_action when we ask the
1559 * user if they want to join the conference.
1562 _join_conference_cb(GSList
* parms
)
1565 NMConference
*conference
;
1568 if (parms
== NULL
|| g_slist_length(parms
) != 2)
1571 user
= g_slist_nth_data(parms
, 0);
1572 conference
= g_slist_nth_data(parms
, 1);
1574 if (user
&& conference
) {
1575 rc
= nm_send_join_conference(user
, conference
,
1576 _join_conf_resp_cb
, conference
);
1577 _check_for_disconnect(user
, rc
);
1580 g_slist_free(parms
);
1583 /* Send a reject conference, the first item in the parms list is the
1584 * NMUser object and the second item is the conference to reject.
1585 * This callback is passed to purple_request_action when we ask the
1586 * user if they want to joing the conference.
1589 _reject_conference_cb(GSList
* parms
)
1592 NMConference
*conference
;
1595 if (parms
== NULL
|| g_slist_length(parms
) != 2)
1598 user
= g_slist_nth_data(parms
, 0);
1599 conference
= g_slist_nth_data(parms
, 1);
1601 if (user
&& conference
) {
1602 rc
= nm_send_reject_conference(user
, conference
, NULL
, NULL
);
1603 _check_for_disconnect(user
, rc
);
1606 g_slist_free(parms
);
1610 _initiate_conference_cb(PurpleBlistNode
*node
, gpointer ignored
)
1613 PurpleConnection
*gc
;
1616 const char *conf_name
;
1617 PurpleChatConversation
*chat
= NULL
;
1618 NMUserRecord
*user_record
;
1619 NMConference
*conference
;
1621 g_return_if_fail(PURPLE_IS_BUDDY(node
));
1623 buddy
= (PurpleBuddy
*) node
;
1624 gc
= purple_account_get_connection(purple_buddy_get_account(buddy
));
1626 user
= purple_connection_get_protocol_data(gc
);
1630 /* We should already have a userrecord for the buddy */
1631 user_record
= nm_find_user_record(user
, purple_buddy_get_name(buddy
));
1632 if (user_record
== NULL
)
1635 conf_name
= _get_conference_name(++user
->conference_count
);
1636 chat
= purple_serv_got_joined_chat(gc
, user
->conference_count
, conf_name
);
1639 conference
= nm_create_conference(NULL
);
1640 nm_conference_set_data(conference
, (gpointer
) chat
);
1641 nm_send_create_conference(user
, conference
, _createconf_resp_send_invite
, user_record
);
1642 nm_release_conference(conference
);
1647 _get_conference_name(int id
)
1649 static char *name
= NULL
;
1653 name
= g_strdup_printf(_("GroupWise Conference %d"), id
);
1659 _show_privacy_locked_error(PurpleConnection
*gc
, NMUser
*user
)
1663 err
= g_strdup_printf(_("Unable to change server side privacy settings (%s)."),
1664 nm_error_to_string(NMERR_ADMIN_LOCKED
));
1665 purple_notify_error(gc
, NULL
, err
, NULL
,
1666 purple_request_cpar_from_connection(gc
));
1670 /*******************************************************************************
1671 * Connect and recv callbacks
1672 ******************************************************************************/
1675 novell_ssl_connect_error(PurpleSslConnection
* gsc
,
1676 PurpleSslErrorType error
, gpointer data
)
1678 PurpleConnection
*gc
;
1682 user
= purple_connection_get_protocol_data(gc
);
1683 user
->conn
->ssl_conn
->data
= NULL
;
1685 purple_connection_ssl_error (gc
, error
);
1689 novell_ssl_recv_cb(gpointer data
, PurpleSslConnection
* gsc
,
1690 PurpleInputCondition condition
)
1692 PurpleConnection
*gc
= data
;
1699 user
= purple_connection_get_protocol_data(gc
);
1703 rc
= nm_process_new_data(user
);
1706 if (_is_disconnect_error(rc
)) {
1708 purple_connection_error(gc
,
1709 PURPLE_CONNECTION_ERROR_NETWORK_ERROR
,
1710 _("Error communicating with server. Closing connection."));
1712 purple_debug(PURPLE_DEBUG_INFO
, "novell",
1713 "Error processing event or response (%d).\n", rc
);
1719 novell_ssl_connected_cb(gpointer data
, PurpleSslConnection
* gsc
,
1720 PurpleInputCondition cond
)
1722 PurpleConnection
*gc
= data
;
1726 const char *pwd
= NULL
;
1727 const char *my_addr
= NULL
;
1730 if (gc
== NULL
|| gsc
== NULL
)
1733 user
= purple_connection_get_protocol_data(gc
);
1734 if ((user
== NULL
) || (conn
= user
->conn
) == NULL
)
1737 purple_connection_update_progress(gc
, _("Authenticating..."),
1738 2, NOVELL_CONNECT_STEPS
);
1740 my_addr
= purple_network_get_my_ip(gsc
->fd
);
1741 pwd
= purple_connection_get_password(gc
);
1742 ua
= _user_agent_string();
1744 rc
= nm_send_login(user
, pwd
, my_addr
, ua
, _login_resp_cb
, NULL
);
1746 conn
->connected
= TRUE
;
1747 purple_ssl_input_add(gsc
, novell_ssl_recv_cb
, gc
);
1749 purple_connection_error(gc
,
1750 PURPLE_CONNECTION_ERROR_NETWORK_ERROR
,
1751 _("Unable to connect"));
1754 purple_connection_update_progress(gc
, _("Waiting for response..."),
1755 3, NOVELL_CONNECT_STEPS
);
1760 /*******************************************************************************
1761 * Event callback and event handlers
1762 ******************************************************************************/
1765 _evt_receive_message(NMUser
* user
, NMEvent
* event
)
1767 NMUserRecord
*user_record
= NULL
;
1768 NMContact
*contact
= NULL
;
1769 PurpleIMConversation
*im
;
1770 NMConference
*conference
;
1771 PurpleMessageFlags flags
;
1774 text
= g_markup_escape_text(nm_event_get_text(event
), -1);
1776 conference
= nm_event_get_conference(event
);
1779 PurpleChatConversation
*chat
= nm_conference_get_data(conference
);
1781 /* Is this a single person 'conversation' or a conference? */
1782 if (chat
== NULL
&& nm_conference_get_participant_count(conference
) == 1) {
1784 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
1788 if (nm_event_get_type(event
) == NMEVT_RECEIVE_AUTOREPLY
)
1789 flags
|= PURPLE_MESSAGE_AUTO_RESP
;
1791 purple_serv_got_im(purple_account_get_connection(user
->client_data
),
1792 nm_user_record_get_display_id(user_record
),
1794 nm_event_get_gmt(event
));
1796 im
= purple_conversations_find_im_with_account(
1797 nm_user_record_get_display_id(user_record
),
1798 (PurpleAccount
*) user
->client_data
);
1801 contact
= nm_find_contact(user
, nm_event_get_source(event
));
1804 purple_conversation_set_title(PURPLE_CONVERSATION(im
),
1805 nm_contact_get_display_name(contact
));
1811 nm_user_record_get_full_name(user_record
);
1814 name
= nm_user_record_get_userid(user_record
);
1816 purple_conversation_set_title(PURPLE_CONVERSATION(im
), name
);
1822 /* this should not happen, see the event code.
1823 * the event code will get the contact details from
1824 * the server if it does not have them before calling
1825 * the event callback.
1831 /* get the contact for send if we have one */
1832 NMContact
*contact
= nm_find_contact(user
,
1833 nm_event_get_source(event
));
1835 /* get the user record for the sender */
1836 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
1838 const char *name
= nm_contact_get_display_name(contact
);
1841 name
= nm_user_record_get_full_name(user_record
);
1843 name
= nm_user_record_get_display_id(user_record
);
1846 purple_serv_got_chat_in(purple_account_get_connection(user
->client_data
),
1847 purple_chat_conversation_get_id(chat
),
1848 name
, PURPLE_MESSAGE_RECV
, text
, nm_event_get_gmt(event
));
1857 _evt_conference_left(NMUser
* user
, NMEvent
* event
)
1859 PurpleChatConversation
*chat
;
1860 NMConference
*conference
;
1862 conference
= nm_event_get_conference(event
);
1864 chat
= nm_conference_get_data(conference
);
1866 NMUserRecord
*ur
= nm_find_user_record(user
,
1867 nm_event_get_source(event
));
1870 purple_chat_conversation_remove_user(chat
,
1871 nm_user_record_get_display_id(ur
),
1878 _evt_conference_invite_notify(NMUser
* user
, NMEvent
* event
)
1880 PurpleConversation
*gconv
;
1881 NMConference
*conference
;
1882 NMUserRecord
*user_record
= NULL
;
1885 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
1886 conference
= nm_event_get_conference(event
);
1887 if (user_record
&& conference
) {
1888 gconv
= nm_conference_get_data(conference
);
1889 str
= g_strdup_printf(_("%s has been invited to this conversation."),
1890 nm_user_record_get_display_id(user_record
));
1891 purple_conversation_write_system_message(gconv
, str
, 0);
1897 _evt_conference_invite(NMUser
* user
, NMEvent
* event
)
1900 PurpleConnection
*gc
;
1901 GSList
*parms
= NULL
;
1902 const char *title
= NULL
;
1903 const char *secondary
= NULL
;
1904 const char *name
= NULL
;
1905 char *primary
= NULL
;
1908 ur
= nm_find_user_record(user
, nm_event_get_source(event
));
1910 name
= nm_user_record_get_full_name(ur
);
1913 name
= nm_event_get_source(event
);
1915 gmt
= nm_event_get_gmt(event
);
1916 title
= _("Invitation to Conversation");
1917 primary
= g_strdup_printf(_("Invitation from: %s\n\nSent: %s"),
1918 name
, purple_date_format_full(localtime(&gmt
)));
1919 secondary
= _("Would you like to join the conversation?");
1921 /* Set up parms list for the callbacks
1922 * We need to send the NMUser object and
1923 * the NMConference object to the callbacks
1926 parms
= g_slist_append(parms
, user
);
1927 parms
= g_slist_append(parms
, nm_event_get_conference(event
));
1929 /* Prompt the user */
1930 /* TODO: Would it be better to use purple_serv_got_chat_invite() here? */
1931 gc
= purple_account_get_connection(user
->client_data
);
1932 purple_request_action(gc
, title
, primary
, secondary
,
1933 PURPLE_DEFAULT_ACTION_NONE
,
1934 purple_request_cpar_from_connection(gc
),
1936 _("Yes"), G_CALLBACK(_join_conference_cb
),
1937 _("No"), G_CALLBACK(_reject_conference_cb
));
1944 _evt_conference_joined(NMUser
* user
, NMEvent
* event
)
1946 PurpleChatConversation
*chat
= NULL
;
1947 PurpleConnection
*gc
;
1948 NMConference
*conference
= NULL
;
1949 NMUserRecord
*ur
= NULL
;
1951 const char *conf_name
;
1953 gc
= purple_account_get_connection(user
->client_data
);
1957 conference
= nm_event_get_conference(event
);
1959 chat
= nm_conference_get_data(conference
);
1960 if (nm_conference_get_participant_count(conference
) == 2 && chat
== NULL
) {
1961 ur
= nm_conference_get_participant(conference
, 0);
1963 conf_name
= _get_conference_name(++user
->conference_count
);
1965 purple_serv_got_joined_chat(gc
, user
->conference_count
, conf_name
);
1968 nm_conference_set_data(conference
, (gpointer
) chat
);
1970 name
= nm_user_record_get_display_id(ur
);
1971 purple_chat_conversation_add_user(chat
, name
, NULL
,
1972 PURPLE_CHAT_USER_NONE
, TRUE
);
1979 ur
= nm_find_user_record(user
, nm_event_get_source(event
));
1981 name
= nm_user_record_get_display_id(ur
);
1982 if (!purple_chat_conversation_has_user(chat
, name
)) {
1983 purple_chat_conversation_add_user(chat
, name
, NULL
,
1984 PURPLE_CHAT_USER_NONE
, TRUE
);
1992 _evt_status_change(NMUser
* user
, NMEvent
* event
)
1994 PurpleBuddy
*buddy
= NULL
;
1997 NMUserRecord
*user_record
;
1998 const char *display_id
;
2001 user_record
= nm_event_get_user_record(event
);
2004 /* Retrieve new status */
2005 status
= nm_user_record_get_status(user_record
);
2007 /* Update status for buddy in all folders */
2008 display_id
= nm_user_record_get_display_id(user_record
);
2009 buddies
= purple_blist_find_buddies(user
->client_data
, display_id
);
2010 for (bnode
= buddies
; bnode
; bnode
= bnode
->next
) {
2011 buddy
= (PurpleBuddy
*) bnode
->data
;
2013 _update_buddy_status(user
, buddy
, status
, nm_event_get_gmt(event
));
2017 g_slist_free(buddies
);
2023 _evt_user_disconnect(NMUser
* user
, NMEvent
* event
)
2025 PurpleConnection
*gc
;
2026 PurpleAccount
*account
= user
->client_data
;
2028 gc
= purple_account_get_connection(account
);
2031 if (!purple_account_get_remember_password(account
))
2032 purple_account_set_password(account
, NULL
, NULL
, NULL
);
2033 purple_connection_error(gc
,
2034 PURPLE_CONNECTION_ERROR_NAME_IN_USE
,
2035 _("You have signed on from another location"));
2040 _evt_user_typing(NMUser
* user
, NMEvent
* event
)
2042 PurpleConnection
*gc
;
2043 NMUserRecord
*user_record
= NULL
;
2045 gc
= purple_account_get_connection((PurpleAccount
*) user
->client_data
);
2047 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
2049 purple_serv_got_typing(gc
, nm_user_record_get_display_id(user_record
),
2050 30, PURPLE_IM_TYPING
);
2056 _evt_user_not_typing(NMUser
* user
, NMEvent
* event
)
2058 PurpleConnection
*gc
;
2059 NMUserRecord
*user_record
;
2061 gc
= purple_account_get_connection((PurpleAccount
*) user
->client_data
);
2063 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
2065 purple_serv_got_typing_stopped(gc
,
2066 nm_user_record_get_display_id(user_record
));
2072 _evt_undeliverable_status(NMUser
* user
, NMEvent
* event
)
2075 PurpleConversation
*gconv
;
2078 ur
= nm_find_user_record(user
, nm_event_get_source(event
));
2080 /* XXX - Should this be PURPLE_CONV_TYPE_IM? */
2082 purple_conversations_find_with_account(nm_user_record_get_display_id(ur
),
2085 const char *name
= nm_user_record_get_full_name(ur
);
2088 name
= nm_user_record_get_display_id(ur
);
2090 str
= g_strdup_printf(_("%s appears to be offline and did not receive"
2091 " the message that you just sent."), name
);
2092 purple_conversation_write_system_message(gconv
, str
, 0);
2099 _event_callback(NMUser
* user
, NMEvent
* event
)
2101 if (user
== NULL
|| event
== NULL
)
2104 switch (nm_event_get_type(event
)) {
2105 case NMEVT_STATUS_CHANGE
:
2106 _evt_status_change(user
, event
);
2108 case NMEVT_RECEIVE_AUTOREPLY
:
2109 case NMEVT_RECEIVE_MESSAGE
:
2110 _evt_receive_message(user
, event
);
2112 case NMEVT_USER_DISCONNECT
:
2113 _evt_user_disconnect(user
, event
);
2115 case NMEVT_USER_TYPING
:
2116 _evt_user_typing(user
, event
);
2118 case NMEVT_USER_NOT_TYPING
:
2119 _evt_user_not_typing(user
, event
);
2121 case NMEVT_SERVER_DISCONNECT
:
2122 /* Nothing to do? */
2124 case NMEVT_INVALID_RECIPIENT
:
2126 case NMEVT_UNDELIVERABLE_STATUS
:
2127 _evt_undeliverable_status(user
, event
);
2129 case NMEVT_CONFERENCE_INVITE_NOTIFY
:
2130 /* Someone else has been invited to join a
2131 * conference that we are currently a part of
2133 _evt_conference_invite_notify(user
, event
);
2135 case NMEVT_CONFERENCE_INVITE
:
2136 /* We have been invited to join a conference */
2137 _evt_conference_invite(user
, event
);
2139 case NMEVT_CONFERENCE_JOINED
:
2140 /* Some one has joined a conference that we
2143 _evt_conference_joined(user
, event
);
2145 case NMEVT_CONFERENCE_LEFT
:
2146 /* Someone else has left a conference that we
2147 * are currently a part of
2149 _evt_conference_left(user
, event
);
2152 purple_debug(PURPLE_DEBUG_INFO
, "novell",
2153 "_event_callback(): unhandled event, %d\n",
2154 nm_event_get_type(event
));
2159 /*******************************************************************************
2161 ******************************************************************************/
2164 novell_login(PurpleAccount
* account
)
2166 PurpleConnection
*gc
;
2167 NMUser
*user
= NULL
;
2172 if (account
== NULL
)
2175 gc
= purple_account_get_connection(account
);
2179 purple_connection_set_flags(gc
, PURPLE_CONNECTION_FLAG_NO_IMAGES
);
2181 server
= purple_account_get_string(account
, "server", NULL
);
2182 if (server
== NULL
|| *server
== '\0') {
2184 /* TODO: Would be nice to prompt if not set!
2185 * purple_request_fields(gc, _("Server Address"),...);
2188 /* ...but for now just error out with a nice message. */
2189 purple_connection_error(gc
,
2190 PURPLE_CONNECTION_ERROR_INVALID_SETTINGS
,
2191 _("Unable to connect to server. Please enter the "
2192 "address of the server to which you wish to connect."));
2196 port
= purple_account_get_int(account
, "port", DEFAULT_PORT
);
2197 name
= purple_account_get_username(account
);
2199 user
= nm_initialize_user(name
, server
, port
, account
, _event_callback
);
2200 if (user
&& user
->conn
) {
2202 purple_connection_set_protocol_data(gc
, user
);
2204 /* connect to the server */
2205 purple_connection_update_progress(gc
, _("Connecting"),
2206 1, NOVELL_CONNECT_STEPS
);
2208 user
->conn
->use_ssl
= TRUE
;
2210 user
->conn
->ssl_conn
= g_new0(NMSSLConn
, 1);
2211 user
->conn
->ssl_conn
->read
= (nm_ssl_read_cb
) purple_ssl_read
;
2212 user
->conn
->ssl_conn
->write
= (nm_ssl_write_cb
) purple_ssl_write
;
2214 user
->conn
->ssl_conn
->data
= purple_ssl_connect(user
->client_data
,
2215 user
->conn
->addr
, user
->conn
->port
,
2216 novell_ssl_connected_cb
, novell_ssl_connect_error
, gc
);
2217 if (user
->conn
->ssl_conn
->data
== NULL
) {
2218 purple_connection_error(gc
,
2219 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT
,
2220 _("SSL support unavailable"));
2226 novell_close(PurpleConnection
* gc
)
2234 user
= purple_connection_get_protocol_data(gc
);
2237 if (conn
&& conn
->ssl_conn
) {
2238 purple_ssl_close(user
->conn
->ssl_conn
->data
);
2240 nm_deinitialize_user(user
);
2242 purple_connection_set_protocol_data(gc
, NULL
);
2246 novell_send_im(PurpleConnection
*gc
, PurpleMessage
*msg
)
2248 NMUserRecord
*user_record
= NULL
;
2249 NMConference
*conf
= NULL
;
2252 const char *dn
= NULL
;
2254 gboolean done
= TRUE
, created_conf
= FALSE
;
2256 const gchar
*name
= purple_message_get_recipient(msg
);
2258 if (gc
== NULL
|| name
== NULL
|| purple_message_is_empty(msg
))
2261 user
= purple_connection_get_protocol_data(gc
);
2265 /* Create a new message */
2266 plain
= purple_unescape_html(purple_message_get_contents(msg
));
2267 message
= nm_create_message(plain
);
2270 /* Need to get the DN for the buddy so we can look up the convo */
2271 dn
= nm_lookup_dn(user
, name
);
2273 /* Do we already know about the sender? */
2274 user_record
= nm_find_user_record(user
, dn
);
2277 /* Do we already have an instantiated conference? */
2278 conf
= nm_find_conversation(user
, dn
);
2281 /* If not, create a blank conference */
2282 conf
= nm_create_conference(NULL
);
2283 created_conf
= TRUE
;
2285 nm_conference_add_participant(conf
, user_record
);
2288 nm_message_set_conference(message
, conf
);
2290 /* Make sure conference is instantiated */
2291 if (!nm_conference_is_instantiated(conf
)) {
2293 /* It is not, so send the createconf. We will
2294 * have to finish sending the message when we
2295 * get the response with the new conference guid.
2297 rc
= nm_send_create_conference(user
, conf
, _createconf_resp_send_msg
, message
);
2298 _check_for_disconnect(user
, rc
);
2305 /* If we don't have details for the user, then we don't have
2306 * a conference yet. So create one and send the getdetails
2307 * to the server. We will have to finish sending the message
2308 * when we get the response from the server.
2310 conf
= nm_create_conference(NULL
);
2311 created_conf
= TRUE
;
2313 nm_message_set_conference(message
, conf
);
2315 rc
= nm_send_get_details(user
, name
, _get_details_resp_send_msg
, message
);
2316 _check_for_disconnect(user
, rc
);
2323 /* Did we find everything we needed? */
2324 rc
= nm_send_message(user
, message
, _send_message_resp_cb
);
2325 _check_for_disconnect(user
, rc
);
2327 nm_release_message(message
);
2330 if (created_conf
&& conf
)
2331 nm_release_conference(conf
);
2337 novell_send_typing(PurpleConnection
* gc
, const char *name
, PurpleIMTypingState state
)
2339 NMConference
*conf
= NULL
;
2341 const char *dn
= NULL
;
2344 if (gc
== NULL
|| name
== NULL
)
2347 user
= purple_connection_get_protocol_data(gc
);
2351 /* Need to get the DN for the buddy so we can look up the convo */
2352 dn
= nm_lookup_dn(user
, name
);
2355 /* Now find the conference in our list */
2356 conf
= nm_find_conversation(user
, dn
);
2359 rc
= nm_send_typing(user
, conf
,
2360 ((state
== PURPLE_IM_TYPING
) ? TRUE
: FALSE
), NULL
);
2361 _check_for_disconnect(user
, rc
);
2371 novell_convo_closed(PurpleConnection
* gc
, const char *who
)
2378 if (gc
== NULL
|| who
== NULL
)
2381 user
= purple_connection_get_protocol_data(gc
);
2382 if (user
&& (dn
= nm_lookup_dn(user
, who
))) {
2383 conf
= nm_find_conversation(user
, dn
);
2385 rc
= nm_send_leave_conference(user
, conf
, NULL
, NULL
);
2386 _check_for_disconnect(user
, rc
);
2392 novell_chat_leave(PurpleConnection
* gc
, int id
)
2394 NMConference
*conference
;
2396 PurpleChatConversation
*chat
;
2403 user
= purple_connection_get_protocol_data(gc
);
2407 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
2408 conference
= cnode
->data
;
2409 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
2410 if (purple_chat_conversation_get_id(chat
) == id
) {
2411 rc
= nm_send_leave_conference(user
, conference
, NULL
, NULL
);
2412 _check_for_disconnect(user
, rc
);
2418 purple_serv_got_chat_left(gc
, id
);
2422 novell_chat_invite(PurpleConnection
*gc
, int id
,
2423 const char *message
, const char *who
)
2425 NMConference
*conference
;
2427 PurpleChatConversation
*chat
;
2430 NMUserRecord
*user_record
= NULL
;
2435 user
= purple_connection_get_protocol_data(gc
);
2439 user_record
= nm_find_user_record(user
, who
);
2440 if (user_record
== NULL
) {
2441 rc
= nm_send_get_details(user
, who
, _get_details_resp_send_invite
, GINT_TO_POINTER(id
));
2442 _check_for_disconnect(user
, rc
);
2446 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
2447 conference
= cnode
->data
;
2448 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
2449 if (purple_chat_conversation_get_id(chat
) == id
) {
2450 rc
= nm_send_conference_invite(user
, conference
, user_record
,
2451 message
, _sendinvite_resp_cb
, NULL
);
2452 _check_for_disconnect(user
, rc
);
2460 novell_chat_send(PurpleConnection
* gc
, int id
, PurpleMessage
*msg
)
2462 NMConference
*conference
;
2463 PurpleChatConversation
*chat
;
2471 if (gc
== NULL
|| purple_message_is_empty(msg
))
2474 user
= purple_connection_get_protocol_data(gc
);
2478 plain
= purple_unescape_html(purple_message_get_contents(msg
));
2479 message
= nm_create_message(plain
);
2482 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
2483 conference
= cnode
->data
;
2484 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
2485 if (purple_chat_conversation_get_id(chat
) == id
) {
2487 nm_message_set_conference(message
, conference
);
2489 /* check to see if the conference is instatiated yet */
2490 if (!nm_conference_is_instantiated(conference
)) {
2491 nm_message_add_ref(message
);
2492 nm_send_create_conference(user
, conference
, _createconf_resp_send_msg
, message
);
2494 rc
= nm_send_message(user
, message
, _send_message_resp_cb
);
2497 nm_release_message(message
);
2499 if (!_check_for_disconnect(user
, rc
)) {
2501 /* Use the account alias if it is set */
2502 name
= purple_account_get_private_alias(user
->client_data
);
2503 if (name
== NULL
|| *name
== '\0') {
2505 /* If there is no account alias, try full name */
2506 name
= nm_user_record_get_full_name(user
->user_record
);
2507 if (name
== NULL
|| *name
== '\0') {
2509 /* Fall back to the username that we are signed in with */
2510 name
= purple_account_get_username(user
->client_data
);
2514 purple_serv_got_chat_in(gc
, id
, name
,
2515 purple_message_get_flags(msg
),
2516 purple_message_get_contents(msg
), time(NULL
));
2526 /* The conference was not found, must be closed */
2527 chat
= purple_conversations_find_chat(gc
, id
);
2529 str
= g_strdup(_("This conference has been closed."
2530 " No more messages can be sent."));
2531 purple_conversation_write_system_message(PURPLE_CONVERSATION(chat
), str
, 0);
2536 nm_release_message(message
);
2542 novell_add_buddy(PurpleConnection
* gc
, PurpleBuddy
*buddy
, PurpleGroup
* group
, const char *message
)
2544 NMFolder
*folder
= NULL
;
2548 const char *alias
, *gname
, *bname
;
2550 if (gc
== NULL
|| buddy
== NULL
|| group
== NULL
)
2553 user
= (NMUser
*) purple_connection_get_protocol_data(gc
);
2557 /* If we haven't synched the contact list yet, ignore
2558 * the add_buddy calls. Server side list is the master.
2560 if (!user
->clist_synched
)
2563 /* Don't re-add a buddy that is already on our contact list */
2564 if (nm_find_user_record(user
, purple_buddy_get_name(buddy
)) != NULL
)
2567 contact
= nm_create_contact();
2568 nm_contact_set_dn(contact
, purple_buddy_get_name(buddy
));
2570 /* Remove the PurpleBuddy (we will add it back after adding it
2571 * to the server side list). Save the alias if there is one.
2573 alias
= purple_buddy_get_alias(buddy
);
2574 bname
= purple_buddy_get_name(buddy
);
2575 if (alias
&& !purple_strequal(alias
, bname
))
2576 nm_contact_set_display_name(contact
, alias
);
2578 purple_blist_remove_buddy(buddy
);
2581 gname
= purple_group_get_name(group
);
2582 if (purple_strequal(gname
, NM_ROOT_FOLDER_NAME
)) {
2586 folder
= nm_find_folder(user
, gname
);
2589 /* We have everything that we need, so send the createcontact */
2590 rc
= nm_send_create_contact(user
, folder
, contact
,
2591 _create_contact_resp_cb
, contact
);
2595 /* Need to create the folder before we can add the contact */
2596 rc
= nm_send_create_folder(user
, gname
,
2597 _create_folder_resp_add_contact
, contact
);
2600 _check_for_disconnect(user
, rc
);
2605 novell_remove_buddy(PurpleConnection
*gc
, PurpleBuddy
*buddy
, PurpleGroup
*group
)
2610 const char *dn
, *gname
;
2613 if (gc
== NULL
|| buddy
== NULL
|| group
== NULL
)
2616 user
= purple_connection_get_protocol_data(gc
);
2617 if (user
&& (dn
= nm_lookup_dn(user
, purple_buddy_get_name(buddy
)))) {
2618 gname
= purple_group_get_name(group
);
2619 if (purple_strequal(gname
, NM_ROOT_FOLDER_NAME
)) {
2622 folder
= nm_find_folder(user
, gname
);
2624 contact
= nm_folder_find_contact(folder
, dn
);
2627 /* Remove the buddy from the contact */
2628 nm_contact_set_data(contact
, NULL
);
2630 /* Tell the server to remove the contact */
2631 rc
= nm_send_remove_contact(user
, folder
, contact
,
2632 _remove_contact_resp_cb
, NULL
);
2633 _check_for_disconnect(user
, rc
);
2640 novell_remove_group(PurpleConnection
* gc
, PurpleGroup
*group
)
2645 if (gc
== NULL
|| group
== NULL
)
2648 user
= purple_connection_get_protocol_data(gc
);
2650 NMFolder
*folder
= nm_find_folder(user
, purple_group_get_name(group
));
2653 rc
= nm_send_remove_folder(user
, folder
,
2654 _remove_folder_resp_cb
, NULL
);
2655 _check_for_disconnect(user
, rc
);
2661 novell_alias_buddy(PurpleConnection
* gc
, const char *name
, const char *alias
)
2665 GList
*contacts
= NULL
;
2666 GList
*cnode
= NULL
;
2667 const char *dn
= NULL
, *fname
= NULL
;
2670 if (gc
== NULL
|| name
== NULL
|| alias
== NULL
)
2673 user
= purple_connection_get_protocol_data(gc
);
2674 if (user
&& (dn
= nm_lookup_dn(user
, name
))) {
2676 /* Alias all of instances of the contact */
2677 contacts
= nm_find_contacts(user
, dn
);
2678 for (cnode
= contacts
; cnode
!= NULL
; cnode
= cnode
->next
) {
2679 contact
= (NMContact
*) cnode
->data
;
2681 PurpleGroup
*group
= NULL
;
2685 /* Alias the Purple buddy? */
2686 folder
= nm_find_folder_by_id(user
,
2687 nm_contact_get_parent_id(contact
));
2689 fname
= nm_folder_get_name(folder
);
2690 if (*fname
== '\0') {
2691 fname
= NM_ROOT_FOLDER_NAME
;
2693 group
= purple_blist_find_group(fname
);
2698 buddy
= purple_blist_find_buddy_in_group(user
->client_data
,
2700 balias
= buddy
? purple_buddy_get_local_alias(buddy
) : NULL
;
2701 if (balias
&& !purple_strequal(balias
, alias
))
2702 purple_buddy_set_local_alias(buddy
, alias
);
2705 /* Tell the server to alias the contact */
2706 rc
= nm_send_rename_contact(user
, contact
, alias
,
2707 _rename_contact_resp_cb
, NULL
);
2708 _check_for_disconnect(user
, rc
);
2712 g_list_free(contacts
);
2717 novell_group_buddy(PurpleConnection
* gc
,
2718 const char *name
, const char *old_group_name
,
2719 const char *new_group_name
)
2721 NMFolder
*old_folder
;
2722 NMFolder
*new_folder
;
2728 if (gc
== NULL
|| name
== NULL
||
2729 old_group_name
== NULL
|| new_group_name
== NULL
)
2732 user
= purple_connection_get_protocol_data(gc
);
2733 if (user
&& (dn
= nm_lookup_dn(user
, name
))) {
2735 /* Find the old folder */
2736 if (purple_strequal(old_group_name
, NM_ROOT_FOLDER_NAME
)) {
2737 old_folder
= nm_get_root_folder(user
);
2738 if (nm_folder_find_contact(old_folder
, dn
) == NULL
)
2739 old_folder
= nm_find_folder(user
, old_group_name
);
2741 old_folder
= nm_find_folder(user
, old_group_name
);
2744 if (old_folder
&& (contact
= nm_folder_find_contact(old_folder
, dn
))) {
2746 /* Find the new folder */
2747 new_folder
= nm_find_folder(user
, new_group_name
);
2748 if (new_folder
== NULL
) {
2749 if (purple_strequal(new_group_name
, NM_ROOT_FOLDER_NAME
))
2750 new_folder
= nm_get_root_folder(user
);
2755 /* Tell the server to move the contact to the new folder */
2756 rc
= nm_send_move_contact(user
, contact
, new_folder
,
2757 _move_contact_resp_cb
, NULL
);
2761 nm_contact_add_ref(contact
);
2763 /* Remove the old contact first */
2764 nm_send_remove_contact(user
, old_folder
, contact
,
2765 _remove_contact_resp_cb
, NULL
);
2767 /* New folder does not exist yet, so create it */
2768 rc
= nm_send_create_folder(user
, new_group_name
,
2769 _create_folder_resp_move_contact
,
2773 _check_for_disconnect(user
, rc
);
2779 novell_rename_group(PurpleConnection
* gc
, const char *old_name
,
2780 PurpleGroup
*group
, GList
*moved_buddies
)
2786 if (gc
== NULL
|| old_name
== NULL
|| group
== NULL
|| moved_buddies
== NULL
) {
2790 user
= purple_connection_get_protocol_data(gc
);
2792 const char *gname
= purple_group_get_name(group
);
2793 /* Does new folder exist already? */
2794 if (nm_find_folder(user
, gname
)) {
2795 /* purple_group_set_name() adds the buddies
2796 * to the new group and removes the old group...
2797 * so there is nothing more to do here.
2802 if (purple_strequal(old_name
, NM_ROOT_FOLDER_NAME
)) {
2803 /* Can't rename the root folder ... need to revisit this */
2807 folder
= nm_find_folder(user
, old_name
);
2809 rc
= nm_send_rename_folder(user
, folder
, gname
,
2810 _rename_folder_resp_cb
, NULL
);
2811 _check_for_disconnect(user
, rc
);
2817 novell_list_icon(PurpleAccount
* account
, PurpleBuddy
* buddy
)
2823 novell_tooltip_text(PurpleBuddy
* buddy
, PurpleNotifyUserInfo
* user_info
, gboolean full
)
2825 NMUserRecord
*user_record
= NULL
;
2826 PurpleConnection
*gc
;
2829 const char *status_str
= NULL
;
2830 const char *text
= NULL
;
2835 gc
= purple_account_get_connection(purple_buddy_get_account(buddy
));
2836 if (gc
== NULL
|| (user
= purple_connection_get_protocol_data(gc
)) == NULL
)
2839 if (PURPLE_BUDDY_IS_ONLINE(buddy
)) {
2840 user_record
= nm_find_user_record(user
, purple_buddy_get_name(buddy
));
2842 status
= nm_user_record_get_status(user_record
);
2843 text
= nm_user_record_get_status_text(user_record
);
2844 /* No custom text, so default it ... */
2846 case NM_STATUS_AVAILABLE
:
2847 status_str
= _("Available");
2849 case NM_STATUS_AWAY
:
2850 status_str
= _("Away");
2852 case NM_STATUS_BUSY
:
2853 status_str
= _("Busy");
2855 case NM_STATUS_AWAY_IDLE
:
2856 status_str
= _("Idle");
2858 case NM_STATUS_OFFLINE
:
2859 status_str
= _("Offline");
2862 status_str
= _("Unknown");
2866 purple_notify_user_info_add_pair_plaintext(user_info
, _("Status"), status_str
);
2869 /* TODO: Check whether it's correct to call add_pair_html,
2870 or if we should be using add_pair_plaintext */
2871 purple_notify_user_info_add_pair_html(user_info
, _("Message"), text
);
2878 novell_set_idle(PurpleConnection
* gc
, int time
)
2882 const char *id
= NULL
;
2883 PurpleStatus
*status
= NULL
;
2888 user
= purple_connection_get_protocol_data(gc
);
2892 status
= purple_account_get_active_status(purple_connection_get_account(gc
));
2893 id
= purple_status_get_id(status
);
2895 /* Only go idle if active status is available */
2896 if (purple_strequal(id
, NOVELL_STATUS_TYPE_AVAILABLE
)) {
2898 rc
= nm_send_set_status(user
, NM_STATUS_AWAY_IDLE
, NULL
, NULL
, NULL
, NULL
);
2900 rc
= nm_send_set_status(user
, NM_STATUS_AVAILABLE
, NULL
, NULL
, NULL
, NULL
);
2904 _check_for_disconnect(user
, rc
);
2908 novell_get_info(PurpleConnection
* gc
, const char *name
)
2910 NMUserRecord
*user_record
;
2914 if (gc
== NULL
|| name
== NULL
)
2917 user
= purple_connection_get_protocol_data(gc
);
2920 user_record
= nm_find_user_record(user
, name
);
2922 _show_info(gc
, user_record
, g_strdup(name
));
2925 rc
= nm_send_get_details(user
, name
,
2926 _get_details_resp_show_info
, g_strdup(name
));
2928 _check_for_disconnect(user
, rc
);
2936 novell_status_text(PurpleBuddy
* buddy
)
2938 const char *text
= NULL
;
2939 const char *dn
= NULL
;
2940 PurpleAccount
*account
;
2942 account
= buddy
? purple_buddy_get_account(buddy
) : NULL
;
2943 if (buddy
&& account
) {
2944 PurpleConnection
*gc
= purple_account_get_connection(account
);
2947 NMUser
*user
= purple_connection_get_protocol_data(gc
);
2950 dn
= nm_lookup_dn(user
, purple_buddy_get_name(buddy
));
2952 NMUserRecord
*user_record
= nm_find_user_record(user
, dn
);
2955 text
= nm_user_record_get_status_text(user_record
);
2957 return g_strdup(text
);
2968 novell_status_types(PurpleAccount
*account
)
2970 GList
*status_types
= NULL
;
2971 PurpleStatusType
*type
;
2973 g_return_val_if_fail(account
!= NULL
, NULL
);
2975 type
= purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE
, NOVELL_STATUS_TYPE_AVAILABLE
,
2976 NULL
, TRUE
, TRUE
, FALSE
,
2977 "message", _("Message"), purple_value_new(G_TYPE_STRING
),
2979 status_types
= g_list_append(status_types
, type
);
2981 type
= purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY
, NOVELL_STATUS_TYPE_AWAY
,
2982 NULL
, TRUE
, TRUE
, FALSE
,
2983 "message", _("Message"), purple_value_new(G_TYPE_STRING
),
2985 status_types
= g_list_append(status_types
, type
);
2987 type
= purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE
, NOVELL_STATUS_TYPE_BUSY
,
2988 _("Busy"), TRUE
, TRUE
, FALSE
,
2989 "message", _("Message"), purple_value_new(G_TYPE_STRING
),
2991 status_types
= g_list_append(status_types
, type
);
2993 type
= purple_status_type_new_full(PURPLE_STATUS_INVISIBLE
, NOVELL_STATUS_TYPE_APPEAR_OFFLINE
,
2994 NULL
, TRUE
, TRUE
, FALSE
);
2995 status_types
= g_list_append(status_types
, type
);
2997 type
= purple_status_type_new_full(PURPLE_STATUS_OFFLINE
, NULL
, NULL
, TRUE
, TRUE
, FALSE
);
2998 status_types
= g_list_append(status_types
, type
);
3000 return status_types
;
3004 novell_set_status(PurpleAccount
*account
, PurpleStatus
*status
)
3006 PurpleConnection
*gc
;
3008 PurplePresence
*presence
;
3009 PurpleStatusType
*type
;
3010 PurpleStatusPrimitive primitive
;
3012 NMSTATUS_T novellstatus
= NM_STATUS_AVAILABLE
;
3014 const char *msg
= NULL
;
3017 connected
= purple_account_is_connected(account
);
3018 presence
= purple_status_get_presence(status
);
3019 type
= purple_status_get_status_type(status
);
3020 primitive
= purple_status_type_get_primitive(type
);
3023 * We don't have any independent statuses, so we don't need to
3024 * do anything when a status is deactivated (because another
3025 * status is about to be activated).
3027 if (!purple_status_is_active(status
))
3033 gc
= purple_account_get_connection(account
);
3034 user
= purple_connection_get_protocol_data(gc
);
3038 if (primitive
== PURPLE_STATUS_AVAILABLE
) {
3039 novellstatus
= NM_STATUS_AVAILABLE
;
3040 } else if (primitive
== PURPLE_STATUS_AWAY
) {
3041 novellstatus
= NM_STATUS_AWAY
;
3042 } else if (primitive
== PURPLE_STATUS_UNAVAILABLE
) {
3043 novellstatus
= NM_STATUS_BUSY
;
3044 } else if (primitive
== PURPLE_STATUS_INVISIBLE
) {
3045 novellstatus
= NM_STATUS_OFFLINE
;
3046 } else if (purple_presence_is_idle(presence
)) {
3047 novellstatus
= NM_STATUS_AWAY_IDLE
;
3049 novellstatus
= NM_STATUS_AVAILABLE
;
3052 if (primitive
== PURPLE_STATUS_AWAY
|| primitive
== PURPLE_STATUS_AVAILABLE
||
3053 primitive
== PURPLE_STATUS_UNAVAILABLE
) {
3054 msg
= purple_status_get_attr_string(status
, "message");
3055 text
= g_strdup(msg
);
3057 if (primitive
== PURPLE_STATUS_AVAILABLE
)
3058 msg
= NULL
; /* no auto replies for online status */
3060 /* Don't want newlines in status text */
3061 purple_util_chrreplace(text
, '\n', ' ');
3064 rc
= nm_send_set_status(user
, novellstatus
, text
, msg
, NULL
, NULL
);
3065 _check_for_disconnect(user
, rc
);
3071 novell_add_permit(PurpleConnection
*gc
, const char *who
)
3075 const char *name
= who
;
3077 if (gc
== NULL
|| who
== NULL
)
3080 user
= purple_connection_get_protocol_data(gc
);
3084 /* Remove first -- we will add it back in when we get
3085 * the okay from the server
3087 purple_account_privacy_permit_remove(purple_connection_get_account(gc
), who
, TRUE
);
3089 if (nm_user_is_privacy_locked(user
)) {
3090 _show_privacy_locked_error(gc
, user
);
3091 _sync_privacy_lists(user
);
3095 /* Work around for problem with un-typed, dotted contexts */
3096 if (strchr(who
, '.')) {
3097 const char *dn
= nm_lookup_dn(user
, who
);
3099 rc
= nm_send_get_details(user
, who
,
3100 _get_details_send_privacy_create
,
3101 GINT_TO_POINTER(TRUE
));
3102 _check_for_disconnect(user
, rc
);
3109 rc
= nm_send_create_privacy_item(user
, name
, TRUE
,
3110 _create_privacy_item_permit_resp_cb
,
3112 _check_for_disconnect(user
, rc
);
3116 novell_add_deny(PurpleConnection
*gc
, const char *who
)
3120 const char *name
= who
;
3122 if (gc
== NULL
|| who
== NULL
)
3125 user
= purple_connection_get_protocol_data(gc
);
3129 /* Remove first -- we will add it back in when we get
3130 * the okay from the server
3132 purple_account_privacy_deny_remove(purple_connection_get_account(gc
), who
, TRUE
);
3134 if (nm_user_is_privacy_locked(user
)) {
3135 _show_privacy_locked_error(gc
, user
);
3136 _sync_privacy_lists(user
);
3140 /* Work around for problem with un-typed, dotted contexts */
3141 if (strchr(who
, '.')) {
3142 const char *dn
= nm_lookup_dn(user
, who
);
3144 rc
= nm_send_get_details(user
, who
,
3145 _get_details_send_privacy_create
,
3146 GINT_TO_POINTER(FALSE
));
3147 _check_for_disconnect(user
, rc
);
3154 rc
= nm_send_create_privacy_item(user
, name
, FALSE
,
3155 _create_privacy_item_deny_resp_cb
,
3157 _check_for_disconnect(user
, rc
);
3161 novell_rem_permit(PurpleConnection
*gc
, const char *who
)
3165 const char *dn
= NULL
;
3167 if (gc
== NULL
|| who
== NULL
)
3170 user
= purple_connection_get_protocol_data(gc
);
3174 if (nm_user_is_privacy_locked(user
)) {
3175 _show_privacy_locked_error(gc
, user
);
3176 _sync_privacy_lists(user
);
3180 dn
= nm_lookup_dn(user
, who
);
3184 rc
= nm_send_remove_privacy_item(user
, dn
, TRUE
,
3185 _remove_privacy_item_resp_cb
,
3187 _check_for_disconnect(user
, rc
);
3191 novell_rem_deny(PurpleConnection
*gc
, const char *who
)
3195 const char *dn
= NULL
;
3197 if (gc
== NULL
|| who
== NULL
)
3200 user
= purple_connection_get_protocol_data(gc
);
3204 if (nm_user_is_privacy_locked(user
)) {
3205 _show_privacy_locked_error(gc
, user
);
3206 _sync_privacy_lists(user
);
3210 dn
= nm_lookup_dn(user
, who
);
3214 rc
= nm_send_remove_privacy_item(user
, dn
, FALSE
,
3215 _remove_privacy_item_resp_cb
,
3217 _check_for_disconnect(user
, rc
);
3221 novell_set_permit_deny(PurpleConnection
*gc
)
3224 const char *dn
, *name
= NULL
;
3225 NMUserRecord
*user_record
= NULL
;
3226 GSList
*node
= NULL
, *copy
= NULL
;
3228 int i
, j
, num_contacts
, num_folders
;
3230 NMFolder
*folder
= NULL
;
3231 PurpleAccount
*account
;
3236 account
= purple_connection_get_account(gc
);
3238 user
= purple_connection_get_protocol_data(gc
);
3242 if (user
->privacy_synched
== FALSE
) {
3243 _sync_privacy_lists(user
);
3244 user
->privacy_synched
= TRUE
;
3248 if (nm_user_is_privacy_locked(user
)) {
3249 _show_privacy_locked_error(gc
, user
);
3250 _sync_privacy_lists(user
);
3254 switch (purple_account_get_privacy_type(account
)) {
3256 case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
:
3257 rc
= nm_send_set_privacy_default(user
, FALSE
,
3258 _set_privacy_default_resp_cb
, NULL
);
3259 _check_for_disconnect(user
, rc
);
3261 /* clear server side deny list */
3263 copy
= g_slist_copy(user
->deny_list
);
3264 for (node
= copy
; node
&& node
->data
; node
= node
->next
) {
3265 rc
= nm_send_remove_privacy_item(user
, (const char *)node
->data
,
3267 if (_check_for_disconnect(user
, rc
))
3271 g_slist_free(user
->deny_list
);
3272 user
->deny_list
= NULL
;
3276 case PURPLE_ACCOUNT_PRIVACY_DENY_ALL
:
3277 rc
= nm_send_set_privacy_default(user
, TRUE
,
3278 _set_privacy_default_resp_cb
, NULL
);
3279 _check_for_disconnect(user
, rc
);
3281 /* clear server side allow list */
3283 copy
= g_slist_copy(user
->allow_list
);
3284 for (node
= copy
; node
&& node
->data
; node
= node
->next
) {
3285 rc
= nm_send_remove_privacy_item(user
, (const char *)node
->data
,
3287 if (_check_for_disconnect(user
, rc
))
3291 g_slist_free(user
->allow_list
);
3292 user
->allow_list
= NULL
;
3296 case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
:
3298 rc
= nm_send_set_privacy_default(user
, TRUE
,
3299 _set_privacy_default_resp_cb
, NULL
);
3300 _check_for_disconnect(user
, rc
);
3302 /* sync allow lists */
3305 for (node
= user
->allow_list
; node
; node
= node
->next
) {
3306 user_record
= nm_find_user_record(user
, (char *)node
->data
);
3308 name
= nm_user_record_get_display_id(user_record
);
3310 if (!g_slist_find_custom(purple_account_privacy_get_permitted(account
),
3311 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3312 purple_account_privacy_permit_add(account
, name
, TRUE
);
3317 for (node
= purple_account_privacy_get_permitted(account
); node
; node
= node
->next
) {
3318 dn
= nm_lookup_dn(user
, (char *)node
->data
);
3321 if (!g_slist_find_custom(user
->allow_list
,
3322 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3323 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
3324 _create_privacy_item_deny_resp_cb
,
3326 _check_for_disconnect(user
, rc
);
3329 purple_account_privacy_permit_remove(account
, (char *)node
->data
, TRUE
);
3335 case PURPLE_ACCOUNT_PRIVACY_DENY_USERS
:
3337 /* set to default allow */
3338 rc
= nm_send_set_privacy_default(user
, FALSE
,
3339 _set_privacy_default_resp_cb
, NULL
);
3340 _check_for_disconnect(user
, rc
);
3342 /* sync deny lists */
3345 for (node
= user
->deny_list
; node
; node
= node
->next
) {
3346 user_record
= nm_find_user_record(user
, (char *)node
->data
);
3348 name
= nm_user_record_get_display_id(user_record
);
3350 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
3351 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3352 purple_account_privacy_deny_add(account
, name
, TRUE
);
3357 for (node
= purple_account_privacy_get_denied(account
); node
; node
= node
->next
) {
3360 dn
= nm_lookup_dn(user
, (char *)node
->data
);
3362 user_record
= nm_find_user_record(user
, dn
);
3363 name
= nm_user_record_get_display_id(user_record
);
3365 if (!g_slist_find_custom(user
->deny_list
,
3366 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3367 rc
= nm_send_create_privacy_item(user
, dn
, FALSE
,
3368 _create_privacy_item_deny_resp_cb
,
3370 _check_for_disconnect(user
, rc
);
3373 purple_account_privacy_deny_remove(account
, (char *)node
->data
, TRUE
);
3380 case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST
:
3382 /* remove users from allow list that are not in buddy list */
3383 copy
= g_slist_copy(user
->allow_list
);
3384 for (node
= copy
; node
&& node
->data
; node
= node
->next
) {
3385 if (!nm_find_contacts(user
, node
->data
)) {
3386 rc
= nm_send_remove_privacy_item(user
, (const char *)node
->data
,
3388 if (_check_for_disconnect(user
, rc
))
3394 /* add all buddies to allow list */
3395 num_contacts
= nm_folder_get_contact_count(user
->root_folder
);
3396 for (i
= 0; i
< num_contacts
; i
++) {
3397 contact
= nm_folder_get_contact(user
->root_folder
, i
);
3398 dn
= nm_contact_get_dn(contact
);
3399 if (dn
&& !g_slist_find_custom(user
->allow_list
,
3400 dn
, (GCompareFunc
)purple_utf8_strcasecmp
))
3402 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
3403 _create_privacy_item_deny_resp_cb
,
3405 if (_check_for_disconnect(user
, rc
))
3411 num_folders
= nm_folder_get_subfolder_count(user
->root_folder
);
3412 for (i
= 0; i
< num_folders
; i
++) {
3413 folder
= nm_folder_get_subfolder(user
->root_folder
, i
);
3414 num_contacts
= nm_folder_get_contact_count(folder
);
3415 for (j
= 0; j
< num_contacts
; j
++) {
3416 contact
= nm_folder_get_contact(folder
, j
);
3417 dn
= nm_contact_get_dn(contact
);
3418 if (dn
&& !g_slist_find_custom(user
->allow_list
,
3419 dn
, (GCompareFunc
)purple_utf8_strcasecmp
))
3421 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
3422 _create_privacy_item_deny_resp_cb
,
3424 if (_check_for_disconnect(user
, rc
))
3430 /* set to default deny */
3431 rc
= nm_send_set_privacy_default(user
, TRUE
,
3432 _set_privacy_default_resp_cb
, NULL
);
3433 if (_check_for_disconnect(user
, rc
))
3441 novell_blist_node_menu(PurpleBlistNode
*node
)
3444 PurpleActionMenu
*act
;
3446 if(PURPLE_IS_BUDDY(node
)) {
3447 act
= purple_action_menu_new(_("Initiate _Chat"),
3448 PURPLE_CALLBACK(_initiate_conference_cb
),
3450 list
= g_list_append(list
, act
);
3457 novell_keepalive(PurpleConnection
*gc
)
3465 user
= purple_connection_get_protocol_data(gc
);
3469 rc
= nm_send_keepalive(user
, NULL
, NULL
);
3470 _check_for_disconnect(user
, rc
);
3474 novell_get_max_message_size(PurpleConversation
*conv
)
3476 /* XXX: got from pidgin-otr - verify and document it */
3481 novell_protocol_init(NovellProtocol
*self
)
3483 PurpleProtocol
*protocol
= PURPLE_PROTOCOL(self
);
3484 PurpleAccountOption
*option
;
3486 protocol
->id
= "prpl-novell";
3487 protocol
->name
= "GroupWise";
3489 option
= purple_account_option_string_new(_("Server address"), "server", NULL
);
3490 protocol
->account_options
=
3491 g_list_append(protocol
->account_options
, option
);
3493 option
= purple_account_option_int_new(_("Server port"), "port", DEFAULT_PORT
);
3494 protocol
->account_options
=
3495 g_list_append(protocol
->account_options
, option
);
3499 novell_protocol_class_init(NovellProtocolClass
*klass
)
3501 PurpleProtocolClass
*protocol_class
= PURPLE_PROTOCOL_CLASS(klass
);
3503 protocol_class
->login
= novell_login
;
3504 protocol_class
->close
= novell_close
;
3505 protocol_class
->status_types
= novell_status_types
;
3506 protocol_class
->list_icon
= novell_list_icon
;
3510 novell_protocol_class_finalize(G_GNUC_UNUSED NovellProtocolClass
*klass
)
3515 novell_protocol_client_iface_init(PurpleProtocolClientInterface
*client_iface
)
3517 client_iface
->status_text
= novell_status_text
;
3518 client_iface
->tooltip_text
= novell_tooltip_text
;
3519 client_iface
->blist_node_menu
= novell_blist_node_menu
;
3520 client_iface
->convo_closed
= novell_convo_closed
;
3521 client_iface
->normalize
= purple_normalize_nocase
;
3522 client_iface
->get_max_message_size
= novell_get_max_message_size
;
3526 novell_protocol_server_iface_init(PurpleProtocolServerInterface
*server_iface
)
3528 server_iface
->get_info
= novell_get_info
;
3529 server_iface
->set_status
= novell_set_status
;
3530 server_iface
->set_idle
= novell_set_idle
;
3531 server_iface
->add_buddy
= novell_add_buddy
;
3532 server_iface
->remove_buddy
= novell_remove_buddy
;
3533 server_iface
->keepalive
= novell_keepalive
;
3534 server_iface
->alias_buddy
= novell_alias_buddy
;
3535 server_iface
->group_buddy
= novell_group_buddy
;
3536 server_iface
->rename_group
= novell_rename_group
;
3537 server_iface
->remove_group
= novell_remove_group
;
3541 novell_protocol_im_iface_init(PurpleProtocolIMInterface
*im_iface
)
3543 im_iface
->send
= novell_send_im
;
3544 im_iface
->send_typing
= novell_send_typing
;
3548 novell_protocol_chat_iface_init(PurpleProtocolChatInterface
*chat_iface
)
3550 chat_iface
->invite
= novell_chat_invite
;
3551 chat_iface
->leave
= novell_chat_leave
;
3552 chat_iface
->send
= novell_chat_send
;
3556 novell_protocol_privacy_iface_init(PurpleProtocolPrivacyInterface
*privacy_iface
)
3558 privacy_iface
->add_permit
= novell_add_permit
;
3559 privacy_iface
->add_deny
= novell_add_deny
;
3560 privacy_iface
->rem_permit
= novell_rem_permit
;
3561 privacy_iface
->rem_deny
= novell_rem_deny
;
3562 privacy_iface
->set_permit_deny
= novell_set_permit_deny
;
3565 G_DEFINE_DYNAMIC_TYPE_EXTENDED(
3566 NovellProtocol
, novell_protocol
, PURPLE_TYPE_PROTOCOL
, 0,
3568 G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CLIENT
,
3569 novell_protocol_client_iface_init
)
3571 G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_SERVER
,
3572 novell_protocol_server_iface_init
)
3574 G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_IM
,
3575 novell_protocol_im_iface_init
)
3577 G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CHAT
,
3578 novell_protocol_chat_iface_init
)
3580 G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_PRIVACY
,
3581 novell_protocol_privacy_iface_init
));
3583 static PurplePluginInfo
*
3584 plugin_query(GError
**error
)
3586 return purple_plugin_info_new(
3587 "id", "prpl-novell",
3588 "name", "Novell GroupWise Protocol",
3589 "version", DISPLAY_VERSION
,
3590 "category", N_("Protocol"),
3591 "summary", N_("Novell GroupWise Messenger Protocol Plugin"),
3592 "description", N_("Novell GroupWise Messenger Protocol Plugin"),
3593 "website", PURPLE_WEBSITE
,
3594 "abi-version", PURPLE_ABI_VERSION
,
3595 "flags", PURPLE_PLUGIN_INFO_FLAGS_INTERNAL
|
3596 PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD
,
3602 plugin_load(PurplePlugin
*plugin
, GError
**error
)
3604 novell_protocol_register_type(G_TYPE_MODULE(plugin
));
3606 my_protocol
= purple_protocols_add(NOVELL_TYPE_PROTOCOL
, error
);
3614 plugin_unload(PurplePlugin
*plugin
, GError
**error
)
3616 if (!purple_protocols_remove(my_protocol
, error
))
3622 PURPLE_PLUGIN_INIT(novell
, plugin_query
, plugin_load
, plugin_unload
);