Included import of LDIF files
authorMatch Grun <match@dimensional.com>
Mon, 24 Sep 2001 05:43:58 +0000 (05:43 +0000)
committerMatch Grun <match@dimensional.com>
Mon, 24 Sep 2001 05:43:58 +0000 (05:43 +0000)
src/addressbook.c
src/importldif.c [new file with mode: 0644]
src/importldif.h [new file with mode: 0644]
src/ldif.c [new file with mode: 0644]
src/ldif.h [new file with mode: 0644]

index 2e98606..6f56f60 100644 (file)
@@ -73,6 +73,8 @@
 #include "editgroup.h"
 #include "editaddress.h"
 #include "editbook.h"
+#include "ldif.h"
+#include "importldif.h"
 
 #ifdef USE_JPILOT
 #include "jpilot.h"
@@ -335,6 +337,8 @@ static void addressbook_list_select_clear   (void);
 static void addressbook_list_select_add                (AddressObject *obj);
 static void addressbook_list_select_remove     (AddressObject *obj);
 
+static void addressbook_import_ldif_cb         ();
+
 static GtkItemFactoryEntry addressbook_entries[] =
 {
        {N_("/_File"),                  NULL,           NULL, 0, "<Branch>"},
@@ -359,6 +363,8 @@ static GtkItemFactoryEntry addressbook_entries[] =
        {N_("/_Address/---"),           NULL,           NULL, 0, "<Separator>"},
        {N_("/_Address/_Edit"),         "<alt>Return",  addressbook_edit_address_cb,    0, NULL},
        {N_("/_Address/_Delete"),       NULL,           addressbook_delete_address_cb,  0, NULL},
+       {N_("/_Tools/---"),             NULL,           NULL, 0, "<Separator>"},
+       {N_("/_Tools/Import _LDIF"),    NULL,           addressbook_import_ldif_cb,     0, NULL},
        {N_("/_Help"),                  NULL,           NULL, 0, "<LastBranch>"},
        {N_("/_Help/_About"),           NULL,           about_show, 0, NULL}
 };
@@ -369,13 +375,6 @@ static GtkItemFactoryEntry addressbook_entries[] =
        {N_("/_Edit/C_ut"),             "<ctl>X",       NULL,                           0, NULL},
        {N_("/_Edit/_Copy"),            "<ctl>C",       NULL,                           0, NULL},
        {N_("/_Edit/_Paste"),           "<ctl>V",       NULL,                           0, NULL},
-       {N_("/_Tools"),                 NULL,           NULL, 0, "<Branch>"},
-       {N_("/_Tools/Import _Mozilla"), NULL,           NULL,                           0, NULL},
-       {N_("/_Tools/Import _LDIF"),    NULL,           NULL,                           0, NULL},
-       {N_("/_Tools/Import _V-Card"),  NULL,           NULL,                           0, NULL},
-       {N_("/_Tools/---"),             NULL,           NULL, 0, "<Separator>"},
-       {N_("/_Tools/Export _LDIF"),    NULL,           NULL,                           0, NULL},
-       {N_("/_Tools/Export V-_Card"),  NULL,           NULL,                           0, NULL},
 */
 
 static GtkItemFactoryEntry addressbook_tree_popup_entries[] =
@@ -1865,6 +1864,7 @@ static void addressbook_edit_address_cb( gpointer data, guint action, GtkWidget
                        person = ( ItemPerson * ) ADDRITEM_PARENT(email);
                        if( addressbook_edit_person( abf, NULL, person, TRUE ) == NULL ) return;
                        gtk_ctree_select( ctree, addrbook.opened );
+                       invalidate_address_completion();
                        return;
                }
        }
@@ -1873,6 +1873,7 @@ static void addressbook_edit_address_cb( gpointer data, guint action, GtkWidget
                ItemPerson *person = ( ItemPerson * ) obj;
                if( addressbook_edit_person( abf, NULL, person, FALSE ) == NULL ) return;
                gtk_ctree_select( ctree, addrbook.opened);
+               invalidate_address_completion();
                return;
        }
        else if( obj->type == ADDR_ITEM_GROUP ) {
@@ -3440,6 +3441,43 @@ gboolean addressbook_load_completion( gint (*callBackFunc) ( const gchar *, cons
        return TRUE;
 }
 
+/* **********************************************************************
+* Address Import.
+* ***********************************************************************
+*/
+
+/*
+* Import LDIF file.
+*/
+static void addressbook_import_ldif_cb() {
+       AddressDataSource *ds = NULL;
+       AdapterDSource *ads = NULL;
+       AddressBookFile *abf = NULL;
+       AdapterInterface *adapter;
+       GtkCTreeNode *newNode;
+
+       adapter = addrbookctl_find_interface( ADDR_IF_BOOK );
+       if( adapter ) {
+               if( adapter->treeNode ) {
+                       abf = addressbook_imp_ldif( _addressIndex_ );
+                       if( abf ) {
+                               ds = addrindex_index_add_datasource( _addressIndex_, ADDR_IF_BOOK, abf );
+                               ads = addressbook_create_ds_adapter( ds, ADDR_BOOK, NULL );
+                               addressbook_ads_set_name( ads, abf->name );
+                               newNode = addressbook_add_object( adapter->treeNode, ADDRESS_OBJECT(ads) );
+                               if( newNode ) {
+                                       gtk_ctree_select( GTK_CTREE(addrbook.ctree), newNode );
+                                       addrbook.treeSelected = newNode;
+                               }
+
+                               /* Notify address completion */
+                               invalidate_address_completion();
+                       }
+               }
+       }
+
+}
+
 /*
 * End of Source.
 */
diff --git a/src/importldif.c b/src/importldif.c
new file mode 100644 (file)
index 0000000..2307eb9
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2001 Match Grun
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Edit VCard address book data.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "defs.h"
+
+#include <glib.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtkbutton.h>
+
+#include "intl.h"
+#include "addrbook.h"
+#include "addressbook.h"
+#include "addressitem.h"
+#include "gtkutils.h"
+#include "prefs_common.h"
+#include "manage_window.h"
+#include "mgutils.h"
+#include "ldif.h"
+
+#define IMPORTLDIF_GUESS_NAME "LDIF Import"
+
+static struct _ImpLdif_Dlg {
+       GtkWidget *window;
+       GtkWidget *file_entry;
+       GtkWidget *name_entry;
+       GtkWidget *ok_btn;
+       GtkWidget *cancel_btn;
+       GtkWidget *statusbar;
+       gint status_cid;
+} impldif_dlg;
+
+static struct _AddressFileSelection _imp_ldif_file_selector_;
+static AddressBookFile *_importedBook_;
+static AddressIndex *_imp_addressIndex_;
+
+/*
+* Edit functions.
+*/
+void imp_ldif_status_show( gchar *msg ) {
+       if( impldif_dlg.statusbar != NULL ) {
+               gtk_statusbar_pop( GTK_STATUSBAR(impldif_dlg.statusbar), impldif_dlg.status_cid );
+               if( msg ) {
+                       gtk_statusbar_push( GTK_STATUSBAR(impldif_dlg.statusbar), impldif_dlg.status_cid, msg );
+               }
+       }
+}
+
+static gchar *imp_ldif_guess_file( AddressBookFile *abf ) {
+       gchar *newFile = NULL;
+       GList *fileList = NULL;
+       gint fileNum = 1;
+       fileList = addrbook_get_bookfile_list( abf );
+       if( fileList ) {
+               fileNum = 1 + abf->maxValue;
+       }
+       newFile = addrbook_gen_new_file_name( fileNum );
+       g_list_free( fileList );
+       fileList = NULL;
+       return newFile;
+}
+
+static gboolean imp_ldif_import_file( gchar *sName, gchar *sFile ) {
+       gboolean retVal = FALSE;
+       gchar *newFile;
+       AddressBookFile *abf = NULL;
+       LdifFile *ldf = NULL;
+
+       if( _importedBook_ ) {
+               addrbook_free_book( _importedBook_ );
+       }
+
+       abf = addrbook_create_book();
+       addrbook_set_path( abf, _imp_addressIndex_->filePath );
+       addrbook_set_name( abf, sName );
+       newFile = imp_ldif_guess_file( abf );
+       addrbook_set_file( abf, newFile );
+       g_free( newFile );
+
+       // Import data into file
+       ldf = ldif_create();
+       ldif_set_file( ldf, sFile );
+       if( ldif_import_data( ldf, abf->addressCache ) == MGU_SUCCESS ) {
+               addrbook_save_data( abf );
+               abf->dirtyFlag = TRUE;
+               _importedBook_ = abf;
+               retVal = TRUE;
+       }
+       else {
+               addrbook_free_book( abf );
+       }
+
+       return retVal;
+}
+
+static void imp_ldif_ok( GtkWidget *widget, gboolean *cancelled ) {
+       gchar *sName;
+       gchar *sFile;
+       gchar *sMsg = NULL;
+       gboolean errFlag = FALSE;
+
+       sFile = gtk_editable_get_chars( GTK_EDITABLE(impldif_dlg.file_entry), 0, -1 );
+       g_strchug( sFile ); g_strchomp( sFile );
+       gtk_entry_set_text( GTK_ENTRY(impldif_dlg.file_entry), sFile );
+
+       sName = gtk_editable_get_chars( GTK_EDITABLE(impldif_dlg.name_entry), 0, -1 );
+       g_strchug( sName ); g_strchomp( sName );
+       gtk_entry_set_text( GTK_ENTRY(impldif_dlg.name_entry), sName );
+
+       if( *sFile == '\0'|| strlen( sFile ) < 1 ) {
+               sMsg = _( "Please select a file." );
+               errFlag = TRUE;
+       }
+
+       if( *sName == '\0'|| strlen( sName ) < 1 ) {
+               if( ! errFlag ) sMsg = _( "Address book name must be supplied." );
+               errFlag = TRUE;
+       }
+
+       if( errFlag ) {
+               imp_ldif_status_show( sMsg );
+       }
+       else {
+               /* Import the file */
+               if( imp_ldif_import_file( sName, sFile ) ) {
+                       *cancelled = FALSE;
+                       gtk_main_quit();
+               }
+               else {
+                       imp_ldif_status_show( _( "Error importing LDIF file." ) );
+               }
+       }
+
+       g_free( sFile );
+       g_free( sName );
+
+}
+
+static void imp_ldif_cancel( GtkWidget *widget, gboolean *cancelled ) {
+       *cancelled = TRUE;
+       gtk_main_quit();
+}
+
+static void imp_ldif_file_ok( GtkWidget *widget, gpointer data ) {
+       gchar *sFile;
+       AddressFileSelection *afs;
+       GtkWidget *fileSel;
+
+       afs = ( AddressFileSelection * ) data;
+       fileSel = afs->fileSelector;
+       sFile = gtk_file_selection_get_filename( GTK_FILE_SELECTION(fileSel) );
+
+       afs->cancelled = FALSE;
+       gtk_entry_set_text( GTK_ENTRY(impldif_dlg.file_entry), sFile );
+       gtk_widget_hide( afs->fileSelector );
+       gtk_grab_remove( afs->fileSelector );
+       gtk_widget_grab_focus( impldif_dlg.file_entry );
+}
+
+static void imp_ldif_file_cancel( GtkWidget *widget, gpointer data ) {
+       AddressFileSelection *afs = ( AddressFileSelection * ) data;
+       afs->cancelled = TRUE;
+       gtk_widget_hide( afs->fileSelector );
+       gtk_grab_remove( afs->fileSelector );
+       gtk_widget_grab_focus( impldif_dlg.file_entry );
+}
+
+static void imp_ldif_file_select_create( AddressFileSelection *afs ) {
+       GtkWidget *fileSelector;
+
+       fileSelector = gtk_file_selection_new( _("Select LDIF File") );
+       gtk_file_selection_hide_fileop_buttons( GTK_FILE_SELECTION(fileSelector) );
+       gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION(fileSelector)->ok_button),
+                             "clicked", GTK_SIGNAL_FUNC (imp_ldif_file_ok), ( gpointer ) afs );
+       gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION(fileSelector)->cancel_button),
+                             "clicked", GTK_SIGNAL_FUNC (imp_ldif_file_cancel), ( gpointer ) afs );
+       afs->fileSelector = fileSelector;
+       afs->cancelled = TRUE;
+}
+
+static void imp_ldif_file_select( void ) {
+       gchar *sFile;
+       if (! _imp_ldif_file_selector_.fileSelector )
+               imp_ldif_file_select_create( & _imp_ldif_file_selector_ );
+
+       sFile = gtk_editable_get_chars( GTK_EDITABLE(impldif_dlg.file_entry), 0, -1 );
+       gtk_file_selection_set_filename( GTK_FILE_SELECTION( _imp_ldif_file_selector_.fileSelector ), sFile );
+       g_free( sFile );
+       gtk_widget_show( _imp_ldif_file_selector_.fileSelector );
+       gtk_grab_add( _imp_ldif_file_selector_.fileSelector );
+}
+
+static gint imp_ldif_delete_event( GtkWidget *widget, GdkEventAny *event, gboolean *cancelled ) {
+       *cancelled = TRUE;
+       gtk_main_quit();
+       return TRUE;
+}
+
+static void imp_ldif_key_pressed( GtkWidget *widget, GdkEventKey *event, gboolean *cancelled ) {
+       if (event && event->keyval == GDK_Escape) {
+               *cancelled = TRUE;
+               gtk_main_quit();
+       }
+}
+
+static void imp_ldif_create( gboolean *cancelled ) {
+       GtkWidget *window;
+       GtkWidget *vbox;
+       GtkWidget *table;
+       GtkWidget *label;
+       GtkWidget *file_entry;
+       GtkWidget *name_entry;
+       GtkWidget *hbbox;
+       GtkWidget *hsep;
+       GtkWidget *ok_btn;
+       GtkWidget *cancel_btn;
+       GtkWidget *file_btn;
+       GtkWidget *statusbar;
+       GtkWidget *hsbox;
+       gint top;
+
+       window = gtk_window_new(GTK_WINDOW_DIALOG);
+       gtk_widget_set_usize(window, 450, -1);
+       gtk_container_set_border_width( GTK_CONTAINER(window), 0 );
+       gtk_window_set_title( GTK_WINDOW(window), _("Import LDIF file into Address Book") );
+       gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+       gtk_window_set_modal(GTK_WINDOW(window), TRUE); 
+       gtk_signal_connect(GTK_OBJECT(window), "delete_event",
+                          GTK_SIGNAL_FUNC(imp_ldif_delete_event),
+                          cancelled);
+       gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
+                          GTK_SIGNAL_FUNC(imp_ldif_key_pressed),
+                          cancelled);
+
+       vbox = gtk_vbox_new(FALSE, 8);
+       gtk_container_add(GTK_CONTAINER(window), vbox);
+       gtk_container_set_border_width( GTK_CONTAINER(vbox), 0 );
+
+       table = gtk_table_new(2, 3, FALSE);
+       gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
+       gtk_container_set_border_width( GTK_CONTAINER(table), 8 );
+       gtk_table_set_row_spacings(GTK_TABLE(table), 8);
+       gtk_table_set_col_spacings(GTK_TABLE(table), 8 );
+
+       // First row
+       top = 0;
+       label = gtk_label_new(_("Name"));
+       gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
+       gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+       name_entry = gtk_entry_new();
+       gtk_table_attach(GTK_TABLE(table), name_entry, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+
+       // Second row
+       top = 1;
+       label = gtk_label_new(_("File"));
+       gtk_table_attach(GTK_TABLE(table), label, 0, 1, top, (top + 1), GTK_FILL, 0, 0, 0);
+       gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+       file_entry = gtk_entry_new();
+       gtk_table_attach(GTK_TABLE(table), file_entry, 1, 2, top, (top + 1), GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0, 0);
+
+       file_btn = gtk_button_new_with_label( _(" ... "));
+       gtk_table_attach(GTK_TABLE(table), file_btn, 2, 3, top, (top + 1), GTK_FILL, 0, 3, 0);
+
+       // Status line
+       hsbox = gtk_hbox_new(FALSE, 0);
+       gtk_box_pack_end(GTK_BOX(vbox), hsbox, FALSE, FALSE, BORDER_WIDTH);
+       statusbar = gtk_statusbar_new();
+       gtk_box_pack_start(GTK_BOX(hsbox), statusbar, TRUE, TRUE, BORDER_WIDTH);
+
+       // Button panel
+       gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
+                               &cancel_btn, _("Cancel"), NULL, NULL);
+       gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
+       gtk_container_set_border_width( GTK_CONTAINER(hbbox), 0 );
+       gtk_widget_grab_default(ok_btn);
+
+       hsep = gtk_hseparator_new();
+       gtk_box_pack_end(GTK_BOX(vbox), hsep, FALSE, FALSE, 0);
+
+       gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
+                          GTK_SIGNAL_FUNC(imp_ldif_ok), cancelled);
+       gtk_signal_connect(GTK_OBJECT(cancel_btn), "clicked",
+                          GTK_SIGNAL_FUNC(imp_ldif_cancel), cancelled);
+       gtk_signal_connect(GTK_OBJECT(file_btn), "clicked",
+                          GTK_SIGNAL_FUNC(imp_ldif_file_select), NULL);
+
+       gtk_widget_show_all(vbox);
+
+       impldif_dlg.window     = window;
+       impldif_dlg.file_entry = file_entry;
+       impldif_dlg.name_entry = name_entry;
+       impldif_dlg.ok_btn     = ok_btn;
+       impldif_dlg.cancel_btn = cancel_btn;
+       impldif_dlg.statusbar  = statusbar;
+       impldif_dlg.status_cid = gtk_statusbar_get_context_id( GTK_STATUSBAR(statusbar), "Import LDIF Dialog" );
+}
+
+AddressBookFile *addressbook_imp_ldif( AddressIndex *addrIndex ) {
+       static gboolean cancelled;
+
+       _importedBook_ = NULL;
+       _imp_addressIndex_ = addrIndex;
+
+       if( ! impldif_dlg.window )
+               imp_ldif_create(&cancelled);
+       gtk_widget_grab_focus(impldif_dlg.ok_btn);
+       gtk_widget_grab_focus(impldif_dlg.file_entry);
+       gtk_widget_show(impldif_dlg.window);
+       manage_window_set_transient(GTK_WINDOW(impldif_dlg.window));
+
+       imp_ldif_status_show( "" );
+       gtk_entry_set_text( GTK_ENTRY(impldif_dlg.name_entry), IMPORTLDIF_GUESS_NAME );
+
+       gtk_main();
+       gtk_widget_hide(impldif_dlg.window);
+       _imp_addressIndex_ = NULL;
+
+       if (cancelled == TRUE) return NULL;
+       return _importedBook_;
+}
+
+/*
+* End of Source.
+*/
+
diff --git a/src/importldif.h b/src/importldif.h
new file mode 100644 (file)
index 0000000..78255e7
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2001 Match Grun
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Import LDIF data.
+ */
+
+#ifndef __IMPORT_LDIF_H__
+#define __IMPORT_LDIF_H__
+
+// Function prototypes
+AddressBookFile *addressbook_imp_ldif( AddressIndex *addrIndex );
+
+#endif /* __IMPORT_LDIF_H__ */
+
+/*
+* End of Source.
+*/
+
diff --git a/src/ldif.c b/src/ldif.c
new file mode 100644 (file)
index 0000000..69cb709
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2001 Match Grun
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Functions necessary to access LDIF files (LDAP Data Interchange Format files).
+ */
+
+#include <sys/stat.h>
+#include <glib.h>
+
+#include "mgutils.h"
+#include "ldif.h"
+#include "addritem.h"
+#include "addrcache.h"
+
+/*
+* Create new cardfile object.
+*/
+LdifFile *ldif_create() {
+       LdifFile *ldifFile;
+       ldifFile = g_new0( LdifFile, 1 );
+       ldifFile->path = NULL;
+       ldifFile->file = NULL;
+       ldifFile->bufptr = ldifFile->buffer;
+       ldifFile->retVal = MGU_SUCCESS;
+       return ldifFile;
+}
+
+/*
+* Properties...
+*/
+void ldif_set_file( LdifFile* ldifFile, const gchar *value ) {
+       g_return_if_fail( ldifFile != NULL );
+       ldifFile->path = mgu_replace_string( ldifFile->path, value );
+       g_strstrip( ldifFile->path );
+}
+
+/*
+* Free up cardfile object by releasing internal memory.
+*/
+void ldif_free( LdifFile *ldifFile ) {
+       g_return_if_fail( ldifFile != NULL );
+
+       /* Close file */
+       if( ldifFile->file ) fclose( ldifFile->file );
+
+       /* Free internal stuff */
+       g_free( ldifFile->path );
+
+       /* Clear pointers */
+       ldifFile->file = NULL;
+       ldifFile->path = NULL;
+       ldifFile->retVal = MGU_SUCCESS;
+
+       /* Now release file object */
+       g_free( ldifFile );
+
+}
+
+/*
+* Display object to specified stream.
+*/
+void ldif_print_file( LdifFile *ldifFile, FILE *stream ) {
+       g_return_if_fail( ldifFile != NULL );
+       fprintf( stream, "LDIF File:\n" );
+       fprintf( stream, "file spec: '%s'\n", ldifFile->path );
+       fprintf( stream, "  ret val: %d\n",   ldifFile->retVal );
+}
+
+/*
+* Open file for read.
+* return: TRUE if file opened successfully.
+*/
+static gint ldif_open_file( LdifFile* ldifFile ) {
+       /* printf( "Opening file\n" ); */
+       if( ldifFile->path ) {
+               ldifFile->file = fopen( ldifFile->path, "r" );
+               if( ! ldifFile->file ) {
+                       /* printf( "can't open %s\n", ldifFile->path ); */
+                       ldifFile->retVal = MGU_OPEN_FILE;
+                       return ldifFile->retVal;
+               }
+       }
+       else {
+               /* printf( "file not specified\n" ); */
+               ldifFile->retVal = MGU_NO_FILE;
+               return ldifFile->retVal;
+       }
+
+       /* Setup a buffer area */
+       ldifFile->buffer[0] = '\0';
+       ldifFile->bufptr = ldifFile->buffer;
+       ldifFile->retVal = MGU_SUCCESS;
+       return ldifFile->retVal;
+}
+
+/*
+* Close file.
+*/
+static void ldif_close_file( LdifFile *ldifFile ) {
+       g_return_if_fail( ldifFile != NULL );
+       if( ldifFile->file ) fclose( ldifFile->file );
+       ldifFile->file = NULL;
+}
+
+/*
+* Read line of text from file.
+* Return: ptr to buffer where line starts.
+*/
+static gchar *ldif_get_line( LdifFile *ldifFile ) {
+       gchar buf[ LDIFBUFSIZE ];
+       gchar ch;
+       gchar *ptr;
+
+       if( feof( ldifFile->file ) ) return NULL;
+
+       ptr = buf;
+       while( TRUE ) {
+               *ptr = '\0';
+               ch = fgetc( ldifFile->file );
+               if( ch == '\0' || ch == EOF ) {
+                       if( *buf == '\0' ) return NULL;
+                       break;
+               }
+               if( ch == '\n' ) break;
+               *ptr = ch;
+               ptr++;
+       }
+
+       /* Copy into private buffer */
+       return g_strdup( buf );
+}
+
+/*
+* Parse tag name from line buffer.
+* Return: Buffer containing the tag name, or NULL if no delimiter char found.
+*/
+static gchar *ldif_get_tagname( char* line, gchar dlm ) {
+       gint len = 0;
+       gchar *tag = NULL;
+       gchar *lptr = line;
+       while( *lptr++ ) {
+               if( *lptr == dlm ) {
+                       len = lptr - line;
+                       tag = g_strndup( line, len+1 );
+                       tag[ len ] = '\0';
+                       g_strdown( tag );
+                       return tag;
+               }
+       }
+       return tag;
+}
+
+/*
+* Parse tag value from line buffer.
+* Return: Buffer containing the tag value. Empty string is returned if
+* no delimiter char found.
+*/
+static gchar *ldif_get_tagvalue( gchar* line, gchar dlm ) {
+       gchar *value = NULL;
+       gchar *start = NULL;
+       gchar *lptr;
+       gint len = 0;
+
+       for( lptr = line; *lptr; lptr++ ) {
+               if( *lptr == dlm ) {
+                       if( ! start )
+                               start = lptr + 1;
+               }
+       }
+       if( start ) {
+               len = lptr - start;
+               value = g_strndup( start, len+1 );
+       }
+       else {
+               /* Ensure that we get an empty string */
+               value = g_strndup( "", 1 );
+       }
+       value[ len ] = '\0';
+       return value;
+}
+
+/*
+* Dump linked lists of character strings (for debug).
+*/
+static void ldif_dump_lists( GSList *listName, GSList *listAddr, GSList *listRem, GSList *listID, FILE *stream ) {
+       fprintf( stream, "dump name\n" );
+       fprintf( stream, "------------\n" );
+       mgu_print_list( listName, stdout );
+       fprintf( stream, "dump address\n" );
+       fprintf( stream, "------------\n" );
+       mgu_print_list( listAddr, stdout );
+       fprintf( stream, "dump remarks\n" );
+       fprintf( stdout, "------------\n" );
+       mgu_print_list( listRem, stdout );
+       fprintf( stream, "dump id\n" );
+       fprintf( stdout, "------------\n" );
+       mgu_print_list( listID, stdout );
+}
+
+typedef struct _Ldif_ParsedRec_ Ldif_ParsedRec;
+struct _Ldif_ParsedRec_ {
+       GSList *listCName;
+       GSList *listFName;
+       GSList *listLName;
+       GSList *listNName;
+       GSList *listAddress;
+       GSList *listID;
+};
+
+/*
+* Build an address list entry and append to list of address items. Name is formatted
+* as "<first-name> <last-name>".
+*/
+static void ldif_build_items( LdifFile *ldifFile, Ldif_ParsedRec *rec, AddressCache *cache ) {
+       GSList *nodeFirst;
+       GSList *nodeAddress;
+       gchar *firstName = NULL, *lastName = NULL, *fullName = NULL, *nickName = NULL;
+       gint iLen = 0, iLenT = 0;
+       ItemPerson *person;
+       ItemEMail *email;
+
+       nodeAddress = rec->listAddress;
+       if( nodeAddress == NULL ) return;
+
+       /* Find longest first name in list */
+       nodeFirst = rec->listFName;
+       while( nodeFirst ) {
+               if( firstName == NULL ) {
+                       firstName = nodeFirst->data;
+                       iLen = strlen( firstName );
+               }
+               else {
+                       if( ( iLenT = strlen( nodeFirst->data ) ) > iLen ) {
+                               firstName = nodeFirst->data;
+                               iLen = iLenT;
+                       }
+               }
+               nodeFirst = g_slist_next( nodeFirst );
+       }
+
+       /* Format name */
+       if( rec->listLName ) {
+               lastName = rec->listLName->data;
+       }
+
+       if( firstName ) {
+               if( lastName ) {
+                       fullName = g_strdup_printf( "%s %s", firstName, lastName );
+               }
+               else {
+                       fullName = g_strdup_printf( "%s", firstName );
+               }
+       }
+       else {
+               if( lastName ) {
+                       fullName = g_strdup_printf( "%s", lastName );
+               }
+       }
+       if( fullName ) {
+               g_strchug( fullName ); g_strchomp( fullName );
+       }
+
+       if( rec->listNName ) {
+               nickName = rec->listNName->data;
+       }
+
+       person = addritem_create_item_person();
+       addritem_person_set_common_name( person, fullName );
+       addritem_person_set_first_name( person, firstName );
+       addritem_person_set_last_name( person, lastName );
+       addritem_person_set_nick_name( person, nickName );
+       addrcache_id_person( cache, person );
+       addrcache_add_person( cache, person );
+
+       /* Add address item */
+       while( nodeAddress ) {
+               email = addritem_create_item_email();
+               addritem_email_set_address( email, nodeAddress->data );
+               addrcache_id_email( cache, email );
+               addrcache_person_add_email( cache, person, email );
+               nodeAddress = g_slist_next( nodeAddress );
+       }
+       g_free( fullName );
+       fullName = firstName = lastName = NULL;
+
+}
+
+static void ldif_add_value( Ldif_ParsedRec *rec, gchar *tagName, gchar *tagValue ) {
+       gchar *nm, *val;
+
+       nm = g_strdup( tagName );
+       g_strdown( nm );
+       if( tagValue ) {
+               val = g_strdup( tagValue );
+       }
+       else {
+               val = g_strdup( "" );
+       }
+       g_strstrip( val );
+       if( strcmp( nm, LDIF_TAG_COMMONNAME ) == 0 ) {
+               rec->listCName = g_slist_append( rec->listCName, val );
+       }
+       else if( strcmp( nm, LDIF_TAG_FIRSTNAME ) == 0 ) {
+               rec->listFName = g_slist_append( rec->listFName, val );
+       }
+       else if( strcmp( nm, LDIF_TAG_LASTNAME ) == 0 ) {
+               rec->listLName = g_slist_append( rec->listLName, val );
+       }
+       else if( strcmp( nm, LDIF_TAG_NICKNAME ) == 0 ) {
+               rec->listNName = g_slist_append( rec->listNName, val );
+       }
+       else if( strcmp( nm, LDIF_TAG_EMAIL ) == 0 ) {
+               rec->listAddress = g_slist_append( rec->listAddress, val );
+       }
+       g_free( nm );
+}
+
+static void ldif_clear_rec( Ldif_ParsedRec *rec ) {
+       g_slist_free( rec->listCName );
+       g_slist_free( rec->listFName );
+       g_slist_free( rec->listLName );
+       g_slist_free( rec->listNName );
+       g_slist_free( rec->listAddress );
+       g_slist_free( rec->listID );
+       rec->listCName = NULL;
+       rec->listFName = NULL;
+       rec->listLName = NULL;
+       rec->listNName = NULL;
+       rec->listAddress = NULL;
+       rec->listID = NULL;
+}
+
+static void ldif_print_record( Ldif_ParsedRec *rec, FILE *stream ) {
+       fprintf( stdout, "LDIF Parsed Record:\n" );
+       fprintf( stdout, "common name:" );
+       mgu_print_list( rec->listCName, stdout );
+       if( ! rec->listCName ) fprintf( stdout, "\n" );
+       fprintf( stdout, "first name:" );
+       mgu_print_list( rec->listFName, stdout );
+       if( ! rec->listFName ) fprintf( stdout, "\n" );
+       fprintf( stdout, "last name:" );
+       mgu_print_list( rec->listLName, stdout );
+       if( ! rec->listLName ) fprintf( stdout, "\n" );
+       fprintf( stdout, "nick name:" );
+       mgu_print_list( rec->listNName, stdout );
+       if( ! rec->listNName ) fprintf( stdout, "\n" );
+       fprintf( stdout, "address:" );
+       mgu_print_list( rec->listAddress, stdout );
+       if( ! rec->listAddress ) fprintf( stdout, "\n" );
+       fprintf( stdout, "id:" );
+       mgu_print_list( rec->listID, stdout );
+       if( ! rec->listID ) fprintf( stdout, "\n" );
+}
+
+/*
+* Read file data into address cache.
+* Note that one LDIF record identifies one entity uniquely with the
+* distinguished name (dn) tag. Each person can have multiple E-Mail
+* addresses. Also, each person can have many common name (cn) tags.
+*/
+static void ldif_read_file( LdifFile *ldifFile, AddressCache *cache ) {
+       gchar *tagName = NULL, *tagValue = NULL;
+       gchar *lastTag = NULL, *fullValue = NULL;
+       GSList *listValue = NULL;
+       gboolean flagEOF = FALSE, flagEOR = FALSE;
+       Ldif_ParsedRec *rec;
+
+       rec = g_new0( Ldif_ParsedRec, 1 );
+       ldif_clear_rec( rec );
+
+       while( ! flagEOF ) {
+               gchar *line =  ldif_get_line( ldifFile );
+               if( line == NULL ) {
+                       flagEOF = flagEOR = TRUE;
+               }
+               else if( *line == '\0' ) {
+                       flagEOR = TRUE;
+               }
+
+               if( flagEOR ) {
+                       /* EOR, Output address data */
+                       if( lastTag ) {
+                               /* Save record */
+                               fullValue = mgu_list_coalesce( listValue );
+                               ldif_add_value( rec, lastTag, fullValue );
+                               /* ldif_print_record( rec, stdout ); */
+                               ldif_build_items( ldifFile, rec, cache );
+                               ldif_clear_rec( rec );
+                               g_free( lastTag );
+                               mgu_free_list( listValue );
+                               lastTag = NULL;
+                               listValue = NULL;
+                       }
+               }
+               if( line ) {
+                       flagEOR = FALSE;
+                       if( *line == ' ' ) {
+                               /* Continuation line */
+                               listValue = g_slist_append( listValue, g_strdup( line+1 ) );
+                       }
+                       else if( *line == '=' ) {
+                               /* Base-64 binary encode field */
+                               listValue = g_slist_append( listValue, g_strdup( line ) );
+                       }
+                       else {
+                               /* Parse line */
+                               tagName = ldif_get_tagname( line, LDIF_SEP_TAG );
+                               if( tagName ) {
+                                       tagValue = ldif_get_tagvalue( line, LDIF_SEP_TAG );
+                                       if( tagValue ) {
+                                               if( lastTag ) {
+                                                       /* Save data */
+                                                       fullValue = mgu_list_coalesce( listValue );
+                                                       ldif_add_value( rec, lastTag, fullValue );
+                                                       g_free( lastTag );
+                                                       mgu_free_list( listValue );
+                                                       lastTag = NULL;
+                                                       listValue = NULL;
+                                               }
+
+                                               lastTag = g_strdup( tagName );
+                                               listValue = g_slist_append( listValue, g_strdup( tagValue ) );
+                                               g_free( tagValue );
+                                       }
+                                       g_free( tagName );
+                               }
+                       }
+               }
+
+       }
+
+       /* Release data */
+       ldif_clear_rec( rec );
+       g_free( rec );
+       g_free( lastTag );
+       mgu_free_list( listValue );
+
+}
+
+// ============================================================================================
+/*
+* Read file into list. Main entry point
+* Enter:  ldifFile LDIF control data.
+*         cache    Address cache to load.
+* Return: Status code.
+*/
+// ============================================================================================
+gint ldif_import_data( LdifFile *ldifFile, AddressCache *cache ) {
+       g_return_val_if_fail( ldifFile != NULL, MGU_BAD_ARGS );
+       ldifFile->retVal = MGU_SUCCESS;
+       addrcache_clear( cache );
+       cache->dataRead = FALSE;
+       ldif_open_file( ldifFile );
+       if( ldifFile->retVal == MGU_SUCCESS ) {
+               /* Read data into the cache */
+               ldif_read_file( ldifFile, cache );
+               ldif_close_file( ldifFile );
+
+               /* Mark cache */
+               cache->modified = FALSE;
+               cache->dataRead = TRUE;
+       }
+       return ldifFile->retVal;
+}
+
+/*
+* End of Source.
+*/
+
diff --git a/src/ldif.h b/src/ldif.h
new file mode 100644 (file)
index 0000000..5325dbe
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2001 Match Grun
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Definitions necessary to access VCard files. VCard files are used
+ * by GnomeCard for addressbook, and Netscape for sending business
+ * card information. Refer to RFC2426 for more information.
+ */
+
+#ifndef __LDIF_H__
+#define __LDIF_H__
+
+#include <stdio.h>
+#include <glib.h>
+
+#include "addritem.h"
+#include "addrcache.h"
+
+#define LDIFBUFSIZE         2048
+
+#define        LDIF_TAG_COMMONNAME "cn"
+#define        LDIF_TAG_FIRSTNAME  "givenname"
+#define        LDIF_TAG_LASTNAME   "sn"
+#define LDIF_TAG_NICKNAME   "xmozillanickname"
+#define        LDIF_TAG_EMAIL      "mail"
+
+#define        LDIF_SEP_TAG        ':'
+
+/*
+// Typical LDIF entry (similar to that generated by Netscape):
+//
+// dn: uid=axel, dc=axel, dc=com
+// cn: Axel Rose
+// sn: Rose
+// givenname: Arnold
+// xmozillanickname: Axel
+// mail: axel@axelrose.com
+// mail: axelrose@aol.com
+// mail: axel@netscape.net
+// mail: axel@hotmail.com
+// uid: axelrose
+// o: The Company
+// locality: Denver
+// st: CO
+// streetaddress: 777 Lexington Avenue
+// postalcode: 80298
+// countryname: USA
+// telephonenumber: 303-555-1234
+// homephone: 303-555-2345
+// cellphone: 303-555-3456
+// homeurl: http://www.axelrose.com
+// objectclass: top
+// objectclass: person
+//
+// Note that first entry is always dn. Empty line defines end of record.
+//
+*/
+
+/* VCard object */
+typedef struct _LdifFile LdifFile;
+struct _LdifFile {
+       FILE         *file;
+       gchar        *path;
+       gchar        *bufptr;
+       gchar        buffer[ LDIFBUFSIZE ];
+       // AddressCache *addressCache;
+       gint         retVal;
+};
+
+/* Function prototypes */
+LdifFile *ldif_create  ( void );
+void ldif_set_file     ( LdifFile* ldifFile, const gchar *value );
+void ldif_free         ( LdifFile *ldifFile );
+gint ldif_import_data  ( LdifFile *ldifFile, AddressCache *cache );
+
+#endif /* __LDIF_H__ */
+