comparison src/protocols/novell/novell.c @ 8933:6663ad2386d9

[gaim-migrate @ 9703] "Initial Comment: * Added support for privacy settings * Added support for invites - ability to initiate multi-user conferences (chats). * Changed the license notice (to the standard GPL notice) * Fixed 64 bit issues * Incorporated Joe Shaw's patch for better error messages * Fixed the buddy list sync problems" --Mike Stoddard of Novell committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Sat, 15 May 2004 14:00:31 +0000
parents 518455386538
children 80b4c956d7ae
comparison
equal deleted inserted replaced
8932:849507541e86 8933:6663ad2386d9
1 /* 1 /*
2 * novell.c 2 * novell.c
3 * 3 *
4 * Copyright © 2004 Unpublished Work of Novell, Inc. All Rights Reserved. 4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
5 * 5 *
6 * THIS WORK IS AN UNPUBLISHED WORK OF NOVELL, INC. NO PART OF THIS WORK MAY BE 6 * This program is free software; you can redistribute it and/or modify
7 * USED, PRACTICED, PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, 7 * it under the terms of the GNU General Public License as published by
8 * TRANSLATED, ABRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, 8 * the Free Software Foundation; version 2 of the License.
9 * RECAST, TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL,
10 * INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT
11 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
12 * 9 *
13 * AS BETWEEN [GAIM] AND NOVELL, NOVELL GRANTS [GAIM] THE RIGHT TO REPUBLISH 10 * This program is distributed in the hope that it will be useful,
14 * THIS WORK UNDER THE GPL (GNU GENERAL PUBLIC LICENSE) WITH ALL RIGHTS AND 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * LICENSES THEREUNDER. IF YOU HAVE RECEIVED THIS WORK DIRECTLY OR INDIRECTLY 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * FROM [GAIM] AS PART OF SUCH A REPUBLICATION, YOU HAVE ALL RIGHTS AND LICENSES 13 * GNU General Public License for more details.
17 * GRANTED BY [GAIM] UNDER THE GPL. IN CONNECTION WITH SUCH A REPUBLICATION, IF 14 *
18 * ANYTHING IN THIS NOTICE CONFLICTS WITH THE TERMS OF THE GPL, SUCH TERMS 15 * You should have received a copy of the GNU General Public License
19 * PREVAIL. 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * 18 *
21 */ 19 */
22 20
23 #include "internal.h" 21 #include "internal.h"
24 #include "accountopt.h" 22 #include "accountopt.h"
29 #include "notify.h" 27 #include "notify.h"
30 #include "util.h" 28 #include "util.h"
31 #include "sslconn.h" 29 #include "sslconn.h"
32 #include "request.h" 30 #include "request.h"
33 #include "network.h" 31 #include "network.h"
32 #include "privacy.h"
33 #include "multi.h"
34 34
35 #define DEFAULT_PORT 8300 35 #define DEFAULT_PORT 8300
36 #define NOVELL_CONNECT_STEPS 4 36 #define NOVELL_CONNECT_STEPS 4
37 37
38 static GaimPlugin *my_protocol = NULL; 38 static GaimPlugin *my_protocol = NULL;
39 39
40 static gboolean set_permit = FALSE;
41
40 static gboolean 42 static gboolean
41 _is_disconnect_error(NMERR_T err); 43 _is_disconnect_error(NMERR_T err);
42 44
43 static gboolean 45 static gboolean
44 _check_for_disconnect(NMUser * user, NMERR_T err); 46 _check_for_disconnect(NMUser * user, NMERR_T err);
57 59
58 static void 60 static void
59 _add_gaim_buddies(NMUser * user); 61 _add_gaim_buddies(NMUser * user);
60 62
61 static void 63 static void
64 _sync_contact_list(NMUser *user);
65
66 static void
67 _sync_privacy_lists(NMUser *user);
68
69 static void
62 _show_info(GaimConnection * gc, NMUserRecord * user_record); 70 _show_info(GaimConnection * gc, NMUserRecord * user_record);
71
72 const char *
73 _get_conference_name(int id);
63 74
64 /******************************************************************************* 75 /*******************************************************************************
65 * Response callbacks 76 * Response callbacks
66 *******************************************************************************/ 77 *******************************************************************************/
67 78
90 101
91 if (alias) 102 if (alias)
92 gaim_account_set_alias(user->client_data, alias); 103 gaim_account_set_alias(user->client_data, alias);
93 } 104 }
94 105
106 _sync_contact_list(user);
107 _sync_privacy_lists(user);
108
95 /* Tell Gaim that we are connected */ 109 /* Tell Gaim that we are connected */
96 gaim_connection_set_state(gc, GAIM_CONNECTED); 110 gaim_connection_set_state(gc, GAIM_CONNECTED);
97 serv_finish_login(gc); 111 serv_finish_login(gc);
98 112
99 /* Sync the contact list. This is pretty simplistic right now,
100 * we just remove all of the GaimBuddy from the client side list
101 * for this account and then add in all of the contacts from the
102 * server side list.
103 */
104 _remove_gaim_buddies(user);
105 _add_gaim_buddies(user);
106
107 rc = nm_send_set_status(user, NM_STATUS_AVAILABLE, NULL, NULL, NULL, 113 rc = nm_send_set_status(user, NM_STATUS_AVAILABLE, NULL, NULL, NULL,
108 NULL); 114 NULL);
109 _check_for_disconnect(user, rc); 115 _check_for_disconnect(user, rc);
110 116
111 } else { 117 } else {
112 118
113 char *err = g_strdup_printf(_("Login failed (0x%X)."), ret_code); 119 char *err = g_strdup_printf(_("Login failed (%s)."),
120 nm_error_to_string (ret_code));
114 121
115 gaim_connection_error(gc, err); 122 gaim_connection_error(gc, err);
116 g_free(err); 123 g_free(err);
117 124
118 } 125 }
221 } else { 228 } else {
222 229
223 gc = gaim_account_get_connection(user->client_data); 230 gc = gaim_account_get_connection(user->client_data);
224 if (gc != NULL) { 231 if (gc != NULL) {
225 char *err = g_strdup_printf(_("Unable to send message." 232 char *err = g_strdup_printf(_("Unable to send message."
226 " Could not get details for user (0x%X)."), 233 " Could not get details for user (%s)."),
227 ret_code); 234 nm_error_to_string (ret_code));
228 235
229 gaim_notify_error(gc, NULL, err, NULL); 236 gaim_notify_error(gc, NULL, err, NULL);
230 g_free(err); 237 g_free(err);
231 } 238 }
232 239
366 GaimConnection *gc = gaim_account_get_connection(user->client_data); 373 GaimConnection *gc = gaim_account_get_connection(user->client_data);
367 const char *name = nm_contact_get_dn(tmp_contact); 374 const char *name = nm_contact_get_dn(tmp_contact);
368 char *err; 375 char *err;
369 376
370 err = 377 err =
371 g_strdup_printf(_("Unable to add %s to your buddy list (0x%X)."), 378 g_strdup_printf(_("Unable to add %s to your buddy list (%s)."),
372 name, ret_code); 379 name, nm_error_to_string (ret_code));
373 gaim_notify_error(gc, NULL, err, NULL); 380 gaim_notify_error(gc, NULL, err, NULL);
374 g_free(err); 381 g_free(err);
375 382
376 } 383 }
377 384
392 399
393 if (ret_code != NM_OK) { 400 if (ret_code != NM_OK) {
394 gc = gaim_account_get_connection(user->client_data); 401 gc = gaim_account_get_connection(user->client_data);
395 402
396 /* TODO: Improve this! message to who or for what conference? */ 403 /* TODO: Improve this! message to who or for what conference? */
397 err = g_strdup_printf(_("Unable to send message (0x%X)."), 404 err = g_strdup_printf(_("Unable to send message (%s)."),
398 ret_code); 405 nm_error_to_string (ret_code));
399 gaim_notify_error(gc, NULL, err, NULL); 406 gaim_notify_error(gc, NULL, err, NULL);
400 g_free(err); 407 g_free(err);
401 } 408 }
402 } 409 }
403 410
449 /* TODO: Display an error? */ 456 /* TODO: Display an error? */
450 457
451 gaim_debug(GAIM_DEBUG_INFO, "novell", 458 gaim_debug(GAIM_DEBUG_INFO, "novell",
452 "_rename_folder_resp_cb(): rc = 0x%x\n", ret_code); 459 "_rename_folder_resp_cb(): rc = 0x%x\n", ret_code);
453 } 460 }
461 }
462
463 static void
464 _sendinvite_resp_cb(NMUser *user, NMERR_T ret_code,
465 gpointer resp_data, gpointer user_data)
466 {
467 char *err;
468 GaimConnection *gc;
469
470 if (user == NULL)
471 return;
472
473 if (ret_code != NM_OK) {
474 gc = gaim_account_get_connection(user->client_data);
475 err = g_strdup_printf(_("Unable to invite user (%s)."), nm_error_to_string(ret_code));
476 gaim_notify_error(gc, NULL, err, NULL);
477 g_free(err);
478
479 gaim_debug(GAIM_DEBUG_INFO, "novell",
480 "_sendinvite_resp_cb(): rc = 0x%x\n", ret_code);
481 }
482
454 } 483 }
455 484
456 /* If the createconf was successful attempt to send the message, 485 /* If the createconf was successful attempt to send the message,
457 * otherwise display an error message to the user. 486 * otherwise display an error message to the user.
458 */ 487 */
481 if (ur) 510 if (ur)
482 name = nm_user_record_get_userid(ur); 511 name = nm_user_record_get_userid(ur);
483 512
484 if (name) 513 if (name)
485 err = g_strdup_printf(_("Unable to send message to %s." 514 err = g_strdup_printf(_("Unable to send message to %s."
486 " Could not create the conference (0x%X)."), 515 " Could not create the conference (%s)."),
487 name, ret_code); 516 name,
517 nm_error_to_string (ret_code));
488 else 518 else
489 err = g_strdup_printf(_("Unable to send message." 519 err = g_strdup_printf(_("Unable to send message."
490 " Could not create the conference (0x%X)."), 520 " Could not create the conference (%s)."),
491 ret_code); 521 nm_error_to_string (ret_code));
492 522
493 gaim_notify_error(gc, NULL, err, NULL); 523 gaim_notify_error(gc, NULL, err, NULL);
494 g_free(err); 524 g_free(err);
495 } 525 }
496 526
515 g_free(folder_name); 545 g_free(folder_name);
516 546
517 return; 547 return;
518 } 548 }
519 549
520 if (ret_code == NM_OK || ret_code == 0xD126) { 550 if (ret_code == NM_OK || ret_code == NMERR_DUPLICATE_FOLDER) {
521 new_folder = nm_find_folder(user, folder_name); 551 new_folder = nm_find_folder(user, folder_name);
522 if (new_folder) { 552 if (new_folder) {
523 553
524 /* Tell the server to move the contact to the new folder */ 554 /* Tell the server to move the contact to the new folder */
525 /* rc = nm_send_move_contact(user, contact, new_folder, 555 /* rc = nm_send_move_contact(user, contact, new_folder,
533 } 563 }
534 } else { 564 } else {
535 GaimConnection *gc = gaim_account_get_connection(user->client_data); 565 GaimConnection *gc = gaim_account_get_connection(user->client_data);
536 char *err = g_strdup_printf(_("Unable to move user %s" 566 char *err = g_strdup_printf(_("Unable to move user %s"
537 " to folder %s in the server side list." 567 " to folder %s in the server side list."
538 " Error while creating folder (0x%X)."), 568 " Error while creating folder (%s)."),
539 nm_contact_get_dn(contact), 569 nm_contact_get_dn(contact),
540 folder_name, 570 folder_name,
541 ret_code); 571 nm_error_to_string (ret_code));
542 572
543 gaim_notify_error(gc, NULL, err, NULL); 573 gaim_notify_error(gc, NULL, err, NULL);
544 g_free(err); 574 g_free(err);
545 } 575 }
546 576
567 g_free(folder_name); 597 g_free(folder_name);
568 598
569 return; 599 return;
570 } 600 }
571 601
572 if (ret_code == NM_OK || ret_code == 0xD126) { 602 if (ret_code == NM_OK || ret_code == NMERR_DUPLICATE_FOLDER) {
573 folder = nm_find_folder(user, folder_name); 603 folder = nm_find_folder(user, folder_name);
574 if (folder) { 604 if (folder) {
575 605
576 rc = nm_send_create_contact(user, folder, contact, 606 rc = nm_send_create_contact(user, folder, contact,
577 _create_contact_resp_cb, contact); 607 _create_contact_resp_cb, contact);
580 } else { 610 } else {
581 GaimConnection *gc = gaim_account_get_connection(user->client_data); 611 GaimConnection *gc = gaim_account_get_connection(user->client_data);
582 const char *name = nm_contact_get_dn(contact); 612 const char *name = nm_contact_get_dn(contact);
583 char *err = 613 char *err =
584 g_strdup_printf(_("Unable to add %s to your buddy list." 614 g_strdup_printf(_("Unable to add %s to your buddy list."
585 " Error creating folder in server side list (0x%X)."), 615 " Error creating folder in server side list (%s)."),
586 name, ret_code); 616 name, nm_error_to_string (ret_code));
587 617
588 gaim_notify_error(gc, NULL, err, NULL); 618 gaim_notify_error(gc, NULL, err, NULL);
589 619
590 nm_release_contact(contact); 620 nm_release_contact(contact);
591 g_free(err); 621 g_free(err);
600 { 630 {
601 GaimConversation *chat; 631 GaimConversation *chat;
602 GaimConnection *gc; 632 GaimConnection *gc;
603 NMUserRecord *ur; 633 NMUserRecord *ur;
604 NMConference *conference = user_data; 634 NMConference *conference = user_data;
605 const char *name; 635 const char *name, *conf_name;
606 char *conf_name;
607 int i, count; 636 int i, count;
608 637
609 if (user == NULL || conference == NULL) 638 if (user == NULL || conference == NULL)
610 return; 639 return;
611 640
612 gc = gaim_account_get_connection(user->client_data); 641 gc = gaim_account_get_connection(user->client_data);
613 642
614 if (ret_code == NM_OK) { 643 if (ret_code == NM_OK) {
615 conf_name = g_strdup_printf(_("GroupWise Conference %d"), 644 conf_name = _get_conference_name(++user->conference_count);
616 ++user->conference_count);
617 chat = serv_got_joined_chat(gc, user->conference_count, conf_name); 645 chat = serv_got_joined_chat(gc, user->conference_count, conf_name);
618 if (chat) { 646 if (chat) {
619 647
620 nm_conference_set_data(conference, (gpointer) chat); 648 nm_conference_set_data(conference, (gpointer) chat);
621 649
626 name = nm_user_record_get_display_id(ur); 654 name = nm_user_record_get_display_id(ur);
627 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); 655 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL);
628 } 656 }
629 } 657 }
630 } 658 }
631 g_free(conf_name);
632 } 659 }
633 } 660 }
634 661
635 /* Show info returned by getdetails */ 662 /* Show info returned by getdetails */
636 static void 663 static void
654 user_record); 681 user_record);
655 } 682 }
656 } else { 683 } else {
657 gc = gaim_account_get_connection(user->client_data); 684 gc = gaim_account_get_connection(user->client_data);
658 err = 685 err =
659 g_strdup_printf(_("Could not get details for user %s (0x%X)."), name, 686 g_strdup_printf(_("Could not get details for user %s (%s)."),
660 ret_code); 687 name, nm_error_to_string (ret_code));
661 gaim_notify_error(gc, NULL, err, NULL); 688 gaim_notify_error(gc, NULL, err, NULL);
662 g_free(err); 689 g_free(err);
663 } 690 }
664 691
665 if (name) 692 if (name)
666 g_free(name); 693 g_free(name);
694 }
695
696 /* Handle get details response add to privacy list */
697 static void
698 _get_details_resp_add_privacy_item(NMUser *user, NMERR_T ret_code,
699 gpointer resp_data, gpointer user_data)
700 {
701 GaimConnection *gc;
702 NMUserRecord *user_record = resp_data;
703 char *err;
704 gboolean allowed = (gboolean)user_data;
705 const char *display_id;
706
707 if (user == NULL)
708 return;
709
710 gc = gaim_account_get_connection(user->client_data);
711 display_id = nm_user_record_get_display_id(user_record);
712
713 if (ret_code == NM_OK) {
714
715 if (allowed) {
716
717 if (!g_slist_find_custom(gc->account->permit,
718 display_id, (GCompareFunc)nm_utf8_strcasecmp)) {
719 gaim_privacy_permit_add(gc->account, display_id, TRUE);
720 }
721
722 } else {
723
724 if (!g_slist_find_custom(gc->account->permit,
725 display_id, (GCompareFunc)nm_utf8_strcasecmp)) {
726 gaim_privacy_deny_add(gc->account, display_id, TRUE);
727 }
728 }
729
730 } else {
731
732 err = g_strdup_printf(_("Unable to add user to privacy list (%s)."),
733 nm_error_to_string(ret_code));
734 gaim_notify_error(gc, NULL, err, NULL);
735 g_free(err);
736
737 }
738 }
739
740 /* Handle response to create privacy item request */
741 static void
742 _create_privacy_item_deny_resp_cb(NMUser *user, NMERR_T ret_code,
743 gpointer resp_data, gpointer user_data)
744 {
745 GaimConnection *gc;
746 NMUserRecord *user_record;
747 char *who = user_data;
748 char *err;
749 NMERR_T rc = NM_OK;
750 const char *display_id = NULL;
751
752 if (user == NULL)
753 return;
754
755 gc = gaim_account_get_connection(user->client_data);
756
757 if (ret_code == NM_OK) {
758
759 user_record = nm_find_user_record(user, who);
760 if (user_record)
761 display_id = nm_user_record_get_display_id(user_record);
762
763 if (display_id) {
764
765 if (!g_slist_find_custom(gc->account->deny,
766 display_id, (GCompareFunc)nm_utf8_strcasecmp)) {
767
768 gaim_privacy_deny_add(gc->account, display_id, TRUE);
769 }
770
771 } else {
772 rc = nm_send_get_details(user, who,
773 _get_details_resp_add_privacy_item,
774 (gpointer)FALSE);
775 _check_for_disconnect(user, rc);
776 }
777 } else {
778
779 err = g_strdup_printf(_("Unable to add %s to deny list (%s)."),
780 who, nm_error_to_string(ret_code));
781 gaim_notify_error(gc, NULL, err, NULL);
782 g_free(err);
783
784 }
785
786 if (who)
787 g_free(who);
788
789 }
790
791 /* Handle response to create privacy item request */
792 static void
793 _create_privacy_item_permit_resp_cb(NMUser *user, NMERR_T ret_code,
794 gpointer resp_data, gpointer user_data)
795 {
796 GaimConnection *gc;
797 NMUserRecord *user_record;
798 char *who = user_data;
799 char *err;
800 NMERR_T rc = NM_OK;
801 const char *display_id = NULL;
802
803 if (user == NULL)
804 return;
805
806 gc = gaim_account_get_connection(user->client_data);
807
808 if (ret_code == NM_OK) {
809
810 user_record = nm_find_user_record(user, who);
811 if (user_record)
812 display_id = nm_user_record_get_display_id(user_record);
813
814 if (display_id) {
815
816 if (!g_slist_find_custom(gc->account->permit,
817 display_id,
818 (GCompareFunc)nm_utf8_strcasecmp)) {
819
820 gaim_privacy_permit_add(gc->account, display_id, TRUE);
821 }
822
823 } else {
824 rc = nm_send_get_details(user, who,
825 _get_details_resp_add_privacy_item,
826 (gpointer)TRUE);
827 _check_for_disconnect(user, rc);
828 }
829
830 } else {
831
832 err = g_strdup_printf(_("Unable to add %s to permit list (%s)."), who,
833 nm_error_to_string(ret_code));
834 gaim_notify_error(gc, NULL, err, NULL);
835 g_free(err);
836
837 }
838
839 if (who)
840 g_free(who);
841 }
842
843 static void
844 _get_details_send_privacy_create(NMUser *user, NMERR_T ret_code,
845 gpointer resp_data, gpointer user_data)
846 {
847 NMERR_T rc = NM_OK;
848 GaimConnection *gc;
849 NMUserRecord *user_record = resp_data;
850 char *err;
851 gboolean allowed = (gboolean)user_data;
852 const char *dn, *display_id;
853
854 if (user == NULL)
855 return;
856
857 gc = gaim_account_get_connection(user->client_data);
858 dn = nm_user_record_get_dn(user_record);
859 display_id = nm_user_record_get_display_id(user_record);
860
861 if (ret_code == NM_OK) {
862
863 if (allowed) {
864 rc = nm_send_create_privacy_item(user, dn, TRUE,
865 _create_privacy_item_permit_resp_cb,
866 g_strdup(display_id));
867 _check_for_disconnect(user, rc);
868
869 } else {
870 rc = nm_send_create_privacy_item(user, dn, FALSE,
871 _create_privacy_item_deny_resp_cb,
872 g_strdup(display_id));
873 _check_for_disconnect(user, rc);
874 }
875
876 } else {
877
878 err = g_strdup_printf(_("Unable to add user to privacy list (%s)."),
879 nm_error_to_string(ret_code));
880 gaim_notify_error(gc, NULL, err, NULL);
881 g_free(err);
882
883 }
884 }
885
886 static void
887 _remove_privacy_item_resp_cb(NMUser *user, NMERR_T ret_code,
888 gpointer resp_data, gpointer user_data)
889 {
890 GaimConnection *gc;
891 char *who = user_data;
892 char *err;
893
894 if (user == NULL)
895 return;
896
897 if (ret_code != NM_OK) {
898
899 gc = gaim_account_get_connection(user->client_data);
900 err = g_strdup_printf(_("Unable to remove %s from privacy list (%s)."), who,
901 nm_error_to_string(ret_code));
902 gaim_notify_error(gc, NULL, err, NULL);
903 g_free(err);
904 }
905
906 if (who)
907 g_free(who);
908 }
909
910 static void
911 _set_privacy_default_resp_cb(NMUser *user, NMERR_T ret_code,
912 gpointer resp_data, gpointer user_data)
913 {
914 GaimConnection *gc;
915 char *err;
916
917 if (user == NULL)
918 return;
919
920 if (ret_code != NM_OK) {
921
922 gc = gaim_account_get_connection(user->client_data);
923 err = g_strdup_printf(_("Unable to change server side privacy settings (%s)."),
924 nm_error_to_string(ret_code));
925 gaim_notify_error(gc, NULL, err, NULL);
926 g_free(err);
927
928 }
929 }
930
931 /* Handle get details response add to privacy list */
932 static void
933 _get_details_resp_send_invite(NMUser *user, NMERR_T ret_code,
934 gpointer resp_data, gpointer user_data)
935 {
936 NMERR_T rc = NM_OK;
937 GaimConnection *gc;
938 NMUserRecord *user_record = resp_data;
939 char *err;
940 const char *display_id;
941 GSList *cnode;
942 NMConference *conference;
943 gpointer chat;
944 long id = (long) user_data;
945
946 if (user == NULL)
947 return;
948
949 gc = gaim_account_get_connection(user->client_data);
950 display_id = nm_user_record_get_display_id(user_record);
951
952 if (ret_code == NM_OK) {
953
954 for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) {
955 conference = cnode->data;
956 if (conference && (chat = nm_conference_get_data(conference))) {
957 if (gaim_conv_chat_get_id(GAIM_CONV_CHAT(chat)) == id) {
958 rc = nm_send_conference_invite(user, conference, user_record,
959 NULL, _sendinvite_resp_cb, NULL);
960 _check_for_disconnect(user, rc);
961 break;
962 }
963 }
964 }
965
966 } else {
967
968 err = g_strdup_printf(_("Unable to invite user (%s)."), nm_error_to_string(ret_code));
969 gaim_notify_error(gc, NULL, err, NULL);
970 g_free(err);
971
972 }
973 }
974
975 static void
976 _createconf_resp_send_invite(NMUser * user, NMERR_T ret_code,
977 gpointer resp_data, gpointer user_data)
978 {
979 NMERR_T rc = NM_OK;
980 NMConference *conference = resp_data;
981 NMUserRecord *user_record = user_data;
982 GaimConnection *gc;
983 char *err;
984
985 if (user == NULL)
986 return;
987
988
989
990 if (ret_code == NM_OK) {
991 rc = nm_send_conference_invite(user, conference, user_record,
992 NULL, _sendinvite_resp_cb, NULL);
993 _check_for_disconnect(user, rc);
994 } else {
995 err = g_strdup_printf(_("Unable to create conference (%s)."), nm_error_to_string(ret_code));
996 gc = gaim_account_get_connection(user->client_data);
997 gaim_notify_error(gc, NULL, err, NULL);
998 g_free(err);
999 }
667 } 1000 }
668 1001
669 /******************************************************************************* 1002 /*******************************************************************************
670 * Helper functions 1003 * Helper functions
671 ******************************************************************************/ 1004 ******************************************************************************/
800 _check_for_disconnect(user, rc); 1133 _check_for_disconnect(user, rc);
801 1134
802 nm_release_message(message); 1135 nm_release_message(message);
803 1136
804 } else { 1137 } else {
805 rc = nm_send_create_conference(user, conf, 1138 rc = nm_send_create_conference(user, conf, _createconf_resp_send_msg, message);
806 _createconf_resp_send_msg, message);
807 _check_for_disconnect(user, rc); 1139 _check_for_disconnect(user, rc);
808 } 1140 }
809 } 1141 }
810 } 1142 }
811 1143
841 } 1173 }
842 1174
843 serv_got_update(gc, buddy->name, loggedin, 0, 0, idle, gstatus); 1175 serv_got_update(gc, buddy->name, loggedin, 0, 0, idle, gstatus);
844 } 1176 }
845 1177
846 /* Iterate through the cached Gaim buddy list and remove all buddies 1178 /* Iterate through the cached Gaim buddy list and remove buddies
847 * for this account. 1179 * that are not in the server side list.
848 */ 1180 */
849 static void 1181 static void
850 _remove_gaim_buddies(NMUser * user) 1182 _remove_gaim_buddies(NMUser *user)
851 { 1183 {
852 GaimBlistNode *gnode; 1184 GaimBlistNode *gnode;
853 GaimBlistNode *cnode; 1185 GaimBlistNode *cnode;
854 GaimBlistNode *bnode; 1186 GaimBlistNode *bnode;
855 GaimGroup *group; 1187 GaimGroup *group;
856 GaimBuddy *buddy; 1188 GaimBuddy *buddy;
857 GaimBuddyList *blist; 1189 GaimBuddyList *blist;
858 GSList *rem_list = NULL; 1190 GSList *rem_list = NULL;
859 GSList *l; 1191 GSList *l;
1192 NMFolder *folder = NULL;
860 1193
861 if ((blist = gaim_get_blist())) { 1194 if ((blist = gaim_get_blist())) {
862 for (gnode = blist->root; gnode; gnode = gnode->next) { 1195 for (gnode = blist->root; gnode; gnode = gnode->next) {
863 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) 1196 if (!GAIM_BLIST_NODE_IS_GROUP(gnode))
864 continue; 1197 continue;
869 for (bnode = cnode->child; bnode; bnode = bnode->next) { 1202 for (bnode = cnode->child; bnode; bnode = bnode->next) {
870 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) 1203 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode))
871 continue; 1204 continue;
872 buddy = (GaimBuddy *) bnode; 1205 buddy = (GaimBuddy *) bnode;
873 if (buddy->account == user->client_data) { 1206 if (buddy->account == user->client_data) {
874 rem_list = g_slist_append(rem_list, buddy); 1207 folder = nm_find_folder(user, group->name);
1208 if (folder == NULL ||
1209 !nm_folder_find_contact_by_display_id(folder, buddy->name)) {
1210 rem_list = g_slist_append(rem_list, buddy);
1211 }
875 } 1212 }
876 } 1213 }
877 } 1214 }
878 } 1215 }
879 1216
897 NMERR_T cnt = 0, i; 1234 NMERR_T cnt = 0, i;
898 const char *text = NULL; 1235 const char *text = NULL;
899 const char *name = NULL; 1236 const char *name = NULL;
900 int status = 0; 1237 int status = 0;
901 1238
1239 /* Does the Gaim group exist already? */
1240 group = gaim_find_group(nm_folder_get_name(folder));
1241
1242 if (group == NULL) {
1243 group = gaim_group_new(nm_folder_get_name(folder));
1244 gaim_blist_add_group(group, NULL);
1245 }
1246
902 /* Get each contact for this folder */ 1247 /* Get each contact for this folder */
903 cnt = nm_folder_get_contact_count(folder); 1248 cnt = nm_folder_get_contact_count(folder);
904 for (i = 0; i < cnt; i++) { 1249 for (i = 0; i < cnt; i++) {
905 contact = nm_folder_get_contact(folder, i); 1250 contact = nm_folder_get_contact(folder, i);
906 if (contact) { 1251 if (contact) {
907 1252
908 name = nm_contact_get_display_id(contact); 1253 name = nm_contact_get_display_id(contact);
909 if (name) { 1254 if (name) {
910 /* Add it to the gaim buddy list */ 1255
911 buddy = gaim_buddy_new(user->client_data, 1256 buddy = gaim_find_buddy_in_group(user->client_data, name, group);
912 name, 1257 if (buddy == NULL) {
913 nm_contact_get_display_name(contact)); 1258 /* Add it to the gaim buddy list */
914 1259 buddy = gaim_buddy_new(user->client_data,
915 /* Does the Gaim group exist already? */ 1260 name,
916 group = gaim_find_group(nm_folder_get_name(folder)); 1261 nm_contact_get_display_name(contact));
917 1262
918 if (group == NULL) { 1263 gaim_blist_add_buddy(buddy, NULL, group, NULL);
919 group = gaim_group_new(nm_folder_get_name(folder));
920 gaim_blist_add_group(group, NULL);
921 } 1264 }
922 1265
923 /* Set the initial status for the buddy */ 1266 /* Set the initial status for the buddy */
924 user_record = nm_contact_get_user_record(contact); 1267 user_record = nm_contact_get_user_record(contact);
925 if (user_record) { 1268 if (user_record) {
926 status = nm_user_record_get_status(user_record); 1269 status = nm_user_record_get_status(user_record);
927 text = nm_user_record_get_status_text(user_record); 1270 text = nm_user_record_get_status_text(user_record);
928 } 1271 }
929
930 gaim_blist_add_buddy(buddy, NULL, group, NULL);
931 _update_buddy_status(buddy, status, time(0)); 1272 _update_buddy_status(buddy, status, time(0));
932 1273
933 /* Save the new buddy as part of the contact object */ 1274 /* Save the new buddy as part of the contact object */
934 nm_contact_set_data(contact, (gpointer) buddy); 1275 nm_contact_set_data(contact, (gpointer) buddy);
935 } 1276 }
939 * let's break out of the loop. 1280 * let's break out of the loop.
940 */ 1281 */
941 break; 1282 break;
942 } 1283 }
943 } 1284 }
944
945 } 1285 }
946 1286
947 /* Add all of the server side contacts to the Gaim buddy list. */ 1287 /* Add all of the server side contacts to the Gaim buddy list. */
948 static void 1288 static void
949 _add_gaim_buddies(NMUser * user) 1289 _add_gaim_buddies(NMUser * user)
964 } 1304 }
965 } 1305 }
966 1306
967 /* Add contacts for the root folder */ 1307 /* Add contacts for the root folder */
968 _add_contacts_to_gaim_blist(user, root_folder); 1308 _add_contacts_to_gaim_blist(user, root_folder);
1309 }
1310 }
1311
1312 static void
1313 _sync_contact_list(NMUser *user)
1314 {
1315 /* Remove all buddies from the local list that are
1316 * not in the server side list and add all buddies
1317 * from the server side list that are not in
1318 * the local list
1319 */
1320 _remove_gaim_buddies(user);
1321 _add_gaim_buddies(user);
1322 }
1323
1324 static void
1325 _sync_privacy_lists(NMUser *user)
1326 {
1327 GSList *node = NULL, *rem_list = NULL;
1328 GaimConnection *gc;
1329 const char *name, *dn;
1330 NMUserRecord *user_record;
1331
1332 if (user == NULL)
1333 return;
1334
1335 gc = gaim_account_get_connection(user->client_data);
1336 if (gc == NULL)
1337 return;
1338
1339 /* Set the Gaim privacy setting */
1340 if (user->default_deny) {
1341 if (user->allow_list == NULL) {
1342 gc->account->perm_deny = GAIM_PRIVACY_DENY_ALL;
1343 } else {
1344 gc->account->perm_deny = GAIM_PRIVACY_ALLOW_USERS;
1345 }
1346 } else {
1347 if (user->deny_list == NULL) {
1348 gc->account->perm_deny = GAIM_PRIVACY_ALLOW_ALL;
1349 } else {
1350 gc->account->perm_deny = GAIM_PRIVACY_DENY_USERS;
1351 }
1352 }
1353
1354 /* Add stuff */
1355 for (node = user->allow_list; node; node = node->next) {
1356 user_record = nm_find_user_record(user, (char *)node->data);
1357 if (user_record)
1358 name = nm_user_record_get_display_id(user_record);
1359 else
1360 name =(char *)node->data;
1361
1362 if (!g_slist_find_custom(gc->account->permit,
1363 name, (GCompareFunc)nm_utf8_strcasecmp)) {
1364 gaim_privacy_permit_add(gc->account, name , TRUE);
1365 }
1366 }
1367
1368 for (node = user->deny_list; node; node = node->next) {
1369 user_record = nm_find_user_record(user, (char *)node->data);
1370 if (user_record)
1371 name = nm_user_record_get_display_id(user_record);
1372 else
1373 name =(char *)node->data;
1374
1375 if (!g_slist_find_custom(gc->account->deny,
1376 name, (GCompareFunc)nm_utf8_strcasecmp)) {
1377 gaim_privacy_deny_add(gc->account, name, TRUE);
1378 }
1379 }
1380
1381
1382 /* Remove stuff */
1383 for (node = gc->account->permit; node; node = node->next) {
1384 dn = nm_lookup_dn(user, (char *)node->data);
1385 if (dn != NULL &&
1386 !g_slist_find_custom(user->allow_list,
1387 dn, (GCompareFunc)nm_utf8_strcasecmp)) {
1388 rem_list = g_slist_append(rem_list, node->data);
1389 }
1390 }
1391
1392 if (rem_list) {
1393 for (node = rem_list; node; node = node->next) {
1394 gaim_privacy_permit_remove(gc->account, (char *)node->data, TRUE);
1395 }
1396 g_free(rem_list);
1397 rem_list = NULL;
1398 }
1399
1400 for (node = gc->account->deny; node; node = node->next) {
1401 dn = nm_lookup_dn(user, (char *)node->data);
1402 if (dn != NULL &&
1403 !g_slist_find_custom(user->deny_list,
1404 dn, (GCompareFunc)nm_utf8_strcasecmp)) {
1405 rem_list = g_slist_append(rem_list, node->data);
1406 }
1407 }
1408
1409 if (rem_list) {
1410 for (node = rem_list; node; node = node->next) {
1411 gaim_privacy_deny_remove(gc->account, (char *)node->data, TRUE);
1412 }
1413 g_slist_free(rem_list);
969 } 1414 }
970 } 1415 }
971 1416
972 /* Display a dialog box showing the properties for the given user record */ 1417 /* Display a dialog box showing the properties for the given user record */
973 static void 1418 static void
1071 } 1516 }
1072 1517
1073 g_slist_free(parms); 1518 g_slist_free(parms);
1074 } 1519 }
1075 1520
1521 static void
1522 _initiate_conference_cb(GaimConnection *gc, const char *who)
1523 {
1524 NMUser *user;
1525 const char *conf_name;
1526 GaimConversation *chat = NULL;
1527 NMUserRecord *user_record;
1528 NMConference *conference;
1529
1530 user = gc->proto_data;
1531 if (user == NULL)
1532 return;
1533
1534 /* We should already have a userrecord for the buddy */
1535 user_record = nm_find_user_record(user, who);
1536 if (user_record == NULL)
1537 return;
1538
1539 conf_name = _get_conference_name(++user->conference_count);
1540 chat = serv_got_joined_chat(gc, user->conference_count, conf_name);
1541 if (chat) {
1542
1543 conference = nm_create_conference(NULL);
1544 nm_conference_set_data(conference, (gpointer) chat);
1545 nm_send_create_conference(user, conference, _createconf_resp_send_invite, user_record);
1546 nm_release_conference(conference);
1547 }
1548 }
1549
1550 const char *
1551 _get_conference_name(int id)
1552 {
1553 static char *name = NULL;
1554
1555 if (name)
1556 g_free(name);
1557
1558 name = g_strdup_printf(_("GroupWise Conference %d"), id);
1559
1560 return name;
1561 }
1562
1563 void
1564 _show_privacy_locked_error(GaimConnection *gc, NMUser *user)
1565 {
1566 char *err;
1567
1568 err = g_strdup_printf(_("Unable to change server side privacy settings (%s)."),
1569 nm_error_to_string(NMERR_ADMIN_LOCKED));
1570 gaim_notify_error(gc, NULL, err, NULL);
1571 g_free(err);
1572 }
1573
1076 /******************************************************************************* 1574 /*******************************************************************************
1077 * Connect and recv callbacks 1575 * Connect and recv callbacks
1078 ******************************************************************************/ 1576 ******************************************************************************/
1079 1577
1080 static void 1578 static void
1102 1600
1103 rc = nm_process_new_data(user); 1601 rc = nm_process_new_data(user);
1104 if (rc != NM_OK) { 1602 if (rc != NM_OK) {
1105 1603
1106 if (_is_disconnect_error(rc)) { 1604 if (_is_disconnect_error(rc)) {
1605
1107 gaim_connection_error(gc, 1606 gaim_connection_error(gc,
1108 _("Error communicating with server." 1607 _("Error communicating with server."
1109 " Closing connection.")); 1608 " Closing connection."));
1110 } else { 1609 } else {
1111 1610
1112 char *error; 1611 char *error;
1113 1612
1114 error = g_strdup_printf(_("Error processing event or response." 1613 error = g_strdup_printf(_("Error processing event or response (%s)."),
1115 " (0x%X)"), rc); 1614 nm_error_to_string (rc));
1116 gaim_notify_error(gc, NULL, error, NULL); 1615 gaim_notify_error(gc, NULL, error, NULL);
1117 g_free(error); 1616 g_free(error);
1118 1617
1119 } 1618 }
1120 1619
1280 } 1779 }
1281 } 1780 }
1282 } 1781 }
1283 1782
1284 static void 1783 static void
1784 _evt_conference_invite_notify(NMUser * user, NMEvent * event)
1785 {
1786 GaimConversation *gconv;
1787 NMConference *conference;
1788 NMUserRecord *user_record = NULL;
1789 char *str = NULL;
1790
1791 user_record = nm_find_user_record(user, nm_event_get_source(event));
1792 conference = nm_event_get_conference(event);
1793 if (user_record && conference) {
1794 gconv = nm_conference_get_data(conference);
1795 str = g_strdup_printf(_("%s has been invited to this conversation."),
1796 nm_user_record_get_display_id(user_record));
1797 gaim_conversation_write(gconv, NULL, str,
1798 GAIM_MESSAGE_SYSTEM, time(NULL));
1799 g_free(str);
1800 }
1801 }
1802
1803 static void
1285 _evt_conference_invite(NMUser * user, NMEvent * event) 1804 _evt_conference_invite(NMUser * user, NMEvent * event)
1286 { 1805 {
1287 NMUserRecord *ur; 1806 NMUserRecord *ur;
1288 GSList *parms = NULL; 1807 GSList *parms = NULL;
1289 const char *title = NULL; 1808 const char *title = NULL;
1328 GaimConversation *chat = NULL; 1847 GaimConversation *chat = NULL;
1329 GaimConnection *gc; 1848 GaimConnection *gc;
1330 NMConference *conference = NULL; 1849 NMConference *conference = NULL;
1331 NMUserRecord *ur = NULL; 1850 NMUserRecord *ur = NULL;
1332 const char *name; 1851 const char *name;
1333 char *conf_name; 1852 const char *conf_name;
1853 GList *list = NULL;
1334 1854
1335 gc = gaim_account_get_connection(user->client_data); 1855 gc = gaim_account_get_connection(user->client_data);
1336 if (gc == NULL) 1856 if (gc == NULL)
1337 return; 1857 return;
1338 1858
1340 if (conference) { 1860 if (conference) {
1341 chat = nm_conference_get_data(conference); 1861 chat = nm_conference_get_data(conference);
1342 if (nm_conference_get_participant_count(conference) == 2 && chat == NULL) { 1862 if (nm_conference_get_participant_count(conference) == 2 && chat == NULL) {
1343 ur = nm_conference_get_participant(conference, 0); 1863 ur = nm_conference_get_participant(conference, 0);
1344 if (ur) { 1864 if (ur) {
1345 conf_name = g_strdup_printf(_("GroupWise Conference %d"), 1865 conf_name = _get_conference_name(++user->conference_count);
1346 ++user->conference_count);
1347 chat = 1866 chat =
1348 serv_got_joined_chat(gc, user->conference_count, conf_name); 1867 serv_got_joined_chat(gc, user->conference_count, conf_name);
1349 g_free(conf_name);
1350 if (chat) { 1868 if (chat) {
1351 1869
1352 nm_conference_set_data(conference, (gpointer) chat); 1870 nm_conference_set_data(conference, (gpointer) chat);
1353 1871
1354 name = nm_user_record_get_display_id(ur); 1872 name = nm_user_record_get_display_id(ur);
1360 1878
1361 if (chat != NULL) { 1879 if (chat != NULL) {
1362 ur = nm_find_user_record(user, nm_event_get_source(event)); 1880 ur = nm_find_user_record(user, nm_event_get_source(event));
1363 if (ur) { 1881 if (ur) {
1364 name = nm_user_record_get_display_id(ur); 1882 name = nm_user_record_get_display_id(ur);
1365 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL); 1883 list = gaim_conv_chat_get_users(GAIM_CONV_CHAT(chat));
1884 if (!g_list_find_custom(list, name, (GCompareFunc)nm_utf8_strcasecmp)) {
1885 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat), name, NULL);
1886 }
1366 } 1887 }
1367 } 1888 }
1368 } 1889 }
1369 } 1890 }
1370 1891
1502 break; 2023 break;
1503 case NMEVT_CONFERENCE_INVITE_NOTIFY: 2024 case NMEVT_CONFERENCE_INVITE_NOTIFY:
1504 /* Someone else has been invited to join a 2025 /* Someone else has been invited to join a
1505 * conference that we are currently a part of 2026 * conference that we are currently a part of
1506 */ 2027 */
1507 /* TODO: show the invite notify in chat window */ 2028 _evt_conference_invite_notify(user, event);
1508 break; 2029 break;
1509 case NMEVT_CONFERENCE_INVITE: 2030 case NMEVT_CONFERENCE_INVITE:
1510 /* We have been invited to join a conference */ 2031 /* We have been invited to join a conference */
1511 _evt_conference_invite(user, event); 2032 _evt_conference_invite(user, event);
1512 break; 2033 break;
1659 2180
1660 /* It is not, so send the createconf. We will 2181 /* It is not, so send the createconf. We will
1661 * have to finish sending the message when we 2182 * have to finish sending the message when we
1662 * get the response with the new conference guid. 2183 * get the response with the new conference guid.
1663 */ 2184 */
1664 rc = nm_send_create_conference(user, conf, 2185 rc = nm_send_create_conference(user, conf, _createconf_resp_send_msg, message);
1665 _createconf_resp_send_msg, message);
1666 _check_for_disconnect(user, rc); 2186 _check_for_disconnect(user, rc);
1667 2187
1668 done = FALSE; 2188 done = FALSE;
1669 } 2189 }
1670 2190
1782 } 2302 }
1783 } 2303 }
1784 } 2304 }
1785 2305
1786 serv_got_chat_left(gc, id); 2306 serv_got_chat_left(gc, id);
2307 }
2308
2309 void
2310 novell_chat_invite(GaimConnection *gc, int id,
2311 const char *message, const char *who)
2312 {
2313 NMConference *conference;
2314 NMUser *user;
2315 GaimConversation *chat;
2316 GSList *cnode;
2317 NMERR_T rc = NM_OK;
2318 NMUserRecord *user_record = NULL;
2319
2320 if (gc == NULL)
2321 return;
2322
2323 user = gc->proto_data;
2324 if (user == NULL)
2325 return;
2326
2327 user_record = nm_find_user_record(user, who);
2328 if (user_record == NULL) {
2329 rc = nm_send_get_details(user, who, _get_details_resp_send_invite, (gpointer)id);
2330 _check_for_disconnect(user, rc);
2331 return;
2332 }
2333
2334 for (cnode = user->conferences; cnode != NULL; cnode = cnode->next) {
2335 conference = cnode->data;
2336 if (conference && (chat = nm_conference_get_data(conference))) {
2337 if (gaim_conv_chat_get_id(GAIM_CONV_CHAT(chat)) == id) {
2338 rc = nm_send_conference_invite(user, conference, user_record,
2339 message, _sendinvite_resp_cb, NULL);
2340 _check_for_disconnect(user, rc);
2341 break;
2342 }
2343 }
2344 }
1787 } 2345 }
1788 2346
1789 static int 2347 static int
1790 novell_chat_send(GaimConnection * gc, int id, const char *text) 2348 novell_chat_send(GaimConnection * gc, int id, const char *text)
1791 { 2349 {
1812 if (conference && (chat = nm_conference_get_data(conference))) { 2370 if (conference && (chat = nm_conference_get_data(conference))) {
1813 if (gaim_conv_chat_get_id(GAIM_CONV_CHAT(chat)) == id) { 2371 if (gaim_conv_chat_get_id(GAIM_CONV_CHAT(chat)) == id) {
1814 2372
1815 nm_message_set_conference(message, conference); 2373 nm_message_set_conference(message, conference);
1816 2374
1817 rc = nm_send_message(user, message, _send_message_resp_cb); 2375 /* check to see if the conference is instatiated yet */
2376 if (!nm_conference_is_instantiated(conference)) {
2377 nm_message_add_ref(message);
2378 nm_send_create_conference(user, conference, _createconf_resp_send_msg, message);
2379 } else {
2380 rc = nm_send_message(user, message, _send_message_resp_cb);
2381 }
2382
1818 nm_release_message(message); 2383 nm_release_message(message);
1819 2384
1820 if (!_check_for_disconnect(user, rc)) { 2385 if (!_check_for_disconnect(user, rc)) {
1821 2386
1822 /* Use the account alias if it is set */ 2387 /* Use the account alias if it is set */
1838 return -1; 2403 return -1;
1839 2404
1840 } 2405 }
1841 } 2406 }
1842 } 2407 }
2408
1843 2409
1844 /* The conference was not found, must be closed */ 2410 /* The conference was not found, must be closed */
1845 chat = gaim_find_chat(gc, id); 2411 chat = gaim_find_chat(gc, id);
1846 if (chat) { 2412 if (chat) {
1847 str = g_strdup_printf(_("This conference has been closed." 2413 str = g_strdup_printf(_("This conference has been closed."
2340 2906
2341 if (text) 2907 if (text)
2342 g_free(text); 2908 g_free(text);
2343 } 2909 }
2344 2910
2911 static void
2912 novell_add_permit(GaimConnection *gc, const char *who)
2913 {
2914 NMUser *user;
2915 NMERR_T rc = NM_OK;
2916 const char *name = who;
2917
2918 if (gc == NULL || who == NULL)
2919 return;
2920
2921 user = gc->proto_data;
2922 if (user == NULL)
2923 return;
2924
2925 /* Remove first -- we will add it back in when we get
2926 * the okay from the server
2927 */
2928 gaim_privacy_permit_remove(gc->account, who, TRUE);
2929
2930 if (nm_user_is_privacy_locked(user)) {
2931 _show_privacy_locked_error(gc, user);
2932 _sync_privacy_lists(user);
2933 return;
2934 }
2935
2936 /* Work around for problem with un-typed, dotted contexts */
2937 if (strchr(who, '.')) {
2938 const char *dn = nm_lookup_dn(user, who);
2939 if (dn == NULL) {
2940 rc = nm_send_get_details(user, who, _get_details_send_privacy_create,
2941 (gpointer)TRUE);
2942 _check_for_disconnect(user, rc);
2943 return;
2944 } else {
2945 name = dn;
2946 }
2947 }
2948
2949 rc = nm_send_create_privacy_item(user, name, TRUE,
2950 _create_privacy_item_permit_resp_cb,
2951 g_strdup(who));
2952 _check_for_disconnect(user, rc);
2953 }
2954
2955 static void
2956 novell_add_deny(GaimConnection *gc, const char *who)
2957 {
2958 NMUser *user;
2959 NMERR_T rc = NM_OK;
2960 const char *name = who;
2961
2962 if (gc == NULL || who == NULL)
2963 return;
2964
2965 user = gc->proto_data;
2966 if (user == NULL)
2967 return;
2968
2969 /* Remove first -- we will add it back in when we get
2970 * the okay from the server
2971 */
2972 gaim_privacy_deny_remove(gc->account, who, TRUE);
2973
2974 if (nm_user_is_privacy_locked(user)) {
2975 _show_privacy_locked_error(gc, user);
2976 _sync_privacy_lists(user);
2977 return;
2978 }
2979
2980 /* Work around for problem with un-typed, dotted contexts */
2981 if (strchr(who, '.')) {
2982 const char *dn = nm_lookup_dn(user, who);
2983 if (dn == NULL) {
2984 rc = nm_send_get_details(user, who, _get_details_send_privacy_create,
2985 (gpointer)FALSE);
2986 _check_for_disconnect(user, rc);
2987 return;
2988 } else {
2989 name = dn;
2990 }
2991 }
2992
2993 rc = nm_send_create_privacy_item(user, name, FALSE,
2994 _create_privacy_item_deny_resp_cb,
2995 g_strdup(who));
2996 _check_for_disconnect(user, rc);
2997 }
2998
2999 static void
3000 novell_rem_permit(GaimConnection *gc, const char *who)
3001 {
3002 NMUser *user;
3003 NMERR_T rc = NM_OK;
3004 const char *dn = NULL;
3005
3006 if (gc == NULL || who == NULL)
3007 return;
3008
3009 user = gc->proto_data;
3010 if (user == NULL)
3011 return;
3012
3013 if (nm_user_is_privacy_locked(user)) {
3014 _show_privacy_locked_error(gc, user);
3015 _sync_privacy_lists(user);
3016 return;
3017 }
3018
3019 dn = nm_lookup_dn(user, who);
3020 if (dn == NULL)
3021 dn = who;
3022
3023 rc = nm_send_remove_privacy_item(user, dn, TRUE,
3024 _remove_privacy_item_resp_cb,
3025 g_strdup(who));
3026 _check_for_disconnect(user, rc);
3027 }
3028
3029 static void
3030 novell_rem_deny(GaimConnection *gc, const char *who)
3031 {
3032 NMUser *user;
3033 NMERR_T rc = NM_OK;
3034 const char *dn = NULL;
3035
3036 if (gc == NULL || who == NULL)
3037 return;
3038
3039 user = gc->proto_data;
3040 if (user == NULL)
3041 return;
3042
3043 if (nm_user_is_privacy_locked(user)) {
3044 _show_privacy_locked_error(gc, user);
3045 _sync_privacy_lists(user);
3046 return;
3047 }
3048
3049 dn = nm_lookup_dn(user, who);
3050 if (dn == NULL)
3051 dn = who;
3052
3053 rc = nm_send_remove_privacy_item(user, dn, FALSE,
3054 _remove_privacy_item_resp_cb,
3055 g_strdup(who));
3056 _check_for_disconnect(user, rc);
3057 }
3058
3059 static void
3060 novell_set_permit_deny(GaimConnection *gc)
3061 {
3062 NMERR_T rc = NM_OK;
3063 const char *dn, *name = NULL;
3064 NMUserRecord *user_record = NULL;
3065 GSList *node = NULL, *copy = NULL;
3066 NMUser *user;
3067 int i, j, num_contacts, num_folders;
3068 NMContact *contact;
3069 NMFolder *folder = NULL;
3070
3071 if (gc == NULL)
3072 return;
3073
3074 user = gc->proto_data;
3075 if (user == NULL)
3076 return;
3077
3078 if (set_permit == FALSE) {
3079 set_permit = TRUE;
3080 return;
3081 }
3082
3083 if (nm_user_is_privacy_locked(user)) {
3084 _show_privacy_locked_error(gc, user);
3085 _sync_privacy_lists(user);
3086 return;
3087 }
3088
3089 switch (gc->account->perm_deny) {
3090
3091 case GAIM_PRIVACY_ALLOW_ALL:
3092 rc = nm_send_set_privacy_default(user, FALSE,
3093 _set_privacy_default_resp_cb, NULL);
3094 _check_for_disconnect(user, rc);
3095
3096 /* clear server side deny list */
3097 if (rc == NM_OK) {
3098 copy = g_slist_copy(user->deny_list);
3099 for (node = copy; node && node->data; node = node->next) {
3100 rc = nm_send_remove_privacy_item(user, (const char *)node->data,
3101 FALSE, NULL, NULL);
3102 if (_check_for_disconnect(user, rc))
3103 break;
3104 }
3105 g_slist_free(copy);
3106 g_slist_free(user->deny_list);
3107 user->deny_list = NULL;
3108 }
3109 break;
3110
3111 case GAIM_PRIVACY_DENY_ALL:
3112 rc = nm_send_set_privacy_default(user, TRUE,
3113 _set_privacy_default_resp_cb, NULL);
3114 _check_for_disconnect(user, rc);
3115
3116 /* clear server side allow list */
3117 if (rc == NM_OK) {
3118 copy = g_slist_copy(user->allow_list);
3119 for (node = copy; node && node->data; node = node->next) {
3120 rc = nm_send_remove_privacy_item(user, (const char *)node->data,
3121 TRUE, NULL, NULL);
3122 if (_check_for_disconnect(user, rc))
3123 break;
3124 }
3125 g_slist_free(copy);
3126 g_slist_free(user->allow_list);
3127 user->allow_list = NULL;
3128 }
3129 break;
3130
3131 case GAIM_PRIVACY_ALLOW_USERS:
3132
3133 rc = nm_send_set_privacy_default(user, TRUE,
3134 _set_privacy_default_resp_cb, NULL);
3135 _check_for_disconnect(user, rc);
3136
3137 /* sync allow lists */
3138 if (rc == NM_OK) {
3139
3140 for (node = user->allow_list; node; node = node->next) {
3141 user_record = nm_find_user_record(user, (char *)node->data);
3142 if (user_record) {
3143 name = nm_user_record_get_display_id(user_record);
3144
3145 if (!g_slist_find_custom(gc->account->permit,
3146 name, (GCompareFunc)nm_utf8_strcasecmp)) {
3147 gaim_privacy_permit_add(gc->account, name , TRUE);
3148 }
3149 }
3150 }
3151
3152 for (node = gc->account->permit; node; node = node->next) {
3153 name = NULL;
3154 dn = nm_lookup_dn(user, (char *)node->data);
3155 if (dn) {
3156 user_record = nm_find_user_record(user, dn);
3157 name = nm_user_record_get_display_id(user_record);
3158
3159 if (!g_slist_find_custom(user->allow_list,
3160 dn, (GCompareFunc)nm_utf8_strcasecmp)) {
3161 rc = nm_send_create_privacy_item(user, dn, TRUE,
3162 _create_privacy_item_deny_resp_cb,
3163 g_strdup(dn));
3164 }
3165 } else {
3166 gaim_privacy_permit_remove(gc->account, (char *)node->data, TRUE);
3167 }
3168 }
3169 }
3170 break;
3171
3172 case GAIM_PRIVACY_DENY_USERS:
3173
3174 /* set to default allow */
3175 rc = nm_send_set_privacy_default(user, FALSE,
3176 _set_privacy_default_resp_cb, NULL);
3177 _check_for_disconnect(user, rc);
3178
3179 /* sync deny lists */
3180 if (rc == NM_OK) {
3181
3182 for (node = user->deny_list; node; node = node->next) {
3183 user_record = nm_find_user_record(user, (char *)node->data);
3184 if (user_record) {
3185 name = nm_user_record_get_display_id(user_record);
3186
3187 if (!g_slist_find_custom(gc->account->deny,
3188 name, (GCompareFunc)nm_utf8_strcasecmp)) {
3189 gaim_privacy_deny_add(gc->account, name , TRUE);
3190 }
3191 }
3192 }
3193
3194 for (node = gc->account->deny; node; node = node->next) {
3195
3196 name = NULL;
3197 dn = nm_lookup_dn(user, (char *)node->data);
3198 if (dn) {
3199 user_record = nm_find_user_record(user, dn);
3200 name = nm_user_record_get_display_id(user_record);
3201
3202 if (!g_slist_find_custom(user->deny_list,
3203 dn, (GCompareFunc)nm_utf8_strcasecmp)) {
3204 rc = nm_send_create_privacy_item(user, dn, FALSE,
3205 _create_privacy_item_deny_resp_cb,
3206 g_strdup(name));
3207 }
3208 } else {
3209 gaim_privacy_deny_remove(gc->account, (char *)node->data, TRUE);
3210 }
3211 }
3212
3213 }
3214 break;
3215
3216 case GAIM_PRIVACY_ALLOW_BUDDYLIST:
3217
3218 /* remove users from allow list that are not in buddy list */
3219 copy = g_slist_copy(user->allow_list);
3220 for (node = copy; node && node->data; node = node->next) {
3221 if (!nm_find_contacts(user, node->data)) {
3222 rc = nm_send_remove_privacy_item(user, (const char *)node->data,
3223 TRUE, NULL, NULL);
3224 if (_check_for_disconnect(user, rc))
3225 return;
3226 }
3227 }
3228 g_slist_free(copy);
3229
3230 /* add all buddies to allow list */
3231 num_contacts = nm_folder_get_contact_count(user->root_folder);
3232 for (i = 0; i < num_contacts; i++) {
3233 contact = nm_folder_get_contact(user->root_folder, i);
3234 dn = nm_contact_get_dn(contact);
3235 if (dn && !g_slist_find_custom(user->allow_list,
3236 dn, (GCompareFunc)nm_utf8_strcasecmp))
3237 {
3238 rc = nm_send_create_privacy_item(user, dn, TRUE,
3239 _create_privacy_item_deny_resp_cb,
3240 g_strdup(dn));
3241 if (_check_for_disconnect(user, rc))
3242 return;
3243 }
3244
3245 }
3246
3247 num_folders = nm_folder_get_subfolder_count(user->root_folder);
3248 for (i = 0; i < num_folders; i++) {
3249 folder = nm_folder_get_subfolder(user->root_folder, i);
3250 num_contacts = nm_folder_get_contact_count(folder);
3251 for (j = 0; j < num_contacts; j++) {
3252 contact = nm_folder_get_contact(folder, j);
3253 dn = nm_contact_get_dn(contact);
3254 if (dn && !g_slist_find_custom(user->allow_list,
3255 dn, (GCompareFunc)nm_utf8_strcasecmp))
3256 {
3257 rc = nm_send_create_privacy_item(user, dn, TRUE,
3258 _create_privacy_item_deny_resp_cb,
3259 g_strdup(dn));
3260 if (_check_for_disconnect(user, rc))
3261 return;
3262 }
3263 }
3264 }
3265
3266 /* set to default deny */
3267 rc = nm_send_set_privacy_default(user, TRUE,
3268 _set_privacy_default_resp_cb, NULL);
3269 if (_check_for_disconnect(user, rc))
3270 break;
3271
3272 break;
3273 }
3274 }
3275
3276 static GList *
3277 novell_buddy_menu(GaimConnection *gc, const char *who)
3278 {
3279 GList *list = NULL;
3280 struct proto_buddy_menu *pbm;
3281
3282 pbm = g_new0(struct proto_buddy_menu, 1);
3283 pbm->label = _("Initiate _Chat");
3284 pbm->callback = _initiate_conference_cb;
3285 pbm->gc = gc;
3286 list = g_list_append(list, pbm);
3287
3288 return list;
3289 }
3290
2345 static GaimPluginProtocolInfo prpl_info = { 3291 static GaimPluginProtocolInfo prpl_info = {
2346 GAIM_PRPL_API_VERSION, 3292 GAIM_PRPL_API_VERSION,
2347 0, 3293 0,
2348 NULL, 3294 NULL,
2349 NULL, 3295 NULL,
2351 novell_list_emblems, 3297 novell_list_emblems,
2352 novell_status_text, 3298 novell_status_text,
2353 novell_tooltip_text, 3299 novell_tooltip_text,
2354 novell_away_states, 3300 novell_away_states,
2355 NULL, /* prpl_actions */ 3301 NULL, /* prpl_actions */
2356 NULL, /* buddy_menu */ 3302 novell_buddy_menu,
2357 NULL, /* chat_info */ 3303 NULL, /* chat_info */
2358 novell_login, 3304 novell_login,
2359 novell_close, 3305 novell_close,
2360 novell_send_im, 3306 novell_send_im,
2361 NULL, /* set_info */ 3307 NULL, /* set_info */
2369 NULL, /* change pwd */ 3315 NULL, /* change pwd */
2370 novell_add_buddy, 3316 novell_add_buddy,
2371 NULL, /* add_buddies */ 3317 NULL, /* add_buddies */
2372 novell_remove_buddy, 3318 novell_remove_buddy,
2373 NULL, /* remove_buddies */ 3319 NULL, /* remove_buddies */
2374 NULL, /* add_permit */ 3320 novell_add_permit,
2375 NULL, /* add_deny */ 3321 novell_add_deny,
2376 NULL, /* rem_permit */ 3322 novell_rem_permit,
2377 NULL, /* rem_deny */ 3323 novell_rem_deny,
2378 NULL, /* set_permit_deny */ 3324 novell_set_permit_deny,
2379 NULL, /* warn */ 3325 NULL, /* warn */
2380 NULL, /* join_chat */ 3326 NULL, /* join_chat */
2381 NULL, /* reject_chat ?? */ 3327 NULL, /* reject_chat ?? */
2382 NULL, /* chat_invite */ 3328 novell_chat_invite, /* chat_invite */
2383 novell_chat_leave, 3329 novell_chat_leave,
2384 NULL, /* chat_whisper */ 3330 NULL, /* chat_whisper */
2385 novell_chat_send, 3331 novell_chat_send,
2386 NULL, /* keepalive */ 3332 NULL, /* keepalive */
2387 NULL, /* register_user */ 3333 NULL, /* register_user */