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 "nmcontact.h"
35 NMUserRecord
*user_record
;
52 static void _release_folder_contacts(NMFolder
* folder
);
53 static void _release_folder_folders(NMFolder
* folder
);
54 static void _add_contacts(NMUser
* user
, NMFolder
* folder
, NMField
* fields
);
55 static void _add_folders(NMFolder
* root
, NMField
* fields
);
57 /*********************************************************************
59 *********************************************************************/
64 NMContact
*contact
= g_new0(NMContact
, 1);
66 contact
->ref_count
= 1;
68 purple_debug(PURPLE_DEBUG_INFO
, "novell", "Creating contact, total=%d\n",
75 * This creates a contact for the contact list. The
76 * field array that is passed in should be a
77 * NM_A_FA_CONTACT array.
81 nm_create_contact_from_fields(NMField
* fields
)
86 if ( fields
== NULL
|| fields
->tag
== NULL
|| fields
->ptr_value
== 0 ||
87 !purple_strequal(fields
->tag
, NM_A_FA_CONTACT
) )
92 contact
= nm_create_contact();
94 if ((field
= nm_locate_field(NM_A_SZ_OBJECT_ID
, (NMField
*) fields
->ptr_value
))) {
97 contact
->id
= atoi((char *) field
->ptr_value
);
101 if ((field
= nm_locate_field(NM_A_SZ_PARENT_ID
, (NMField
*) fields
->ptr_value
))) {
103 if (field
->ptr_value
)
104 contact
->parent_id
= atoi((char *) field
->ptr_value
);
109 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER
, (NMField
*) fields
->ptr_value
))) {
111 if (field
->ptr_value
)
112 contact
->seq
= atoi((char *) field
->ptr_value
);
117 nm_locate_field(NM_A_SZ_DISPLAY_NAME
, (NMField
*) fields
->ptr_value
))) {
119 if (field
->ptr_value
)
120 contact
->display_name
= g_strdup((char *) field
->ptr_value
);
124 if ((field
= nm_locate_field(NM_A_SZ_DN
, (NMField
*) fields
->ptr_value
))) {
126 if (field
->ptr_value
)
127 contact
->dn
= g_strdup((char *) field
->ptr_value
);
135 nm_contact_update_list_properties(NMContact
* contact
, NMField
* fields
)
139 if (contact
== NULL
|| fields
== NULL
|| fields
->ptr_value
== 0)
142 if ((field
= nm_locate_field(NM_A_SZ_OBJECT_ID
, (NMField
*) fields
->ptr_value
))) {
144 if (field
->ptr_value
)
145 contact
->id
= atoi((char *)field
->ptr_value
);
149 if ((field
= nm_locate_field(NM_A_SZ_PARENT_ID
, (NMField
*) fields
->ptr_value
))) {
151 if (field
->ptr_value
)
152 contact
->parent_id
= atoi((char *) field
->ptr_value
);
157 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER
, (NMField
*) fields
->ptr_value
))) {
159 if (field
->ptr_value
)
160 contact
->seq
= atoi((char *) field
->ptr_value
);
165 nm_locate_field(NM_A_SZ_DISPLAY_NAME
, (NMField
*) fields
->ptr_value
))) {
167 if (field
->ptr_value
) {
168 g_free(contact
->display_name
);
170 contact
->display_name
= g_strdup((char *) field
->ptr_value
);
175 if ((field
= nm_locate_field(NM_A_SZ_DN
, (NMField
*) fields
->ptr_value
))) {
177 if (field
->ptr_value
) {
180 contact
->dn
= g_strdup((char *) field
->ptr_value
);
187 nm_contact_to_fields(NMContact
* contact
)
189 NMField
*fields
= NULL
;
194 fields
= nm_field_add_pointer(fields
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
195 g_strdup_printf("%d", contact
->id
), NMFIELD_TYPE_UTF8
);
197 fields
= nm_field_add_pointer(fields
, NM_A_SZ_PARENT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
198 g_strdup_printf("%d", contact
->parent_id
), NMFIELD_TYPE_UTF8
);
200 fields
= nm_field_add_pointer(fields
, NM_A_SZ_SEQUENCE_NUMBER
, 0, NMFIELD_METHOD_VALID
, 0,
201 g_strdup_printf("%d", contact
->seq
), NMFIELD_TYPE_UTF8
);
203 if (contact
->display_name
!= NULL
) {
204 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DISPLAY_NAME
, 0, NMFIELD_METHOD_VALID
, 0,
205 g_strdup(contact
->display_name
), NMFIELD_TYPE_UTF8
);
208 if (contact
->dn
!= NULL
) {
209 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DN
, 0, NMFIELD_METHOD_VALID
, 0,
210 g_strdup(contact
->dn
), NMFIELD_TYPE_UTF8
);
217 nm_contact_add_ref(NMContact
* contact
)
220 contact
->ref_count
++;
224 nm_release_contact(NMContact
* contact
)
229 if (--(contact
->ref_count
) == 0) {
231 purple_debug(PURPLE_DEBUG_INFO
, "novell",
232 "Releasing contact, total=%d\n", --count
);
234 g_free(contact
->display_name
);
237 if (contact
->user_record
) {
238 nm_release_user_record(contact
->user_record
);
247 nm_contact_get_display_name(NMContact
* contact
)
252 if (contact
->user_record
!= NULL
&& contact
->display_name
== NULL
) {
253 const char *full_name
, *lname
, *fname
, *cn
, *display_id
;
255 full_name
= nm_user_record_get_full_name(contact
->user_record
);
256 fname
= nm_user_record_get_first_name(contact
->user_record
);
257 lname
= nm_user_record_get_last_name(contact
->user_record
);
258 cn
= nm_user_record_get_userid(contact
->user_record
);
259 display_id
= nm_user_record_get_display_id(contact
->user_record
);
261 /* Try to build a display name. */
264 contact
->display_name
= g_strdup(full_name
);
266 } else if (fname
&& lname
) {
268 contact
->display_name
= g_strdup_printf("%s %s", fname
, lname
);
272 /* If auth attribute is set use it */
273 if (nm_user_record_get_auth_attr(contact
->user_record
) &&
274 display_id
!= NULL
) {
276 contact
->display_name
= g_strdup(display_id
);
280 /* Use CN or display id */
283 contact
->display_name
= g_strdup(cn
);
285 } else if (display_id
) {
287 contact
->display_name
= g_strdup(display_id
);
296 return contact
->display_name
;
300 nm_contact_set_display_name(NMContact
* contact
, const char *display_name
)
305 g_free(contact
->display_name
);
306 contact
->display_name
= NULL
;
309 contact
->display_name
= g_strdup(display_name
);
313 nm_contact_set_dn(NMContact
* contact
, const char *dn
)
322 contact
->dn
= g_strdup(dn
);
326 nm_contact_get_dn(NMContact
* contact
)
335 nm_contact_get_data(NMContact
* contact
)
340 return contact
->data
;
344 nm_contact_get_id(NMContact
* contact
)
353 nm_contact_get_parent_id(NMContact
* contact
)
358 return contact
->parent_id
;
362 nm_contact_set_data(NMContact
* contact
, gpointer data
)
367 contact
->data
= data
;
371 nm_contact_set_user_record(NMContact
* contact
, NMUserRecord
* user_record
)
376 if (contact
->user_record
) {
377 nm_release_user_record(contact
->user_record
);
380 nm_user_record_add_ref(user_record
);
381 contact
->user_record
= user_record
;
385 nm_contact_get_user_record(NMContact
* contact
)
390 return contact
->user_record
;
394 nm_contact_get_userid(NMContact
* contact
)
396 NMUserRecord
*user_record
;
397 const char *userid
= NULL
;
402 user_record
= nm_contact_get_user_record(contact
);
404 userid
= nm_user_record_get_userid(user_record
);
411 nm_contact_get_display_id(NMContact
* contact
)
413 NMUserRecord
*user_record
;
414 const char *id
= NULL
;
419 user_record
= nm_contact_get_user_record(contact
);
421 id
= nm_user_record_get_display_id(user_record
);
428 /*********************************************************************
430 *********************************************************************/
433 nm_create_folder(const char *name
)
435 NMFolder
*folder
= g_new0(NMFolder
, 1);
438 folder
->name
= g_strdup(name
);
440 folder
->ref_count
= 1;
446 nm_create_folder_from_fields(NMField
* fields
)
451 if (fields
== NULL
|| fields
->ptr_value
== 0)
454 folder
= g_new0(NMFolder
, 1);
456 if ((field
= nm_locate_field(NM_A_SZ_OBJECT_ID
, (NMField
*) fields
->ptr_value
))) {
458 if (field
->ptr_value
)
459 folder
->id
= atoi((char *) field
->ptr_value
);
463 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER
, (NMField
*) fields
->ptr_value
))) {
465 if (field
->ptr_value
)
466 folder
->seq
= atoi((char *) field
->ptr_value
);
470 nm_locate_field(NM_A_SZ_DISPLAY_NAME
, (NMField
*) fields
->ptr_value
))) {
472 if (field
->ptr_value
)
473 folder
->name
= g_strdup((char *) field
->ptr_value
);
476 folder
->ref_count
= 1;
481 nm_folder_to_fields(NMFolder
* folder
)
483 NMField
*fields
= NULL
;
488 fields
= nm_field_add_pointer(fields
, NM_A_SZ_OBJECT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
489 g_strdup_printf("%d", folder
->id
), NMFIELD_TYPE_UTF8
);
491 fields
= nm_field_add_pointer(fields
, NM_A_SZ_PARENT_ID
, 0, NMFIELD_METHOD_VALID
, 0,
492 g_strdup("0"), NMFIELD_TYPE_UTF8
);
494 fields
= nm_field_add_pointer(fields
, NM_A_SZ_TYPE
, 0, NMFIELD_METHOD_VALID
, 0,
495 g_strdup("1"), NMFIELD_TYPE_UTF8
);
497 fields
= nm_field_add_pointer(fields
, NM_A_SZ_SEQUENCE_NUMBER
, 0, NMFIELD_METHOD_VALID
, 0,
498 g_strdup_printf("%d", folder
->seq
), NMFIELD_TYPE_UTF8
);
500 if (folder
->name
!= NULL
) {
501 fields
= nm_field_add_pointer(fields
, NM_A_SZ_DISPLAY_NAME
, 0, NMFIELD_METHOD_VALID
, 0,
502 g_strdup(folder
->name
), NMFIELD_TYPE_UTF8
);
510 nm_folder_update_list_properties(NMFolder
* folder
, NMField
* fields
)
514 if (folder
== NULL
|| fields
== NULL
|| fields
->ptr_value
== 0)
517 if ((field
= nm_locate_field(NM_A_SZ_OBJECT_ID
, (NMField
*) fields
->ptr_value
))) {
519 if (field
->ptr_value
)
520 folder
->id
= atoi((char *) field
->ptr_value
);
525 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER
, (NMField
*) fields
->ptr_value
))) {
527 if (field
->ptr_value
)
528 folder
->seq
= atoi((char *) field
->ptr_value
);
533 nm_locate_field(NM_A_SZ_DISPLAY_NAME
, (NMField
*) fields
->ptr_value
))) {
535 if (field
->ptr_value
) {
536 g_free(folder
->name
);
538 folder
->name
= g_strdup((char *) field
->ptr_value
);
546 nm_release_folder(NMFolder
* folder
)
551 if (--(folder
->ref_count
) == 0) {
552 g_free(folder
->name
);
554 if (folder
->folders
) {
555 _release_folder_folders(folder
);
558 if (folder
->contacts
) {
559 _release_folder_contacts(folder
);
568 nm_folder_add_ref(NMFolder
* folder
)
575 nm_folder_get_subfolder_count(NMFolder
* folder
)
581 return g_slist_length(folder
->folders
);
587 nm_folder_get_subfolder(NMFolder
* folder
, int index
)
593 return (NMFolder
*) g_slist_nth_data(folder
->folders
, index
);
599 nm_folder_get_contact_count(NMFolder
* folder
)
604 if (folder
->contacts
!= NULL
)
605 return g_slist_length(folder
->contacts
);
611 nm_folder_get_contact(NMFolder
* folder
, int index
)
616 if (folder
->contacts
)
617 return (NMContact
*) g_slist_nth_data(folder
->contacts
, index
);
623 nm_folder_get_name(NMFolder
* folder
)
632 nm_folder_set_name(NMFolder
* folder
, const char *name
)
634 if (folder
== NULL
|| name
== NULL
)
637 g_free(folder
->name
);
639 folder
->name
= g_strdup(name
);
643 nm_folder_get_id(NMFolder
* folder
)
645 if (folder
== NULL
) {
653 nm_folder_add_folder_to_list(NMFolder
* root
, NMFolder
* folder
)
657 if (root
== NULL
|| folder
== NULL
)
660 node
= root
->folders
;
662 if (folder
->seq
<= ((NMFolder
*) node
->data
)->seq
) {
663 nm_folder_add_ref(folder
);
664 root
->folders
= g_slist_insert_before(root
->folders
, node
, folder
);
667 node
= g_slist_next(node
);
670 nm_folder_add_ref(folder
);
671 root
->folders
= g_slist_append(root
->folders
, folder
);
676 nm_folder_remove_contact(NMFolder
* folder
, NMContact
* contact
)
680 if (folder
== NULL
|| contact
== NULL
)
683 node
= folder
->contacts
;
685 if (contact
->id
== ((NMContact
*) (node
->data
))->id
) {
686 folder
->contacts
= g_slist_remove(folder
->contacts
, node
->data
);
687 nm_release_contact(contact
);
690 node
= g_slist_next(node
);
695 nm_folder_add_contact_to_list(NMFolder
* root_folder
, NMContact
* contact
)
698 NMFolder
*folder
= root_folder
;
700 if (folder
== NULL
|| contact
== NULL
)
703 /* Find folder to add contact to */
704 if (contact
->parent_id
!= 0) {
705 node
= folder
->folders
;
707 folder
= (NMFolder
*) node
->data
;
708 if (contact
->parent_id
== folder
->id
) {
712 node
= g_slist_next(node
);
716 /* Add contact to list */
718 node
= folder
->contacts
;
720 if (contact
->seq
<= ((NMContact
*) (node
->data
))->seq
) {
721 nm_contact_add_ref(contact
);
723 g_slist_insert_before(folder
->contacts
, node
, contact
);
726 node
= g_slist_next(node
);
730 nm_contact_add_ref(contact
);
731 folder
->contacts
= g_slist_append(folder
->contacts
, contact
);
737 nm_folder_add_contacts_and_folders(NMUser
* user
, NMFolder
* root
,
740 /* Add the contacts and folders from the field array */
741 if (user
&& root
&& fields
) {
742 _add_folders(root
, fields
);
743 _add_contacts(user
, root
, fields
);
748 nm_folder_find_item_by_object_id(NMFolder
* root_folder
, int object_id
)
751 gpointer item
= NULL
;
755 if (root_folder
== NULL
)
758 /* Check all contacts for the top level folder */
759 cnt
= nm_folder_get_contact_count(root_folder
);
760 for (i
= 0; i
< cnt
; i
++) {
761 contact
= nm_folder_get_contact(root_folder
, i
);
762 if (contact
&& (contact
->id
== object_id
)) {
768 /* If we haven't found the item yet, check the subfolders */
770 cnt
= nm_folder_get_subfolder_count(root_folder
);
771 for (i
= 0; (i
< cnt
) && (item
== NULL
); i
++) {
772 folder
= nm_folder_get_subfolder(root_folder
, i
);
774 /* Check the id of this folder */
775 if (folder
&& (folder
->id
== object_id
)) {
780 /* Check all contacts for this folder */
781 cnt2
= nm_folder_get_contact_count(folder
);
782 for (j
= 0; j
< cnt2
; j
++) {
783 contact
= nm_folder_get_contact(folder
, j
);
784 if (contact
&& (contact
->id
== object_id
)) {
796 nm_folder_find_contact_by_userid(NMFolder
* folder
, const char *userid
)
799 NMContact
*tmp
, *contact
= NULL
;
801 if (folder
== NULL
|| userid
== NULL
)
804 cnt
= nm_folder_get_contact_count(folder
);
805 for (i
= 0; i
< cnt
; i
++) {
806 tmp
= nm_folder_get_contact(folder
, i
);
807 if (tmp
&& nm_utf8_str_equal(nm_contact_get_userid(tmp
), userid
)) {
817 nm_folder_find_contact_by_display_id(NMFolder
* folder
, const char *display_id
)
820 NMContact
*tmp
, *contact
= NULL
;
822 if (folder
== NULL
|| display_id
== NULL
)
825 cnt
= nm_folder_get_contact_count(folder
);
826 for (i
= 0; i
< cnt
; i
++) {
827 tmp
= nm_folder_get_contact(folder
, i
);
828 if (tmp
&& nm_utf8_str_equal(nm_contact_get_display_id(tmp
), display_id
)) {
838 nm_folder_find_contact(NMFolder
* folder
, const char *dn
)
841 NMContact
*tmp
, *contact
= NULL
;
843 if (folder
== NULL
|| dn
== NULL
)
846 cnt
= nm_folder_get_contact_count(folder
);
847 for (i
= 0; i
< cnt
; i
++) {
848 tmp
= nm_folder_get_contact(folder
, i
);
849 if (tmp
&& nm_utf8_str_equal(nm_contact_get_dn(tmp
), dn
)) {
859 /*********************************************************************
861 *********************************************************************/
864 _release_folder_contacts(NMFolder
* folder
)
869 for (cnode
= folder
->contacts
; cnode
; cnode
= cnode
->next
) {
870 contact
= cnode
->data
;
872 nm_release_contact(contact
);
875 g_slist_free(folder
->contacts
);
876 folder
->contacts
= NULL
;
880 _release_folder_folders(NMFolder
* folder
)
888 for (fnode
= folder
->folders
; fnode
; fnode
= fnode
->next
) {
889 subfolder
= fnode
->data
;
891 nm_release_folder(subfolder
);
894 g_slist_free(folder
->folders
);
895 folder
->folders
= NULL
;
899 _add_folders(NMFolder
* root
, NMField
* fields
)
901 NMFolder
*folder
= NULL
;
902 NMField
*locate
= NULL
;
904 locate
= nm_locate_field(NM_A_FA_FOLDER
, fields
);
905 while (locate
!= NULL
) {
907 /* Create a new folder */
908 folder
= nm_create_folder_from_fields(locate
);
910 /* Add subfolder to roots folder list */
911 nm_folder_add_folder_to_list(root
, folder
);
913 /* Decrement the ref count */
914 nm_release_folder(folder
);
916 /* Find the next folder */
917 locate
= nm_locate_field(NM_A_FA_FOLDER
, locate
+1);
923 _add_contacts(NMUser
* user
, NMFolder
* folder
, NMField
* fields
)
925 NMContact
*contact
= NULL
;
926 NMField
*locate
= NULL
, *details
;
927 NMUserRecord
*user_record
= NULL
;
929 locate
= nm_locate_field(NM_A_FA_CONTACT
, fields
);
930 while (locate
!= NULL
) {
932 /* Create a new contact from the fields */
933 contact
= nm_create_contact_from_fields(locate
);
935 /* Add it to our contact list */
936 nm_folder_add_contact_to_list(folder
, contact
);
938 /* Update the contact cache */
939 nm_user_add_contact(user
, contact
);
941 /* Update the user record cache */
942 if ((details
= nm_locate_field(NM_A_FA_USER_DETAILS
,
943 (NMField
*) locate
->ptr_value
))) {
944 user_record
= nm_find_user_record(user
, nm_contact_get_dn(contact
));
945 if (user_record
== NULL
) {
946 user_record
= nm_create_user_record_from_fields(details
);
947 nm_user_record_set_dn(user_record
, nm_contact_get_dn(contact
));
948 nm_user_add_user_record(user
, user_record
);
949 nm_release_user_record(user_record
);
951 nm_contact_set_user_record(contact
, user_record
);
954 nm_release_contact(contact
);
956 locate
= nm_locate_field(NM_A_FA_CONTACT
, locate
+1);