2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2012 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/>.
21 * Functions necessary to access LDIF files (LDAP Data Interchange Format
26 #include <glib/gi18n.h>
33 #include "addrcache.h"
38 #define LDIF_SEP_TAG ':'
39 #define LDIF_LANG_TAG ';'
43 * \return Initialized LDIF file object.
45 LdifFile *ldif_create() {
47 ldifFile = g_new0( LdifFile, 1 );
48 ldifFile->path = NULL;
49 ldifFile->file = NULL;
50 ldifFile->hashFields = g_hash_table_new( g_str_hash, g_str_equal );
51 ldifFile->tempList = NULL;
52 ldifFile->dirtyFlag = TRUE;
53 ldifFile->accessFlag = FALSE;
54 ldifFile->retVal = MGU_SUCCESS;
55 ldifFile->cbProgress = NULL;
56 ldifFile->importCount = 0;
61 * Specify full file specification of LDIF file.
62 * \param ldifFile LDIF import control object.
63 * \param value Value of access flag.
65 void ldif_set_file( LdifFile *ldifFile, const gchar *value ) {
66 cm_return_if_fail( ldifFile != NULL );
68 if( ldifFile->path ) {
69 if( strcmp( ldifFile->path, value ) != 0 )
70 ldifFile->dirtyFlag = TRUE;
73 ldifFile->dirtyFlag = TRUE;
75 ldifFile->path = mgu_replace_string( ldifFile->path, value );
76 g_strstrip( ldifFile->path );
77 ldifFile->importCount = 0;
81 * Set the file access indicator.
82 * \param ldifFile LDIF import control object.
83 * \param value File specification.
85 void ldif_set_accessed( LdifFile *ldifFile, const gboolean value ) {
86 cm_return_if_fail( ldifFile != NULL );
87 ldifFile->accessFlag = value;
91 * Create field record object.
92 * \return Initialized LDIF field object.
94 static Ldif_FieldRec *ldif_create_fieldrec( const gchar *field ) {
95 Ldif_FieldRec *rec = g_new0( Ldif_FieldRec, 1 );
96 rec->tagName = g_strdup( field );
98 rec->reserved = FALSE;
99 rec->selected = FALSE;
104 * Free field record object.
105 * \param rec LDIF field object.
107 static void ldif_free_fieldrec( Ldif_FieldRec *rec ) {
109 g_free( rec->tagName );
110 g_free( rec->userName );
112 rec->userName = NULL;
113 rec->reserved = FALSE;
114 rec->selected = FALSE;
120 * Set user name for field record.
121 * \param rec LDIF field object.
122 * \param value User name to set. Note that reserved fields cannot be
125 void ldif_field_set_name( Ldif_FieldRec *rec, const gchar *value ) {
126 cm_return_if_fail( rec != NULL );
128 if( ! rec->reserved ) {
129 rec->userName = mgu_replace_string( rec->userName, value );
130 g_strstrip( rec->userName );
135 * Specify selection for field record.
136 * \param rec LDIF field object.
137 * \param value Set to <i>TRUE</i> to select field. Note that reserved
138 * fields cannot be unselected.
140 void ldif_field_set_selected( Ldif_FieldRec *rec, const gboolean value ) {
141 cm_return_if_fail( rec != NULL );
143 if( ! rec->reserved ) {
144 rec->selected = value;
149 * Toggle selection for field record. Note that reserved fields cannot be
151 * \param rec LDIF field object.
153 void ldif_field_toggle( Ldif_FieldRec *rec ) {
154 cm_return_if_fail( rec != NULL );
156 if( ! rec->reserved ) {
157 rec->selected = !rec->selected;
162 * Free hash table entry visitor function.
164 * \param value Value (the LDIF field record).
165 * \param data User data.
166 * \return <code>-1</code>.
168 static gint ldif_hash_free_vis( gpointer key, gpointer value, gpointer data ) {
169 ldif_free_fieldrec( ( Ldif_FieldRec * ) value );
176 * Free up object by releasing internal memory.
177 * \param ldifFile LDIF import control object.
179 void ldif_free( LdifFile *ldifFile ) {
180 cm_return_if_fail( ldifFile != NULL );
183 if( ldifFile->file ) fclose( ldifFile->file );
185 /* Free internal stuff */
186 g_free( ldifFile->path );
188 /* Free field list */
189 g_hash_table_foreach_remove( ldifFile->hashFields, ldif_hash_free_vis, NULL );
190 g_hash_table_destroy( ldifFile->hashFields );
191 ldifFile->hashFields = NULL;
194 ldifFile->file = NULL;
195 ldifFile->path = NULL;
196 ldifFile->retVal = MGU_SUCCESS;
197 ldifFile->tempList = NULL;
198 ldifFile->dirtyFlag = FALSE;
199 ldifFile->accessFlag = FALSE;
200 ldifFile->cbProgress = NULL;
202 /* Now release file object */
207 * Open file for read.
208 * \param ldifFile LDIF import control object.
209 * \return <i>TRUE</i> if file opened successfully.
211 static gint ldif_open_file( LdifFile* ldifFile ) {
212 /* g_print( "Opening file\n" ); */
213 if( ldifFile->path ) {
214 ldifFile->file = g_fopen( ldifFile->path, "rb" );
215 if( ! ldifFile->file ) {
216 /* g_print( "can't open %s\n", ldifFile->path ); */
217 ldifFile->retVal = MGU_OPEN_FILE;
218 return ldifFile->retVal;
222 /* g_print( "file not specified\n" ); */
223 ldifFile->retVal = MGU_NO_FILE;
224 return ldifFile->retVal;
227 /* Setup a buffer area */
228 ldifFile->retVal = MGU_SUCCESS;
229 return ldifFile->retVal;
234 * \param ldifFile LDIF import control object.
236 static void ldif_close_file( LdifFile *ldifFile ) {
237 cm_return_if_fail( ldifFile != NULL );
238 if( ldifFile->file ) fclose( ldifFile->file );
239 ldifFile->file = NULL;
243 * Read line of text from file.
244 * \param ldifFile LDIF import control object.
245 * \return ptr to buffer where line starts.
247 static gchar *ldif_get_line( LdifFile *ldifFile ) {
248 gchar *buf = g_malloc(LDIFBUFSIZE);
251 int cur_alloc = LDIFBUFSIZE;
253 if( feof( ldifFile->file ) ) {
258 while( i < cur_alloc-1 ) {
259 ch = fgetc( ldifFile->file );
260 if (ferror( ldifFile->file ))
261 ldifFile->retVal = MGU_ERROR_READ;
262 if( ch == '\0' || ch == EOF ) {
263 if( i == 0 ) return NULL;
266 #if HAVE_DOSISH_SYSTEM
275 if (i == cur_alloc-1 && cur_alloc < LDIFBUFSIZE * 32) {
276 cur_alloc += LDIFBUFSIZE;
277 buf = g_realloc(buf, cur_alloc);
282 /* Return a copy of buffer */
283 return g_strdup( buf );
287 * Parse tag name from line buffer.
288 * \param line Buffer.
289 * \param flag64 Base-64 encoder flag.
290 * \return Buffer containing the tag name, or NULL if no delimiter char found.
291 * If a double delimiter (::) is found, flag64 is set.
293 static gchar *ldif_get_tagname( char* line, gboolean *flag64 ) {
300 /* Check for language tag */
301 if( *lptr == LDIF_LANG_TAG ) {
302 if( sptr == NULL ) sptr = lptr;
305 /* Check for delimiter */
306 if( *lptr == LDIF_SEP_TAG ) {
314 /* Base-64 encoding? */
315 if( * ++lptr == LDIF_SEP_TAG ) *flag64 = TRUE;
317 tag = g_strndup( line, len+1 );
326 * Parse tag value from line buffer.
327 * \param line Buffer.
328 * \return Buffer containing the tag value. Empty string is returned if
329 * no delimiter char found.
331 static gchar *ldif_get_tagvalue( gchar* line ) {
337 for( lptr = line; *lptr; lptr++ ) {
338 if( *lptr == LDIF_SEP_TAG ) {
344 if( *start == LDIF_SEP_TAG ) start++;
346 value = g_strndup( start, len+1 );
350 /* Ensure that we get an empty string */
351 value = g_strndup( "", 1 );
358 * Parsed address data record.
360 typedef struct _Ldif_ParsedRec_ Ldif_ParsedRec;
361 struct _Ldif_ParsedRec_ {
372 * User attribute data record.
374 typedef struct _Ldif_UserAttr_ Ldif_UserAttr;
375 struct _Ldif_UserAttr_ {
381 * Build an address list entry and append to list of address items in the
382 * address cache. Name is formatted as "<first-name> <last-name>".
383 * \param ldifFile LDIF import control object.
384 * \param rec LDIF field object.
385 * \param cache Address cache to be populated with data.
387 static void ldif_build_items(
388 LdifFile *ldifFile, Ldif_ParsedRec *rec, AddressCache *cache )
393 gchar *firstName = NULL, *lastName = NULL, *fullName = NULL;
394 gchar *nickName = NULL;
395 gint iLen = 0, iLenT = 0;
399 nodeAddress = rec->listAddress;
400 // if( nodeAddress == NULL ) return;
402 /* Find longest first name in list */
403 nodeFirst = rec->listFName;
405 if( firstName == NULL ) {
406 firstName = nodeFirst->data;
407 iLen = strlen( firstName );
410 if( ( iLenT = strlen( nodeFirst->data ) ) > iLen ) {
411 firstName = nodeFirst->data;
415 nodeFirst = g_slist_next( nodeFirst );
419 if( rec->listLName ) {
420 lastName = rec->listLName->data;
425 fullName = g_strdup_printf(
426 "%s %s", firstName, lastName );
429 fullName = g_strdup_printf( "%s", firstName );
434 fullName = g_strdup_printf( "%s", lastName );
438 if (!fullName || strlen(fullName) == 0) {
442 fullName = g_strdup(rec->listCName->data);
446 g_strchug( fullName ); g_strchomp( fullName );
449 if( rec->listNName ) {
450 nickName = rec->listNName->data;
453 person = addritem_create_item_person();
454 addritem_person_set_common_name( person, fullName );
455 addritem_person_set_first_name( person, firstName );
456 addritem_person_set_last_name( person, lastName );
457 addritem_person_set_nick_name( person, nickName );
458 addrcache_id_person( cache, person );
459 addrcache_add_person( cache, person );
460 ++ldifFile->importCount;
462 /* Add address item */
463 while( nodeAddress ) {
464 email = addritem_create_item_email();
465 addritem_email_set_address( email, nodeAddress->data );
466 addrcache_id_email( cache, email );
467 addrcache_person_add_email( cache, person, email );
468 nodeAddress = g_slist_next( nodeAddress );
471 fullName = firstName = lastName = NULL;
473 /* Add user attributes */
474 nodeAttr = rec->userAttr;
476 Ldif_UserAttr *attr = nodeAttr->data;
477 UserAttribute *attrib = addritem_create_attribute();
478 addritem_attrib_set_name( attrib, attr->name );
479 addritem_attrib_set_value( attrib, attr->value );
480 addritem_person_add_attribute( person, attrib );
481 nodeAttr = g_slist_next( nodeAttr );
487 * Add selected field as user attribute.
488 * \param rec LDIF field object.
489 * \param tagName LDIF tag name.
490 * \param tagValue Data value.
491 * \param hashField Hash table to populate.
493 static void ldif_add_user_attr(
494 Ldif_ParsedRec *rec, gchar *tagName, gchar *tagValue,
495 GHashTable *hashField )
497 Ldif_FieldRec *fld = NULL;
498 Ldif_UserAttr *attr = NULL;
501 fld = g_hash_table_lookup( hashField, tagName );
503 if( ! fld->selected ) return;
506 if( fld->userName ) {
507 name = fld->userName;
509 attr = g_new0( Ldif_UserAttr, 1 );
510 attr->name = g_strdup( name );
511 attr->value = g_strdup( tagValue );
512 rec->userAttr = g_slist_append( rec->userAttr, attr );
517 * Add value to parsed data.
518 * \param rec LDIF field object.
519 * \param tagName LDIF tag name.
520 * \param tagValue Data value.
521 * \param hashField Hash table to populate.
523 static void ldif_add_value(
524 Ldif_ParsedRec *rec, gchar *tagName, gchar *tagValue,
525 GHashTable *hashField )
529 nm = g_utf8_strdown( tagName, -1 );
531 val = g_strdup( tagValue );
534 val = g_strdup( "" );
538 if( g_utf8_collate( nm, g_utf8_strdown( LDIF_TAG_COMMONNAME, -1 ) ) == 0 ) {
539 rec->listCName = g_slist_append( rec->listCName, val );
541 else if( g_utf8_collate( nm, g_utf8_strdown( LDIF_TAG_FIRSTNAME, -1 ) ) == 0 ) {
542 rec->listFName = g_slist_append( rec->listFName, val );
544 else if( g_utf8_collate( nm, g_utf8_strdown( LDIF_TAG_LASTNAME, -1 ) ) == 0 ) {
545 rec->listLName = g_slist_append( rec->listLName, val );
547 else if( g_utf8_collate( nm, g_utf8_strdown( LDIF_TAG_NICKNAME, -1 ) ) == 0 ) {
548 rec->listNName = g_slist_append( rec->listNName, val );
550 else if( g_utf8_collate( nm, g_utf8_strdown( LDIF_TAG_EMAIL, -1 ) ) == 0 ) {
551 rec->listAddress = g_slist_append( rec->listAddress, val );
554 /* Add field as user attribute */
555 ldif_add_user_attr( rec, tagName, tagValue, hashField );
561 * Clear parsed data record.
562 * \param rec LDIF field object.
564 static void ldif_clear_rec( Ldif_ParsedRec *rec ) {
567 /* Free up user attributes */
568 list = rec->userAttr;
570 Ldif_UserAttr *attr = list->data;
571 g_free( attr->name );
572 g_free( attr->value );
574 list = g_slist_next( list );
576 g_slist_free( rec->userAttr );
578 g_slist_free( rec->listCName );
579 g_slist_free( rec->listFName );
580 g_slist_free( rec->listLName );
581 g_slist_free( rec->listNName );
582 g_slist_free( rec->listAddress );
583 g_slist_free( rec->listID );
585 rec->userAttr = NULL;
586 rec->listCName = NULL;
587 rec->listFName = NULL;
588 rec->listLName = NULL;
589 rec->listNName = NULL;
590 rec->listAddress = NULL;
595 * Read file data into address cache.
596 * Note that one LDIF record identifies one entity uniquely with the
597 * distinguished name (dn) tag. Each person can have multiple E-Mail
598 * addresses. Also, each person can have many common name (cn) tags.
600 * \param ldifFile LDIF import control object.
601 * \param cache Address cache to be populated with data.
603 static void ldif_read_file( LdifFile *ldifFile, AddressCache *cache ) {
604 gchar *tagName = NULL, *tagValue = NULL;
605 gchar *lastTag = NULL, *fullValue = NULL;
606 GSList *listValue = NULL;
607 gboolean flagEOF = FALSE, flagEOR = FALSE;
608 gboolean flag64 = FALSE, last64 = FALSE;
612 GHashTable *hashField;
614 hashField = ldifFile->hashFields;
615 rec = g_new0( Ldif_ParsedRec, 1 );
616 ldif_clear_rec( rec );
618 /* Find EOF for progress indicator */
619 fseek( ldifFile->file, 0L, SEEK_END );
620 posEnd = ftell( ldifFile->file );
621 fseek( ldifFile->file, 0L, SEEK_SET );
624 gchar *line = ldif_get_line( ldifFile );
626 posCur = ftell( ldifFile->file );
627 if( ldifFile->cbProgress ) {
628 /* Call progress indicator */
629 ( ldifFile->cbProgress ) ( ldifFile, & posEnd, & posCur );
634 flagEOF = flagEOR = TRUE;
636 else if( *line == '\0' ) {
641 /* EOR, Output address data */
644 fullValue = mgu_list_coalesce( listValue );
645 if (fullValue && last64) {
646 gchar *out = g_malloc(strlen(fullValue));
648 if ((len = base64_decode(out, fullValue,
649 strlen(fullValue))) >= 0) {
652 fullValue[len] = '\0';
656 /* Base-64 encoded data */
659 ldif_dump_b64( fullValue );
663 ldif_add_value( rec, lastTag, fullValue, hashField );
664 /* ldif_print_record( rec, stdout ); */
665 ldif_build_items( ldifFile, rec, cache );
666 ldif_clear_rec( rec );
668 mgu_free_list( listValue );
677 /* Continuation line */
678 listValue = g_slist_append(
679 listValue, g_strdup( line+1 ) );
681 else if( *line == '=' ) {
682 /* Base-64 encoded continuation field */
683 listValue = g_slist_append(
684 listValue, g_strdup( line ) );
688 tagName = ldif_get_tagname( line, &flag64 );
690 tagValue = ldif_get_tagvalue( line );
695 mgu_list_coalesce( listValue );
696 if (fullValue && last64) {
697 gchar *out = g_malloc(strlen(fullValue));
699 if ((len = base64_decode(out, fullValue,
700 strlen(fullValue))) >= 0) {
703 fullValue[len] = '\0';
707 /* Base-64 encoded data */
710 ldif_dump_b64( fullValue );
715 rec, lastTag, fullValue,
718 mgu_free_list( listValue );
723 lastTag = g_strdup( tagName );
724 listValue = g_slist_append(
726 g_strdup( tagValue ) );
738 ldif_clear_rec( rec );
741 mgu_free_list( listValue );
745 * Add list of field names to hash table.
746 * \param table Hashtable.
747 * \param list List of fields.
749 static void ldif_hash_add_list( GHashTable *table, GSList *list ) {
752 /* mgu_print_list( list, stdout ); */
754 gchar *tag = node->data;
755 if( ! g_hash_table_lookup( table, tag ) ) {
756 Ldif_FieldRec *rec = NULL;
757 gchar *key = g_utf8_strdown( tag, -1 );
759 rec = ldif_create_fieldrec( tag );
760 if( g_utf8_collate( key, LDIF_TAG_DN ) == 0 ) {
761 rec->reserved = rec->selected = TRUE;
762 rec->userName = g_strdup( "dn" );
764 else if( g_utf8_collate( key, g_utf8_strdown( LDIF_TAG_COMMONNAME, -1 ) ) == 0 ) {
765 rec->reserved = rec->selected = TRUE;
766 rec->userName = g_strdup( _( "Display Name" ) );
768 else if( g_utf8_collate( key, g_utf8_strdown( LDIF_TAG_FIRSTNAME, -1 ) ) == 0 ) {
769 rec->reserved = rec->selected = TRUE;
770 rec->userName = g_strdup( _( "First Name" ) );
772 else if( g_utf8_collate( key, g_utf8_strdown( LDIF_TAG_LASTNAME, -1 ) ) == 0 ) {
773 rec->reserved = rec->selected = TRUE;
774 rec->userName = g_strdup( _( "Last Name" ) );
776 else if( g_utf8_collate( key, g_utf8_strdown( LDIF_TAG_NICKNAME, -1 ) ) == 0 ) {
777 rec->reserved = rec->selected = TRUE;
778 rec->userName = g_strdup( _( "Nick Name" ) );
780 else if( g_utf8_collate( key, g_utf8_strdown( LDIF_TAG_EMAIL, -1 ) ) == 0 ) {
781 rec->reserved = rec->selected = TRUE;
782 rec->userName = g_strdup( _( "Email Address" ) );
784 g_hash_table_insert( table, key, rec );
786 node = g_slist_next( node );
791 * Sorted list comparison function.
792 * \param ptr1 First field.
793 * \param ptr2 Second field.
794 * \return <code>-1, 0, +1</code> if first record less than, equal,
795 * greater than second.
797 static gint ldif_field_compare( gconstpointer ptr1, gconstpointer ptr2 ) {
798 const Ldif_FieldRec *rec1 = ptr1;
799 const Ldif_FieldRec *rec2 = ptr2;
801 if( rec1->reserved ) {
802 if( ! rec2->reserved ) {
807 if( rec2->reserved ) {
811 return g_utf8_collate( rec1->tagName, rec2->tagName );
815 * Append hash table entry to list - visitor function.
817 * \param value Data value.
818 * \param data User data (the LDIF import control object).
820 static void ldif_hash2list_vis( gpointer key, gpointer value, gpointer data ) {
821 LdifFile *ldf = data;
823 g_list_insert_sorted( ldf->tempList, value, ldif_field_compare );
827 * Read tag names for file data.
828 * \param ldifFile LDIF import control object.
830 static void ldif_read_tag_list( LdifFile *ldifFile ) {
831 gchar *tagName = NULL;
832 GSList *listTags = NULL;
833 gboolean flagEOF = FALSE, flagEOR = FALSE, flagMail = FALSE;
834 gboolean flag64 = FALSE;
838 /* Clear hash table */
839 g_hash_table_foreach_remove(
840 ldifFile->hashFields, ldif_hash_free_vis, NULL );
842 /* Find EOF for progress indicator */
843 fseek( ldifFile->file, 0L, SEEK_END );
844 posEnd = ftell( ldifFile->file );
845 fseek( ldifFile->file, 0L, SEEK_SET );
848 ldifFile->retVal = MGU_EOF;
854 gchar *line = ldif_get_line( ldifFile );
855 posCur = ftell( ldifFile->file );
856 if( ldifFile->cbProgress ) {
857 /* Call progress indicator */
858 ( ldifFile->cbProgress ) ( ldifFile, & posEnd, & posCur );
863 flagEOF = flagEOR = TRUE;
865 else if( *line == '\0' ) {
870 /* EOR, Output address data */
871 /* Save field list to hash table */
874 ldifFile->hashFields, listTags );
876 mgu_free_list( listTags );
883 /* Continuation line */
885 else if( *line == '=' ) {
886 /* Base-64 encoded continuation field */
890 tagName = ldif_get_tagname( line, &flag64 );
892 /* Add tag to list */
893 listTags = g_slist_append( listTags, tagName );
896 tagName, LDIF_TAG_EMAIL ) == 0 )
903 debug_print("ldif: bad format: '%s'\n", line);
904 ldifFile->retVal = MGU_BAD_FORMAT;
913 mgu_free_list( listTags );
918 * Read file into list. Main entry point
919 * \param ldifFile LDIF import control object.
920 * \param cache Address cache to load.
921 * \return Status code.
923 gint ldif_import_data( LdifFile *ldifFile, AddressCache *cache ) {
924 cm_return_val_if_fail( ldifFile != NULL, MGU_BAD_ARGS );
925 ldifFile->retVal = MGU_SUCCESS;
926 addrcache_clear( cache );
927 cache->dataRead = FALSE;
928 ldif_open_file( ldifFile );
929 if( ldifFile->retVal == MGU_SUCCESS ) {
930 /* Read data into the cache */
931 ldif_read_file( ldifFile, cache );
932 ldif_close_file( ldifFile );
935 cache->modified = FALSE;
936 cache->dataRead = TRUE;
938 return ldifFile->retVal;
942 * Process entire file reading list of unique fields. List of fields may be
943 * accessed with the <code>ldif_get_fieldlist()</code> function.
944 * \param ldifFile LDIF import control object.
945 * \return Status code.
947 gint ldif_read_tags( LdifFile *ldifFile ) {
948 cm_return_val_if_fail( ldifFile != NULL, MGU_BAD_ARGS );
949 ldifFile->retVal = MGU_SUCCESS;
950 if( ldifFile->dirtyFlag ) {
951 ldif_open_file( ldifFile );
952 if( ldifFile->retVal == MGU_SUCCESS ) {
953 /* Read data into the cache */
954 ldif_read_tag_list( ldifFile );
955 ldif_close_file( ldifFile );
956 ldifFile->dirtyFlag = FALSE;
957 ldifFile->accessFlag = TRUE;
960 return ldifFile->retVal;
964 * Return list of fields for LDIF file.
965 * \param ldifFile LDIF import control object.
966 * \return Linked list of <code>Ldif_FieldRec</code> objects. This list may be
967 * <code>g_free()</code>. Note that the objects in the list should not
968 * be freed since they refer to objects inside the internal cache.
969 * These objects will be freed when LDIF file object is freed.
971 GList *ldif_get_fieldlist( LdifFile *ldifFile ) {
974 cm_return_val_if_fail( ldifFile != NULL, NULL );
975 if( ldifFile->hashFields ) {
976 ldifFile->tempList = NULL;
977 g_hash_table_foreach( ldifFile->hashFields, ldif_hash2list_vis, ldifFile );
978 list = ldifFile->tempList;
979 ldifFile->tempList = NULL;
985 * Output LDIF name-value pair to stream. Only non-empty names and values will
987 * \param stream File output stream.
989 * \param value Data value.
990 * \return <i>TRUE</i> if data output.
992 gboolean ldif_write_value( FILE *stream, const gchar *name, const gchar *value ) {
993 if( name == NULL ) return FALSE;
994 if( value == NULL ) return FALSE;
995 if( strlen( name ) < 1 ) return FALSE;
996 if( strlen( value ) < 1 ) return FALSE;
997 fprintf( stream, "%s: ", name );
998 fprintf( stream, "%s\n", value );
1003 * Output LDIF End of Record to stream.
1004 * \param stream File output stream.
1005 * \return <i>TRUE</i> if data output.
1007 void ldif_write_eor( FILE *stream ) {
1008 /* Simple but caller should not need to know how to end record. */
1009 fprintf( stream, "\n" );
1013 * ============================================================================
1015 * ============================================================================