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
23 #include "accountopt.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
));
266 nm_release_message(msg
);
270 /* Set up the new PurpleBuddy based on the response from getdetails */
272 _get_details_resp_setup_buddy(NMUser
* user
, NMERR_T ret_code
,
273 gpointer resp_data
, gpointer user_data
)
275 NMUserRecord
*user_record
;
281 if (user
== NULL
|| resp_data
== NULL
|| user_data
== NULL
)
286 if (ret_code
== NM_OK
) {
287 user_record
= resp_data
;
289 buddy
= nm_contact_get_data(contact
);
291 nm_contact_set_user_record(contact
, user_record
);
293 /* Set the display id */
294 purple_buddy_set_name(buddy
,
295 nm_user_record_get_display_id(user_record
));
297 alias
= purple_buddy_get_alias(buddy
);
298 if (alias
== NULL
|| *alias
== '\0' || purple_strequal(alias
, purple_buddy_get_name(buddy
))) {
299 purple_buddy_set_local_alias(buddy
,
300 nm_user_record_get_full_name(user_record
));
302 /* Tell the server about the new display name */
303 rc
= nm_send_rename_contact(user
, contact
,
304 nm_user_record_get_full_name(user_record
),
306 _check_for_disconnect(user
, rc
);
311 /* Get initial status for the buddy */
312 rc
= nm_send_get_status(user
, resp_data
, _get_status_resp_cb
, NULL
);
313 _check_for_disconnect(user
, rc
);
315 /* nm_release_contact(contact);*/
320 nm_release_contact(contact
);
323 /* Add the new contact into the PurpleBuddy list */
325 _create_contact_resp_cb(NMUser
* user
, NMERR_T ret_code
,
326 gpointer resp_data
, gpointer user_data
)
328 NMContact
*tmp_contact
= (NMContact
*) user_data
;
329 NMContact
*new_contact
= NULL
;
330 NMFolder
*folder
= NULL
;
333 const char *folder_name
= NULL
;
339 if (ret_code
== NM_OK
) {
341 new_contact
= (NMContact
*) resp_data
;
342 if (new_contact
== NULL
|| tmp_contact
== NULL
)
345 /* Get the userid and folder name for the new contact */
346 folder
= nm_find_folder_by_id(user
,
347 nm_contact_get_parent_id(new_contact
));
349 folder_name
= nm_folder_get_name(folder
);
352 if (folder_name
== NULL
|| *folder_name
== '\0')
353 folder_name
= NM_ROOT_FOLDER_NAME
;
355 /* Re-add the buddy now that we got the okay from the server */
356 if (folder_name
&& (group
= purple_blist_find_group(folder_name
))) {
358 const char *alias
= nm_contact_get_display_name(tmp_contact
);
359 const char *display_id
= nm_contact_get_display_id(new_contact
);
361 if (display_id
== NULL
)
362 display_id
= nm_contact_get_dn(new_contact
);
364 if (alias
&& !purple_strequal(alias
, display_id
)) {
366 /* The user requested an alias, tell the server about it. */
367 rc
= nm_send_rename_contact(user
, new_contact
, alias
,
368 _rename_contact_resp_cb
, NULL
);
369 _check_for_disconnect(user
, rc
);
377 /* Add it to the purple buddy list if it is not there */
378 buddy
= purple_blist_find_buddy_in_group(user
->client_data
, display_id
, group
);
380 buddy
= purple_buddy_new(user
->client_data
, display_id
, alias
);
381 purple_blist_add_buddy(buddy
, NULL
, group
, NULL
);
384 /* Save the new buddy as part of the contact object */
385 nm_contact_set_data(new_contact
, (gpointer
) buddy
);
387 /* We need details for the user before we can setup the
388 * new Purple buddy. We always call this because the
389 * 'createcontact' response fields do not always contain
390 * everything that we need.
392 nm_contact_add_ref(new_contact
);
394 rc
= nm_send_get_details(user
, nm_contact_get_dn(new_contact
),
395 _get_details_resp_setup_buddy
, new_contact
);
396 _check_for_disconnect(user
, rc
);
401 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
402 const char *name
= nm_contact_get_dn(tmp_contact
);
406 g_strdup_printf(_("Unable to add %s to your buddy list (%s)."),
407 name
, nm_error_to_string (ret_code
));
408 purple_notify_error(gc
, NULL
, err
, NULL
,
409 purple_request_cpar_from_connection(gc
));
415 nm_release_contact(tmp_contact
);
418 /* Show an error if we failed to send the message */
420 _send_message_resp_cb(NMUser
* user
, NMERR_T ret_code
,
421 gpointer resp_data
, gpointer user_data
)
423 PurpleConnection
*gc
;
429 if (ret_code
!= NM_OK
) {
430 gc
= purple_account_get_connection(user
->client_data
);
432 /* TODO: Improve this! message to who or for what conference? */
433 err
= g_strdup_printf(_("Unable to send message (%s)."),
434 nm_error_to_string (ret_code
));
435 purple_notify_error(gc
, NULL
, err
, NULL
,
436 purple_request_cpar_from_connection(gc
));
441 /* Show an error if the remove failed */
443 _remove_contact_resp_cb(NMUser
* user
, NMERR_T ret_code
,
444 gpointer resp_data
, gpointer user_data
)
446 if (ret_code
!= NM_OK
) {
447 /* TODO: Display an error? */
449 purple_debug(PURPLE_DEBUG_INFO
, "novell",
450 "_remove_contact_resp_cb(): rc = 0x%x\n", ret_code
);
454 /* Show an error if the remove failed */
456 _remove_folder_resp_cb(NMUser
* user
, NMERR_T ret_code
,
457 gpointer resp_data
, gpointer user_data
)
459 if (ret_code
!= NM_OK
) {
460 /* TODO: Display an error? */
462 purple_debug(PURPLE_DEBUG_INFO
, "novell",
463 "_remove_folder_resp_cb(): rc = 0x%x\n", ret_code
);
467 /* Show an error if the move failed */
469 _move_contact_resp_cb(NMUser
* user
, NMERR_T ret_code
,
470 gpointer resp_data
, gpointer user_data
)
472 if (ret_code
!= NM_OK
) {
473 /* TODO: Display an error? */
475 purple_debug(PURPLE_DEBUG_INFO
, "novell",
476 "_move_contact_resp_cb(): rc = 0x%x\n", ret_code
);
480 /* Show an error if the rename failed */
482 _rename_folder_resp_cb(NMUser
* user
, NMERR_T ret_code
,
483 gpointer resp_data
, gpointer user_data
)
485 if (ret_code
!= NM_OK
) {
486 /* TODO: Display an error? */
488 purple_debug(PURPLE_DEBUG_INFO
, "novell",
489 "_rename_folder_resp_cb(): rc = 0x%x\n", ret_code
);
494 _sendinvite_resp_cb(NMUser
*user
, NMERR_T ret_code
,
495 gpointer resp_data
, gpointer user_data
)
498 PurpleConnection
*gc
;
503 if (ret_code
!= NM_OK
) {
504 gc
= purple_account_get_connection(user
->client_data
);
505 err
= g_strdup_printf(_("Unable to invite user (%s)."), nm_error_to_string(ret_code
));
506 purple_notify_error(gc
, NULL
, err
, NULL
,
507 purple_request_cpar_from_connection(gc
));
510 purple_debug(PURPLE_DEBUG_INFO
, "novell",
511 "_sendinvite_resp_cb(): rc = 0x%x\n", ret_code
);
516 /* If the createconf was successful attempt to send the message,
517 * otherwise display an error message to the user.
520 _createconf_resp_send_msg(NMUser
* user
, NMERR_T ret_code
,
521 gpointer resp_data
, gpointer user_data
)
524 NMMessage
*msg
= user_data
;
526 if (user
== NULL
|| msg
== NULL
)
529 if (ret_code
== NM_OK
) {
530 _send_message(user
, msg
);
533 if ((conf
= nm_message_get_conference(msg
))) {
535 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
536 const char *name
= NULL
;
540 ur
= nm_conference_get_participant(conf
, 0);
542 name
= nm_user_record_get_userid(ur
);
545 err
= g_strdup_printf(_("Unable to send message to %s."
546 " Could not create the conference (%s)."),
548 nm_error_to_string (ret_code
));
550 err
= g_strdup_printf(_("Unable to send message."
551 " Could not create the conference (%s)."),
552 nm_error_to_string (ret_code
));
554 purple_notify_error(gc
, NULL
, err
, NULL
,
555 purple_request_cpar_from_connection(gc
));
560 nm_release_message(msg
);
564 /* Move contact to newly created folder */
566 _create_folder_resp_move_contact(NMUser
* user
, NMERR_T ret_code
,
567 gpointer resp_data
, gpointer user_data
)
569 NMContact
*contact
= user_data
;
570 NMFolder
*new_folder
;
571 char *folder_name
= resp_data
;
574 if (user
== NULL
|| folder_name
== NULL
|| contact
== NULL
) {
581 if (ret_code
== NM_OK
|| ret_code
== NMERR_DUPLICATE_FOLDER
) {
582 new_folder
= nm_find_folder(user
, folder_name
);
585 /* Tell the server to move the contact to the new folder */
586 /* rc = nm_send_move_contact(user, contact, new_folder,
587 _move_contact_resp_cb, NULL); */
589 rc
= nm_send_create_contact(user
, new_folder
, contact
,
592 _check_for_disconnect(user
, rc
);
596 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
597 char *err
= g_strdup_printf(_("Unable to move user %s"
598 " to folder %s in the server side list."
599 " Error while creating folder (%s)."),
600 nm_contact_get_dn(contact
),
602 nm_error_to_string (ret_code
));
604 purple_notify_error(gc
, NULL
, err
, NULL
,
605 purple_request_cpar_from_connection(gc
));
612 /* Add contact to newly create folder */
614 _create_folder_resp_add_contact(NMUser
* user
, NMERR_T ret_code
,
615 gpointer resp_data
, gpointer user_data
)
617 NMContact
*contact
= (NMContact
*) user_data
;
619 char *folder_name
= (char *) resp_data
;
622 if (user
== NULL
|| folder_name
== NULL
|| contact
== NULL
) {
625 nm_release_contact(contact
);
632 if (ret_code
== NM_OK
|| ret_code
== NMERR_DUPLICATE_FOLDER
) {
633 folder
= nm_find_folder(user
, folder_name
);
636 rc
= nm_send_create_contact(user
, folder
, contact
,
637 _create_contact_resp_cb
, contact
);
638 _check_for_disconnect(user
, rc
);
641 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
642 const char *name
= nm_contact_get_dn(contact
);
644 g_strdup_printf(_("Unable to add %s to your buddy list."
645 " Error creating folder in server side list (%s)."),
646 name
, nm_error_to_string (ret_code
));
648 purple_notify_error(gc
, NULL
, err
, NULL
,
649 purple_request_cpar_from_connection(gc
));
651 nm_release_contact(contact
);
659 _join_conf_resp_cb(NMUser
* user
, NMERR_T ret_code
,
660 gpointer resp_data
, gpointer user_data
)
662 PurpleChatConversation
*chat
;
663 PurpleConnection
*gc
;
665 NMConference
*conference
= user_data
;
666 const char *name
, *conf_name
;
669 if (user
== NULL
|| conference
== NULL
)
672 gc
= purple_account_get_connection(user
->client_data
);
674 if (ret_code
== NM_OK
) {
675 conf_name
= _get_conference_name(++user
->conference_count
);
676 chat
= purple_serv_got_joined_chat(gc
, user
->conference_count
, conf_name
);
679 nm_conference_set_data(conference
, (gpointer
) chat
);
681 count
= nm_conference_get_participant_count(conference
);
682 for (i
= 0; i
< count
; i
++) {
683 ur
= nm_conference_get_participant(conference
, i
);
685 name
= nm_user_record_get_display_id(ur
);
686 purple_chat_conversation_add_user(chat
, name
, NULL
,
687 PURPLE_CHAT_USER_NONE
, TRUE
);
694 /* Show info returned by getdetails */
696 _get_details_resp_show_info(NMUser
* user
, NMERR_T ret_code
,
697 gpointer resp_data
, gpointer user_data
)
699 PurpleConnection
*gc
;
700 NMUserRecord
*user_record
;
709 if (ret_code
== NM_OK
) {
710 user_record
= (NMUserRecord
*) resp_data
;
712 _show_info(purple_account_get_connection(user
->client_data
),
713 user_record
, g_strdup(name
));
716 gc
= purple_account_get_connection(user
->client_data
);
718 g_strdup_printf(_("Could not get details for user %s (%s)."),
719 name
, nm_error_to_string (ret_code
));
720 purple_notify_error(gc
, NULL
, err
, NULL
,
721 purple_request_cpar_from_connection(gc
));
728 /* Handle get details response add to privacy list */
730 _get_details_resp_add_privacy_item(NMUser
*user
, NMERR_T ret_code
,
731 gpointer resp_data
, gpointer user_data
)
733 PurpleConnection
*gc
;
734 PurpleAccount
*account
;
735 NMUserRecord
*user_record
= resp_data
;
737 gboolean allowed
= GPOINTER_TO_INT(user_data
);
738 const char *display_id
;
743 gc
= purple_account_get_connection(user
->client_data
);
744 display_id
= nm_user_record_get_display_id(user_record
);
745 account
= purple_connection_get_account(gc
);
747 if (ret_code
== NM_OK
) {
751 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
752 display_id
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
753 purple_account_privacy_permit_add(account
, display_id
, TRUE
);
758 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
759 display_id
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
760 purple_account_privacy_deny_add(account
, display_id
, TRUE
);
766 err
= g_strdup_printf(_("Unable to add user to privacy list (%s)."),
767 nm_error_to_string(ret_code
));
768 purple_notify_error(gc
, NULL
, err
, NULL
,
769 purple_request_cpar_from_connection(gc
));
775 /* Handle response to create privacy item request */
777 _create_privacy_item_deny_resp_cb(NMUser
*user
, NMERR_T ret_code
,
778 gpointer resp_data
, gpointer user_data
)
780 PurpleConnection
*gc
;
781 PurpleAccount
*account
;
782 NMUserRecord
*user_record
;
783 char *who
= user_data
;
786 const char *display_id
= NULL
;
791 gc
= purple_account_get_connection(user
->client_data
);
792 account
= purple_connection_get_account(gc
);
794 if (ret_code
== NM_OK
) {
796 user_record
= nm_find_user_record(user
, who
);
798 display_id
= nm_user_record_get_display_id(user_record
);
802 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
803 display_id
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
805 purple_account_privacy_deny_add(account
, display_id
, TRUE
);
809 rc
= nm_send_get_details(user
, who
,
810 _get_details_resp_add_privacy_item
,
812 _check_for_disconnect(user
, rc
);
816 err
= g_strdup_printf(_("Unable to add %s to deny list (%s)."),
817 who
, nm_error_to_string(ret_code
));
818 purple_notify_error(gc
, NULL
, err
, NULL
,
819 purple_request_cpar_from_connection(gc
));
828 /* Handle response to create privacy item request */
830 _create_privacy_item_permit_resp_cb(NMUser
*user
, NMERR_T ret_code
,
831 gpointer resp_data
, gpointer user_data
)
833 PurpleConnection
*gc
;
834 PurpleAccount
*account
;
835 NMUserRecord
*user_record
;
836 char *who
= user_data
;
839 const char *display_id
= NULL
;
844 gc
= purple_account_get_connection(user
->client_data
);
845 account
= purple_connection_get_account(gc
);
847 if (ret_code
== NM_OK
) {
849 user_record
= nm_find_user_record(user
, who
);
851 display_id
= nm_user_record_get_display_id(user_record
);
855 if (!g_slist_find_custom(purple_account_privacy_get_permitted(account
),
857 (GCompareFunc
)purple_utf8_strcasecmp
)) {
859 purple_account_privacy_permit_add(account
, display_id
, TRUE
);
863 rc
= nm_send_get_details(user
, who
,
864 _get_details_resp_add_privacy_item
,
866 _check_for_disconnect(user
, rc
);
871 err
= g_strdup_printf(_("Unable to add %s to permit list (%s)."), who
,
872 nm_error_to_string(ret_code
));
873 purple_notify_error(gc
, NULL
, err
, NULL
,
874 purple_request_cpar_from_connection(gc
));
883 _get_details_send_privacy_create(NMUser
*user
, NMERR_T ret_code
,
884 gpointer resp_data
, gpointer user_data
)
887 PurpleConnection
*gc
;
888 NMUserRecord
*user_record
= resp_data
;
890 gboolean allowed
= GPOINTER_TO_INT(user_data
);
891 const char *dn
, *display_id
;
896 gc
= purple_account_get_connection(user
->client_data
);
897 dn
= nm_user_record_get_dn(user_record
);
898 display_id
= nm_user_record_get_display_id(user_record
);
900 if (ret_code
== NM_OK
) {
903 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
904 _create_privacy_item_permit_resp_cb
,
905 g_strdup(display_id
));
906 _check_for_disconnect(user
, rc
);
909 rc
= nm_send_create_privacy_item(user
, dn
, FALSE
,
910 _create_privacy_item_deny_resp_cb
,
911 g_strdup(display_id
));
912 _check_for_disconnect(user
, rc
);
917 err
= g_strdup_printf(_("Unable to add user to privacy list (%s)."),
918 nm_error_to_string(ret_code
));
919 purple_notify_error(gc
, NULL
, err
, NULL
,
920 purple_request_cpar_from_connection(gc
));
927 _remove_privacy_item_resp_cb(NMUser
*user
, NMERR_T ret_code
,
928 gpointer resp_data
, gpointer user_data
)
930 PurpleConnection
*gc
;
931 char *who
= user_data
;
937 if (ret_code
!= NM_OK
) {
939 gc
= purple_account_get_connection(user
->client_data
);
940 err
= g_strdup_printf(_("Unable to remove %s from privacy list (%s)."), who
,
941 nm_error_to_string(ret_code
));
942 purple_notify_error(gc
, NULL
, err
, NULL
,
943 purple_request_cpar_from_connection(gc
));
951 _set_privacy_default_resp_cb(NMUser
*user
, NMERR_T ret_code
,
952 gpointer resp_data
, gpointer user_data
)
954 PurpleConnection
*gc
;
960 if (ret_code
!= NM_OK
) {
962 gc
= purple_account_get_connection(user
->client_data
);
963 err
= g_strdup_printf(_("Unable to change server side privacy settings (%s)."),
964 nm_error_to_string(ret_code
));
965 purple_notify_error(gc
, NULL
, err
, NULL
,
966 purple_request_cpar_from_connection(gc
));
972 /* Handle get details response add to privacy list */
974 _get_details_resp_send_invite(NMUser
*user
, NMERR_T ret_code
,
975 gpointer resp_data
, gpointer user_data
)
978 PurpleConnection
*gc
;
979 NMUserRecord
*user_record
= resp_data
;
982 NMConference
*conference
;
984 long id
= (long) user_data
;
989 gc
= purple_account_get_connection(user
->client_data
);
991 if (ret_code
== NM_OK
) {
993 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
994 conference
= cnode
->data
;
995 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
996 if (purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(chat
)) == id
) {
997 rc
= nm_send_conference_invite(user
, conference
, user_record
,
998 NULL
, _sendinvite_resp_cb
, NULL
);
999 _check_for_disconnect(user
, rc
);
1007 err
= g_strdup_printf(_("Unable to invite user (%s)."), nm_error_to_string(ret_code
));
1008 purple_notify_error(gc
, NULL
, err
, NULL
,
1009 purple_request_cpar_from_connection(gc
));
1016 _createconf_resp_send_invite(NMUser
* user
, NMERR_T ret_code
,
1017 gpointer resp_data
, gpointer user_data
)
1020 NMConference
*conference
= resp_data
;
1021 NMUserRecord
*user_record
= user_data
;
1022 PurpleConnection
*gc
;
1030 if (ret_code
== NM_OK
) {
1031 rc
= nm_send_conference_invite(user
, conference
, user_record
,
1032 NULL
, _sendinvite_resp_cb
, NULL
);
1033 _check_for_disconnect(user
, rc
);
1035 err
= g_strdup_printf(_("Unable to create conference (%s)."), nm_error_to_string(ret_code
));
1036 gc
= purple_account_get_connection(user
->client_data
);
1037 purple_notify_error(gc
, NULL
, err
, NULL
,
1038 purple_request_cpar_from_connection(gc
));
1043 /*******************************************************************************
1045 ******************************************************************************/
1048 _user_agent_string(void)
1051 #if !defined(_WIN32)
1053 const char *sysname
= "";
1054 const char *release
= "";
1057 if (uname(&u
) == 0) {
1058 sysname
= u
.sysname
;
1059 release
= u
.release
;
1062 release
= "Unknown";
1065 return g_strdup_printf("Purple/%s (%s; %s)", VERSION
, sysname
, release
);
1069 const char *sysname
= "";
1070 OSVERSIONINFO os_info
;
1071 SYSTEM_INFO sys_info
;
1073 os_info
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
1074 GetVersionEx(&os_info
);
1075 GetSystemInfo(&sys_info
);
1077 if (os_info
.dwPlatformId
== VER_PLATFORM_WIN32_NT
) {
1078 switch (os_info
.dwMajorVersion
) {
1081 sysname
= "Windows NT";
1084 switch (os_info
.dwMinorVersion
) {
1086 sysname
= "Windows 2000";
1089 sysname
= "Windows XP";
1092 sysname
= "Windows Server 2003";
1095 sysname
= "Windows";
1100 sysname
= "Windows";
1104 } else if (os_info
.dwPlatformId
== VER_PLATFORM_WIN32_WINDOWS
) {
1105 switch (os_info
.dwMinorVersion
) {
1107 sysname
= "Windows 95";
1110 sysname
= "Windows 98";
1113 sysname
= "Windows ME";
1116 sysname
= "Windows";
1120 sysname
= "Windows";
1123 return g_strdup_printf("Purple/%s (%s; %ld.%ld)", VERSION
, sysname
,
1124 os_info
.dwMajorVersion
, os_info
.dwMinorVersion
);
1132 _is_disconnect_error(NMERR_T err
)
1134 return (err
== NMERR_TCP_WRITE
||
1135 err
== NMERR_TCP_READ
|| err
== NMERR_PROTOCOL
);
1139 _check_for_disconnect(NMUser
* user
, NMERR_T err
)
1141 PurpleConnection
*gc
= purple_account_get_connection(user
->client_data
);
1143 if (_is_disconnect_error(err
)) {
1145 purple_connection_error(gc
,
1146 PURPLE_CONNECTION_ERROR_NETWORK_ERROR
,
1147 _("Error communicating with server. Closing connection."));
1155 /* Check to see if the conference is instantiated, if so send the message.
1156 * If not send the create conference -- the response handler for the createconf
1157 * will call this function again.
1160 _send_message(NMUser
* user
, NMMessage
* message
)
1165 conf
= nm_message_get_conference(message
);
1167 /* We have a conference make sure that the
1168 server knows about it already. */
1169 if (nm_conference_is_instantiated(conf
)) {
1171 /* We have everything that we need...finally! */
1172 rc
= nm_send_message(user
, message
, _send_message_resp_cb
);
1173 _check_for_disconnect(user
, rc
);
1175 nm_release_message(message
);
1178 rc
= nm_send_create_conference(user
, conf
, _createconf_resp_send_msg
, message
);
1179 _check_for_disconnect(user
, rc
);
1185 * Update the status of the given buddy in the Purple buddy list
1188 _update_buddy_status(NMUser
*user
, PurpleBuddy
* buddy
, int novellstatus
, int gmt
)
1190 PurpleAccount
*account
;
1191 const char *status_id
;
1192 const char *text
= NULL
;
1197 account
= purple_buddy_get_account(buddy
);
1198 name
= purple_buddy_get_name(buddy
);
1200 switch (novellstatus
) {
1201 case NM_STATUS_AVAILABLE
:
1202 status_id
= NOVELL_STATUS_TYPE_AVAILABLE
;
1204 case NM_STATUS_AWAY
:
1205 status_id
= NOVELL_STATUS_TYPE_AWAY
;
1207 case NM_STATUS_BUSY
:
1208 status_id
= NOVELL_STATUS_TYPE_BUSY
;
1210 case NM_STATUS_OFFLINE
:
1211 status_id
= NOVELL_STATUS_TYPE_OFFLINE
;
1213 case NM_STATUS_AWAY_IDLE
:
1214 status_id
= NOVELL_STATUS_TYPE_AWAY
;
1218 status_id
= NOVELL_STATUS_TYPE_OFFLINE
;
1222 /* Get status text for the user */
1223 dn
= nm_lookup_dn(user
, name
);
1225 NMUserRecord
*user_record
= nm_find_user_record(user
, dn
);
1227 text
= nm_user_record_get_status_text(user_record
);
1231 purple_protocol_got_user_status(account
, name
, status_id
,
1232 "message", text
, NULL
);
1233 purple_protocol_got_user_idle(account
, name
,
1234 (novellstatus
== NM_STATUS_AWAY_IDLE
), idle
);
1237 /* Iterate through the cached Purple buddy list and remove buddies
1238 * that are not in the server side list.
1241 _remove_purple_buddies(NMUser
*user
)
1243 PurpleBlistNode
*gnode
;
1244 PurpleBlistNode
*cnode
;
1245 PurpleBlistNode
*bnode
;
1248 GSList
*rem_list
= NULL
;
1250 NMFolder
*folder
= NULL
;
1251 const char *gname
= NULL
;
1253 for (gnode
= purple_blist_get_default_root(); gnode
;
1254 gnode
= purple_blist_node_get_sibling_next(gnode
)) {
1255 if (!PURPLE_IS_GROUP(gnode
))
1257 group
= (PurpleGroup
*) gnode
;
1258 gname
= purple_group_get_name(group
);
1259 for (cnode
= purple_blist_node_get_first_child(gnode
);
1261 cnode
= purple_blist_node_get_sibling_next(cnode
)) {
1262 if (!PURPLE_IS_CONTACT(cnode
))
1264 for (bnode
= purple_blist_node_get_first_child(cnode
);
1266 bnode
= purple_blist_node_get_sibling_next(bnode
)) {
1267 if (!PURPLE_IS_BUDDY(bnode
))
1269 buddy
= (PurpleBuddy
*) bnode
;
1270 if (purple_buddy_get_account(buddy
) == user
->client_data
) {
1271 if (purple_strequal(gname
, NM_ROOT_FOLDER_NAME
))
1273 folder
= nm_find_folder(user
, gname
);
1274 if (folder
== NULL
||
1275 !nm_folder_find_contact_by_display_id(folder
, purple_buddy_get_name(buddy
))) {
1276 rem_list
= g_slist_append(rem_list
, buddy
);
1284 for (l
= rem_list
; l
; l
= l
->next
) {
1285 purple_blist_remove_buddy(l
->data
);
1287 g_slist_free(rem_list
);
1291 /* Add all of the contacts in the given folder to the Purple buddy list */
1293 _add_contacts_to_purple_blist(NMUser
* user
, NMFolder
* folder
)
1295 NMUserRecord
*user_record
= NULL
;
1296 NMContact
*contact
= NULL
;
1297 PurpleBuddy
*buddy
= NULL
;
1300 const char *name
= NULL
;
1301 const char *fname
= NULL
;
1304 /* If this is the root folder give it a name. Purple does not have the concept of
1307 fname
= nm_folder_get_name(folder
);
1308 if (fname
== NULL
|| *fname
== '\0') {
1309 fname
= NM_ROOT_FOLDER_NAME
;
1312 /* Does the Purple group exist already? */
1313 group
= purple_blist_find_group(fname
);
1314 if (group
== NULL
) {
1315 group
= purple_group_new(fname
);
1316 purple_blist_add_group(group
, NULL
);
1319 /* Get each contact for this folder */
1320 cnt
= nm_folder_get_contact_count(folder
);
1321 for (i
= 0; i
< cnt
; i
++) {
1322 contact
= nm_folder_get_contact(folder
, i
);
1325 name
= nm_contact_get_display_id(contact
);
1328 buddy
= purple_blist_find_buddy_in_group(user
->client_data
, name
, group
);
1329 if (buddy
== NULL
) {
1330 /* Add it to the purple buddy list */
1331 buddy
= purple_buddy_new(user
->client_data
,
1333 nm_contact_get_display_name(contact
));
1335 purple_blist_add_buddy(buddy
, NULL
, group
, NULL
);
1338 /* Set the initial status for the buddy */
1339 user_record
= nm_contact_get_user_record(contact
);
1341 status
= nm_user_record_get_status(user_record
);
1343 _update_buddy_status(user
, buddy
, status
, time(0));
1345 /* Save the new buddy as part of the contact object */
1346 nm_contact_set_data(contact
, (gpointer
) buddy
);
1350 /* NULL contact. This should not happen, but
1351 * let's break out of the loop.
1358 /* Add all of the server side contacts to the Purple buddy list. */
1360 _add_purple_buddies(NMUser
* user
)
1363 NMFolder
*root_folder
= NULL
;
1364 NMFolder
*folder
= NULL
;
1366 root_folder
= nm_get_root_folder(user
);
1369 /* Add sub-folders and contacts to sub-folders...
1370 * iterate throught the sub-folders in reverse order
1371 * because Purple adds the folders to the front -- so we
1372 * want to add the first folder last
1374 cnt
= nm_folder_get_subfolder_count(root_folder
);
1375 for (i
= cnt
-1; i
>= 0; i
--) {
1376 folder
= nm_folder_get_subfolder(root_folder
, i
);
1378 _add_contacts_to_purple_blist(user
, folder
);
1382 /* Add contacts for the root folder */
1383 _add_contacts_to_purple_blist(user
, root_folder
);
1388 _sync_contact_list(NMUser
*user
)
1390 /* Remove all buddies from the local list that are
1391 * not in the server side list and add all buddies
1392 * from the server side list that are not in
1395 _remove_purple_buddies(user
);
1396 _add_purple_buddies(user
);
1397 user
->clist_synched
= TRUE
;
1401 _sync_privacy_lists(NMUser
*user
)
1403 GSList
*node
= NULL
, *rem_list
= NULL
;
1404 PurpleConnection
*gc
;
1405 PurpleAccount
*account
;
1406 const char *name
, *dn
;
1407 NMUserRecord
*user_record
;
1412 gc
= purple_account_get_connection(user
->client_data
);
1416 account
= purple_connection_get_account(gc
);
1418 /* Set the Purple privacy setting */
1419 if (user
->default_deny
) {
1420 if (user
->allow_list
== NULL
) {
1421 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_DENY_ALL
);
1423 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
);
1426 if (user
->deny_list
== NULL
) {
1427 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
);
1429 purple_account_set_privacy_type(account
, PURPLE_ACCOUNT_PRIVACY_DENY_USERS
);
1434 for (node
= user
->allow_list
; node
; node
= node
->next
) {
1435 user_record
= nm_find_user_record(user
, (char *)node
->data
);
1437 name
= nm_user_record_get_display_id(user_record
);
1439 name
=(char *)node
->data
;
1441 if (!g_slist_find_custom(purple_account_privacy_get_permitted(account
),
1442 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1443 purple_account_privacy_permit_add(account
, name
, TRUE
);
1447 for (node
= user
->deny_list
; node
; node
= node
->next
) {
1448 user_record
= nm_find_user_record(user
, (char *)node
->data
);
1450 name
= nm_user_record_get_display_id(user_record
);
1452 name
=(char *)node
->data
;
1454 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
1455 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1456 purple_account_privacy_deny_add(account
, name
, TRUE
);
1462 for (node
= purple_account_privacy_get_permitted(account
); node
; node
= node
->next
) {
1463 dn
= nm_lookup_dn(user
, (char *)node
->data
);
1465 !g_slist_find_custom(user
->allow_list
,
1466 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1467 rem_list
= g_slist_append(rem_list
, node
->data
);
1472 for (node
= rem_list
; node
; node
= node
->next
) {
1473 purple_account_privacy_permit_remove(account
, (char *)node
->data
, TRUE
);
1475 g_slist_free(rem_list
);
1479 for (node
= purple_account_privacy_get_denied(account
); node
; node
= node
->next
) {
1480 dn
= nm_lookup_dn(user
, (char *)node
->data
);
1482 !g_slist_find_custom(user
->deny_list
,
1483 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
1484 rem_list
= g_slist_append(rem_list
, node
->data
);
1489 for (node
= rem_list
; node
; node
= node
->next
) {
1490 purple_account_privacy_deny_remove(account
, (char *)node
->data
, TRUE
);
1492 g_slist_free(rem_list
);
1496 /* Map known property tags to user-friendly strings */
1498 _map_property_tag(const char *tag
)
1500 if (tag
== NULL
) return NULL
;
1502 if (purple_strequal(tag
, "telephoneNumber"))
1503 return _("Telephone Number");
1504 else if (purple_strequal(tag
, "L"))
1505 return _("Location");
1506 else if (purple_strequal(tag
, "OU"))
1507 return _("Department");
1508 else if (purple_strequal(tag
, "personalTitle"))
1509 return _("Personal Title");
1510 else if (purple_strequal(tag
, "Title"))
1511 return _("Job Title");
1512 else if (purple_strequal(tag
, "mailstop"))
1513 return _("Mailstop");
1514 else if (purple_strequal(tag
, "Internet EMail Address"))
1515 return _("Email Address");
1520 /* Display a dialog box showing the properties for the given user record */
1522 _show_info(PurpleConnection
* gc
, NMUserRecord
* user_record
, char * name
)
1524 PurpleNotifyUserInfo
*user_info
= purple_notify_user_info_new();
1526 NMProperty
*property
;
1527 const char *tag
, *value
;
1530 value
= nm_user_record_get_userid(user_record
);
1532 /* TODO: Check whether it's correct to call add_pair_html,
1533 or if we should be using add_pair_plaintext */
1534 purple_notify_user_info_add_pair_html(user_info
, tag
, value
);
1537 tag
= _("Full name");
1538 value
= nm_user_record_get_full_name(user_record
);
1540 /* TODO: Check whether it's correct to call add_pair_html,
1541 or if we should be using add_pair_plaintext */
1542 purple_notify_user_info_add_pair_html(user_info
, tag
, value
);
1545 count
= nm_user_record_get_property_count(user_record
);
1546 for (i
= 0; i
< count
; i
++) {
1547 property
= nm_user_record_get_property(user_record
, i
);
1549 tag
= _map_property_tag(nm_property_get_tag(property
));
1550 value
= nm_property_get_value(property
);
1552 /* TODO: Check whether it's correct to call add_pair_html,
1553 or if we should be using add_pair_plaintext */
1554 purple_notify_user_info_add_pair_html(user_info
, tag
, value
);
1556 nm_release_property(property
);
1560 purple_notify_userinfo(gc
, name
, user_info
, NULL
, NULL
);
1561 purple_notify_user_info_destroy(user_info
);
1566 /* Send a join conference, the first item in the parms list is the
1567 * NMUser object and the second item is the conference to join.
1568 * This callback is passed to purple_request_action when we ask the
1569 * user if they want to join the conference.
1572 _join_conference_cb(GSList
* parms
)
1575 NMConference
*conference
;
1578 if (parms
== NULL
|| g_slist_length(parms
) != 2)
1581 user
= g_slist_nth_data(parms
, 0);
1582 conference
= g_slist_nth_data(parms
, 1);
1584 if (user
&& conference
) {
1585 rc
= nm_send_join_conference(user
, conference
,
1586 _join_conf_resp_cb
, conference
);
1587 _check_for_disconnect(user
, rc
);
1590 g_slist_free(parms
);
1593 /* Send a reject conference, the first item in the parms list is the
1594 * NMUser object and the second item is the conference to reject.
1595 * This callback is passed to purple_request_action when we ask the
1596 * user if they want to joing the conference.
1599 _reject_conference_cb(GSList
* parms
)
1602 NMConference
*conference
;
1605 if (parms
== NULL
|| g_slist_length(parms
) != 2)
1608 user
= g_slist_nth_data(parms
, 0);
1609 conference
= g_slist_nth_data(parms
, 1);
1611 if (user
&& conference
) {
1612 rc
= nm_send_reject_conference(user
, conference
, NULL
, NULL
);
1613 _check_for_disconnect(user
, rc
);
1616 g_slist_free(parms
);
1620 _initiate_conference_cb(PurpleBlistNode
*node
, gpointer ignored
)
1623 PurpleConnection
*gc
;
1626 const char *conf_name
;
1627 PurpleChatConversation
*chat
= NULL
;
1628 NMUserRecord
*user_record
;
1629 NMConference
*conference
;
1631 g_return_if_fail(PURPLE_IS_BUDDY(node
));
1633 buddy
= (PurpleBuddy
*) node
;
1634 gc
= purple_account_get_connection(purple_buddy_get_account(buddy
));
1636 user
= purple_connection_get_protocol_data(gc
);
1640 /* We should already have a userrecord for the buddy */
1641 user_record
= nm_find_user_record(user
, purple_buddy_get_name(buddy
));
1642 if (user_record
== NULL
)
1645 conf_name
= _get_conference_name(++user
->conference_count
);
1646 chat
= purple_serv_got_joined_chat(gc
, user
->conference_count
, conf_name
);
1649 conference
= nm_create_conference(NULL
);
1650 nm_conference_set_data(conference
, (gpointer
) chat
);
1651 nm_send_create_conference(user
, conference
, _createconf_resp_send_invite
, user_record
);
1652 nm_release_conference(conference
);
1657 _get_conference_name(int id
)
1659 static char *name
= NULL
;
1663 name
= g_strdup_printf(_("GroupWise Conference %d"), id
);
1669 _show_privacy_locked_error(PurpleConnection
*gc
, NMUser
*user
)
1673 err
= g_strdup_printf(_("Unable to change server side privacy settings (%s)."),
1674 nm_error_to_string(NMERR_ADMIN_LOCKED
));
1675 purple_notify_error(gc
, NULL
, err
, NULL
,
1676 purple_request_cpar_from_connection(gc
));
1680 /*******************************************************************************
1681 * Connect and recv callbacks
1682 ******************************************************************************/
1685 novell_ssl_connect_error(PurpleSslConnection
* gsc
,
1686 PurpleSslErrorType error
, gpointer data
)
1688 PurpleConnection
*gc
;
1692 user
= purple_connection_get_protocol_data(gc
);
1693 user
->conn
->ssl_conn
->data
= NULL
;
1695 purple_connection_ssl_error (gc
, error
);
1699 novell_ssl_recv_cb(gpointer data
, PurpleSslConnection
* gsc
,
1700 PurpleInputCondition condition
)
1702 PurpleConnection
*gc
= data
;
1709 user
= purple_connection_get_protocol_data(gc
);
1713 rc
= nm_process_new_data(user
);
1716 if (_is_disconnect_error(rc
)) {
1718 purple_connection_error(gc
,
1719 PURPLE_CONNECTION_ERROR_NETWORK_ERROR
,
1720 _("Error communicating with server. Closing connection."));
1722 purple_debug(PURPLE_DEBUG_INFO
, "novell",
1723 "Error processing event or response (%d).\n", rc
);
1729 novell_ssl_connected_cb(gpointer data
, PurpleSslConnection
* gsc
,
1730 PurpleInputCondition cond
)
1732 PurpleConnection
*gc
= data
;
1736 const char *pwd
= NULL
;
1737 const char *my_addr
= NULL
;
1740 if (gc
== NULL
|| gsc
== NULL
)
1743 user
= purple_connection_get_protocol_data(gc
);
1744 if ((user
== NULL
) || (conn
= user
->conn
) == NULL
)
1747 purple_connection_update_progress(gc
, _("Authenticating..."),
1748 2, NOVELL_CONNECT_STEPS
);
1750 my_addr
= purple_network_get_my_ip(gsc
->fd
);
1751 pwd
= purple_connection_get_password(gc
);
1752 ua
= _user_agent_string();
1754 rc
= nm_send_login(user
, pwd
, my_addr
, ua
, _login_resp_cb
, NULL
);
1756 conn
->connected
= TRUE
;
1757 purple_ssl_input_add(gsc
, novell_ssl_recv_cb
, gc
);
1759 purple_connection_error(gc
,
1760 PURPLE_CONNECTION_ERROR_NETWORK_ERROR
,
1761 _("Unable to connect"));
1764 purple_connection_update_progress(gc
, _("Waiting for response..."),
1765 3, NOVELL_CONNECT_STEPS
);
1770 /*******************************************************************************
1771 * Event callback and event handlers
1772 ******************************************************************************/
1775 _evt_receive_message(NMUser
* user
, NMEvent
* event
)
1777 NMUserRecord
*user_record
= NULL
;
1778 NMContact
*contact
= NULL
;
1779 PurpleIMConversation
*im
;
1780 NMConference
*conference
;
1781 PurpleMessageFlags flags
;
1784 text
= g_markup_escape_text(nm_event_get_text(event
), -1);
1786 conference
= nm_event_get_conference(event
);
1789 PurpleChatConversation
*chat
= nm_conference_get_data(conference
);
1791 /* Is this a single person 'conversation' or a conference? */
1792 if (chat
== NULL
&& nm_conference_get_participant_count(conference
) == 1) {
1794 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
1798 if (nm_event_get_type(event
) == NMEVT_RECEIVE_AUTOREPLY
)
1799 flags
|= PURPLE_MESSAGE_AUTO_RESP
;
1801 purple_serv_got_im(purple_account_get_connection(user
->client_data
),
1802 nm_user_record_get_display_id(user_record
),
1804 nm_event_get_gmt(event
));
1806 im
= purple_conversations_find_im_with_account(
1807 nm_user_record_get_display_id(user_record
),
1808 (PurpleAccount
*) user
->client_data
);
1811 contact
= nm_find_contact(user
, nm_event_get_source(event
));
1814 purple_conversation_set_title(PURPLE_CONVERSATION(im
),
1815 nm_contact_get_display_name(contact
));
1821 nm_user_record_get_full_name(user_record
);
1824 name
= nm_user_record_get_userid(user_record
);
1826 purple_conversation_set_title(PURPLE_CONVERSATION(im
), name
);
1832 /* this should not happen, see the event code.
1833 * the event code will get the contact details from
1834 * the server if it does not have them before calling
1835 * the event callback.
1841 /* get the contact for send if we have one */
1842 NMContact
*contact
= nm_find_contact(user
,
1843 nm_event_get_source(event
));
1845 /* get the user record for the sender */
1846 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
1848 const char *name
= nm_contact_get_display_name(contact
);
1851 name
= nm_user_record_get_full_name(user_record
);
1853 name
= nm_user_record_get_display_id(user_record
);
1856 purple_serv_got_chat_in(purple_account_get_connection(user
->client_data
),
1857 purple_chat_conversation_get_id(chat
),
1858 name
, PURPLE_MESSAGE_RECV
, text
, nm_event_get_gmt(event
));
1867 _evt_conference_left(NMUser
* user
, NMEvent
* event
)
1869 PurpleChatConversation
*chat
;
1870 NMConference
*conference
;
1872 conference
= nm_event_get_conference(event
);
1874 chat
= nm_conference_get_data(conference
);
1876 NMUserRecord
*ur
= nm_find_user_record(user
,
1877 nm_event_get_source(event
));
1880 purple_chat_conversation_remove_user(chat
,
1881 nm_user_record_get_display_id(ur
),
1888 _evt_conference_invite_notify(NMUser
* user
, NMEvent
* event
)
1890 PurpleConversation
*gconv
;
1891 NMConference
*conference
;
1892 NMUserRecord
*user_record
= NULL
;
1895 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
1896 conference
= nm_event_get_conference(event
);
1897 if (user_record
&& conference
) {
1898 gconv
= nm_conference_get_data(conference
);
1899 str
= g_strdup_printf(_("%s has been invited to this conversation."),
1900 nm_user_record_get_display_id(user_record
));
1901 purple_conversation_write_system_message(gconv
, str
, 0);
1907 _evt_conference_invite(NMUser
* user
, NMEvent
* event
)
1910 PurpleConnection
*gc
;
1911 GSList
*parms
= NULL
;
1912 const char *title
= NULL
;
1913 const char *secondary
= NULL
;
1914 const char *name
= NULL
;
1915 char *primary
= NULL
;
1918 ur
= nm_find_user_record(user
, nm_event_get_source(event
));
1920 name
= nm_user_record_get_full_name(ur
);
1923 name
= nm_event_get_source(event
);
1925 gmt
= nm_event_get_gmt(event
);
1926 title
= _("Invitation to Conversation");
1927 primary
= g_strdup_printf(_("Invitation from: %s\n\nSent: %s"),
1928 name
, purple_date_format_full(localtime(&gmt
)));
1929 secondary
= _("Would you like to join the conversation?");
1931 /* Set up parms list for the callbacks
1932 * We need to send the NMUser object and
1933 * the NMConference object to the callbacks
1936 parms
= g_slist_append(parms
, user
);
1937 parms
= g_slist_append(parms
, nm_event_get_conference(event
));
1939 /* Prompt the user */
1940 /* TODO: Would it be better to use purple_serv_got_chat_invite() here? */
1941 gc
= purple_account_get_connection(user
->client_data
);
1942 purple_request_action(gc
, title
, primary
, secondary
,
1943 PURPLE_DEFAULT_ACTION_NONE
,
1944 purple_request_cpar_from_connection(gc
),
1946 _("Yes"), G_CALLBACK(_join_conference_cb
),
1947 _("No"), G_CALLBACK(_reject_conference_cb
));
1954 _evt_conference_joined(NMUser
* user
, NMEvent
* event
)
1956 PurpleChatConversation
*chat
= NULL
;
1957 PurpleConnection
*gc
;
1958 NMConference
*conference
= NULL
;
1959 NMUserRecord
*ur
= NULL
;
1961 const char *conf_name
;
1963 gc
= purple_account_get_connection(user
->client_data
);
1967 conference
= nm_event_get_conference(event
);
1969 chat
= nm_conference_get_data(conference
);
1970 if (nm_conference_get_participant_count(conference
) == 2 && chat
== NULL
) {
1971 ur
= nm_conference_get_participant(conference
, 0);
1973 conf_name
= _get_conference_name(++user
->conference_count
);
1975 purple_serv_got_joined_chat(gc
, user
->conference_count
, conf_name
);
1978 nm_conference_set_data(conference
, (gpointer
) chat
);
1980 name
= nm_user_record_get_display_id(ur
);
1981 purple_chat_conversation_add_user(chat
, name
, NULL
,
1982 PURPLE_CHAT_USER_NONE
, TRUE
);
1989 ur
= nm_find_user_record(user
, nm_event_get_source(event
));
1991 name
= nm_user_record_get_display_id(ur
);
1992 if (!purple_chat_conversation_has_user(chat
, name
)) {
1993 purple_chat_conversation_add_user(chat
, name
, NULL
,
1994 PURPLE_CHAT_USER_NONE
, TRUE
);
2002 _evt_status_change(NMUser
* user
, NMEvent
* event
)
2004 PurpleBuddy
*buddy
= NULL
;
2007 NMUserRecord
*user_record
;
2008 const char *display_id
;
2011 user_record
= nm_event_get_user_record(event
);
2014 /* Retrieve new status */
2015 status
= nm_user_record_get_status(user_record
);
2017 /* Update status for buddy in all folders */
2018 display_id
= nm_user_record_get_display_id(user_record
);
2019 buddies
= purple_blist_find_buddies(user
->client_data
, display_id
);
2020 for (bnode
= buddies
; bnode
; bnode
= bnode
->next
) {
2021 buddy
= (PurpleBuddy
*) bnode
->data
;
2023 _update_buddy_status(user
, buddy
, status
, nm_event_get_gmt(event
));
2027 g_slist_free(buddies
);
2033 _evt_user_disconnect(NMUser
* user
, NMEvent
* event
)
2035 PurpleConnection
*gc
;
2036 PurpleAccount
*account
= user
->client_data
;
2038 gc
= purple_account_get_connection(account
);
2041 if (!purple_account_get_remember_password(account
))
2042 purple_account_set_password(account
, NULL
, NULL
, NULL
);
2043 purple_connection_error(gc
,
2044 PURPLE_CONNECTION_ERROR_NAME_IN_USE
,
2045 _("You have signed on from another location"));
2050 _evt_user_typing(NMUser
* user
, NMEvent
* event
)
2052 PurpleConnection
*gc
;
2053 NMUserRecord
*user_record
= NULL
;
2055 gc
= purple_account_get_connection((PurpleAccount
*) user
->client_data
);
2057 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
2059 purple_serv_got_typing(gc
, nm_user_record_get_display_id(user_record
),
2060 30, PURPLE_IM_TYPING
);
2066 _evt_user_not_typing(NMUser
* user
, NMEvent
* event
)
2068 PurpleConnection
*gc
;
2069 NMUserRecord
*user_record
;
2071 gc
= purple_account_get_connection((PurpleAccount
*) user
->client_data
);
2073 user_record
= nm_find_user_record(user
, nm_event_get_source(event
));
2075 purple_serv_got_typing_stopped(gc
,
2076 nm_user_record_get_display_id(user_record
));
2082 _evt_undeliverable_status(NMUser
* user
, NMEvent
* event
)
2085 PurpleConversation
*gconv
;
2088 ur
= nm_find_user_record(user
, nm_event_get_source(event
));
2090 /* XXX - Should this be PURPLE_CONV_TYPE_IM? */
2092 purple_conversations_find_with_account(nm_user_record_get_display_id(ur
),
2095 const char *name
= nm_user_record_get_full_name(ur
);
2098 name
= nm_user_record_get_display_id(ur
);
2100 str
= g_strdup_printf(_("%s appears to be offline and did not receive"
2101 " the message that you just sent."), name
);
2102 purple_conversation_write_system_message(gconv
, str
, 0);
2109 _event_callback(NMUser
* user
, NMEvent
* event
)
2111 if (user
== NULL
|| event
== NULL
)
2114 switch (nm_event_get_type(event
)) {
2115 case NMEVT_STATUS_CHANGE
:
2116 _evt_status_change(user
, event
);
2118 case NMEVT_RECEIVE_AUTOREPLY
:
2119 case NMEVT_RECEIVE_MESSAGE
:
2120 _evt_receive_message(user
, event
);
2122 case NMEVT_USER_DISCONNECT
:
2123 _evt_user_disconnect(user
, event
);
2125 case NMEVT_USER_TYPING
:
2126 _evt_user_typing(user
, event
);
2128 case NMEVT_USER_NOT_TYPING
:
2129 _evt_user_not_typing(user
, event
);
2131 case NMEVT_SERVER_DISCONNECT
:
2132 /* Nothing to do? */
2134 case NMEVT_INVALID_RECIPIENT
:
2136 case NMEVT_UNDELIVERABLE_STATUS
:
2137 _evt_undeliverable_status(user
, event
);
2139 case NMEVT_CONFERENCE_INVITE_NOTIFY
:
2140 /* Someone else has been invited to join a
2141 * conference that we are currently a part of
2143 _evt_conference_invite_notify(user
, event
);
2145 case NMEVT_CONFERENCE_INVITE
:
2146 /* We have been invited to join a conference */
2147 _evt_conference_invite(user
, event
);
2149 case NMEVT_CONFERENCE_JOINED
:
2150 /* Some one has joined a conference that we
2153 _evt_conference_joined(user
, event
);
2155 case NMEVT_CONFERENCE_LEFT
:
2156 /* Someone else has left a conference that we
2157 * are currently a part of
2159 _evt_conference_left(user
, event
);
2162 purple_debug(PURPLE_DEBUG_INFO
, "novell",
2163 "_event_callback(): unhandled event, %d\n",
2164 nm_event_get_type(event
));
2169 /*******************************************************************************
2171 ******************************************************************************/
2174 novell_login(PurpleAccount
* account
)
2176 PurpleConnection
*gc
;
2177 NMUser
*user
= NULL
;
2182 if (account
== NULL
)
2185 gc
= purple_account_get_connection(account
);
2189 purple_connection_set_flags(gc
, PURPLE_CONNECTION_FLAG_NO_IMAGES
);
2191 server
= purple_account_get_string(account
, "server", NULL
);
2192 if (server
== NULL
|| *server
== '\0') {
2194 /* TODO: Would be nice to prompt if not set!
2195 * purple_request_fields(gc, _("Server Address"),...);
2198 /* ...but for now just error out with a nice message. */
2199 purple_connection_error(gc
,
2200 PURPLE_CONNECTION_ERROR_INVALID_SETTINGS
,
2201 _("Unable to connect to server. Please enter the "
2202 "address of the server to which you wish to connect."));
2206 port
= purple_account_get_int(account
, "port", DEFAULT_PORT
);
2207 name
= purple_account_get_username(account
);
2209 user
= nm_initialize_user(name
, server
, port
, account
, _event_callback
);
2210 if (user
&& user
->conn
) {
2212 purple_connection_set_protocol_data(gc
, user
);
2214 /* connect to the server */
2215 purple_connection_update_progress(gc
, _("Connecting"),
2216 1, NOVELL_CONNECT_STEPS
);
2218 user
->conn
->use_ssl
= TRUE
;
2220 user
->conn
->ssl_conn
= g_new0(NMSSLConn
, 1);
2221 user
->conn
->ssl_conn
->read
= (nm_ssl_read_cb
) purple_ssl_read
;
2222 user
->conn
->ssl_conn
->write
= (nm_ssl_write_cb
) purple_ssl_write
;
2224 user
->conn
->ssl_conn
->data
= purple_ssl_connect(user
->client_data
,
2225 user
->conn
->addr
, user
->conn
->port
,
2226 novell_ssl_connected_cb
, novell_ssl_connect_error
, gc
);
2227 if (user
->conn
->ssl_conn
->data
== NULL
) {
2228 purple_connection_error(gc
,
2229 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT
,
2230 _("SSL support unavailable"));
2236 novell_close(PurpleConnection
* gc
)
2244 user
= purple_connection_get_protocol_data(gc
);
2247 if (conn
&& conn
->ssl_conn
) {
2248 purple_ssl_close(user
->conn
->ssl_conn
->data
);
2250 nm_deinitialize_user(user
);
2252 purple_connection_set_protocol_data(gc
, NULL
);
2256 novell_send_im(PurpleConnection
*gc
, PurpleMessage
*msg
)
2258 NMUserRecord
*user_record
= NULL
;
2259 NMConference
*conf
= NULL
;
2262 const char *dn
= NULL
;
2264 gboolean done
= TRUE
, created_conf
= FALSE
;
2266 const gchar
*name
= purple_message_get_recipient(msg
);
2268 if (gc
== NULL
|| name
== NULL
|| purple_message_is_empty(msg
))
2271 user
= purple_connection_get_protocol_data(gc
);
2275 /* Create a new message */
2276 plain
= purple_unescape_html(purple_message_get_contents(msg
));
2277 message
= nm_create_message(plain
);
2280 /* Need to get the DN for the buddy so we can look up the convo */
2281 dn
= nm_lookup_dn(user
, name
);
2283 /* Do we already know about the sender? */
2284 user_record
= nm_find_user_record(user
, dn
);
2287 /* Do we already have an instantiated conference? */
2288 conf
= nm_find_conversation(user
, dn
);
2291 /* If not, create a blank conference */
2292 conf
= nm_create_conference(NULL
);
2293 created_conf
= TRUE
;
2295 nm_conference_add_participant(conf
, user_record
);
2298 nm_message_set_conference(message
, conf
);
2300 /* Make sure conference is instantiated */
2301 if (!nm_conference_is_instantiated(conf
)) {
2303 /* It is not, so send the createconf. We will
2304 * have to finish sending the message when we
2305 * get the response with the new conference guid.
2307 rc
= nm_send_create_conference(user
, conf
, _createconf_resp_send_msg
, message
);
2308 _check_for_disconnect(user
, rc
);
2315 /* If we don't have details for the user, then we don't have
2316 * a conference yet. So create one and send the getdetails
2317 * to the server. We will have to finish sending the message
2318 * when we get the response from the server.
2320 conf
= nm_create_conference(NULL
);
2321 created_conf
= TRUE
;
2323 nm_message_set_conference(message
, conf
);
2325 rc
= nm_send_get_details(user
, name
, _get_details_resp_send_msg
, message
);
2326 _check_for_disconnect(user
, rc
);
2333 /* Did we find everything we needed? */
2334 rc
= nm_send_message(user
, message
, _send_message_resp_cb
);
2335 _check_for_disconnect(user
, rc
);
2337 nm_release_message(message
);
2340 if (created_conf
&& conf
)
2341 nm_release_conference(conf
);
2347 novell_send_typing(PurpleConnection
* gc
, const char *name
, PurpleIMTypingState state
)
2349 NMConference
*conf
= NULL
;
2351 const char *dn
= NULL
;
2354 if (gc
== NULL
|| name
== NULL
)
2357 user
= purple_connection_get_protocol_data(gc
);
2361 /* Need to get the DN for the buddy so we can look up the convo */
2362 dn
= nm_lookup_dn(user
, name
);
2365 /* Now find the conference in our list */
2366 conf
= nm_find_conversation(user
, dn
);
2369 rc
= nm_send_typing(user
, conf
,
2370 ((state
== PURPLE_IM_TYPING
) ? TRUE
: FALSE
), NULL
);
2371 _check_for_disconnect(user
, rc
);
2381 novell_convo_closed(PurpleConnection
* gc
, const char *who
)
2388 if (gc
== NULL
|| who
== NULL
)
2391 user
= purple_connection_get_protocol_data(gc
);
2392 if (user
&& (dn
= nm_lookup_dn(user
, who
))) {
2393 conf
= nm_find_conversation(user
, dn
);
2395 rc
= nm_send_leave_conference(user
, conf
, NULL
, NULL
);
2396 _check_for_disconnect(user
, rc
);
2402 novell_chat_leave(PurpleConnection
* gc
, int id
)
2404 NMConference
*conference
;
2406 PurpleChatConversation
*chat
;
2413 user
= purple_connection_get_protocol_data(gc
);
2417 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
2418 conference
= cnode
->data
;
2419 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
2420 if (purple_chat_conversation_get_id(chat
) == id
) {
2421 rc
= nm_send_leave_conference(user
, conference
, NULL
, NULL
);
2422 _check_for_disconnect(user
, rc
);
2428 purple_serv_got_chat_left(gc
, id
);
2432 novell_chat_invite(PurpleConnection
*gc
, int id
,
2433 const char *message
, const char *who
)
2435 NMConference
*conference
;
2437 PurpleChatConversation
*chat
;
2440 NMUserRecord
*user_record
= NULL
;
2445 user
= purple_connection_get_protocol_data(gc
);
2449 user_record
= nm_find_user_record(user
, who
);
2450 if (user_record
== NULL
) {
2451 rc
= nm_send_get_details(user
, who
, _get_details_resp_send_invite
, GINT_TO_POINTER(id
));
2452 _check_for_disconnect(user
, rc
);
2456 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
2457 conference
= cnode
->data
;
2458 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
2459 if (purple_chat_conversation_get_id(chat
) == id
) {
2460 rc
= nm_send_conference_invite(user
, conference
, user_record
,
2461 message
, _sendinvite_resp_cb
, NULL
);
2462 _check_for_disconnect(user
, rc
);
2470 novell_chat_send(PurpleConnection
* gc
, int id
, PurpleMessage
*msg
)
2472 NMConference
*conference
;
2473 PurpleChatConversation
*chat
;
2481 if (gc
== NULL
|| purple_message_is_empty(msg
))
2484 user
= purple_connection_get_protocol_data(gc
);
2488 plain
= purple_unescape_html(purple_message_get_contents(msg
));
2489 message
= nm_create_message(plain
);
2492 for (cnode
= user
->conferences
; cnode
!= NULL
; cnode
= cnode
->next
) {
2493 conference
= cnode
->data
;
2494 if (conference
&& (chat
= nm_conference_get_data(conference
))) {
2495 if (purple_chat_conversation_get_id(chat
) == id
) {
2497 nm_message_set_conference(message
, conference
);
2499 /* check to see if the conference is instatiated yet */
2500 if (!nm_conference_is_instantiated(conference
)) {
2501 nm_message_add_ref(message
);
2502 nm_send_create_conference(user
, conference
, _createconf_resp_send_msg
, message
);
2504 rc
= nm_send_message(user
, message
, _send_message_resp_cb
);
2507 nm_release_message(message
);
2509 if (!_check_for_disconnect(user
, rc
)) {
2511 /* Use the account alias if it is set */
2512 name
= purple_account_get_private_alias(user
->client_data
);
2513 if (name
== NULL
|| *name
== '\0') {
2515 /* If there is no account alias, try full name */
2516 name
= nm_user_record_get_full_name(user
->user_record
);
2517 if (name
== NULL
|| *name
== '\0') {
2519 /* Fall back to the username that we are signed in with */
2520 name
= purple_account_get_username(user
->client_data
);
2524 purple_serv_got_chat_in(gc
, id
, name
,
2525 purple_message_get_flags(msg
),
2526 purple_message_get_contents(msg
), time(NULL
));
2536 /* The conference was not found, must be closed */
2537 chat
= purple_conversations_find_chat(gc
, id
);
2539 str
= g_strdup(_("This conference has been closed."
2540 " No more messages can be sent."));
2541 purple_conversation_write_system_message(PURPLE_CONVERSATION(chat
), str
, 0);
2546 nm_release_message(message
);
2552 novell_add_buddy(PurpleConnection
* gc
, PurpleBuddy
*buddy
, PurpleGroup
* group
, const char *message
)
2554 NMFolder
*folder
= NULL
;
2558 const char *alias
, *gname
, *bname
;
2560 if (gc
== NULL
|| buddy
== NULL
|| group
== NULL
)
2563 user
= (NMUser
*) purple_connection_get_protocol_data(gc
);
2567 /* If we haven't synched the contact list yet, ignore
2568 * the add_buddy calls. Server side list is the master.
2570 if (!user
->clist_synched
)
2573 /* Don't re-add a buddy that is already on our contact list */
2574 if (nm_find_user_record(user
, purple_buddy_get_name(buddy
)) != NULL
)
2577 contact
= nm_create_contact();
2578 nm_contact_set_dn(contact
, purple_buddy_get_name(buddy
));
2580 /* Remove the PurpleBuddy (we will add it back after adding it
2581 * to the server side list). Save the alias if there is one.
2583 alias
= purple_buddy_get_alias(buddy
);
2584 bname
= purple_buddy_get_name(buddy
);
2585 if (alias
&& !purple_strequal(alias
, bname
))
2586 nm_contact_set_display_name(contact
, alias
);
2588 purple_blist_remove_buddy(buddy
);
2591 gname
= purple_group_get_name(group
);
2592 if (purple_strequal(gname
, NM_ROOT_FOLDER_NAME
)) {
2596 folder
= nm_find_folder(user
, gname
);
2599 /* We have everything that we need, so send the createcontact */
2600 rc
= nm_send_create_contact(user
, folder
, contact
,
2601 _create_contact_resp_cb
, contact
);
2605 /* Need to create the folder before we can add the contact */
2606 rc
= nm_send_create_folder(user
, gname
,
2607 _create_folder_resp_add_contact
, contact
);
2610 _check_for_disconnect(user
, rc
);
2615 novell_remove_buddy(PurpleConnection
*gc
, PurpleBuddy
*buddy
, PurpleGroup
*group
)
2620 const char *dn
, *gname
;
2623 if (gc
== NULL
|| buddy
== NULL
|| group
== NULL
)
2626 user
= purple_connection_get_protocol_data(gc
);
2627 if (user
&& (dn
= nm_lookup_dn(user
, purple_buddy_get_name(buddy
)))) {
2628 gname
= purple_group_get_name(group
);
2629 if (purple_strequal(gname
, NM_ROOT_FOLDER_NAME
)) {
2632 folder
= nm_find_folder(user
, gname
);
2634 contact
= nm_folder_find_contact(folder
, dn
);
2637 /* Remove the buddy from the contact */
2638 nm_contact_set_data(contact
, NULL
);
2640 /* Tell the server to remove the contact */
2641 rc
= nm_send_remove_contact(user
, folder
, contact
,
2642 _remove_contact_resp_cb
, NULL
);
2643 _check_for_disconnect(user
, rc
);
2650 novell_remove_group(PurpleConnection
* gc
, PurpleGroup
*group
)
2655 if (gc
== NULL
|| group
== NULL
)
2658 user
= purple_connection_get_protocol_data(gc
);
2660 NMFolder
*folder
= nm_find_folder(user
, purple_group_get_name(group
));
2663 rc
= nm_send_remove_folder(user
, folder
,
2664 _remove_folder_resp_cb
, NULL
);
2665 _check_for_disconnect(user
, rc
);
2671 novell_alias_buddy(PurpleConnection
* gc
, const char *name
, const char *alias
)
2675 GList
*contacts
= NULL
;
2676 GList
*cnode
= NULL
;
2677 const char *dn
= NULL
, *fname
= NULL
;
2680 if (gc
== NULL
|| name
== NULL
|| alias
== NULL
)
2683 user
= purple_connection_get_protocol_data(gc
);
2684 if (user
&& (dn
= nm_lookup_dn(user
, name
))) {
2686 /* Alias all of instances of the contact */
2687 contacts
= nm_find_contacts(user
, dn
);
2688 for (cnode
= contacts
; cnode
!= NULL
; cnode
= cnode
->next
) {
2689 contact
= (NMContact
*) cnode
->data
;
2691 PurpleGroup
*group
= NULL
;
2695 /* Alias the Purple buddy? */
2696 folder
= nm_find_folder_by_id(user
,
2697 nm_contact_get_parent_id(contact
));
2699 fname
= nm_folder_get_name(folder
);
2700 if (*fname
== '\0') {
2701 fname
= NM_ROOT_FOLDER_NAME
;
2703 group
= purple_blist_find_group(fname
);
2708 buddy
= purple_blist_find_buddy_in_group(user
->client_data
,
2710 balias
= buddy
? purple_buddy_get_local_alias(buddy
) : NULL
;
2711 if (balias
&& !purple_strequal(balias
, alias
))
2712 purple_buddy_set_local_alias(buddy
, alias
);
2715 /* Tell the server to alias the contact */
2716 rc
= nm_send_rename_contact(user
, contact
, alias
,
2717 _rename_contact_resp_cb
, NULL
);
2718 _check_for_disconnect(user
, rc
);
2722 g_list_free(contacts
);
2727 novell_group_buddy(PurpleConnection
* gc
,
2728 const char *name
, const char *old_group_name
,
2729 const char *new_group_name
)
2731 NMFolder
*old_folder
;
2732 NMFolder
*new_folder
;
2738 if (gc
== NULL
|| name
== NULL
||
2739 old_group_name
== NULL
|| new_group_name
== NULL
)
2742 user
= purple_connection_get_protocol_data(gc
);
2743 if (user
&& (dn
= nm_lookup_dn(user
, name
))) {
2745 /* Find the old folder */
2746 if (purple_strequal(old_group_name
, NM_ROOT_FOLDER_NAME
)) {
2747 old_folder
= nm_get_root_folder(user
);
2748 if (nm_folder_find_contact(old_folder
, dn
) == NULL
)
2749 old_folder
= nm_find_folder(user
, old_group_name
);
2751 old_folder
= nm_find_folder(user
, old_group_name
);
2754 if (old_folder
&& (contact
= nm_folder_find_contact(old_folder
, dn
))) {
2756 /* Find the new folder */
2757 new_folder
= nm_find_folder(user
, new_group_name
);
2758 if (new_folder
== NULL
) {
2759 if (purple_strequal(new_group_name
, NM_ROOT_FOLDER_NAME
))
2760 new_folder
= nm_get_root_folder(user
);
2765 /* Tell the server to move the contact to the new folder */
2766 rc
= nm_send_move_contact(user
, contact
, new_folder
,
2767 _move_contact_resp_cb
, NULL
);
2771 nm_contact_add_ref(contact
);
2773 /* Remove the old contact first */
2774 nm_send_remove_contact(user
, old_folder
, contact
,
2775 _remove_contact_resp_cb
, NULL
);
2777 /* New folder does not exist yet, so create it */
2778 rc
= nm_send_create_folder(user
, new_group_name
,
2779 _create_folder_resp_move_contact
,
2783 _check_for_disconnect(user
, rc
);
2789 novell_rename_group(PurpleConnection
* gc
, const char *old_name
,
2790 PurpleGroup
*group
, GList
*moved_buddies
)
2796 if (gc
== NULL
|| old_name
== NULL
|| group
== NULL
|| moved_buddies
== NULL
) {
2800 user
= purple_connection_get_protocol_data(gc
);
2802 const char *gname
= purple_group_get_name(group
);
2803 /* Does new folder exist already? */
2804 if (nm_find_folder(user
, gname
)) {
2805 /* purple_group_set_name() adds the buddies
2806 * to the new group and removes the old group...
2807 * so there is nothing more to do here.
2812 if (purple_strequal(old_name
, NM_ROOT_FOLDER_NAME
)) {
2813 /* Can't rename the root folder ... need to revisit this */
2817 folder
= nm_find_folder(user
, old_name
);
2819 rc
= nm_send_rename_folder(user
, folder
, gname
,
2820 _rename_folder_resp_cb
, NULL
);
2821 _check_for_disconnect(user
, rc
);
2827 novell_list_icon(PurpleAccount
* account
, PurpleBuddy
* buddy
)
2833 novell_tooltip_text(PurpleBuddy
* buddy
, PurpleNotifyUserInfo
* user_info
, gboolean full
)
2835 NMUserRecord
*user_record
= NULL
;
2836 PurpleConnection
*gc
;
2839 const char *status_str
= NULL
;
2840 const char *text
= NULL
;
2845 gc
= purple_account_get_connection(purple_buddy_get_account(buddy
));
2846 if (gc
== NULL
|| (user
= purple_connection_get_protocol_data(gc
)) == NULL
)
2849 if (PURPLE_BUDDY_IS_ONLINE(buddy
)) {
2850 user_record
= nm_find_user_record(user
, purple_buddy_get_name(buddy
));
2852 status
= nm_user_record_get_status(user_record
);
2853 text
= nm_user_record_get_status_text(user_record
);
2854 /* No custom text, so default it ... */
2856 case NM_STATUS_AVAILABLE
:
2857 status_str
= _("Available");
2859 case NM_STATUS_AWAY
:
2860 status_str
= _("Away");
2862 case NM_STATUS_BUSY
:
2863 status_str
= _("Busy");
2865 case NM_STATUS_AWAY_IDLE
:
2866 status_str
= _("Idle");
2868 case NM_STATUS_OFFLINE
:
2869 status_str
= _("Offline");
2872 status_str
= _("Unknown");
2876 purple_notify_user_info_add_pair_plaintext(user_info
, _("Status"), status_str
);
2879 /* TODO: Check whether it's correct to call add_pair_html,
2880 or if we should be using add_pair_plaintext */
2881 purple_notify_user_info_add_pair_html(user_info
, _("Message"), text
);
2888 novell_set_idle(PurpleConnection
* gc
, int time
)
2892 const char *id
= NULL
;
2893 PurpleStatus
*status
= NULL
;
2898 user
= purple_connection_get_protocol_data(gc
);
2902 status
= purple_account_get_active_status(purple_connection_get_account(gc
));
2903 id
= purple_status_get_id(status
);
2905 /* Only go idle if active status is available */
2906 if (purple_strequal(id
, NOVELL_STATUS_TYPE_AVAILABLE
)) {
2908 rc
= nm_send_set_status(user
, NM_STATUS_AWAY_IDLE
, NULL
, NULL
, NULL
, NULL
);
2910 rc
= nm_send_set_status(user
, NM_STATUS_AVAILABLE
, NULL
, NULL
, NULL
, NULL
);
2914 _check_for_disconnect(user
, rc
);
2918 novell_get_info(PurpleConnection
* gc
, const char *name
)
2920 NMUserRecord
*user_record
;
2924 if (gc
== NULL
|| name
== NULL
)
2927 user
= purple_connection_get_protocol_data(gc
);
2930 user_record
= nm_find_user_record(user
, name
);
2932 _show_info(gc
, user_record
, g_strdup(name
));
2935 rc
= nm_send_get_details(user
, name
,
2936 _get_details_resp_show_info
, g_strdup(name
));
2938 _check_for_disconnect(user
, rc
);
2946 novell_status_text(PurpleBuddy
* buddy
)
2948 const char *text
= NULL
;
2949 const char *dn
= NULL
;
2950 PurpleAccount
*account
;
2952 account
= buddy
? purple_buddy_get_account(buddy
) : NULL
;
2953 if (buddy
&& account
) {
2954 PurpleConnection
*gc
= purple_account_get_connection(account
);
2957 NMUser
*user
= purple_connection_get_protocol_data(gc
);
2960 dn
= nm_lookup_dn(user
, purple_buddy_get_name(buddy
));
2962 NMUserRecord
*user_record
= nm_find_user_record(user
, dn
);
2965 text
= nm_user_record_get_status_text(user_record
);
2967 return g_strdup(text
);
2978 novell_status_types(PurpleAccount
*account
)
2980 GList
*status_types
= NULL
;
2981 PurpleStatusType
*type
;
2983 g_return_val_if_fail(account
!= NULL
, NULL
);
2985 type
= purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE
, NOVELL_STATUS_TYPE_AVAILABLE
,
2986 NULL
, TRUE
, TRUE
, FALSE
,
2987 "message", _("Message"), purple_value_new(G_TYPE_STRING
),
2989 status_types
= g_list_append(status_types
, type
);
2991 type
= purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY
, NOVELL_STATUS_TYPE_AWAY
,
2992 NULL
, TRUE
, TRUE
, FALSE
,
2993 "message", _("Message"), purple_value_new(G_TYPE_STRING
),
2995 status_types
= g_list_append(status_types
, type
);
2997 type
= purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE
, NOVELL_STATUS_TYPE_BUSY
,
2998 _("Busy"), TRUE
, TRUE
, FALSE
,
2999 "message", _("Message"), purple_value_new(G_TYPE_STRING
),
3001 status_types
= g_list_append(status_types
, type
);
3003 type
= purple_status_type_new_full(PURPLE_STATUS_INVISIBLE
, NOVELL_STATUS_TYPE_APPEAR_OFFLINE
,
3004 NULL
, TRUE
, TRUE
, FALSE
);
3005 status_types
= g_list_append(status_types
, type
);
3007 type
= purple_status_type_new_full(PURPLE_STATUS_OFFLINE
, NULL
, NULL
, TRUE
, TRUE
, FALSE
);
3008 status_types
= g_list_append(status_types
, type
);
3010 return status_types
;
3014 novell_set_status(PurpleAccount
*account
, PurpleStatus
*status
)
3016 PurpleConnection
*gc
;
3018 PurplePresence
*presence
;
3019 PurpleStatusType
*type
;
3020 PurpleStatusPrimitive primitive
;
3022 NMSTATUS_T novellstatus
= NM_STATUS_AVAILABLE
;
3024 const char *msg
= NULL
;
3027 connected
= purple_account_is_connected(account
);
3028 presence
= purple_status_get_presence(status
);
3029 type
= purple_status_get_status_type(status
);
3030 primitive
= purple_status_type_get_primitive(type
);
3033 * We don't have any independent statuses, so we don't need to
3034 * do anything when a status is deactivated (because another
3035 * status is about to be activated).
3037 if (!purple_status_is_active(status
))
3043 gc
= purple_account_get_connection(account
);
3044 user
= purple_connection_get_protocol_data(gc
);
3048 if (primitive
== PURPLE_STATUS_AVAILABLE
) {
3049 novellstatus
= NM_STATUS_AVAILABLE
;
3050 } else if (primitive
== PURPLE_STATUS_AWAY
) {
3051 novellstatus
= NM_STATUS_AWAY
;
3052 } else if (primitive
== PURPLE_STATUS_UNAVAILABLE
) {
3053 novellstatus
= NM_STATUS_BUSY
;
3054 } else if (primitive
== PURPLE_STATUS_INVISIBLE
) {
3055 novellstatus
= NM_STATUS_OFFLINE
;
3056 } else if (purple_presence_is_idle(presence
)) {
3057 novellstatus
= NM_STATUS_AWAY_IDLE
;
3059 novellstatus
= NM_STATUS_AVAILABLE
;
3062 if (primitive
== PURPLE_STATUS_AWAY
|| primitive
== PURPLE_STATUS_AVAILABLE
||
3063 primitive
== PURPLE_STATUS_UNAVAILABLE
) {
3064 msg
= purple_status_get_attr_string(status
, "message");
3065 text
= g_strdup(msg
);
3067 if (primitive
== PURPLE_STATUS_AVAILABLE
)
3068 msg
= NULL
; /* no auto replies for online status */
3070 /* Don't want newlines in status text */
3071 purple_util_chrreplace(text
, '\n', ' ');
3074 rc
= nm_send_set_status(user
, novellstatus
, text
, msg
, NULL
, NULL
);
3075 _check_for_disconnect(user
, rc
);
3081 novell_add_permit(PurpleConnection
*gc
, const char *who
)
3085 const char *name
= who
;
3087 if (gc
== NULL
|| who
== NULL
)
3090 user
= purple_connection_get_protocol_data(gc
);
3094 /* Remove first -- we will add it back in when we get
3095 * the okay from the server
3097 purple_account_privacy_permit_remove(purple_connection_get_account(gc
), who
, TRUE
);
3099 if (nm_user_is_privacy_locked(user
)) {
3100 _show_privacy_locked_error(gc
, user
);
3101 _sync_privacy_lists(user
);
3105 /* Work around for problem with un-typed, dotted contexts */
3106 if (strchr(who
, '.')) {
3107 const char *dn
= nm_lookup_dn(user
, who
);
3109 rc
= nm_send_get_details(user
, who
, _get_details_send_privacy_create
,
3111 _check_for_disconnect(user
, rc
);
3118 rc
= nm_send_create_privacy_item(user
, name
, TRUE
,
3119 _create_privacy_item_permit_resp_cb
,
3121 _check_for_disconnect(user
, rc
);
3125 novell_add_deny(PurpleConnection
*gc
, const char *who
)
3129 const char *name
= who
;
3131 if (gc
== NULL
|| who
== NULL
)
3134 user
= purple_connection_get_protocol_data(gc
);
3138 /* Remove first -- we will add it back in when we get
3139 * the okay from the server
3141 purple_account_privacy_deny_remove(purple_connection_get_account(gc
), who
, TRUE
);
3143 if (nm_user_is_privacy_locked(user
)) {
3144 _show_privacy_locked_error(gc
, user
);
3145 _sync_privacy_lists(user
);
3149 /* Work around for problem with un-typed, dotted contexts */
3150 if (strchr(who
, '.')) {
3151 const char *dn
= nm_lookup_dn(user
, who
);
3153 rc
= nm_send_get_details(user
, who
, _get_details_send_privacy_create
,
3155 _check_for_disconnect(user
, rc
);
3162 rc
= nm_send_create_privacy_item(user
, name
, FALSE
,
3163 _create_privacy_item_deny_resp_cb
,
3165 _check_for_disconnect(user
, rc
);
3169 novell_rem_permit(PurpleConnection
*gc
, const char *who
)
3173 const char *dn
= NULL
;
3175 if (gc
== NULL
|| who
== NULL
)
3178 user
= purple_connection_get_protocol_data(gc
);
3182 if (nm_user_is_privacy_locked(user
)) {
3183 _show_privacy_locked_error(gc
, user
);
3184 _sync_privacy_lists(user
);
3188 dn
= nm_lookup_dn(user
, who
);
3192 rc
= nm_send_remove_privacy_item(user
, dn
, TRUE
,
3193 _remove_privacy_item_resp_cb
,
3195 _check_for_disconnect(user
, rc
);
3199 novell_rem_deny(PurpleConnection
*gc
, const char *who
)
3203 const char *dn
= NULL
;
3205 if (gc
== NULL
|| who
== NULL
)
3208 user
= purple_connection_get_protocol_data(gc
);
3212 if (nm_user_is_privacy_locked(user
)) {
3213 _show_privacy_locked_error(gc
, user
);
3214 _sync_privacy_lists(user
);
3218 dn
= nm_lookup_dn(user
, who
);
3222 rc
= nm_send_remove_privacy_item(user
, dn
, FALSE
,
3223 _remove_privacy_item_resp_cb
,
3225 _check_for_disconnect(user
, rc
);
3229 novell_set_permit_deny(PurpleConnection
*gc
)
3232 const char *dn
, *name
= NULL
;
3233 NMUserRecord
*user_record
= NULL
;
3234 GSList
*node
= NULL
, *copy
= NULL
;
3236 int i
, j
, num_contacts
, num_folders
;
3238 NMFolder
*folder
= NULL
;
3239 PurpleAccount
*account
;
3244 account
= purple_connection_get_account(gc
);
3246 user
= purple_connection_get_protocol_data(gc
);
3250 if (user
->privacy_synched
== FALSE
) {
3251 _sync_privacy_lists(user
);
3252 user
->privacy_synched
= TRUE
;
3256 if (nm_user_is_privacy_locked(user
)) {
3257 _show_privacy_locked_error(gc
, user
);
3258 _sync_privacy_lists(user
);
3262 switch (purple_account_get_privacy_type(account
)) {
3264 case PURPLE_ACCOUNT_PRIVACY_ALLOW_ALL
:
3265 rc
= nm_send_set_privacy_default(user
, FALSE
,
3266 _set_privacy_default_resp_cb
, NULL
);
3267 _check_for_disconnect(user
, rc
);
3269 /* clear server side deny list */
3271 copy
= g_slist_copy(user
->deny_list
);
3272 for (node
= copy
; node
&& node
->data
; node
= node
->next
) {
3273 rc
= nm_send_remove_privacy_item(user
, (const char *)node
->data
,
3275 if (_check_for_disconnect(user
, rc
))
3279 g_slist_free(user
->deny_list
);
3280 user
->deny_list
= NULL
;
3284 case PURPLE_ACCOUNT_PRIVACY_DENY_ALL
:
3285 rc
= nm_send_set_privacy_default(user
, TRUE
,
3286 _set_privacy_default_resp_cb
, NULL
);
3287 _check_for_disconnect(user
, rc
);
3289 /* clear server side allow list */
3291 copy
= g_slist_copy(user
->allow_list
);
3292 for (node
= copy
; node
&& node
->data
; node
= node
->next
) {
3293 rc
= nm_send_remove_privacy_item(user
, (const char *)node
->data
,
3295 if (_check_for_disconnect(user
, rc
))
3299 g_slist_free(user
->allow_list
);
3300 user
->allow_list
= NULL
;
3304 case PURPLE_ACCOUNT_PRIVACY_ALLOW_USERS
:
3306 rc
= nm_send_set_privacy_default(user
, TRUE
,
3307 _set_privacy_default_resp_cb
, NULL
);
3308 _check_for_disconnect(user
, rc
);
3310 /* sync allow lists */
3313 for (node
= user
->allow_list
; node
; node
= node
->next
) {
3314 user_record
= nm_find_user_record(user
, (char *)node
->data
);
3316 name
= nm_user_record_get_display_id(user_record
);
3318 if (!g_slist_find_custom(purple_account_privacy_get_permitted(account
),
3319 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3320 purple_account_privacy_permit_add(account
, name
, TRUE
);
3325 for (node
= purple_account_privacy_get_permitted(account
); node
; node
= node
->next
) {
3326 dn
= nm_lookup_dn(user
, (char *)node
->data
);
3329 if (!g_slist_find_custom(user
->allow_list
,
3330 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3331 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
3332 _create_privacy_item_deny_resp_cb
,
3334 _check_for_disconnect(user
, rc
);
3337 purple_account_privacy_permit_remove(account
, (char *)node
->data
, TRUE
);
3343 case PURPLE_ACCOUNT_PRIVACY_DENY_USERS
:
3345 /* set to default allow */
3346 rc
= nm_send_set_privacy_default(user
, FALSE
,
3347 _set_privacy_default_resp_cb
, NULL
);
3348 _check_for_disconnect(user
, rc
);
3350 /* sync deny lists */
3353 for (node
= user
->deny_list
; node
; node
= node
->next
) {
3354 user_record
= nm_find_user_record(user
, (char *)node
->data
);
3356 name
= nm_user_record_get_display_id(user_record
);
3358 if (!g_slist_find_custom(purple_account_privacy_get_denied(account
),
3359 name
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3360 purple_account_privacy_deny_add(account
, name
, TRUE
);
3365 for (node
= purple_account_privacy_get_denied(account
); node
; node
= node
->next
) {
3368 dn
= nm_lookup_dn(user
, (char *)node
->data
);
3370 user_record
= nm_find_user_record(user
, dn
);
3371 name
= nm_user_record_get_display_id(user_record
);
3373 if (!g_slist_find_custom(user
->deny_list
,
3374 dn
, (GCompareFunc
)purple_utf8_strcasecmp
)) {
3375 rc
= nm_send_create_privacy_item(user
, dn
, FALSE
,
3376 _create_privacy_item_deny_resp_cb
,
3378 _check_for_disconnect(user
, rc
);
3381 purple_account_privacy_deny_remove(account
, (char *)node
->data
, TRUE
);
3388 case PURPLE_ACCOUNT_PRIVACY_ALLOW_BUDDYLIST
:
3390 /* remove users from allow list that are not in buddy list */
3391 copy
= g_slist_copy(user
->allow_list
);
3392 for (node
= copy
; node
&& node
->data
; node
= node
->next
) {
3393 if (!nm_find_contacts(user
, node
->data
)) {
3394 rc
= nm_send_remove_privacy_item(user
, (const char *)node
->data
,
3396 if (_check_for_disconnect(user
, rc
))
3402 /* add all buddies to allow list */
3403 num_contacts
= nm_folder_get_contact_count(user
->root_folder
);
3404 for (i
= 0; i
< num_contacts
; i
++) {
3405 contact
= nm_folder_get_contact(user
->root_folder
, i
);
3406 dn
= nm_contact_get_dn(contact
);
3407 if (dn
&& !g_slist_find_custom(user
->allow_list
,
3408 dn
, (GCompareFunc
)purple_utf8_strcasecmp
))
3410 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
3411 _create_privacy_item_deny_resp_cb
,
3413 if (_check_for_disconnect(user
, rc
))
3419 num_folders
= nm_folder_get_subfolder_count(user
->root_folder
);
3420 for (i
= 0; i
< num_folders
; i
++) {
3421 folder
= nm_folder_get_subfolder(user
->root_folder
, i
);
3422 num_contacts
= nm_folder_get_contact_count(folder
);
3423 for (j
= 0; j
< num_contacts
; j
++) {
3424 contact
= nm_folder_get_contact(folder
, j
);
3425 dn
= nm_contact_get_dn(contact
);
3426 if (dn
&& !g_slist_find_custom(user
->allow_list
,
3427 dn
, (GCompareFunc
)purple_utf8_strcasecmp
))
3429 rc
= nm_send_create_privacy_item(user
, dn
, TRUE
,
3430 _create_privacy_item_deny_resp_cb
,
3432 if (_check_for_disconnect(user
, rc
))
3438 /* set to default deny */
3439 rc
= nm_send_set_privacy_default(user
, TRUE
,
3440 _set_privacy_default_resp_cb
, NULL
);
3441 if (_check_for_disconnect(user
, rc
))
3449 novell_blist_node_menu(PurpleBlistNode
*node
)
3452 PurpleActionMenu
*act
;
3454 if(PURPLE_IS_BUDDY(node
)) {
3455 act
= purple_action_menu_new(_("Initiate _Chat"),
3456 PURPLE_CALLBACK(_initiate_conference_cb
),
3458 list
= g_list_append(list
, act
);
3465 novell_keepalive(PurpleConnection
*gc
)
3473 user
= purple_connection_get_protocol_data(gc
);
3477 rc
= nm_send_keepalive(user
, NULL
, NULL
);
3478 _check_for_disconnect(user
, rc
);
3482 novell_get_max_message_size(PurpleConversation
*conv
)
3484 /* XXX: got from pidgin-otr - verify and document it */
3489 novell_protocol_init(PurpleProtocol
*protocol
)
3491 PurpleAccountOption
*option
;
3493 protocol
->id
= "prpl-novell";
3494 protocol
->name
= "GroupWise";
3496 option
= purple_account_option_string_new(_("Server address"), "server", NULL
);
3497 protocol
->account_options
=
3498 g_list_append(protocol
->account_options
, option
);
3500 option
= purple_account_option_int_new(_("Server port"), "port", DEFAULT_PORT
);
3501 protocol
->account_options
=
3502 g_list_append(protocol
->account_options
, option
);
3506 novell_protocol_class_init(PurpleProtocolClass
*klass
)
3508 klass
->login
= novell_login
;
3509 klass
->close
= novell_close
;
3510 klass
->status_types
= novell_status_types
;
3511 klass
->list_icon
= novell_list_icon
;
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 PURPLE_DEFINE_TYPE_EXTENDED(
3566 NovellProtocol
, novell_protocol
, PURPLE_TYPE_PROTOCOL
, 0,
3568 PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CLIENT
,
3569 novell_protocol_client_iface_init
)
3571 PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_SERVER
,
3572 novell_protocol_server_iface_init
)
3574 PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_IM
,
3575 novell_protocol_im_iface_init
)
3577 PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CHAT
,
3578 novell_protocol_chat_iface_init
)
3580 PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_PRIVACY
,
3581 novell_protocol_privacy_iface_init
)
3584 static PurplePluginInfo
*
3585 plugin_query(GError
**error
)
3587 return purple_plugin_info_new(
3588 "id", "prpl-novell",
3589 "name", "Novell GroupWise Protocol",
3590 "version", DISPLAY_VERSION
,
3591 "category", N_("Protocol"),
3592 "summary", N_("Novell GroupWise Messenger Protocol Plugin"),
3593 "description", N_("Novell GroupWise Messenger Protocol Plugin"),
3594 "website", PURPLE_WEBSITE
,
3595 "abi-version", PURPLE_ABI_VERSION
,
3596 "flags", PURPLE_PLUGIN_INFO_FLAGS_INTERNAL
|
3597 PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD
,
3603 plugin_load(PurplePlugin
*plugin
, GError
**error
)
3605 novell_protocol_register_type(plugin
);
3607 my_protocol
= purple_protocols_add(NOVELL_TYPE_PROTOCOL
, error
);
3615 plugin_unload(PurplePlugin
*plugin
, GError
**error
)
3617 if (!purple_protocols_remove(my_protocol
, error
))
3623 PURPLE_PLUGIN_INIT(novell
, plugin_query
, plugin_load
, plugin_unload
);