2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2015 Match Grun and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
20 * Functions necessary to access LDIF files (LDAP Data Interchange Format
25 #include <glib/gi18n.h>
32 #include "addrcache.h"
36 #define LDIF_SEP_TAG ':'
37 #define LDIF_LANG_TAG ';'
41 * \return Initialized LDIF file object.
43 LdifFile
*ldif_create() {
45 ldifFile
= g_new0( LdifFile
, 1 );
46 ldifFile
->path
= NULL
;
47 ldifFile
->file
= NULL
;
48 ldifFile
->hashFields
= g_hash_table_new( g_str_hash
, g_str_equal
);
49 ldifFile
->tempList
= NULL
;
50 ldifFile
->dirtyFlag
= TRUE
;
51 ldifFile
->accessFlag
= FALSE
;
52 ldifFile
->retVal
= MGU_SUCCESS
;
53 ldifFile
->cbProgress
= NULL
;
54 ldifFile
->importCount
= 0;
59 * Specify full file specification of LDIF file.
60 * \param ldifFile LDIF import control object.
61 * \param value Value of access flag.
63 void ldif_set_file( LdifFile
*ldifFile
, const gchar
*value
) {
64 cm_return_if_fail( ldifFile
!= NULL
);
66 if( ldifFile
->path
) {
67 if( strcmp( ldifFile
->path
, value
) != 0 )
68 ldifFile
->dirtyFlag
= TRUE
;
71 ldifFile
->dirtyFlag
= TRUE
;
73 ldifFile
->path
= mgu_replace_string( ldifFile
->path
, value
);
74 g_strstrip( ldifFile
->path
);
75 ldifFile
->importCount
= 0;
79 * Set the file access indicator.
80 * \param ldifFile LDIF import control object.
81 * \param value File specification.
83 void ldif_set_accessed( LdifFile
*ldifFile
, const gboolean value
) {
84 cm_return_if_fail( ldifFile
!= NULL
);
85 ldifFile
->accessFlag
= value
;
89 * Create field record object.
90 * \return Initialized LDIF field object.
92 static Ldif_FieldRec
*ldif_create_fieldrec( const gchar
*field
) {
93 Ldif_FieldRec
*rec
= g_new0( Ldif_FieldRec
, 1 );
94 rec
->tagName
= g_strdup( field
);
96 rec
->reserved
= FALSE
;
97 rec
->selected
= FALSE
;
102 * Free field record object.
103 * \param rec LDIF field object.
105 static void ldif_free_fieldrec( Ldif_FieldRec
*rec
) {
107 g_free( rec
->tagName
);
108 g_free( rec
->userName
);
110 rec
->userName
= NULL
;
111 rec
->reserved
= FALSE
;
112 rec
->selected
= FALSE
;
118 * Set user name for field record.
119 * \param rec LDIF field object.
120 * \param value User name to set. Note that reserved fields cannot be
123 void ldif_field_set_name( Ldif_FieldRec
*rec
, const gchar
*value
) {
124 cm_return_if_fail( rec
!= NULL
);
126 if( ! rec
->reserved
) {
127 rec
->userName
= mgu_replace_string( rec
->userName
, value
);
128 g_strstrip( rec
->userName
);
133 * Specify selection for field record.
134 * \param rec LDIF field object.
135 * \param value Set to <i>TRUE</i> to select field. Note that reserved
136 * fields cannot be unselected.
138 void ldif_field_set_selected( Ldif_FieldRec
*rec
, const gboolean value
) {
139 cm_return_if_fail( rec
!= NULL
);
141 if( ! rec
->reserved
) {
142 rec
->selected
= value
;
147 * Toggle selection for field record. Note that reserved fields cannot be
149 * \param rec LDIF field object.
151 void ldif_field_toggle( Ldif_FieldRec
*rec
) {
152 cm_return_if_fail( rec
!= NULL
);
154 if( ! rec
->reserved
) {
155 rec
->selected
= !rec
->selected
;
160 * Free hash table entry visitor function.
162 * \param value Value (the LDIF field record).
163 * \param data User data.
164 * \return <code>-1</code>.
166 static gint
ldif_hash_free_vis( gpointer key
, gpointer value
, gpointer data
) {
167 ldif_free_fieldrec( ( Ldif_FieldRec
* ) value
);
172 * Free up object by releasing internal memory.
173 * \param ldifFile LDIF import control object.
175 void ldif_free( LdifFile
*ldifFile
) {
176 cm_return_if_fail( ldifFile
!= NULL
);
179 if( ldifFile
->file
) fclose( ldifFile
->file
);
181 /* Free internal stuff */
182 g_free( ldifFile
->path
);
184 /* Free field list */
185 g_hash_table_foreach_remove( ldifFile
->hashFields
, ldif_hash_free_vis
, NULL
);
186 g_hash_table_destroy( ldifFile
->hashFields
);
187 ldifFile
->hashFields
= NULL
;
190 ldifFile
->file
= NULL
;
191 ldifFile
->path
= NULL
;
192 ldifFile
->retVal
= MGU_SUCCESS
;
193 ldifFile
->tempList
= NULL
;
194 ldifFile
->dirtyFlag
= FALSE
;
195 ldifFile
->accessFlag
= FALSE
;
196 ldifFile
->cbProgress
= NULL
;
198 /* Now release file object */
203 * Open file for read.
204 * \param ldifFile LDIF import control object.
205 * \return <i>TRUE</i> if file opened successfully.
207 static gint
ldif_open_file( LdifFile
* ldifFile
) {
208 /* g_print( "Opening file\n" ); */
209 if( ldifFile
->path
) {
210 ldifFile
->file
= g_fopen( ldifFile
->path
, "rb" );
211 if( ! ldifFile
->file
) {
212 /* g_print( "can't open %s\n", ldifFile->path ); */
213 ldifFile
->retVal
= MGU_OPEN_FILE
;
214 return ldifFile
->retVal
;
218 /* g_print( "file not specified\n" ); */
219 ldifFile
->retVal
= MGU_NO_FILE
;
220 return ldifFile
->retVal
;
223 /* Setup a buffer area */
224 ldifFile
->retVal
= MGU_SUCCESS
;
225 return ldifFile
->retVal
;
230 * \param ldifFile LDIF import control object.
232 static void ldif_close_file( LdifFile
*ldifFile
) {
233 cm_return_if_fail( ldifFile
!= NULL
);
234 if( ldifFile
->file
) fclose( ldifFile
->file
);
235 ldifFile
->file
= NULL
;
239 * Read line of text from file.
240 * \param ldifFile LDIF import control object.
241 * \return ptr to buffer where line starts.
243 static gchar
*ldif_get_line( LdifFile
*ldifFile
) {
244 gchar
*buf
= g_malloc(LDIFBUFSIZE
);
247 int cur_alloc
= LDIFBUFSIZE
;
249 if( feof( ldifFile
->file
) ) {
254 while( i
< cur_alloc
-1 ) {
255 ch
= fgetc( ldifFile
->file
);
256 if (ferror( ldifFile
->file
))
257 ldifFile
->retVal
= MGU_ERROR_READ
;
258 if( ch
== '\0' || ch
== EOF
) {
259 if( i
== 0 ) return NULL
;
262 #if HAVE_DOSISH_SYSTEM
271 if (i
== cur_alloc
-1 && cur_alloc
< LDIFBUFSIZE
* 32) {
272 cur_alloc
+= LDIFBUFSIZE
;
273 buf
= g_realloc(buf
, cur_alloc
);
278 /* Return a copy of buffer */
279 return g_strdup( buf
);
283 * Parse tag name from line buffer.
284 * \param line Buffer.
285 * \param flag64 Base-64 encoder flag.
286 * \return Buffer containing the tag name, or NULL if no delimiter char found.
287 * If a double delimiter (::) is found, flag64 is set.
289 static gchar
*ldif_get_tagname( char* line
, gboolean
*flag64
) {
296 /* Check for language tag */
297 if( *lptr
== LDIF_LANG_TAG
) {
298 if( sptr
== NULL
) sptr
= lptr
;
301 /* Check for delimiter */
302 if( *lptr
== LDIF_SEP_TAG
) {
310 /* Base-64 encoding? */
311 if( * ++lptr
== LDIF_SEP_TAG
) *flag64
= TRUE
;
313 tag
= g_strndup( line
, len
+1 );
322 * Parse tag value from line buffer.
323 * \param line Buffer.
324 * \return Buffer containing the tag value. Empty string is returned if
325 * no delimiter char found.
327 static gchar
*ldif_get_tagvalue( gchar
* line
) {
333 for( lptr
= line
; *lptr
; lptr
++ ) {
334 if( *lptr
== LDIF_SEP_TAG
) {
340 if( *start
== LDIF_SEP_TAG
) start
++;
342 value
= g_strndup( start
, len
+1 );
346 /* Ensure that we get an empty string */
347 value
= g_strndup( "", 1 );
354 * Parsed address data record.
356 typedef struct _Ldif_ParsedRec_ Ldif_ParsedRec
;
357 struct _Ldif_ParsedRec_
{
368 * User attribute data record.
370 typedef struct _Ldif_UserAttr_ Ldif_UserAttr
;
371 struct _Ldif_UserAttr_
{
377 * Build an address list entry and append to list of address items in the
378 * address cache. Name is formatted as "<first-name> <last-name>".
379 * \param ldifFile LDIF import control object.
380 * \param rec LDIF field object.
381 * \param cache Address cache to be populated with data.
383 static void ldif_build_items(
384 LdifFile
*ldifFile
, Ldif_ParsedRec
*rec
, AddressCache
*cache
)
389 gchar
*firstName
= NULL
, *lastName
= NULL
, *fullName
= NULL
;
390 gchar
*nickName
= NULL
;
391 gint iLen
= 0, iLenT
= 0;
395 nodeAddress
= rec
->listAddress
;
396 // if( nodeAddress == NULL ) return;
398 /* Find longest first name in list */
399 nodeFirst
= rec
->listFName
;
401 if( firstName
== NULL
) {
402 firstName
= nodeFirst
->data
;
403 iLen
= strlen( firstName
);
406 if( ( iLenT
= strlen( nodeFirst
->data
) ) > iLen
) {
407 firstName
= nodeFirst
->data
;
411 nodeFirst
= g_slist_next( nodeFirst
);
415 if( rec
->listLName
) {
416 lastName
= rec
->listLName
->data
;
421 fullName
= g_strdup_printf(
422 "%s %s", firstName
, lastName
);
425 fullName
= g_strdup_printf( "%s", firstName
);
430 fullName
= g_strdup_printf( "%s", lastName
);
434 if (!fullName
|| strlen(fullName
) == 0) {
438 fullName
= g_strdup(rec
->listCName
->data
);
442 g_strstrip( fullName
);
445 if( rec
->listNName
) {
446 nickName
= rec
->listNName
->data
;
449 person
= addritem_create_item_person();
450 addritem_person_set_common_name( person
, fullName
);
451 addritem_person_set_first_name( person
, firstName
);
452 addritem_person_set_last_name( person
, lastName
);
453 addritem_person_set_nick_name( person
, nickName
);
454 addrcache_id_person( cache
, person
);
455 addrcache_add_person( cache
, person
);
456 ++ldifFile
->importCount
;
458 /* Add address item */
459 while( nodeAddress
) {
460 email
= addritem_create_item_email();
461 addritem_email_set_address( email
, nodeAddress
->data
);
462 addrcache_id_email( cache
, email
);
463 addrcache_person_add_email( cache
, person
, email
);
464 nodeAddress
= g_slist_next( nodeAddress
);
467 fullName
= firstName
= lastName
= NULL
;
469 /* Add user attributes */
470 nodeAttr
= rec
->userAttr
;
472 Ldif_UserAttr
*attr
= nodeAttr
->data
;
473 UserAttribute
*attrib
= addritem_create_attribute();
474 addritem_attrib_set_name( attrib
, attr
->name
);
475 addritem_attrib_set_value( attrib
, attr
->value
);
476 addritem_person_add_attribute( person
, attrib
);
477 nodeAttr
= g_slist_next( nodeAttr
);
483 * Add selected field as user attribute.
484 * \param rec LDIF field object.
485 * \param tagName LDIF tag name.
486 * \param tagValue Data value.
487 * \param hashField Hash table to populate.
489 static void ldif_add_user_attr(
490 Ldif_ParsedRec
*rec
, gchar
*tagName
, gchar
*tagValue
,
491 GHashTable
*hashField
)
493 Ldif_FieldRec
*fld
= NULL
;
494 Ldif_UserAttr
*attr
= NULL
;
497 fld
= g_hash_table_lookup( hashField
, tagName
);
499 if( ! fld
->selected
) return;
502 if( fld
->userName
) {
503 name
= fld
->userName
;
505 attr
= g_new0( Ldif_UserAttr
, 1 );
506 attr
->name
= g_strdup( name
);
507 attr
->value
= g_strdup( tagValue
);
508 rec
->userAttr
= g_slist_append( rec
->userAttr
, attr
);
513 * Add value to parsed data.
514 * \param rec LDIF field object.
515 * \param tagName LDIF tag name.
516 * \param tagValue Data value.
517 * \param hashField Hash table to populate.
519 static void ldif_add_value(
520 Ldif_ParsedRec
*rec
, gchar
*tagName
, gchar
*tagValue
,
521 GHashTable
*hashField
)
525 nm
= g_utf8_strdown( tagName
, -1 );
527 val
= g_strdup( tagValue
);
530 val
= g_strdup( "" );
534 if( g_utf8_collate( nm
, g_utf8_strdown( LDIF_TAG_COMMONNAME
, -1 ) ) == 0 ) {
535 rec
->listCName
= g_slist_append( rec
->listCName
, val
);
537 else if( g_utf8_collate( nm
, g_utf8_strdown( LDIF_TAG_FIRSTNAME
, -1 ) ) == 0 ) {
538 rec
->listFName
= g_slist_append( rec
->listFName
, val
);
540 else if( g_utf8_collate( nm
, g_utf8_strdown( LDIF_TAG_LASTNAME
, -1 ) ) == 0 ) {
541 rec
->listLName
= g_slist_append( rec
->listLName
, val
);
543 else if( g_utf8_collate( nm
, g_utf8_strdown( LDIF_TAG_NICKNAME
, -1 ) ) == 0 ) {
544 rec
->listNName
= g_slist_append( rec
->listNName
, val
);
546 else if( g_utf8_collate( nm
, g_utf8_strdown( LDIF_TAG_EMAIL
, -1 ) ) == 0 ) {
547 rec
->listAddress
= g_slist_append( rec
->listAddress
, val
);
550 /* Add field as user attribute */
551 ldif_add_user_attr( rec
, tagName
, tagValue
, hashField
);
557 * Clear parsed data record.
558 * \param rec LDIF field object.
560 static void ldif_clear_rec( Ldif_ParsedRec
*rec
) {
563 /* Free up user attributes */
564 list
= rec
->userAttr
;
566 Ldif_UserAttr
*attr
= list
->data
;
567 g_free( attr
->name
);
568 g_free( attr
->value
);
570 list
= g_slist_next( list
);
572 g_slist_free( rec
->userAttr
);
574 g_slist_free( rec
->listCName
);
575 g_slist_free( rec
->listFName
);
576 g_slist_free( rec
->listLName
);
577 g_slist_free( rec
->listNName
);
578 g_slist_free( rec
->listAddress
);
579 g_slist_free( rec
->listID
);
581 rec
->userAttr
= NULL
;
582 rec
->listCName
= NULL
;
583 rec
->listFName
= NULL
;
584 rec
->listLName
= NULL
;
585 rec
->listNName
= NULL
;
586 rec
->listAddress
= NULL
;
591 * Read file data into address cache.
592 * Note that one LDIF record identifies one entity uniquely with the
593 * distinguished name (dn) tag. Each person can have multiple E-Mail
594 * addresses. Also, each person can have many common name (cn) tags.
596 * \param ldifFile LDIF import control object.
597 * \param cache Address cache to be populated with data.
599 static void ldif_read_file( LdifFile
*ldifFile
, AddressCache
*cache
) {
600 gchar
*tagName
= NULL
, *tagValue
= NULL
;
601 gchar
*lastTag
= NULL
, *fullValue
= NULL
;
602 GSList
*listValue
= NULL
;
603 gboolean flagEOF
= FALSE
, flagEOR
= FALSE
;
604 gboolean flag64
= FALSE
, last64
= FALSE
;
608 GHashTable
*hashField
;
611 hashField
= ldifFile
->hashFields
;
612 rec
= g_new0( Ldif_ParsedRec
, 1 );
613 ldif_clear_rec( rec
);
615 /* Find EOF for progress indicator */
616 fseek( ldifFile
->file
, 0L, SEEK_END
);
617 posEnd
= ftell( ldifFile
->file
);
618 fseek( ldifFile
->file
, 0L, SEEK_SET
);
621 gchar
*line
= ldif_get_line( ldifFile
);
623 posCur
= ftell( ldifFile
->file
);
624 if( ldifFile
->cbProgress
) {
625 /* Call progress indicator */
626 ( ldifFile
->cbProgress
) ( ldifFile
, & posEnd
, & posCur
);
631 flagEOF
= flagEOR
= TRUE
;
633 else if( *line
== '\0' ) {
638 /* EOR, Output address data */
641 fullValue
= mgu_list_coalesce( listValue
);
642 if (fullValue
&& last64
) {
643 gchar
*tmp
= g_base64_decode_zero(fullValue
, &len
);
648 ldif_add_value( rec
, lastTag
, fullValue
, hashField
);
649 /* ldif_print_record( rec, stdout ); */
650 ldif_build_items( ldifFile
, rec
, cache
);
651 ldif_clear_rec( rec
);
653 mgu_free_list( listValue
);
663 /* Continuation line */
664 listValue
= g_slist_append(
665 listValue
, g_strdup( line
+1 ) );
667 else if( *line
== '=' ) {
668 /* Base-64 encoded continuation field */
669 listValue
= g_slist_append(
670 listValue
, g_strdup( line
) );
674 tagName
= ldif_get_tagname( line
, &flag64
);
676 tagValue
= ldif_get_tagvalue( line
);
681 mgu_list_coalesce( listValue
);
682 if (fullValue
&& last64
) {
683 gchar
*tmp
= g_base64_decode_zero(fullValue
, &len
);
687 /* Base-64 encoded data */
690 ldif_dump_b64( fullValue );
695 rec
, lastTag
, fullValue
,
698 mgu_free_list( listValue
);
703 lastTag
= g_strdup( tagName
);
704 listValue
= g_slist_append(
706 g_strdup( tagValue
) );
718 ldif_clear_rec( rec
);
721 mgu_free_list( listValue
);
725 * Add list of field names to hash table.
726 * \param table Hashtable.
727 * \param list List of fields.
729 static void ldif_hash_add_list( GHashTable
*table
, GSList
*list
) {
732 /* mgu_print_list( list, stdout ); */
734 gchar
*tag
= node
->data
;
735 if( ! g_hash_table_lookup( table
, tag
) ) {
736 Ldif_FieldRec
*rec
= NULL
;
737 gchar
*key
= g_utf8_strdown( tag
, -1 );
739 rec
= ldif_create_fieldrec( tag
);
740 if( g_utf8_collate( key
, LDIF_TAG_DN
) == 0 ) {
741 rec
->reserved
= rec
->selected
= TRUE
;
742 rec
->userName
= g_strdup( "dn" );
744 else if( g_utf8_collate( key
, g_utf8_strdown( LDIF_TAG_COMMONNAME
, -1 ) ) == 0 ) {
745 rec
->reserved
= rec
->selected
= TRUE
;
746 rec
->userName
= g_strdup( _( "Display Name" ) );
748 else if( g_utf8_collate( key
, g_utf8_strdown( LDIF_TAG_FIRSTNAME
, -1 ) ) == 0 ) {
749 rec
->reserved
= rec
->selected
= TRUE
;
750 rec
->userName
= g_strdup( _( "First Name" ) );
752 else if( g_utf8_collate( key
, g_utf8_strdown( LDIF_TAG_LASTNAME
, -1 ) ) == 0 ) {
753 rec
->reserved
= rec
->selected
= TRUE
;
754 rec
->userName
= g_strdup( _( "Last Name" ) );
756 else if( g_utf8_collate( key
, g_utf8_strdown( LDIF_TAG_NICKNAME
, -1 ) ) == 0 ) {
757 rec
->reserved
= rec
->selected
= TRUE
;
758 rec
->userName
= g_strdup( _( "Nick Name" ) );
760 else if( g_utf8_collate( key
, g_utf8_strdown( LDIF_TAG_EMAIL
, -1 ) ) == 0 ) {
761 rec
->reserved
= rec
->selected
= TRUE
;
762 rec
->userName
= g_strdup( _( "Email Address" ) );
764 g_hash_table_insert( table
, key
, rec
);
766 node
= g_slist_next( node
);
771 * Sorted list comparison function.
772 * \param ptr1 First field.
773 * \param ptr2 Second field.
774 * \return <code>-1, 0, +1</code> if first record less than, equal,
775 * greater than second.
777 static gint
ldif_field_compare( gconstpointer ptr1
, gconstpointer ptr2
) {
778 const Ldif_FieldRec
*rec1
= ptr1
;
779 const Ldif_FieldRec
*rec2
= ptr2
;
781 if( rec1
->reserved
) {
782 if( ! rec2
->reserved
) {
787 if( rec2
->reserved
) {
791 return g_utf8_collate( rec1
->tagName
, rec2
->tagName
);
795 * Append hash table entry to list - visitor function.
797 * \param value Data value.
798 * \param data User data (the LDIF import control object).
800 static void ldif_hash2list_vis( gpointer key
, gpointer value
, gpointer data
) {
801 LdifFile
*ldf
= data
;
803 g_list_insert_sorted( ldf
->tempList
, value
, ldif_field_compare
);
807 * Read tag names for file data.
808 * \param ldifFile LDIF import control object.
810 static void ldif_read_tag_list( LdifFile
*ldifFile
) {
811 gchar
*tagName
= NULL
;
812 GSList
*listTags
= NULL
;
813 gboolean flagEOF
= FALSE
, flagEOR
= FALSE
, flagMail
= FALSE
;
814 gboolean flag64
= FALSE
;
818 /* Clear hash table */
819 g_hash_table_foreach_remove(
820 ldifFile
->hashFields
, ldif_hash_free_vis
, NULL
);
822 /* Find EOF for progress indicator */
823 fseek( ldifFile
->file
, 0L, SEEK_END
);
824 posEnd
= ftell( ldifFile
->file
);
825 fseek( ldifFile
->file
, 0L, SEEK_SET
);
828 ldifFile
->retVal
= MGU_EOF
;
834 gchar
*line
= ldif_get_line( ldifFile
);
835 posCur
= ftell( ldifFile
->file
);
836 if( ldifFile
->cbProgress
) {
837 /* Call progress indicator */
838 ( ldifFile
->cbProgress
) ( ldifFile
, & posEnd
, & posCur
);
843 flagEOF
= flagEOR
= TRUE
;
845 else if( *line
== '\0' ) {
850 /* EOR, Output address data */
851 /* Save field list to hash table */
854 ldifFile
->hashFields
, listTags
);
856 mgu_free_list( listTags
);
863 /* Continuation line */
865 else if( *line
== '=' ) {
866 /* Base-64 encoded continuation field */
870 tagName
= ldif_get_tagname( line
, &flag64
);
872 /* Add tag to list */
873 listTags
= g_slist_append( listTags
, tagName
);
876 tagName
, LDIF_TAG_EMAIL
) == 0 )
883 debug_print("ldif: bad format: '%s'\n", line
);
884 ldifFile
->retVal
= MGU_BAD_FORMAT
;
893 mgu_free_list( listTags
);
898 * Read file into list. Main entry point
899 * \param ldifFile LDIF import control object.
900 * \param cache Address cache to load.
901 * \return Status code.
903 gint
ldif_import_data( LdifFile
*ldifFile
, AddressCache
*cache
) {
904 cm_return_val_if_fail( ldifFile
!= NULL
, MGU_BAD_ARGS
);
905 ldifFile
->retVal
= MGU_SUCCESS
;
906 addrcache_clear( cache
);
907 cache
->dataRead
= FALSE
;
908 ldif_open_file( ldifFile
);
909 if( ldifFile
->retVal
== MGU_SUCCESS
) {
910 /* Read data into the cache */
911 ldif_read_file( ldifFile
, cache
);
912 ldif_close_file( ldifFile
);
915 cache
->modified
= FALSE
;
916 cache
->dataRead
= TRUE
;
918 return ldifFile
->retVal
;
922 * Process entire file reading list of unique fields. List of fields may be
923 * accessed with the <code>ldif_get_fieldlist()</code> function.
924 * \param ldifFile LDIF import control object.
925 * \return Status code.
927 gint
ldif_read_tags( LdifFile
*ldifFile
) {
928 cm_return_val_if_fail( ldifFile
!= NULL
, MGU_BAD_ARGS
);
929 ldifFile
->retVal
= MGU_SUCCESS
;
930 if( ldifFile
->dirtyFlag
) {
931 ldif_open_file( ldifFile
);
932 if( ldifFile
->retVal
== MGU_SUCCESS
) {
933 /* Read data into the cache */
934 ldif_read_tag_list( ldifFile
);
935 ldif_close_file( ldifFile
);
936 ldifFile
->dirtyFlag
= FALSE
;
937 ldifFile
->accessFlag
= TRUE
;
940 return ldifFile
->retVal
;
944 * Return list of fields for LDIF file.
945 * \param ldifFile LDIF import control object.
946 * \return Linked list of <code>Ldif_FieldRec</code> objects. This list may be
947 * <code>g_free()</code>. Note that the objects in the list should not
948 * be freed since they refer to objects inside the internal cache.
949 * These objects will be freed when LDIF file object is freed.
951 GList
*ldif_get_fieldlist( LdifFile
*ldifFile
) {
954 cm_return_val_if_fail( ldifFile
!= NULL
, NULL
);
955 if( ldifFile
->hashFields
) {
956 ldifFile
->tempList
= NULL
;
957 g_hash_table_foreach( ldifFile
->hashFields
, ldif_hash2list_vis
, ldifFile
);
958 list
= ldifFile
->tempList
;
959 ldifFile
->tempList
= NULL
;
965 * Output LDIF name-value pair to stream. Only non-empty names and values will
967 * \param stream File output stream.
969 * \param value Data value.
970 * \return <i>TRUE</i> if data output.
972 gboolean
ldif_write_value( FILE *stream
, const gchar
*name
, const gchar
*value
) {
973 if( name
== NULL
) return FALSE
;
974 if( value
== NULL
) return FALSE
;
975 if( strlen( name
) < 1 ) return FALSE
;
976 if( strlen( value
) < 1 ) return FALSE
;
977 fprintf( stream
, "%s: ", name
);
978 fprintf( stream
, "%s\n", value
);
983 * Output LDIF End of Record to stream.
984 * \param stream File output stream.
985 * \return <i>TRUE</i> if data output.
987 void ldif_write_eor( FILE *stream
) {
988 /* Simple but caller should not need to know how to end record. */
989 fprintf( stream
, "\n" );
993 * ============================================================================
995 * ============================================================================