2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001 Match Grun
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 2 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, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Functions necessary to access LDIF files (LDAP Data Interchange Format files).
30 #include "addrcache.h"
33 * Create new cardfile object.
35 LdifFile *ldif_create() {
37 ldifFile = g_new0( LdifFile, 1 );
38 ldifFile->path = NULL;
39 ldifFile->file = NULL;
40 ldifFile->bufptr = ldifFile->buffer;
41 ldifFile->retVal = MGU_SUCCESS;
48 void ldif_set_file( LdifFile* ldifFile, const gchar *value ) {
49 g_return_if_fail( ldifFile != NULL );
50 ldifFile->path = mgu_replace_string( ldifFile->path, value );
51 g_strstrip( ldifFile->path );
55 * Free up cardfile object by releasing internal memory.
57 void ldif_free( LdifFile *ldifFile ) {
58 g_return_if_fail( ldifFile != NULL );
61 if( ldifFile->file ) fclose( ldifFile->file );
63 /* Free internal stuff */
64 g_free( ldifFile->path );
67 ldifFile->file = NULL;
68 ldifFile->path = NULL;
69 ldifFile->retVal = MGU_SUCCESS;
71 /* Now release file object */
77 * Display object to specified stream.
79 void ldif_print_file( LdifFile *ldifFile, FILE *stream ) {
80 g_return_if_fail( ldifFile != NULL );
81 fprintf( stream, "LDIF File:\n" );
82 fprintf( stream, "file spec: '%s'\n", ldifFile->path );
83 fprintf( stream, " ret val: %d\n", ldifFile->retVal );
88 * return: TRUE if file opened successfully.
90 static gint ldif_open_file( LdifFile* ldifFile ) {
91 /* printf( "Opening file\n" ); */
92 if( ldifFile->path ) {
93 ldifFile->file = fopen( ldifFile->path, "r" );
94 if( ! ldifFile->file ) {
95 /* printf( "can't open %s\n", ldifFile->path ); */
96 ldifFile->retVal = MGU_OPEN_FILE;
97 return ldifFile->retVal;
101 /* printf( "file not specified\n" ); */
102 ldifFile->retVal = MGU_NO_FILE;
103 return ldifFile->retVal;
106 /* Setup a buffer area */
107 ldifFile->buffer[0] = '\0';
108 ldifFile->bufptr = ldifFile->buffer;
109 ldifFile->retVal = MGU_SUCCESS;
110 return ldifFile->retVal;
116 static void ldif_close_file( LdifFile *ldifFile ) {
117 g_return_if_fail( ldifFile != NULL );
118 if( ldifFile->file ) fclose( ldifFile->file );
119 ldifFile->file = NULL;
123 * Read line of text from file.
124 * Return: ptr to buffer where line starts.
126 static gchar *ldif_get_line( LdifFile *ldifFile ) {
127 gchar buf[ LDIFBUFSIZE ];
131 if( feof( ldifFile->file ) ) return NULL;
136 ch = fgetc( ldifFile->file );
137 if( ch == '\0' || ch == EOF ) {
138 if( *buf == '\0' ) return NULL;
141 if( ch == '\n' ) break;
146 /* Copy into private buffer */
147 return g_strdup( buf );
151 * Parse tag name from line buffer.
152 * Return: Buffer containing the tag name, or NULL if no delimiter char found.
154 static gchar *ldif_get_tagname( char* line, gchar dlm ) {
161 tag = g_strndup( line, len+1 );
171 * Parse tag value from line buffer.
172 * Return: Buffer containing the tag value. Empty string is returned if
173 * no delimiter char found.
175 static gchar *ldif_get_tagvalue( gchar* line, gchar dlm ) {
181 for( lptr = line; *lptr; lptr++ ) {
189 value = g_strndup( start, len+1 );
192 /* Ensure that we get an empty string */
193 value = g_strndup( "", 1 );
200 * Dump linked lists of character strings (for debug).
202 static void ldif_dump_lists( GSList *listName, GSList *listAddr, GSList *listRem, GSList *listID, FILE *stream ) {
203 fprintf( stream, "dump name\n" );
204 fprintf( stream, "------------\n" );
205 mgu_print_list( listName, stdout );
206 fprintf( stream, "dump address\n" );
207 fprintf( stream, "------------\n" );
208 mgu_print_list( listAddr, stdout );
209 fprintf( stream, "dump remarks\n" );
210 fprintf( stdout, "------------\n" );
211 mgu_print_list( listRem, stdout );
212 fprintf( stream, "dump id\n" );
213 fprintf( stdout, "------------\n" );
214 mgu_print_list( listID, stdout );
217 typedef struct _Ldif_ParsedRec_ Ldif_ParsedRec;
218 struct _Ldif_ParsedRec_ {
228 * Build an address list entry and append to list of address items. Name is formatted
229 * as "<first-name> <last-name>".
231 static void ldif_build_items( LdifFile *ldifFile, Ldif_ParsedRec *rec, AddressCache *cache ) {
234 gchar *firstName = NULL, *lastName = NULL, *fullName = NULL, *nickName = NULL;
235 gint iLen = 0, iLenT = 0;
239 nodeAddress = rec->listAddress;
240 if( nodeAddress == NULL ) return;
242 /* Find longest first name in list */
243 nodeFirst = rec->listFName;
245 if( firstName == NULL ) {
246 firstName = nodeFirst->data;
247 iLen = strlen( firstName );
250 if( ( iLenT = strlen( nodeFirst->data ) ) > iLen ) {
251 firstName = nodeFirst->data;
255 nodeFirst = g_slist_next( nodeFirst );
259 if( rec->listLName ) {
260 lastName = rec->listLName->data;
265 fullName = g_strdup_printf( "%s %s", firstName, lastName );
268 fullName = g_strdup_printf( "%s", firstName );
273 fullName = g_strdup_printf( "%s", lastName );
277 g_strchug( fullName ); g_strchomp( fullName );
280 if( rec->listNName ) {
281 nickName = rec->listNName->data;
284 person = addritem_create_item_person();
285 addritem_person_set_common_name( person, fullName );
286 addritem_person_set_first_name( person, firstName );
287 addritem_person_set_last_name( person, lastName );
288 addritem_person_set_nick_name( person, nickName );
289 addrcache_id_person( cache, person );
290 addrcache_add_person( cache, person );
292 /* Add address item */
293 while( nodeAddress ) {
294 email = addritem_create_item_email();
295 addritem_email_set_address( email, nodeAddress->data );
296 addrcache_id_email( cache, email );
297 addrcache_person_add_email( cache, person, email );
298 nodeAddress = g_slist_next( nodeAddress );
301 fullName = firstName = lastName = NULL;
305 static void ldif_add_value( Ldif_ParsedRec *rec, gchar *tagName, gchar *tagValue ) {
308 nm = g_strdup( tagName );
311 val = g_strdup( tagValue );
314 val = g_strdup( "" );
317 if( strcmp( nm, LDIF_TAG_COMMONNAME ) == 0 ) {
318 rec->listCName = g_slist_append( rec->listCName, val );
320 else if( strcmp( nm, LDIF_TAG_FIRSTNAME ) == 0 ) {
321 rec->listFName = g_slist_append( rec->listFName, val );
323 else if( strcmp( nm, LDIF_TAG_LASTNAME ) == 0 ) {
324 rec->listLName = g_slist_append( rec->listLName, val );
326 else if( strcmp( nm, LDIF_TAG_NICKNAME ) == 0 ) {
327 rec->listNName = g_slist_append( rec->listNName, val );
329 else if( strcmp( nm, LDIF_TAG_EMAIL ) == 0 ) {
330 rec->listAddress = g_slist_append( rec->listAddress, val );
335 static void ldif_clear_rec( Ldif_ParsedRec *rec ) {
336 g_slist_free( rec->listCName );
337 g_slist_free( rec->listFName );
338 g_slist_free( rec->listLName );
339 g_slist_free( rec->listNName );
340 g_slist_free( rec->listAddress );
341 g_slist_free( rec->listID );
342 rec->listCName = NULL;
343 rec->listFName = NULL;
344 rec->listLName = NULL;
345 rec->listNName = NULL;
346 rec->listAddress = NULL;
350 static void ldif_print_record( Ldif_ParsedRec *rec, FILE *stream ) {
351 fprintf( stdout, "LDIF Parsed Record:\n" );
352 fprintf( stdout, "common name:" );
353 mgu_print_list( rec->listCName, stdout );
354 if( ! rec->listCName ) fprintf( stdout, "\n" );
355 fprintf( stdout, "first name:" );
356 mgu_print_list( rec->listFName, stdout );
357 if( ! rec->listFName ) fprintf( stdout, "\n" );
358 fprintf( stdout, "last name:" );
359 mgu_print_list( rec->listLName, stdout );
360 if( ! rec->listLName ) fprintf( stdout, "\n" );
361 fprintf( stdout, "nick name:" );
362 mgu_print_list( rec->listNName, stdout );
363 if( ! rec->listNName ) fprintf( stdout, "\n" );
364 fprintf( stdout, "address:" );
365 mgu_print_list( rec->listAddress, stdout );
366 if( ! rec->listAddress ) fprintf( stdout, "\n" );
367 fprintf( stdout, "id:" );
368 mgu_print_list( rec->listID, stdout );
369 if( ! rec->listID ) fprintf( stdout, "\n" );
373 * Read file data into address cache.
374 * Note that one LDIF record identifies one entity uniquely with the
375 * distinguished name (dn) tag. Each person can have multiple E-Mail
376 * addresses. Also, each person can have many common name (cn) tags.
378 static void ldif_read_file( LdifFile *ldifFile, AddressCache *cache ) {
379 gchar *tagName = NULL, *tagValue = NULL;
380 gchar *lastTag = NULL, *fullValue = NULL;
381 GSList *listValue = NULL;
382 gboolean flagEOF = FALSE, flagEOR = FALSE;
385 rec = g_new0( Ldif_ParsedRec, 1 );
386 ldif_clear_rec( rec );
389 gchar *line = ldif_get_line( ldifFile );
391 flagEOF = flagEOR = TRUE;
393 else if( *line == '\0' ) {
398 /* EOR, Output address data */
401 fullValue = mgu_list_coalesce( listValue );
402 ldif_add_value( rec, lastTag, fullValue );
403 /* ldif_print_record( rec, stdout ); */
404 ldif_build_items( ldifFile, rec, cache );
405 ldif_clear_rec( rec );
407 mgu_free_list( listValue );
415 /* Continuation line */
416 listValue = g_slist_append( listValue, g_strdup( line+1 ) );
418 else if( *line == '=' ) {
419 /* Base-64 binary encode field */
420 listValue = g_slist_append( listValue, g_strdup( line ) );
424 tagName = ldif_get_tagname( line, LDIF_SEP_TAG );
426 tagValue = ldif_get_tagvalue( line, LDIF_SEP_TAG );
430 fullValue = mgu_list_coalesce( listValue );
431 ldif_add_value( rec, lastTag, fullValue );
433 mgu_free_list( listValue );
438 lastTag = g_strdup( tagName );
439 listValue = g_slist_append( listValue, g_strdup( tagValue ) );
450 ldif_clear_rec( rec );
453 mgu_free_list( listValue );
457 // ============================================================================================
459 * Read file into list. Main entry point
460 * Enter: ldifFile LDIF control data.
461 * cache Address cache to load.
462 * Return: Status code.
464 // ============================================================================================
465 gint ldif_import_data( LdifFile *ldifFile, AddressCache *cache ) {
466 g_return_val_if_fail( ldifFile != NULL, MGU_BAD_ARGS );
467 ldifFile->retVal = MGU_SUCCESS;
468 addrcache_clear( cache );
469 cache->dataRead = FALSE;
470 ldif_open_file( ldifFile );
471 if( ldifFile->retVal == MGU_SUCCESS ) {
472 /* Read data into the cache */
473 ldif_read_file( ldifFile, cache );
474 ldif_close_file( ldifFile );
477 cache->modified = FALSE;
478 cache->dataRead = TRUE;
480 return ldifFile->retVal;