Statistics
| Revision:

root / src / ldif.c @ 901

History | View | Annotate | Download (22.9 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 1 hiro
 * Copyright (C) 2001 Match Grun
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
/*
21 1 hiro
 * Functions necessary to access LDIF files (LDAP Data Interchange Format
22 1 hiro
 * files).
23 1 hiro
 */
24 1 hiro
25 1 hiro
#include <glib.h>
26 1 hiro
#include <string.h>
27 1 hiro
#include <sys/stat.h>
28 1 hiro
29 1 hiro
#include "mgutils.h"
30 1 hiro
#include "ldif.h"
31 1 hiro
#include "addritem.h"
32 1 hiro
#include "addrcache.h"
33 1 hiro
34 1 hiro
#include "base64.h"
35 478 hiro
#include "utils.h"
36 1 hiro
37 1 hiro
/*
38 1 hiro
* Create new object.
39 1 hiro
*/
40 1 hiro
LdifFile *ldif_create() {
41 1 hiro
        LdifFile *ldifFile;
42 1 hiro
        ldifFile = g_new0( LdifFile, 1 );
43 1 hiro
        ldifFile->path = NULL;
44 1 hiro
        ldifFile->file = NULL;
45 1 hiro
        ldifFile->bufptr = ldifFile->buffer;
46 1 hiro
        ldifFile->hashFields = g_hash_table_new( g_str_hash, g_str_equal );
47 1 hiro
        ldifFile->tempList = NULL;
48 1 hiro
        ldifFile->dirtyFlag = TRUE;
49 1 hiro
        ldifFile->accessFlag = FALSE;
50 1 hiro
        ldifFile->retVal = MGU_SUCCESS;
51 1 hiro
        ldifFile->cbProgress = NULL;
52 1 hiro
        ldifFile->importCount = 0;
53 1 hiro
        return ldifFile;
54 1 hiro
}
55 1 hiro
56 1 hiro
/*
57 1 hiro
* Properties...
58 1 hiro
*/
59 1 hiro
void ldif_set_file( LdifFile *ldifFile, const gchar *value ) {
60 1 hiro
        g_return_if_fail( ldifFile != NULL );
61 1 hiro
62 1 hiro
        if( ldifFile->path ) {
63 1 hiro
                if( strcmp( ldifFile->path, value ) != 0 )
64 1 hiro
                        ldifFile->dirtyFlag = TRUE;
65 1 hiro
        }
66 1 hiro
        else {
67 1 hiro
                ldifFile->dirtyFlag = TRUE;
68 1 hiro
        }
69 1 hiro
        ldifFile->path = mgu_replace_string( ldifFile->path, value );
70 1 hiro
        g_strstrip( ldifFile->path );
71 1 hiro
        ldifFile->importCount = 0;
72 1 hiro
}
73 1 hiro
void ldif_set_accessed( LdifFile *ldifFile, const gboolean value ) {
74 1 hiro
        g_return_if_fail( ldifFile != NULL );
75 1 hiro
        ldifFile->accessFlag = value;
76 1 hiro
}
77 1 hiro
78 1 hiro
/*
79 1 hiro
* Register a callback function. When called, the function will be passed
80 1 hiro
* the following arguments:
81 1 hiro
*        LdifFile object,
82 1 hiro
*        File size (long),
83 1 hiro
*        Current position (long)
84 1 hiro
* This can be used for a progress indicator.
85 1 hiro
*/
86 1 hiro
void ldif_set_callback( LdifFile *ldifFile, void *func ) {
87 1 hiro
        ldifFile->cbProgress = func;
88 1 hiro
}
89 1 hiro
90 1 hiro
/*
91 1 hiro
* Create field record object.
92 1 hiro
*/
93 1 hiro
static Ldif_FieldRec *ldif_create_fieldrec( gchar *field ) {
94 1 hiro
        Ldif_FieldRec *rec = g_new0( Ldif_FieldRec, 1 );
95 1 hiro
        rec->tagName = g_strdup( field );
96 1 hiro
        rec->userName = NULL;
97 1 hiro
        rec->reserved = FALSE;
98 1 hiro
        rec->selected = FALSE;
99 1 hiro
        return rec;
100 1 hiro
}
101 1 hiro
102 1 hiro
/*
103 1 hiro
* Free field record object.
104 1 hiro
*/
105 1 hiro
static void ldif_free_fieldrec( Ldif_FieldRec *rec ) {
106 1 hiro
        if( rec ) {
107 1 hiro
                g_free( rec->tagName );
108 1 hiro
                g_free( rec->userName );
109 1 hiro
                rec->tagName = NULL;
110 1 hiro
                rec->userName = NULL;
111 1 hiro
                rec->reserved = FALSE;
112 1 hiro
                rec->selected = FALSE;
113 1 hiro
                g_free( rec );
114 1 hiro
        }
115 1 hiro
}
116 1 hiro
117 1 hiro
/*
118 1 hiro
* Free hash table entry visitor function.
119 1 hiro
*/
120 1 hiro
static gint ldif_hash_free_vis( gpointer key, gpointer value, gpointer data ) {
121 1 hiro
        ldif_free_fieldrec( ( Ldif_FieldRec * ) value );
122 1 hiro
        value = NULL;
123 1 hiro
        key = NULL;
124 1 hiro
        return -1;
125 1 hiro
}
126 1 hiro
127 1 hiro
/*
128 1 hiro
* Free up object by releasing internal memory.
129 1 hiro
*/
130 1 hiro
void ldif_free( LdifFile *ldifFile ) {
131 1 hiro
        g_return_if_fail( ldifFile != NULL );
132 1 hiro
133 1 hiro
        /* Close file */
134 1 hiro
        if( ldifFile->file ) fclose( ldifFile->file );
135 1 hiro
136 1 hiro
        /* Free internal stuff */
137 1 hiro
        g_free( ldifFile->path );
138 1 hiro
139 1 hiro
        /* Free field list */
140 1 hiro
        g_hash_table_foreach_remove( ldifFile->hashFields, ldif_hash_free_vis, NULL );
141 1 hiro
        g_hash_table_destroy( ldifFile->hashFields );
142 1 hiro
        ldifFile->hashFields = NULL;
143 1 hiro
144 1 hiro
        /* Clear pointers */
145 1 hiro
        ldifFile->file = NULL;
146 1 hiro
        ldifFile->path = NULL;
147 1 hiro
        ldifFile->retVal = MGU_SUCCESS;
148 1 hiro
        ldifFile->tempList = NULL;
149 1 hiro
        ldifFile->dirtyFlag = FALSE;
150 1 hiro
        ldifFile->accessFlag = FALSE;
151 1 hiro
        ldifFile->cbProgress = NULL;
152 1 hiro
153 1 hiro
        /* Now release file object */
154 1 hiro
        g_free( ldifFile );
155 1 hiro
}
156 1 hiro
157 1 hiro
/*
158 1 hiro
* Display field record.
159 1 hiro
*/
160 1 hiro
void ldif_print_fieldrec( Ldif_FieldRec *rec, FILE *stream ) {
161 1 hiro
        fprintf( stream, "\ttag:\t%s", rec->reserved ? "yes" : "no" );
162 1 hiro
        fprintf( stream, "\t%s", rec->selected ? "yes" : "no" );
163 1 hiro
        fprintf( stream, "\t:%s:\t:%s:\n", rec->userName, rec->tagName );
164 1 hiro
}
165 1 hiro
166 1 hiro
/*
167 1 hiro
* Display field record.
168 1 hiro
 *
169 1 hiro
*/
170 1 hiro
static void ldif_print_file_vis( gpointer key, gpointer value, gpointer data ) {
171 1 hiro
        Ldif_FieldRec *rec = value;
172 1 hiro
        FILE *stream = data;
173 1 hiro
        ldif_print_fieldrec( rec, stream );
174 1 hiro
}
175 1 hiro
176 1 hiro
/*
177 1 hiro
* Display object to specified stream.
178 1 hiro
*/
179 1 hiro
void ldif_print_file( LdifFile *ldifFile, FILE *stream ) {
180 1 hiro
        g_return_if_fail( ldifFile != NULL );
181 1 hiro
        fprintf( stream, "LDIF File:\n" );
182 1 hiro
        fprintf( stream, "file spec: '%s'\n", ldifFile->path );
183 1 hiro
        fprintf( stream, "  ret val: %d\n",   ldifFile->retVal );
184 1 hiro
        fprintf( stream, "   fields: {\n" );
185 1 hiro
        g_hash_table_foreach( ldifFile->hashFields, ldif_print_file_vis, stream );
186 1 hiro
        fprintf( stream, "} ---\n" );
187 1 hiro
}
188 1 hiro
189 1 hiro
/*
190 1 hiro
* Open file for read.
191 1 hiro
* return: TRUE if file opened successfully.
192 1 hiro
*/
193 1 hiro
static gint ldif_open_file( LdifFile* ldifFile ) {
194 1 hiro
        /* printf( "Opening file\n" ); */
195 1 hiro
        if( ldifFile->path ) {
196 478 hiro
                ldifFile->file = g_fopen( ldifFile->path, "rb" );
197 1 hiro
                if( ! ldifFile->file ) {
198 1 hiro
                        /* printf( "can't open %s\n", ldifFile->path ); */
199 1 hiro
                        ldifFile->retVal = MGU_OPEN_FILE;
200 1 hiro
                        return ldifFile->retVal;
201 1 hiro
                }
202 1 hiro
        }
203 1 hiro
        else {
204 1 hiro
                /* printf( "file not specified\n" ); */
205 1 hiro
                ldifFile->retVal = MGU_NO_FILE;
206 1 hiro
                return ldifFile->retVal;
207 1 hiro
        }
208 1 hiro
209 1 hiro
        /* Setup a buffer area */
210 1 hiro
        ldifFile->buffer[0] = '\0';
211 1 hiro
        ldifFile->bufptr = ldifFile->buffer;
212 1 hiro
        ldifFile->retVal = MGU_SUCCESS;
213 1 hiro
        return ldifFile->retVal;
214 1 hiro
}
215 1 hiro
216 1 hiro
/*
217 1 hiro
* Close file.
218 1 hiro
*/
219 1 hiro
static void ldif_close_file( LdifFile *ldifFile ) {
220 1 hiro
        g_return_if_fail( ldifFile != NULL );
221 1 hiro
        if( ldifFile->file ) fclose( ldifFile->file );
222 1 hiro
        ldifFile->file = NULL;
223 1 hiro
}
224 1 hiro
225 1 hiro
/*
226 1 hiro
* Read line of text from file.
227 1 hiro
* Return: ptr to buffer where line starts.
228 1 hiro
*/
229 1 hiro
static gchar *ldif_get_line( LdifFile *ldifFile ) {
230 1 hiro
        gchar buf[ LDIFBUFSIZE ];
231 1 hiro
        gint ch;
232 720 hiro
        gint i = 0;
233 1 hiro
234 720 hiro
        if( feof( ldifFile->file ) )
235 720 hiro
                return NULL;
236 1 hiro
237 720 hiro
        while( i < LDIFBUFSIZE - 1 ) {
238 1 hiro
                ch = fgetc( ldifFile->file );
239 1 hiro
                if( ch == '\0' || ch == EOF ) {
240 720 hiro
                        if( i == 0 )
241 720 hiro
                                return NULL;
242 1 hiro
                        break;
243 1 hiro
                }
244 1 hiro
#if HAVE_DOSISH_SYSTEM
245 1 hiro
#else
246 720 hiro
                if( ch == '\r' )
247 720 hiro
                        continue;
248 1 hiro
#endif
249 720 hiro
                if( ch == '\n' )
250 720 hiro
                        break;
251 720 hiro
                buf[i] = ch;
252 720 hiro
                i++;
253 1 hiro
        }
254 720 hiro
        buf[i] = '\0';
255 1 hiro
256 1 hiro
        /* Return a copy of buffer */
257 1 hiro
        return g_strdup( buf );
258 1 hiro
}
259 1 hiro
260 1 hiro
/*
261 1 hiro
* Parse tag name from line buffer.
262 1 hiro
* Enter: line   Buffer.
263 1 hiro
*        flag64 Base-64 encoder flag.
264 1 hiro
* Return: Buffer containing the tag name, or NULL if no delimiter char found.
265 1 hiro
* If a double delimiter (::) is found, flag64 is set.
266 1 hiro
*/
267 1 hiro
static gchar *ldif_get_tagname( char* line, gboolean *flag64 ) {
268 1 hiro
        gint len = 0;
269 1 hiro
        gchar *tag = NULL;
270 1 hiro
        gchar *lptr = line;
271 1 hiro
        gchar *sptr = NULL;
272 1 hiro
273 1 hiro
        while( *lptr++ ) {
274 1 hiro
                /* Check for language tag */
275 1 hiro
                if( *lptr == LDIF_LANG_TAG ) {
276 1 hiro
                        if( sptr == NULL ) sptr = lptr;
277 1 hiro
                }
278 1 hiro
279 1 hiro
                /* Check for delimiter */
280 1 hiro
                if( *lptr == LDIF_SEP_TAG ) {
281 1 hiro
                        if( sptr ) {
282 1 hiro
                                len = sptr - line;
283 1 hiro
                        }
284 1 hiro
                        else {
285 1 hiro
                                len = lptr - line;
286 1 hiro
                        }
287 1 hiro
288 1 hiro
                        /* Base-64 encoding? */
289 1 hiro
                        if( * ++lptr == LDIF_SEP_TAG ) *flag64 = TRUE;
290 1 hiro
291 1 hiro
                        tag = g_strndup( line, len+1 );
292 1 hiro
                        tag[ len ] = '\0';
293 1 hiro
                        g_strdown( tag );
294 1 hiro
                        return tag;
295 1 hiro
                }
296 1 hiro
        }
297 1 hiro
        return tag;
298 1 hiro
}
299 1 hiro
300 1 hiro
/*
301 1 hiro
* Parse tag value from line buffer.
302 1 hiro
* Enter: line   Buffer.
303 1 hiro
* Return: Buffer containing the tag value. Empty string is returned if
304 1 hiro
* no delimiter char found.
305 1 hiro
*/
306 1 hiro
static gchar *ldif_get_tagvalue( gchar* line ) {
307 1 hiro
        gchar *value = NULL;
308 1 hiro
        gchar *start = NULL;
309 1 hiro
        gchar *lptr;
310 1 hiro
        gint len = 0;
311 1 hiro
312 1 hiro
        for( lptr = line; *lptr; lptr++ ) {
313 1 hiro
                if( *lptr == LDIF_SEP_TAG ) {
314 1 hiro
                        if( ! start )
315 1 hiro
                                start = lptr + 1;
316 1 hiro
                }
317 1 hiro
        }
318 1 hiro
        if( start ) {
319 1 hiro
                if( *start == LDIF_SEP_TAG ) start++;
320 1 hiro
                len = lptr - start;
321 1 hiro
                value = g_strndup( start, len+1 );
322 1 hiro
                g_strstrip( value );
323 1 hiro
        }
324 1 hiro
        else {
325 1 hiro
                /* Ensure that we get an empty string */
326 1 hiro
                value = g_strndup( "", 1 );
327 1 hiro
        }
328 1 hiro
        value[ len ] = '\0';
329 1 hiro
        return value;
330 1 hiro
}
331 1 hiro
332 1 hiro
#if 0
333 1 hiro
/*
334 1 hiro
* Dump linked lists of character strings (for debug).
335 1 hiro
*/
336 1 hiro
static void ldif_dump_lists( GSList *listName, GSList *listAddr, GSList *listRem, GSList *listID, FILE *stream ) {
337 1 hiro
        fprintf( stream, "dump name\n" );
338 1 hiro
        fprintf( stream, "------------\n" );
339 1 hiro
        mgu_print_list( listName, stdout );
340 1 hiro
        fprintf( stream, "dump address\n" );
341 1 hiro
        fprintf( stream, "------------\n" );
342 1 hiro
        mgu_print_list( listAddr, stdout );
343 1 hiro
        fprintf( stream, "dump remarks\n" );
344 1 hiro
        fprintf( stdout, "------------\n" );
345 1 hiro
        mgu_print_list( listRem, stdout );
346 1 hiro
        fprintf( stream, "dump id\n" );
347 1 hiro
        fprintf( stdout, "------------\n" );
348 1 hiro
        mgu_print_list( listID, stdout );
349 1 hiro
}
350 1 hiro
#endif
351 1 hiro
352 1 hiro
/*
353 1 hiro
* Parsed address data.
354 1 hiro
*/
355 1 hiro
typedef struct _Ldif_ParsedRec_ Ldif_ParsedRec;
356 1 hiro
struct _Ldif_ParsedRec_ {
357 1 hiro
        GSList *listCName;
358 1 hiro
        GSList *listFName;
359 1 hiro
        GSList *listLName;
360 1 hiro
        GSList *listNName;
361 1 hiro
        GSList *listAddress;
362 1 hiro
        GSList *listID;
363 1 hiro
        GSList *userAttr;
364 1 hiro
};
365 1 hiro
366 1 hiro
/*
367 1 hiro
* User attribute data.
368 1 hiro
*/
369 1 hiro
typedef struct _Ldif_UserAttr_ Ldif_UserAttr;
370 1 hiro
struct _Ldif_UserAttr_ {
371 1 hiro
        gchar *name;
372 1 hiro
        gchar *value;
373 1 hiro
};
374 1 hiro
375 1 hiro
/*
376 1 hiro
* Build an address list entry and append to list of address items. Name is formatted
377 1 hiro
* as "<first-name> <last-name>".
378 1 hiro
*/
379 1 hiro
static void ldif_build_items( LdifFile *ldifFile, Ldif_ParsedRec *rec, AddressCache *cache ) {
380 1 hiro
        GSList *nodeFirst;
381 1 hiro
        GSList *nodeAddress;
382 1 hiro
        GSList *nodeAttr;
383 1 hiro
        gchar *firstName = NULL, *lastName = NULL, *fullName = NULL, *nickName = NULL;
384 1 hiro
        gint iLen = 0, iLenT = 0;
385 1 hiro
        ItemPerson *person;
386 1 hiro
        ItemEMail *email;
387 1 hiro
388 1 hiro
        nodeAddress = rec->listAddress;
389 1 hiro
        if( nodeAddress == NULL ) return;
390 1 hiro
391 1 hiro
        /* Find longest first name in list */
392 1 hiro
        nodeFirst = rec->listFName;
393 1 hiro
        while( nodeFirst ) {
394 1 hiro
                if( firstName == NULL ) {
395 1 hiro
                        firstName = nodeFirst->data;
396 1 hiro
                        iLen = strlen( firstName );
397 1 hiro
                }
398 1 hiro
                else {
399 1 hiro
                        if( ( iLenT = strlen( nodeFirst->data ) ) > iLen ) {
400 1 hiro
                                firstName = nodeFirst->data;
401 1 hiro
                                iLen = iLenT;
402 1 hiro
                        }
403 1 hiro
                }
404 1 hiro
                nodeFirst = g_slist_next( nodeFirst );
405 1 hiro
        }
406 1 hiro
407 1 hiro
        /* Format name */
408 1 hiro
        if( rec->listLName ) {
409 1 hiro
                lastName = rec->listLName->data;
410 1 hiro
        }
411 1 hiro
412 1 hiro
        if( firstName ) {
413 1 hiro
                if( lastName ) {
414 1 hiro
                        fullName = g_strdup_printf( "%s %s", firstName, lastName );
415 1 hiro
                }
416 1 hiro
                else {
417 1 hiro
                        fullName = g_strdup_printf( "%s", firstName );
418 1 hiro
                }
419 1 hiro
        }
420 1 hiro
        else {
421 1 hiro
                if( lastName ) {
422 1 hiro
                        fullName = g_strdup_printf( "%s", lastName );
423 1 hiro
                }
424 1 hiro
        }
425 1 hiro
        if( fullName ) {
426 1 hiro
                g_strchug( fullName ); g_strchomp( fullName );
427 1 hiro
        }
428 1 hiro
429 1 hiro
        if( rec->listNName ) {
430 1 hiro
                nickName = rec->listNName->data;
431 1 hiro
        }
432 1 hiro
433 1 hiro
        person = addritem_create_item_person();
434 1 hiro
        addritem_person_set_common_name( person, fullName );
435 1 hiro
        addritem_person_set_first_name( person, firstName );
436 1 hiro
        addritem_person_set_last_name( person, lastName );
437 1 hiro
        addritem_person_set_nick_name( person, nickName );
438 1 hiro
        addrcache_id_person( cache, person );
439 1 hiro
        addrcache_add_person( cache, person );
440 1 hiro
        ++ldifFile->importCount;
441 1 hiro
442 1 hiro
        /* Add address item */
443 1 hiro
        while( nodeAddress ) {
444 1 hiro
                email = addritem_create_item_email();
445 1 hiro
                addritem_email_set_address( email, nodeAddress->data );
446 1 hiro
                addrcache_id_email( cache, email );
447 1 hiro
                addrcache_person_add_email( cache, person, email );
448 1 hiro
                nodeAddress = g_slist_next( nodeAddress );
449 1 hiro
        }
450 1 hiro
        g_free( fullName );
451 1 hiro
        fullName = firstName = lastName = NULL;
452 1 hiro
453 1 hiro
        /* Add user attributes */
454 1 hiro
        nodeAttr = rec->userAttr;
455 1 hiro
        while( nodeAttr ) {
456 1 hiro
                Ldif_UserAttr *attr = nodeAttr->data;
457 1 hiro
                UserAttribute *attrib = addritem_create_attribute();
458 1 hiro
                addritem_attrib_set_name( attrib, attr->name );
459 1 hiro
                addritem_attrib_set_value( attrib, attr->value );
460 1 hiro
                addritem_person_add_attribute( person, attrib );
461 1 hiro
                nodeAttr = g_slist_next( nodeAttr );
462 1 hiro
        }
463 1 hiro
        nodeAttr = NULL;
464 1 hiro
}
465 1 hiro
466 1 hiro
/*
467 1 hiro
* Add selected field as user attribute.
468 1 hiro
*/
469 1 hiro
static void ldif_add_user_attr( Ldif_ParsedRec *rec, gchar *tagName, gchar *tagValue, GHashTable *hashField ) {
470 1 hiro
        Ldif_FieldRec *fld = NULL;
471 1 hiro
        Ldif_UserAttr *attr = NULL;
472 1 hiro
        gchar *name;
473 1 hiro
474 1 hiro
        fld = g_hash_table_lookup( hashField, tagName );
475 1 hiro
        if( fld ) {
476 1 hiro
                if( fld->reserved ) return;
477 1 hiro
                if( ! fld->selected ) return;
478 1 hiro
479 1 hiro
                name = fld->tagName;
480 1 hiro
                if( fld->userName ) {
481 1 hiro
                        name = fld->userName;
482 1 hiro
                }
483 1 hiro
                attr = g_new0( Ldif_UserAttr, 1 );
484 1 hiro
                attr->name = g_strdup( name );
485 1 hiro
                attr->value = g_strdup( tagValue );
486 1 hiro
                rec->userAttr = g_slist_append( rec->userAttr, attr );
487 1 hiro
        }
488 1 hiro
}
489 1 hiro
490 1 hiro
/*
491 1 hiro
* Add value to parsed data.
492 1 hiro
*/
493 1 hiro
static void ldif_add_value( Ldif_ParsedRec *rec, gchar *tagName, gchar *tagValue, GHashTable *hashField ) {
494 1 hiro
        gchar *nm, *val;
495 1 hiro
496 1 hiro
        nm = g_strdup( tagName );
497 1 hiro
        g_strdown( nm );
498 1 hiro
        if( tagValue ) {
499 1 hiro
                val = g_strdup( tagValue );
500 1 hiro
        }
501 1 hiro
        else {
502 1 hiro
                val = g_strdup( "" );
503 1 hiro
        }
504 1 hiro
        g_strstrip( val );
505 333 hiro
        if( g_ascii_strcasecmp( nm, LDIF_TAG_COMMONNAME ) == 0 ) {
506 1 hiro
                rec->listCName = g_slist_append( rec->listCName, val );
507 1 hiro
        }
508 333 hiro
        else if( g_ascii_strcasecmp( nm, LDIF_TAG_FIRSTNAME ) == 0 ) {
509 1 hiro
                rec->listFName = g_slist_append( rec->listFName, val );
510 1 hiro
        }
511 333 hiro
        else if( g_ascii_strcasecmp( nm, LDIF_TAG_LASTNAME ) == 0 ) {
512 1 hiro
                rec->listLName = g_slist_append( rec->listLName, val );
513 1 hiro
        }
514 333 hiro
        else if( g_ascii_strcasecmp( nm, LDIF_TAG_NICKNAME ) == 0 ) {
515 1 hiro
                rec->listNName = g_slist_append( rec->listNName, val );
516 1 hiro
        }
517 333 hiro
        else if( g_ascii_strcasecmp( nm, LDIF_TAG_EMAIL ) == 0 ) {
518 1 hiro
                rec->listAddress = g_slist_append( rec->listAddress, val );
519 1 hiro
        }
520 1 hiro
        else {
521 1 hiro
                /* Add field as user attribute */
522 1 hiro
                ldif_add_user_attr( rec, tagName, tagValue, hashField );
523 1 hiro
        }
524 1 hiro
        g_free( nm );
525 1 hiro
}
526 1 hiro
527 1 hiro
/*
528 1 hiro
* Clear parsed data.
529 1 hiro
*/
530 1 hiro
static void ldif_clear_rec( Ldif_ParsedRec *rec ) {
531 1 hiro
        GSList *list;
532 1 hiro
533 1 hiro
        /* Free up user attributes */
534 1 hiro
        list = rec->userAttr;
535 1 hiro
        while( list ) {
536 1 hiro
                Ldif_UserAttr *attr = list->data;
537 1 hiro
                g_free( attr->name );
538 1 hiro
                g_free( attr->value );
539 1 hiro
                g_free( attr );
540 1 hiro
                list = g_slist_next( list );
541 1 hiro
        }
542 1 hiro
        g_slist_free( rec->userAttr );
543 1 hiro
544 1 hiro
        g_slist_free( rec->listCName );
545 1 hiro
        g_slist_free( rec->listFName );
546 1 hiro
        g_slist_free( rec->listLName );
547 1 hiro
        g_slist_free( rec->listNName );
548 1 hiro
        g_slist_free( rec->listAddress );
549 1 hiro
        g_slist_free( rec->listID );
550 1 hiro
551 1 hiro
        rec->userAttr = NULL;
552 1 hiro
        rec->listCName = NULL;
553 1 hiro
        rec->listFName = NULL;
554 1 hiro
        rec->listLName = NULL;
555 1 hiro
        rec->listNName = NULL;
556 1 hiro
        rec->listAddress = NULL;
557 1 hiro
        rec->listID = NULL;
558 1 hiro
}
559 1 hiro
560 1 hiro
#if 0
561 1 hiro
/*
562 1 hiro
* Print parsed data.
563 1 hiro
*/
564 1 hiro
static void ldif_print_record( Ldif_ParsedRec *rec, FILE *stream ) {
565 1 hiro
        GSList *list;
566 1 hiro
567 1 hiro
        fprintf( stream, "LDIF Parsed Record:\n" );
568 1 hiro
        fprintf( stream, "common name:" );
569 1 hiro
        mgu_print_list( rec->listCName, stream );
570 1 hiro
        if( ! rec->listCName ) fprintf( stream, "\n" );
571 1 hiro
        fprintf( stream, "first name:" );
572 1 hiro
        mgu_print_list( rec->listFName, stream );
573 1 hiro
        if( ! rec->listFName ) fprintf( stream, "\n" );
574 1 hiro
        fprintf( stream, "last name:" );
575 1 hiro
        mgu_print_list( rec->listLName, stream );
576 1 hiro
        if( ! rec->listLName ) fprintf( stream, "\n" );
577 1 hiro
        fprintf( stream, "nick name:" );
578 1 hiro
        mgu_print_list( rec->listNName, stream );
579 1 hiro
        if( ! rec->listNName ) fprintf( stream, "\n" );
580 1 hiro
        fprintf( stream, "address:" );
581 1 hiro
        mgu_print_list( rec->listAddress, stream );
582 1 hiro
        if( ! rec->listAddress ) fprintf( stream, "\n" );
583 1 hiro
        fprintf( stream, "id:" );
584 1 hiro
        mgu_print_list( rec->listID, stream );
585 1 hiro
        if( ! rec->listID ) fprintf( stream, "\n" );
586 1 hiro
587 1 hiro
        list = rec->userAttr;
588 1 hiro
        while( list ) {
589 1 hiro
                Ldif_UserAttr *attr = list->data;
590 1 hiro
                fprintf( stream, "n/v:\t%s:\t:%s:\n", attr->name, attr->value );
591 1 hiro
                list = g_slist_next( list );
592 1 hiro
        }
593 1 hiro
        list = NULL;
594 1 hiro
}
595 1 hiro
596 1 hiro
static void ldif_dump_b64( gchar *buf ) {
597 1 hiro
        Base64Decoder *decoder = NULL;
598 1 hiro
        gchar outBuf[8192];
599 1 hiro
        gint len;
600 1 hiro
601 1 hiro
        printf( "base-64 : inbuf : %s\n", buf );
602 1 hiro
        decoder = base64_decoder_new();
603 1 hiro
        len = base64_decoder_decode( decoder, buf, outBuf );
604 1 hiro
        if (len < 0) {
605 1 hiro
                printf( "base-64 : Bad BASE64 content\n" );
606 1 hiro
        }
607 1 hiro
        else {
608 1 hiro
                outBuf[len] = '\0';
609 1 hiro
                printf( "base-64 : %d : %s\n\n", len, outBuf );
610 1 hiro
        }
611 1 hiro
        base64_decoder_free( decoder );
612 1 hiro
        decoder = NULL;
613 1 hiro
}
614 1 hiro
#endif
615 1 hiro
616 1 hiro
/*
617 1 hiro
* Read file data into address cache.
618 1 hiro
* Note that one LDIF record identifies one entity uniquely with the
619 1 hiro
* distinguished name (dn) tag. Each person can have multiple E-Mail
620 1 hiro
* addresses. Also, each person can have many common name (cn) tags.
621 1 hiro
*/
622 1 hiro
static void ldif_read_file( LdifFile *ldifFile, AddressCache *cache ) {
623 1 hiro
        gchar *tagName = NULL, *tagValue = NULL;
624 1 hiro
        gchar *lastTag = NULL, *fullValue = NULL;
625 1 hiro
        GSList *listValue = NULL;
626 1 hiro
        gboolean flagEOF = FALSE, flagEOR = FALSE;
627 1 hiro
        gboolean flag64 = FALSE, last64 = FALSE;
628 1 hiro
        Ldif_ParsedRec *rec;
629 1 hiro
        long posEnd = 0L;
630 1 hiro
        long posCur = 0L;
631 1 hiro
        GHashTable *hashField;
632 1 hiro
633 1 hiro
        hashField = ldifFile->hashFields;
634 1 hiro
        rec = g_new0( Ldif_ParsedRec, 1 );
635 1 hiro
        ldif_clear_rec( rec );
636 1 hiro
637 1 hiro
        /* Find EOF for progress indicator */
638 1 hiro
        fseek( ldifFile->file, 0L, SEEK_END );
639 1 hiro
        posEnd = ftell( ldifFile->file );
640 1 hiro
        fseek( ldifFile->file, 0L, SEEK_SET );
641 1 hiro
642 1 hiro
        while( ! flagEOF ) {
643 1 hiro
                gchar *line =  ldif_get_line( ldifFile );
644 1 hiro
645 1 hiro
                posCur = ftell( ldifFile->file );
646 1 hiro
                if( ldifFile->cbProgress ) {
647 1 hiro
                        /* Call progress indicator */
648 1 hiro
                        ( ldifFile->cbProgress ) ( ldifFile, & posEnd, & posCur );
649 1 hiro
                }
650 1 hiro
651 1 hiro
                flag64 = FALSE;
652 1 hiro
                if( line == NULL ) {
653 1 hiro
                        flagEOF = flagEOR = TRUE;
654 1 hiro
                }
655 1 hiro
                else if( *line == '\0' ) {
656 1 hiro
                        flagEOR = TRUE;
657 1 hiro
                }
658 1 hiro
659 1 hiro
                if( flagEOR ) {
660 1 hiro
                        /* EOR, Output address data */
661 1 hiro
                        if( lastTag ) {
662 1 hiro
                                /* Save record */
663 1 hiro
                                fullValue = mgu_list_coalesce( listValue );
664 1 hiro
665 1 hiro
                                /* Base-64 encoded data */
666 1 hiro
                                /*
667 1 hiro
                                if( last64 ) {
668 1 hiro
                                        ldif_dump_b64( fullValue );
669 1 hiro
                                }
670 1 hiro
                                */
671 1 hiro
672 1 hiro
                                ldif_add_value( rec, lastTag, fullValue, hashField );
673 1 hiro
                                /* ldif_print_record( rec, stdout ); */
674 1 hiro
                                ldif_build_items( ldifFile, rec, cache );
675 1 hiro
                                ldif_clear_rec( rec );
676 1 hiro
                                g_free( lastTag );
677 1 hiro
                                mgu_free_list( listValue );
678 1 hiro
                                lastTag = NULL;
679 1 hiro
                                listValue = NULL;
680 1 hiro
                                last64 = FALSE;
681 1 hiro
                        }
682 1 hiro
                }
683 1 hiro
                if( line ) {
684 1 hiro
                        flagEOR = FALSE;
685 1 hiro
                        if( *line == ' ' ) {
686 1 hiro
                                /* Continuation line */
687 1 hiro
                                listValue = g_slist_append( listValue, g_strdup( line+1 ) );
688 1 hiro
                        }
689 1 hiro
                        else if( *line == '=' ) {
690 1 hiro
                                /* Base-64 encoded continuation field */
691 1 hiro
                                listValue = g_slist_append( listValue, g_strdup( line ) );
692 1 hiro
                        }
693 1 hiro
                        else {
694 1 hiro
                                /* Parse line */
695 1 hiro
                                tagName = ldif_get_tagname( line, &flag64 );
696 1 hiro
                                if( tagName ) {
697 1 hiro
                                        tagValue = ldif_get_tagvalue( line );
698 1 hiro
                                        if( tagValue ) {
699 1 hiro
                                                if( lastTag ) {
700 1 hiro
                                                        /* Save data */
701 1 hiro
                                                        fullValue = mgu_list_coalesce( listValue );
702 1 hiro
                                                        /* Base-64 encoded data */
703 1 hiro
                                                        /*
704 1 hiro
                                                        if( last64 ) {
705 1 hiro
                                                                ldif_dump_b64( fullValue );
706 1 hiro
                                                        }
707 1 hiro
                                                        */
708 1 hiro
709 1 hiro
                                                        ldif_add_value( rec, lastTag, fullValue, hashField );
710 1 hiro
                                                        g_free( lastTag );
711 1 hiro
                                                        mgu_free_list( listValue );
712 1 hiro
                                                        lastTag = NULL;
713 1 hiro
                                                        listValue = NULL;
714 1 hiro
                                                        last64 = FALSE;
715 1 hiro
                                                }
716 1 hiro
717 1 hiro
                                                lastTag = g_strdup( tagName );
718 1 hiro
                                                listValue = g_slist_append( listValue, g_strdup( tagValue ) );
719 1 hiro
                                                g_free( tagValue );
720 1 hiro
                                                last64 = flag64;
721 1 hiro
                                        }
722 1 hiro
                                        g_free( tagName );
723 1 hiro
                                }
724 1 hiro
                        }
725 1 hiro
                }
726 1 hiro
                g_free( line );
727 1 hiro
        }
728 1 hiro
729 1 hiro
        /* Release data */
730 1 hiro
        ldif_clear_rec( rec );
731 1 hiro
        g_free( rec );
732 1 hiro
        g_free( lastTag );
733 1 hiro
        mgu_free_list( listValue );
734 1 hiro
}
735 1 hiro
736 1 hiro
/*
737 1 hiro
* Add list of field names to hash table.
738 1 hiro
*/
739 1 hiro
static void ldif_hash_add_list( GHashTable *table, GSList *list ) {
740 1 hiro
        GSList *node = list;
741 1 hiro
742 1 hiro
        /* mgu_print_list( list, stdout ); */
743 1 hiro
        while( node ) {
744 1 hiro
                gchar *tag = node->data;
745 1 hiro
                if( ! g_hash_table_lookup( table, tag ) ) {
746 1 hiro
                        Ldif_FieldRec *rec = NULL;
747 1 hiro
                        gchar *key = g_strdup( tag );
748 1 hiro
749 1 hiro
                        rec = ldif_create_fieldrec( tag );
750 333 hiro
                        if( g_ascii_strcasecmp( tag, LDIF_TAG_COMMONNAME ) == 0 ) {
751 1 hiro
                                rec->reserved = TRUE;
752 1 hiro
                        }
753 333 hiro
                        else if( g_ascii_strcasecmp( tag, LDIF_TAG_FIRSTNAME ) == 0 ) {
754 1 hiro
                                rec->reserved = TRUE;
755 1 hiro
                        }
756 333 hiro
                        else if( g_ascii_strcasecmp( tag, LDIF_TAG_LASTNAME ) == 0 ) {
757 1 hiro
                                rec->reserved = TRUE;
758 1 hiro
                        }
759 333 hiro
                        else if( g_ascii_strcasecmp( tag, LDIF_TAG_NICKNAME ) == 0 ) {
760 1 hiro
                                rec->reserved = TRUE;
761 1 hiro
                        }
762 333 hiro
                        else if( g_ascii_strcasecmp( tag, LDIF_TAG_EMAIL ) == 0 ) {
763 1 hiro
                                rec->reserved = TRUE;
764 1 hiro
                        }
765 1 hiro
                        g_hash_table_insert( table, key, rec );
766 1 hiro
                }
767 1 hiro
                node = g_slist_next( node );
768 1 hiro
        }
769 1 hiro
}
770 1 hiro
771 1 hiro
/*
772 1 hiro
* Sorted list comparison function.
773 1 hiro
*/
774 1 hiro
static int ldif_field_compare( gconstpointer ptr1, gconstpointer ptr2 ) {
775 1 hiro
        const Ldif_FieldRec *rec1 = ptr1;
776 1 hiro
        const Ldif_FieldRec *rec2 = ptr2;
777 333 hiro
        return g_ascii_strcasecmp( rec1->tagName, rec2->tagName );
778 1 hiro
}
779 1 hiro
780 1 hiro
/*
781 1 hiro
* Append hash table entry to list - visitor function.
782 1 hiro
*/
783 1 hiro
static void ldif_hash2list_vis( gpointer key, gpointer value, gpointer data ) {
784 1 hiro
        LdifFile *ldf = data;
785 1 hiro
        ldf->tempList = g_list_insert_sorted( ldf->tempList, value, ldif_field_compare );
786 1 hiro
}
787 1 hiro
788 1 hiro
/*
789 1 hiro
* Read tag names for file data.
790 1 hiro
*/
791 1 hiro
static void ldif_read_tag_list( LdifFile *ldifFile ) {
792 1 hiro
        gchar *tagName = NULL;
793 1 hiro
        GSList *listTags = NULL;
794 1 hiro
        gboolean flagEOF = FALSE, flagEOR = FALSE, flagMail = FALSE;
795 1 hiro
        gboolean flag64 = FALSE;
796 1 hiro
        long posEnd = 0L;
797 1 hiro
        long posCur = 0L;
798 1 hiro
799 1 hiro
        /* Clear hash table */
800 1 hiro
        g_hash_table_foreach_remove( ldifFile->hashFields, ldif_hash_free_vis, NULL );
801 1 hiro
802 1 hiro
        /* Find EOF for progress indicator */
803 1 hiro
        fseek( ldifFile->file, 0L, SEEK_END );
804 1 hiro
        posEnd = ftell( ldifFile->file );
805 1 hiro
        fseek( ldifFile->file, 0L, SEEK_SET );
806 1 hiro
807 1 hiro
        /* Process file */
808 1 hiro
        while( ! flagEOF ) {
809 1 hiro
                gchar *line = ldif_get_line( ldifFile );
810 1 hiro
811 1 hiro
                posCur = ftell( ldifFile->file );
812 1 hiro
                if( ldifFile->cbProgress ) {
813 1 hiro
                        /* Call progress indicator */
814 1 hiro
                        ( ldifFile->cbProgress ) ( ldifFile, & posEnd, & posCur );
815 1 hiro
                }
816 1 hiro
817 1 hiro
                flag64 = FALSE;
818 1 hiro
                if( line == NULL ) {
819 1 hiro
                        flagEOF = flagEOR = TRUE;
820 1 hiro
                }
821 1 hiro
                else if( *line == '\0' ) {
822 1 hiro
                        flagEOR = TRUE;
823 1 hiro
                }
824 1 hiro
825 1 hiro
                if( flagEOR ) {
826 1 hiro
                        /* EOR, Output address data */
827 1 hiro
                        /* Save field list to hash table */
828 1 hiro
                        if( flagMail ) {
829 1 hiro
                                ldif_hash_add_list( ldifFile->hashFields, listTags );
830 1 hiro
                        }
831 1 hiro
                        mgu_free_list( listTags );
832 1 hiro
                        listTags = NULL;
833 1 hiro
                        flagMail = FALSE;
834 1 hiro
                }
835 1 hiro
                if( line ) {
836 1 hiro
                        flagEOR = FALSE;
837 1 hiro
                        if( *line == ' ' ) {
838 1 hiro
                                /* Continuation line */
839 1 hiro
                        }
840 1 hiro
                        else if( *line == '=' ) {
841 1 hiro
                                /* Base-64 encoded continuation field */
842 1 hiro
                        }
843 1 hiro
                        else {
844 1 hiro
                                /* Parse line */
845 1 hiro
                                tagName = ldif_get_tagname( line, &flag64 );
846 1 hiro
                                if( tagName ) {
847 1 hiro
                                        /* Add tag to list */
848 1 hiro
                                        listTags = g_slist_append( listTags, tagName );
849 333 hiro
                                        if( g_ascii_strcasecmp( tagName, LDIF_TAG_EMAIL ) == 0 ) {
850 1 hiro
                                                flagMail = TRUE;
851 1 hiro
                                        }
852 1 hiro
                                }
853 1 hiro
                        }
854 1 hiro
                }
855 1 hiro
                g_free( line );
856 1 hiro
        }
857 1 hiro
858 1 hiro
        /* Release data */
859 1 hiro
        mgu_free_list( listTags );
860 1 hiro
        listTags = NULL;
861 1 hiro
}
862 1 hiro
863 1 hiro
/*
864 1 hiro
* ============================================================================
865 1 hiro
* Read file into list. Main entry point
866 1 hiro
* Enter:  ldifFile LDIF control data.
867 1 hiro
*         cache    Address cache to load.
868 1 hiro
* Return: Status code.
869 1 hiro
* ============================================================================
870 1 hiro
*/
871 1 hiro
gint ldif_import_data( LdifFile *ldifFile, AddressCache *cache ) {
872 1 hiro
        g_return_val_if_fail( ldifFile != NULL, MGU_BAD_ARGS );
873 1 hiro
        ldifFile->retVal = MGU_SUCCESS;
874 1 hiro
        addrcache_clear( cache );
875 1 hiro
        cache->dataRead = FALSE;
876 1 hiro
        ldif_open_file( ldifFile );
877 1 hiro
        if( ldifFile->retVal == MGU_SUCCESS ) {
878 1 hiro
                /* Read data into the cache */
879 1 hiro
                ldif_read_file( ldifFile, cache );
880 1 hiro
                ldif_close_file( ldifFile );
881 1 hiro
882 1 hiro
                /* Mark cache */
883 1 hiro
                cache->modified = FALSE;
884 1 hiro
                cache->dataRead = TRUE;
885 1 hiro
        }
886 1 hiro
        return ldifFile->retVal;
887 1 hiro
}
888 1 hiro
889 1 hiro
/*
890 1 hiro
* ============================================================================
891 1 hiro
* Process entire file reading list of unique fields. List of fields may be
892 1 hiro
* accessed with the ldif_get_fieldlist() function.
893 1 hiro
* Enter:  ldifFile LDIF control data.
894 1 hiro
* Return: Status code.
895 1 hiro
* ============================================================================
896 1 hiro
*/
897 1 hiro
gint ldif_read_tags( LdifFile *ldifFile ) {
898 1 hiro
        g_return_val_if_fail( ldifFile != NULL, MGU_BAD_ARGS );
899 1 hiro
        ldifFile->retVal = MGU_SUCCESS;
900 1 hiro
        if( ldifFile->dirtyFlag ) {
901 1 hiro
                ldif_open_file( ldifFile );
902 1 hiro
                if( ldifFile->retVal == MGU_SUCCESS ) {
903 1 hiro
                        /* Read data into the cache */
904 1 hiro
                        ldif_read_tag_list( ldifFile );
905 1 hiro
                        ldif_close_file( ldifFile );
906 1 hiro
                        ldifFile->dirtyFlag = FALSE;
907 1 hiro
                        ldifFile->accessFlag = TRUE;
908 1 hiro
                }
909 1 hiro
        }
910 1 hiro
        return ldifFile->retVal;
911 1 hiro
}
912 1 hiro
913 1 hiro
/*
914 1 hiro
* Return list of fields for LDIF file.
915 1 hiro
* Enter: ldifFile LdifFile object.
916 1 hiro
* Return: Linked list of Ldif_FieldRec objects. This list may be g_free'd.
917 1 hiro
* Note that the objects in the list should not be freed since they refer to
918 1 hiro
* objects inside the internal cache. These objects will be freed when
919 1 hiro
* LDIF file object is freed.
920 1 hiro
*/
921 1 hiro
GList *ldif_get_fieldlist( LdifFile *ldifFile ) {
922 1 hiro
        GList *list = NULL;
923 1 hiro
924 1 hiro
        g_return_val_if_fail( ldifFile != NULL, NULL );
925 1 hiro
        if( ldifFile->hashFields ) {
926 1 hiro
                ldifFile->tempList = NULL;
927 1 hiro
                g_hash_table_foreach( ldifFile->hashFields, ldif_hash2list_vis, ldifFile );
928 1 hiro
                list = ldifFile->tempList;
929 1 hiro
                ldifFile->tempList = NULL;
930 1 hiro
        }
931 1 hiro
        return list;
932 1 hiro
}
933 1 hiro
934 1 hiro
/*
935 1 hiro
* End of Source.
936 1 hiro
*/