1 /*
2 * nmcontact.c
3 *
4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
5 *
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.
9 *
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.
14 *
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
18 *
19 */
20
21 #include <glib.h>
22 #include <string.h>
23 #include "nmcontact.h"
24 #include "nmfield.h"
25 #include "nmuser.h"
26 #include "util.h"
27
28 struct _NMContact
29 {
30 int id;
31 int parent_id;
32 int seq;
33 char *dn;
34 char *display_name;
35 NMUserRecord *user_record;
36 gpointer data;
37 int ref_count;
38 };
39
40 struct _NMFolder
41 {
42 int id;
43 int seq;
44 char *name;
45 GSList *folders;
46 GSList *contacts;
47 int ref_count;
48 };
49
50 static int count = 0;
51
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);
56
57 /*********************************************************************
58 * Contact API
59 *********************************************************************/
60
61 NMContact *
nm_create_contact()62 nm_create_contact()
63 {
64 NMContact *contact = g_new0(NMContact, 1);
65
66 contact->ref_count = 1;
67
68 purple_debug(PURPLE_DEBUG_INFO, "novell", "Creating contact, total=%d\n",
69 count++);
70
71 return contact;
72 }
73
74 /*
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.
78 *
79 */
80 NMContact *
nm_create_contact_from_fields(NMField * fields)81 nm_create_contact_from_fields(NMField * fields)
82 {
83 NMContact *contact;
84 NMField *field;
85
86 if ( fields == NULL || fields->tag == NULL || fields->ptr_value == 0 ||
87 !purple_strequal(fields->tag, NM_A_FA_CONTACT) )
88 {
89 return NULL;
90 }
91
92 contact = nm_create_contact();
93
94 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) {
95
96 if (field->ptr_value)
97 contact->id = atoi((char *) field->ptr_value);
98
99 }
100
101 if ((field = nm_locate_field(NM_A_SZ_PARENT_ID, (NMField *) fields->ptr_value))) {
102
103 if (field->ptr_value)
104 contact->parent_id = atoi((char *) field->ptr_value);
105
106 }
107
108 if ((field =
109 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) {
110
111 if (field->ptr_value)
112 contact->seq = atoi((char *) field->ptr_value);
113
114 }
115
116 if ((field =
117 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) {
118
119 if (field->ptr_value)
120 contact->display_name = g_strdup((char *) field->ptr_value);
121
122 }
123
124 if ((field = nm_locate_field(NM_A_SZ_DN, (NMField *) fields->ptr_value))) {
125
126 if (field->ptr_value)
127 contact->dn = g_strdup((char *) field->ptr_value);
128
129 }
130
131 return contact;
132 }
133
134 void
nm_contact_update_list_properties(NMContact * contact,NMField * fields)135 nm_contact_update_list_properties(NMContact * contact, NMField * fields)
136 {
137 NMField *field;
138
139 if (contact == NULL || fields == NULL || fields->ptr_value == 0)
140 return;
141
142 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) {
143
144 if (field->ptr_value)
145 contact->id = atoi((char *)field->ptr_value);
146
147 }
148
149 if ((field = nm_locate_field(NM_A_SZ_PARENT_ID, (NMField *) fields->ptr_value))) {
150
151 if (field->ptr_value)
152 contact->parent_id = atoi((char *) field->ptr_value);
153
154 }
155
156 if ((field =
157 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) {
158
159 if (field->ptr_value)
160 contact->seq = atoi((char *) field->ptr_value);
161
162 }
163
164 if ((field =
165 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) {
166
167 if (field->ptr_value) {
168 if (contact->display_name)
169 g_free(contact->display_name);
170
171 contact->display_name = g_strdup((char *) field->ptr_value);
172 }
173
174 }
175
176 if ((field = nm_locate_field(NM_A_SZ_DN, (NMField *) fields->ptr_value))) {
177
178 if (field->ptr_value) {
179 if (contact->dn)
180 g_free(contact->dn);
181
182 contact->dn = g_strdup((char *) field->ptr_value);
183 }
184
185 }
186 }
187
188 NMField *
nm_contact_to_fields(NMContact * contact)189 nm_contact_to_fields(NMContact * contact)
190 {
191 NMField *fields = NULL;
192
193 if (contact == NULL)
194 return NULL;
195
196 fields = nm_field_add_pointer(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
197 g_strdup_printf("%d", contact->id), NMFIELD_TYPE_UTF8);
198
199 fields = nm_field_add_pointer(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
200 g_strdup_printf("%d", contact->parent_id), NMFIELD_TYPE_UTF8);
201
202 fields = nm_field_add_pointer(fields, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID, 0,
203 g_strdup_printf("%d", contact->seq), NMFIELD_TYPE_UTF8);
204
205 if (contact->display_name != NULL) {
206 fields = nm_field_add_pointer(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0,
207 g_strdup(contact->display_name), NMFIELD_TYPE_UTF8);
208 }
209
210 if (contact->dn != NULL) {
211 fields = nm_field_add_pointer(fields, NM_A_SZ_DN, 0, NMFIELD_METHOD_VALID, 0,
212 g_strdup(contact->dn), NMFIELD_TYPE_UTF8);
213 }
214
215 return fields;
216 }
217
218 void
nm_contact_add_ref(NMContact * contact)219 nm_contact_add_ref(NMContact * contact)
220 {
221 if (contact)
222 contact->ref_count++;
223 }
224
225 void
nm_release_contact(NMContact * contact)226 nm_release_contact(NMContact * contact)
227 {
228 if (contact == NULL)
229 return;
230
231 if (--(contact->ref_count) == 0) {
232
233 purple_debug(PURPLE_DEBUG_INFO, "novell",
234 "Releasing contact, total=%d\n", --count);
235
236 if (contact->display_name) {
237 g_free(contact->display_name);
238 }
239
240 if (contact->dn) {
241 g_free(contact->dn);
242 }
243
244 if (contact->user_record) {
245 nm_release_user_record(contact->user_record);
246 }
247
248 g_free(contact);
249 }
250
251 }
252
253 const char *
nm_contact_get_display_name(NMContact * contact)254 nm_contact_get_display_name(NMContact * contact)
255 {
256 if (contact == NULL)
257 return NULL;
258
259 if (contact->user_record != NULL && contact->display_name == NULL) {
260 const char *full_name, *lname, *fname, *cn, *display_id;
261
262 full_name = nm_user_record_get_full_name(contact->user_record);
263 fname = nm_user_record_get_first_name(contact->user_record);
264 lname = nm_user_record_get_last_name(contact->user_record);
265 cn = nm_user_record_get_userid(contact->user_record);
266 display_id = nm_user_record_get_display_id(contact->user_record);
267
268 /* Try to build a display name. */
269 if (full_name) {
270
271 contact->display_name = g_strdup(full_name);
272
273 } else if (fname && lname) {
274
275 contact->display_name = g_strdup_printf("%s %s", fname, lname);
276
277 } else {
278
279 /* If auth attribute is set use it */
280 if (nm_user_record_get_auth_attr(contact->user_record) &&
281 display_id != NULL) {
282
283 contact->display_name = g_strdup(display_id);
284
285 } else {
286
287 /* Use CN or display id */
288 if (cn) {
289
290 contact->display_name = g_strdup(cn);
291
292 } else if (display_id) {
293
294 contact->display_name = g_strdup(display_id);
295
296 }
297
298 }
299
300 }
301 }
302
303 return contact->display_name;
304 }
305
306 void
nm_contact_set_display_name(NMContact * contact,const char * display_name)307 nm_contact_set_display_name(NMContact * contact, const char *display_name)
308 {
309 if (contact == NULL)
310 return;
311
312 if (contact->display_name) {
313 g_free(contact->display_name);
314 contact->display_name = NULL;
315 }
316
317 if (display_name)
318 contact->display_name = g_strdup(display_name);
319 }
320
321 void
nm_contact_set_dn(NMContact * contact,const char * dn)322 nm_contact_set_dn(NMContact * contact, const char *dn)
323 {
324 if (contact == NULL)
325 return;
326
327 if (contact->dn) {
328 g_free(contact->dn);
329 contact->dn = NULL;
330 }
331
332 if (dn)
333 contact->dn = g_strdup(dn);
334 }
335
336 const char *
nm_contact_get_dn(NMContact * contact)337 nm_contact_get_dn(NMContact * contact)
338 {
339 if (contact == NULL)
340 return NULL;
341
342 return contact->dn;
343 }
344
345 gpointer
nm_contact_get_data(NMContact * contact)346 nm_contact_get_data(NMContact * contact)
347 {
348 if (contact == NULL)
349 return NULL;
350
351 return contact->data;
352 }
353
354 int
nm_contact_get_id(NMContact * contact)355 nm_contact_get_id(NMContact * contact)
356 {
357 if (contact == NULL)
358 return -1;
359
360 return contact->id;
361 }
362
363 int
nm_contact_get_parent_id(NMContact * contact)364 nm_contact_get_parent_id(NMContact * contact)
365 {
366 if (contact == NULL)
367 return -1;
368
369 return contact->parent_id;
370 }
371
372 void
nm_contact_set_data(NMContact * contact,gpointer data)373 nm_contact_set_data(NMContact * contact, gpointer data)
374 {
375 if (contact == NULL)
376 return;
377
378 contact->data = data;
379 }
380
381 void
nm_contact_set_user_record(NMContact * contact,NMUserRecord * user_record)382 nm_contact_set_user_record(NMContact * contact, NMUserRecord * user_record)
383 {
384 if (contact == NULL)
385 return;
386
387 if (contact->user_record) {
388 nm_release_user_record(contact->user_record);
389 }
390
391 nm_user_record_add_ref(user_record);
392 contact->user_record = user_record;
393 }
394
395 NMUserRecord *
nm_contact_get_user_record(NMContact * contact)396 nm_contact_get_user_record(NMContact * contact)
397 {
398 if (contact == NULL)
399 return NULL;
400
401 return contact->user_record;
402 }
403
404 const char *
nm_contact_get_userid(NMContact * contact)405 nm_contact_get_userid(NMContact * contact)
406 {
407 NMUserRecord *user_record;
408 const char *userid = NULL;
409
410 if (contact == NULL)
411 return NULL;
412
413 user_record = nm_contact_get_user_record(contact);
414 if (user_record) {
415 userid = nm_user_record_get_userid(user_record);
416 }
417
418 return userid;
419 }
420
421 const char *
nm_contact_get_display_id(NMContact * contact)422 nm_contact_get_display_id(NMContact * contact)
423 {
424 NMUserRecord *user_record;
425 const char *id = NULL;
426
427 if (contact == NULL)
428 return NULL;
429
430 user_record = nm_contact_get_user_record(contact);
431 if (user_record) {
432 id = nm_user_record_get_display_id(user_record);
433 }
434
435 return id;
436 }
437
438
439 /*********************************************************************
440 * Folder API
441 *********************************************************************/
442
443 NMFolder *
nm_create_folder(const char * name)444 nm_create_folder(const char *name)
445 {
446 NMFolder *folder = g_new0(NMFolder, 1);
447
448 if (name)
449 folder->name = g_strdup(name);
450
451 folder->ref_count = 1;
452
453 return folder;
454 }
455
456 NMFolder *
nm_create_folder_from_fields(NMField * fields)457 nm_create_folder_from_fields(NMField * fields)
458 {
459 NMField *field;
460 NMFolder *folder;
461
462 if (fields == NULL || fields->ptr_value == 0)
463 return NULL;
464
465 folder = g_new0(NMFolder, 1);
466
467 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) {
468
469 if (field->ptr_value)
470 folder->id = atoi((char *) field->ptr_value);
471 }
472
473 if ((field =
474 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) {
475
476 if (field->ptr_value)
477 folder->seq = atoi((char *) field->ptr_value);
478 }
479
480 if ((field =
481 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) {
482
483 if (field->ptr_value)
484 folder->name = g_strdup((char *) field->ptr_value);
485 }
486
487 folder->ref_count = 1;
488 return folder;
489 }
490
491 NMField *
nm_folder_to_fields(NMFolder * folder)492 nm_folder_to_fields(NMFolder * folder)
493 {
494 NMField *fields = NULL;
495
496 if (folder == NULL)
497 return NULL;
498
499 fields = nm_field_add_pointer(fields, NM_A_SZ_OBJECT_ID, 0, NMFIELD_METHOD_VALID, 0,
500 g_strdup_printf("%d", folder->id), NMFIELD_TYPE_UTF8);
501
502 fields = nm_field_add_pointer(fields, NM_A_SZ_PARENT_ID, 0, NMFIELD_METHOD_VALID, 0,
503 g_strdup("0"), NMFIELD_TYPE_UTF8);
504
505 fields = nm_field_add_pointer(fields, NM_A_SZ_TYPE, 0, NMFIELD_METHOD_VALID, 0,
506 g_strdup("1"), NMFIELD_TYPE_UTF8);
507
508 fields = nm_field_add_pointer(fields, NM_A_SZ_SEQUENCE_NUMBER, 0, NMFIELD_METHOD_VALID, 0,
509 g_strdup_printf("%d", folder->seq), NMFIELD_TYPE_UTF8);
510
511 if (folder->name != NULL) {
512 fields = nm_field_add_pointer(fields, NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_METHOD_VALID, 0,
513 g_strdup(folder->name), NMFIELD_TYPE_UTF8);
514 }
515
516
517 return fields;
518 }
519
520 void
nm_folder_update_list_properties(NMFolder * folder,NMField * fields)521 nm_folder_update_list_properties(NMFolder * folder, NMField * fields)
522 {
523 NMField *field;
524
525 if (folder == NULL || fields == NULL || fields->ptr_value == 0)
526 return;
527
528 if ((field = nm_locate_field(NM_A_SZ_OBJECT_ID, (NMField *) fields->ptr_value))) {
529
530 if (field->ptr_value)
531 folder->id = atoi((char *) field->ptr_value);
532
533 }
534
535 if ((field =
536 nm_locate_field(NM_A_SZ_SEQUENCE_NUMBER, (NMField *) fields->ptr_value))) {
537
538 if (field->ptr_value)
539 folder->seq = atoi((char *) field->ptr_value);
540
541 }
542
543 if ((field =
544 nm_locate_field(NM_A_SZ_DISPLAY_NAME, (NMField *) fields->ptr_value))) {
545
546 if (field->ptr_value) {
547 if (folder->name)
548 g_free(folder->name);
549
550 folder->name = g_strdup((char *) field->ptr_value);
551 }
552
553 }
554
555 }
556
557 void
nm_release_folder(NMFolder * folder)558 nm_release_folder(NMFolder * folder)
559 {
560 if (folder == NULL)
561 return;
562
563 if (--(folder->ref_count) == 0) {
564 if (folder->name) {
565 g_free(folder->name);
566 }
567
568 if (folder->folders) {
569 _release_folder_folders(folder);
570 }
571
572 if (folder->contacts) {
573 _release_folder_contacts(folder);
574 }
575
576 g_free(folder);
577 }
578 }
579
580
581 void
nm_folder_add_ref(NMFolder * folder)582 nm_folder_add_ref(NMFolder * folder)
583 {
584 if (folder)
585 folder->ref_count++;
586 }
587
588 int
nm_folder_get_subfolder_count(NMFolder * folder)589 nm_folder_get_subfolder_count(NMFolder * folder)
590 {
591 if (folder == NULL)
592 return 0;
593
594 if (folder->folders)
595 return g_slist_length(folder->folders);
596 else
597 return 0;
598 }
599
600 NMFolder *
nm_folder_get_subfolder(NMFolder * folder,int index)601 nm_folder_get_subfolder(NMFolder * folder, int index)
602 {
603 if (folder == NULL)
604 return NULL;
605
606 if (folder->folders)
607 return (NMFolder *) g_slist_nth_data(folder->folders, index);
608 else
609 return NULL;
610 }
611
612 int
nm_folder_get_contact_count(NMFolder * folder)613 nm_folder_get_contact_count(NMFolder * folder)
614 {
615 if (folder == NULL)
616 return 0;
617
618 if (folder->contacts != NULL)
619 return g_slist_length(folder->contacts);
620 else
621 return 0;
622 }
623
624 NMContact *
nm_folder_get_contact(NMFolder * folder,int index)625 nm_folder_get_contact(NMFolder * folder, int index)
626 {
627 if (folder == NULL)
628 return NULL;
629
630 if (folder->contacts)
631 return (NMContact *) g_slist_nth_data(folder->contacts, index);
632 else
633 return NULL;
634 }
635
636 const char *
nm_folder_get_name(NMFolder * folder)637 nm_folder_get_name(NMFolder * folder)
638 {
639 if (folder == NULL)
640 return NULL;
641
642 return folder->name;
643 }
644
645 void
nm_folder_set_name(NMFolder * folder,const char * name)646 nm_folder_set_name(NMFolder * folder, const char *name)
647 {
648 if (folder == NULL || name == NULL)
649 return;
650
651 if (folder->name)
652 g_free(folder->name);
653
654 folder->name = g_strdup(name);
655 }
656
657 int
nm_folder_get_id(NMFolder * folder)658 nm_folder_get_id(NMFolder * folder)
659 {
660 if (folder == NULL) {
661 return -1;
662 }
663
664 return folder->id;
665 }
666
667 void
nm_folder_add_folder_to_list(NMFolder * root,NMFolder * folder)668 nm_folder_add_folder_to_list(NMFolder * root, NMFolder * folder)
669 {
670 GSList *node;
671
672 if (root == NULL || folder == NULL)
673 return;
674
675 node = root->folders;
676 while (node) {
677 if (folder->seq <= ((NMFolder *) node->data)->seq) {
678 nm_folder_add_ref(folder);
679 root->folders = g_slist_insert_before(root->folders, node, folder);
680 break;
681 }
682 node = g_slist_next(node);
683 }
684 if (node == NULL) {
685 nm_folder_add_ref(folder);
686 root->folders = g_slist_append(root->folders, folder);
687 }
688 }
689
690 void
nm_folder_remove_contact(NMFolder * folder,NMContact * contact)691 nm_folder_remove_contact(NMFolder * folder, NMContact * contact)
692 {
693 GSList *node;
694
695 if (folder == NULL || contact == NULL)
696 return;
697
698 node = folder->contacts;
699 while (node) {
700 if (contact->id == ((NMContact *) (node->data))->id) {
701 folder->contacts = g_slist_remove(folder->contacts, node->data);
702 nm_release_contact(contact);
703 break;
704 }
705 node = g_slist_next(node);
706 }
707 }
708
709 void
nm_folder_add_contact_to_list(NMFolder * root_folder,NMContact * contact)710 nm_folder_add_contact_to_list(NMFolder * root_folder, NMContact * contact)
711 {
712 GSList *node = NULL;
713 NMFolder *folder = root_folder;
714
715 if (folder == NULL || contact == NULL)
716 return;
717
718 /* Find folder to add contact to */
719 if (contact->parent_id != 0) {
720 node = folder->folders;
721 while (node) {
722 folder = (NMFolder *) node->data;
723 if (contact->parent_id == folder->id) {
724 break;
725 }
726 folder = NULL;
727 node = g_slist_next(node);
728 }
729 }
730
731 /* Add contact to list */
732 if (folder) {
733 node = folder->contacts;
734 while (node) {
735 if (contact->seq <= ((NMContact *) (node->data))->seq) {
736 nm_contact_add_ref(contact);
737 folder->contacts =
738 g_slist_insert_before(folder->contacts, node, contact);
739 break;
740 }
741 node = g_slist_next(node);
742 }
743
744 if (node == NULL) {
745 nm_contact_add_ref(contact);
746 folder->contacts = g_slist_append(folder->contacts, contact);
747 }
748 }
749 }
750
751 void
nm_folder_add_contacts_and_folders(NMUser * user,NMFolder * root,NMField * fields)752 nm_folder_add_contacts_and_folders(NMUser * user, NMFolder * root,
753 NMField * fields)
754 {
755 /* Add the contacts and folders from the field array */
756 if (user && root && fields) {
757 _add_folders(root, fields);
758 _add_contacts(user, root, fields);
759 }
760 }
761
762 gpointer
nm_folder_find_item_by_object_id(NMFolder * root_folder,int object_id)763 nm_folder_find_item_by_object_id(NMFolder * root_folder, int object_id)
764 {
765 int cnt, cnt2, i, j;
766 gpointer item = NULL;
767 NMFolder *folder;
768 NMContact *contact;
769
770 if (root_folder == NULL)
771 return NULL;
772
773 /* Check all contacts for the top level folder */
774 cnt = nm_folder_get_contact_count(root_folder);
775 for (i = 0; i < cnt; i++) {
776 contact = nm_folder_get_contact(root_folder, i);
777 if (contact && (contact->id == object_id)) {
778 item = contact;
779 break;
780 }
781 }
782
783 /* If we haven't found the item yet, check the subfolders */
784 if (item == NULL) {
785 cnt = nm_folder_get_subfolder_count(root_folder);
786 for (i = 0; (i < cnt) && (item == NULL); i++) {
787 folder = nm_folder_get_subfolder(root_folder, i);
788
789 /* Check the id of this folder */
790 if (folder && (folder->id == object_id)) {
791 item = folder;
792 break;
793 }
794
795 /* Check all contacts for this folder */
796 cnt2 = nm_folder_get_contact_count(folder);
797 for (j = 0; j < cnt2; j++) {
798 contact = nm_folder_get_contact(folder, j);
799 if (contact && (contact->id == object_id)) {
800 item = contact;
801 break;
802 }
803 }
804 }
805 }
806
807 return item;
808 }
809
810 NMContact *
nm_folder_find_contact_by_userid(NMFolder * folder,const char * userid)811 nm_folder_find_contact_by_userid(NMFolder * folder, const char *userid)
812 {
813 int cnt, i;
814 NMContact *tmp, *contact = NULL;
815
816 if (folder == NULL || userid == NULL)
817 return NULL;
818
819 cnt = nm_folder_get_contact_count(folder);
820 for (i = 0; i < cnt; i++) {
821 tmp = nm_folder_get_contact(folder, i);
822 if (tmp && nm_utf8_str_equal(nm_contact_get_userid(tmp), userid)) {
823 contact = tmp;
824 break;
825 }
826 }
827
828 return contact;
829 }
830
831 NMContact *
nm_folder_find_contact_by_display_id(NMFolder * folder,const char * display_id)832 nm_folder_find_contact_by_display_id(NMFolder * folder, const char *display_id)
833 {
834 int cnt, i;
835 NMContact *tmp, *contact = NULL;
836
837 if (folder == NULL || display_id == NULL)
838 return NULL;
839
840 cnt = nm_folder_get_contact_count(folder);
841 for (i = 0; i < cnt; i++) {
842 tmp = nm_folder_get_contact(folder, i);
843 if (tmp && nm_utf8_str_equal(nm_contact_get_display_id(tmp), display_id)) {
844 contact = tmp;
845 break;
846 }
847 }
848
849 return contact;
850 }
851
852 NMContact *
nm_folder_find_contact(NMFolder * folder,const char * dn)853 nm_folder_find_contact(NMFolder * folder, const char *dn)
854 {
855 int cnt, i;
856 NMContact *tmp, *contact = NULL;
857
858 if (folder == NULL || dn == NULL)
859 return NULL;
860
861 cnt = nm_folder_get_contact_count(folder);
862 for (i = 0; i < cnt; i++) {
863 tmp = nm_folder_get_contact(folder, i);
864 if (tmp && nm_utf8_str_equal(nm_contact_get_dn(tmp), dn)) {
865 contact = tmp;
866 break;
867 }
868 }
869
870 return contact;
871 }
872
873
874 /*********************************************************************
875 * Utility functions
876 *********************************************************************/
877
878 static void
_release_folder_contacts(NMFolder * folder)879 _release_folder_contacts(NMFolder * folder)
880 {
881 GSList *cnode;
882 NMContact *contact;
883
884 for (cnode = folder->contacts; cnode; cnode = cnode->next) {
885 contact = cnode->data;
886 cnode->data = NULL;
887 nm_release_contact(contact);
888 }
889
890 g_slist_free(folder->contacts);
891 folder->contacts = NULL;
892 }
893
894 static void
_release_folder_folders(NMFolder * folder)895 _release_folder_folders(NMFolder * folder)
896 {
897 GSList *fnode;
898 NMFolder *subfolder;
899
900 if (folder == NULL)
901 return;
902
903 for (fnode = folder->folders; fnode; fnode = fnode->next) {
904 subfolder = fnode->data;
905 fnode->data = NULL;
906 nm_release_folder(subfolder);
907 }
908
909 g_slist_free(folder->folders);
910 folder->folders = NULL;
911 }
912
913 static void
_add_folders(NMFolder * root,NMField * fields)914 _add_folders(NMFolder * root, NMField * fields)
915 {
916 NMFolder *folder = NULL;
917 NMField *locate = NULL;
918
919 locate = nm_locate_field(NM_A_FA_FOLDER, fields);
920 while (locate != NULL) {
921
922 /* Create a new folder */
923 folder = nm_create_folder_from_fields(locate);
924
925 /* Add subfolder to roots folder list */
926 nm_folder_add_folder_to_list(root, folder);
927
928 /* Decrement the ref count */
929 nm_release_folder(folder);
930
931 /* Find the next folder */
932 locate = nm_locate_field(NM_A_FA_FOLDER, locate+1);
933
934 }
935 }
936
937 static void
_add_contacts(NMUser * user,NMFolder * folder,NMField * fields)938 _add_contacts(NMUser * user, NMFolder * folder, NMField * fields)
939 {
940 NMContact *contact = NULL;
941 NMField *locate = NULL, *details;
942 NMUserRecord *user_record = NULL;
943
944 locate = nm_locate_field(NM_A_FA_CONTACT, fields);
945 while (locate != NULL) {
946
947 /* Create a new contact from the fields */
948 contact = nm_create_contact_from_fields(locate);
949
950 /* Add it to our contact list */
951 nm_folder_add_contact_to_list(folder, contact);
952
953 /* Update the contact cache */
954 nm_user_add_contact(user, contact);
955
956 /* Update the user record cache */
957 if ((details = nm_locate_field(NM_A_FA_USER_DETAILS,
958 (NMField *) locate->ptr_value))) {
959 user_record = nm_find_user_record(user, nm_contact_get_dn(contact));
960 if (user_record == NULL) {
961 user_record = nm_create_user_record_from_fields(details);
962 nm_user_record_set_dn(user_record, nm_contact_get_dn(contact));
963 nm_user_add_user_record(user, user_record);
964 nm_release_user_record(user_record);
965 }
966 nm_contact_set_user_record(contact, user_record);
967 }
968
969 nm_release_contact(contact);
970
971 locate = nm_locate_field(NM_A_FA_CONTACT, locate+1);
972 }
973 }
974