summaryrefslogtreecommitdiff
path: root/ImportTrillian/main.c
diff options
context:
space:
mode:
authormataes2007 <mataes2007@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb>2011-11-26 12:28:23 +0000
committermataes2007 <mataes2007@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb>2011-11-26 12:28:23 +0000
commit93d3575dff1db593b516821478510a4fecf0649e (patch)
treeaa407bd7452b3ef9d7b2a42e0d04212315c56621 /ImportTrillian/main.c
parentbc970507965a809727b3d5877884f21605fdf1a6 (diff)
added ImportTrillian
git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@211 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb
Diffstat (limited to 'ImportTrillian/main.c')
-rw-r--r--ImportTrillian/main.c925
1 files changed, 925 insertions, 0 deletions
diff --git a/ImportTrillian/main.c b/ImportTrillian/main.c
new file mode 100644
index 0000000..05a0724
--- /dev/null
+++ b/ImportTrillian/main.c
@@ -0,0 +1,925 @@
+/*
+ importTrillian: History & Contacts import plugin for Miranda-IM.
+ Copyright (C) 2005 Daniel 'Spin' Hofer
+
+ 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.
+*/
+#include <windows.h>
+#include <time.h>
+#include <commctrl.h>
+#include <shlobj.h>
+#include <stdio.h>
+#include <io.h>
+#include "resource.h"
+#include "newpluginapi.h"
+#include "m_langpack.h"
+#include "m_system.h"
+#include "m_database.h"
+#include "m_clist.h"
+#include "m_protomod.h"
+
+#pragma warning( disable: 4311 )
+#pragma warning( disable: 4312 )
+
+#define IMPORT_MODULE "MIMImportTrillian"
+#define IMPORT_SERVICE "MIMImportTrillian/ImportTrillian"
+#define DLG_UPDATE 0x2000
+
+#define SESS_START1 "Session Start ("
+#define SESS_START2 "Start (ICQ - "
+#define SESS_START3 "Start (MSN - "
+#define SESS_START4 "Start (AIM - "
+#define SESS_START5 "Start (Yahoo! - "
+#define SESS_START6 "Start (IRC - "
+#define SESS_STOP "Session Close ("
+
+void Utf8ToAnsi(const char *szIn, char *szOut, int cchOut);
+
+static int ImportCommand( WPARAM wParam,LPARAM lParam );
+static int ImportMessages( );
+static char line[2048];
+static char file[MAX_PATH];
+static char delBeforeDate[MAX_PATH];
+static char icqUin[32];
+
+time_t delBeforeTS;
+static HANDLE hHookModulesLoaded;
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+char status[256];
+BOOL importProt[5] = { 1, 1, 1, 1, 1 };
+BOOL importNic = TRUE;
+BOOL importCha = TRUE;
+BOOL importMsg = TRUE;
+BOOL importStat = TRUE;
+BOOL importAdd = FALSE;
+BOOL importEx = TRUE;
+BOOL skipDup = FALSE;
+BOOL repDup = TRUE;
+BOOL delBefore = FALSE;
+BOOL speedMode = TRUE;
+BOOL utf8AutoDetect = FALSE;
+BOOL utf8DoAlways = FALSE;
+int aborting = 0;
+int finished = 0;
+
+int getNick = 0;
+char lastNick[256];
+
+PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+ "Import Trillian history/contacts",
+ PLUGIN_MAKE_VERSION(0,2,0,0),
+ "Miranda IM history/contact import plugin.",
+ "Daniel \'Zpin\' Hofer",
+ "dhofer@freesurf.ch",
+ "©2006 by Daniel \'Zpin\' Hofer",
+ "http://www.zpin.ch",
+ 0,
+ 0
+};
+
+
+BOOL WINAPI DllMain( HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved )
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+static int readLine( FILE *f )
+{
+ int i = 0;
+ char chr;
+ chr = fgetc( f );
+ while( chr != '\n' && !feof( f ) && i < 2047 )
+ {
+ line[i++] = chr;
+ chr = fgetc( f );
+ }
+ line[i] = '\0';
+ return !feof( f );
+}
+
+struct tm string2Tm( char *string )
+{
+ char mon[4];
+ int mt = 0, day, hr, min, sec, yr;
+ struct tm starttime;
+
+ sscanf( string, "%3s %d %d:%d:%d %d", &mon, &day, &hr, &min, &sec, &yr );
+ if( !strcmp( mon, "Jan" ) )
+ mt = 0;
+ else if( !strcmp( mon, "Feb" ) )
+ mt = 1;
+ else if( !strcmp( mon, "Mar" ) )
+ mt = 2;
+ else if( !strcmp( mon, "Apr" ) )
+ mt = 3;
+ else if( !strcmp( mon, "May" ) )
+ mt = 4;
+ else if( !strcmp( mon, "Jun" ) )
+ mt = 5;
+ else if( !strcmp( mon, "Jul" ) )
+ mt = 6;
+ else if( !strcmp( mon, "Aug" ) )
+ mt = 7;
+ else if( !strcmp( mon, "Sep" ) )
+ mt = 8;
+ else if( !strcmp( mon, "Oct" ) )
+ mt = 9;
+ else if( !strcmp( mon, "Nov" ) )
+ mt = 10;
+ else if( !strcmp( mon, "Dec" ) )
+ mt = 11;
+
+ starttime.tm_mon = mt;
+ starttime.tm_mday = day;
+ starttime.tm_hour = hr;
+ starttime.tm_min = min;
+ starttime.tm_sec = sec;
+ starttime.tm_year = yr - 1900;
+ return starttime;
+}
+
+BOOL CALLBACK StartupDialogProc( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ FILE *fl;
+ switch( message )
+ {
+ case WM_INITDIALOG:
+ SetWindowText( hdlg, Translate( "Import settings" ) );
+
+ SetDlgItemText( hdlg, IDC_INFO1, Translate( "Trillian logs directory" ) );
+ SetDlgItemText( hdlg, IDC_INFO2, Translate( "Protocols" ) );
+ SetDlgItemText( hdlg, IDC_INFO3, Translate( "Contacts" ) );
+ SetDlgItemText( hdlg, IDC_INFO4, Translate( "Import" ) );
+ SetDlgItemText( hdlg, IDC_BROWSE, Translate( "Browse" ) );
+ SetDlgItemText( hdlg, IDC_UTF8, Translate( "UTF8" ) );
+
+ SetDlgItemText( hdlg, IDOK, Translate( "Start" ) );
+ SetDlgItemText( hdlg, IDCANCEL, Translate( "Cancel" ) );
+
+ SetDlgItemText( hdlg, IDC_IMPICQ, Translate( "Import ICQ history" ) );
+ SetDlgItemText( hdlg, IDC_IMPMSN, Translate( "Import MSN history" ) );
+ SetDlgItemText( hdlg, IDC_IMPAIM, Translate( "Import AIM history" ) );
+ SetDlgItemText( hdlg, IDC_IMPICQ, Translate( "Import ICQ history" ) );
+ SetDlgItemText( hdlg, IDC_IMPYAHOO, Translate( "Import Yahoo! history" ) );
+ SetDlgItemText( hdlg, IDC_IMPIRC, Translate( "Import IRC history" ) );
+ SetDlgItemText( hdlg, IDC_IMPCHA, Translate( "Import IRC channel history" ) );
+
+ SetDlgItemText( hdlg, IDC_IMPEX, Translate( "Import history of existing contacts" ) );
+ SetDlgItemText( hdlg, IDC_IMPADD, Translate( "Add new contacts if a contact from the history is not on the list" ) );
+ SetDlgItemText( hdlg, IDC_IMPMSG, Translate( "Import messages" ) );
+ SetDlgItemText( hdlg, IDC_SKIPDUP, Translate( "Skip duplicate messages" ) );
+ SetDlgItemText( hdlg, IDC_REPDUP, Translate( "Replace duplicate messages" ) );
+ SetDlgItemText( hdlg, IDC_DELBEF, Translate( "Delete entries before" ) );
+ SetDlgItemText( hdlg, IDC_DELBEFINFO, Translate( "(Must match this format exactly: MMM DD HH:mm:ss YYYY)" ) );
+ SetDlgItemText( hdlg, IDC_IMPSTAT, Translate( "Import status reports (filetransfers, away msg, etc.)" ) );
+ SetDlgItemText( hdlg, IDC_SPEEDMODE, Translate( "Fast mode (backup your db!)" ) );
+ SetDlgItemText( hdlg, IDC_UTF8AUTO, Translate( "Try to auto-detect UTF8 strings (is slow, detects öäüßéàèç)" ) );
+ SetDlgItemText( hdlg, IDC_UTF8ALWAYS, Translate( "Interpret logs as UTF8 files" ) );
+
+
+ ShowWindow( hdlg, SW_SHOW );
+ SendMessage( hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT)));
+ fl = fopen( "importTrillian.ini", "r" );
+ if( fl )
+ {
+ int i = -1;
+ do
+ {
+ i++;
+ file[i] = fgetc( fl );
+ } while( file[i] != EOF && file[i] != '\n' && i < MAX_PATH );
+ file[i] = '\0';
+ fclose( fl );
+ }
+
+ SendDlgItemMessage( hdlg, IDC_LOGDIR, WM_SETTEXT, 0, (DWORD)file );
+ SendDlgItemMessage( hdlg, IDC_DELBEFDATE, WM_SETTEXT, 0, (DWORD)"Mar 16 20:31:29 2005" );
+ CheckDlgButton( hdlg, IDC_IMPICQ, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPMSN, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPAIM, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPYAHOO, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPIRC, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPCHA, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPMSG, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPSTAT, TRUE );
+ CheckDlgButton( hdlg, IDC_IMPEX, TRUE );
+ CheckDlgButton( hdlg, IDC_REPDUP, TRUE );
+ CheckDlgButton( hdlg, IDC_SPEEDMODE, TRUE );
+ return TRUE;
+ case WM_COMMAND:
+ switch( LOWORD( wParam ) )
+ {
+ case IDC_BROWSE:
+ {
+ BROWSEINFO bi = { 0 };
+ LPITEMIDLIST pidl = SHBrowseForFolder( &bi );
+ bi.lpszTitle = Translate( "Please select the \'logs\' folder in your Trillian directory" );
+ if( pidl != 0 )
+ SHGetPathFromIDList ( pidl, file );
+ SendDlgItemMessage( hdlg, IDC_LOGDIR, WM_SETTEXT, 0, (DWORD)file );
+ }
+ break;
+ case IDOK:
+ {
+ struct tm time;
+ importProt[0] = IsDlgButtonChecked( hdlg, IDC_IMPICQ );
+ importProt[1] = IsDlgButtonChecked( hdlg, IDC_IMPMSN );
+ importProt[2] = IsDlgButtonChecked( hdlg, IDC_IMPAIM );
+ importProt[3] = IsDlgButtonChecked( hdlg, IDC_IMPYAHOO );
+ importNic = IsDlgButtonChecked( hdlg, IDC_IMPIRC );
+ importCha = IsDlgButtonChecked( hdlg, IDC_IMPCHA );
+ importProt[4] = importNic || importCha;
+ importMsg = IsDlgButtonChecked( hdlg, IDC_IMPMSG );
+ importStat = IsDlgButtonChecked( hdlg, IDC_IMPSTAT );
+ importAdd = IsDlgButtonChecked( hdlg, IDC_IMPADD );
+ importEx = IsDlgButtonChecked( hdlg, IDC_IMPEX );
+ skipDup = IsDlgButtonChecked( hdlg, IDC_SKIPDUP );
+ repDup = IsDlgButtonChecked( hdlg, IDC_REPDUP );
+ delBefore = IsDlgButtonChecked( hdlg, IDC_DELBEF );
+ speedMode = IsDlgButtonChecked( hdlg, IDC_SPEEDMODE );
+ utf8AutoDetect = IsDlgButtonChecked( hdlg, IDC_UTF8AUTO );
+ utf8DoAlways = IsDlgButtonChecked( hdlg, IDC_UTF8ALWAYS );
+ GetDlgItemText( hdlg, IDC_LOGDIR, file, MAX_PATH-1 );
+ GetDlgItemText( hdlg, IDC_DELBEFDATE, delBeforeDate, MAX_PATH-1 );
+ time = string2Tm( delBeforeDate );
+ delBeforeTS = mktime( &time );
+ fl = fopen( "importTrillian.ini", "w" );
+ if( fl )
+ {
+ fprintf( fl, "%s", file );
+ fclose( fl );
+ }
+ if( ( importProt[0] || importProt[1] || importProt[2] || importProt[3] || importProt[4] ) && ( importMsg || importStat ) )
+ {
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ DestroyWindow(hdlg);
+ ImportMessages( );
+ }
+ else
+ MessageBox( hdlg, Translate( "There's nothing to import, please\nselect a protocol." ), Translate( "Invalid settings" ), 0 );
+ } break;
+ case IDCANCEL:
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ break;
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hdlg);
+ aborting = 1;
+ break;
+ }
+ return FALSE;
+}
+
+BOOL CALLBACK ProgressDialogProc( HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ switch( message )
+ {
+ case WM_INITDIALOG:
+ SetWindowText( hdlg, Translate( "Importing History" ) );
+
+ SetDlgItemText( hdlg, IDC_INFO5, Translate( "Import in progress..." ) );
+ SetDlgItemText( hdlg, IDC_INFO6, Translate( "Overall (current protocol)" ) );
+ SetDlgItemText( hdlg, IDC_INFO7, Translate( "File" ) );
+
+ SetDlgItemText( hdlg, IDOK, Translate( "OK" ) );
+ SetDlgItemText( hdlg, IDCANCEL, Translate( "Cancel" ) );
+
+ ShowWindow( hdlg, SW_SHOW );
+ SendMessage( hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon( hInst,MAKEINTRESOURCE(IDI_IMPORT) ) );
+ return TRUE;
+ case WM_COMMAND:
+ switch( LOWORD( wParam ) )
+ {
+ case IDOK:
+ if( finished )
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ break;
+ case IDCANCEL:
+ {
+ int ret;
+ ret = MessageBox( hdlg, Translate( "WARNING: If you cancel now and continue later you might\nget duplicate entries. Cancel anyways?" ), Translate( "Warning" ), MB_YESNO );
+ if( ret == IDYES )
+ PostMessage( hdlg, WM_CLOSE, 0, 0 );
+ break;
+ }
+ }
+ break;
+ case DLG_UPDATE:
+ SendDlgItemMessage( hdlg, IDC_STATUS, WM_SETTEXT, 0, (DWORD)status );
+ SendDlgItemMessage( hdlg, IDC_FILEP, PBM_SETPOS, wParam, 0 );
+ SendDlgItemMessage( hdlg, IDC_OVERP, PBM_SETPOS, lParam, 0 );
+ break;
+ case WM_CLOSE:
+ DestroyWindow( hdlg );
+ aborting = 1;
+ break;
+ }
+ return FALSE;
+}
+
+HANDLE GetContactByID( char* proto, char *idname, char* id )
+{
+ HANDLE contact;
+ char *otherproto;
+ DBVARIANT dbv;
+ DWORD idnum = atol(id);
+
+ contact = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while( contact != NULL)
+ {
+ otherproto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)contact, 0 );
+ if( ( otherproto != NULL ) && !strcmp( otherproto, proto ) )
+ {
+ if( !DBGetContactSetting( contact, proto, idname, &dbv ) )
+ {
+ switch( dbv.type )
+ {
+ case DBVT_BYTE:
+ if( dbv.bVal == idnum )
+ return contact;
+ break;
+ case DBVT_WORD:
+ if( dbv.wVal == idnum )
+ return contact;
+ break;
+ case DBVT_DWORD:
+ if( dbv.dVal == idnum )
+ return contact;
+ break;
+ default:
+ case DBVT_ASCIIZ:
+ if( !strcmp( id, dbv.pszVal ) )
+ {
+ DBFreeVariant( &dbv );
+ return contact;
+ }
+ break;
+ }
+ }
+ }
+ contact = (HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)contact, 0 );
+ }
+ return INVALID_HANDLE_VALUE;
+}
+
+HANDLE DeleteContactEventsBefore( HANDLE hContact, time_t ts )
+{
+ HANDLE hDbEvent, hPrev;
+ DBEVENTINFO dbei;
+
+ if( !( hDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0 ) ) )
+ return INVALID_HANDLE_VALUE;
+
+ while( hDbEvent != NULL )
+ {
+ ZeroMemory( &dbei, sizeof(dbei) );
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = 0;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei );
+
+ hPrev = hDbEvent;
+ hDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDNEXT, (WPARAM)hDbEvent, 0 );
+ if( (time_t)dbei.timestamp < ts )
+ CallService( MS_DB_EVENT_DELETE, (WPARAM)hContact, (LPARAM)hPrev );
+ }
+ return INVALID_HANDLE_VALUE;
+}
+
+//*****************************************
+// MODIFIED CODE FROM THE IMPORT.DLL PLUGIN!
+//*****************************************
+HANDLE IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei )
+{
+ HANDLE hExistingDbEvent;
+ DBEVENTINFO dbeiExisting;
+
+ if( !( hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0 ) ) )
+ return INVALID_HANDLE_VALUE;
+ ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) );
+ dbeiExisting.cbSize = sizeof(dbeiExisting);
+ dbeiExisting.cbBlob = 0;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting );
+ if( dbei.timestamp > dbeiExisting.timestamp )
+ return INVALID_HANDLE_VALUE;
+
+ if( !( hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0 ) ) )
+ return INVALID_HANDLE_VALUE;
+ ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) );
+ dbeiExisting.cbSize = sizeof(dbeiExisting);
+ dbeiExisting.cbBlob = 0;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting );
+ if( dbei.timestamp < dbeiExisting.timestamp )
+ return INVALID_HANDLE_VALUE;
+
+
+ while( hExistingDbEvent != NULL )
+ {
+ char *blob;
+ ZeroMemory( &dbeiExisting, sizeof(dbeiExisting) );
+ dbeiExisting.cbSize = sizeof(dbeiExisting);
+ dbeiExisting.cbBlob = CallService( MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hExistingDbEvent, (LPARAM)0 );
+ blob = malloc( dbeiExisting.cbBlob );
+ dbeiExisting.pBlob = blob;
+ CallService( MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting );
+ if( dbei.timestamp < dbeiExisting.timestamp )
+ {
+ free( blob );
+ return INVALID_HANDLE_VALUE;
+ }
+ // Compare event with import candidate
+ if( ( dbei.timestamp == dbeiExisting.timestamp ) &&
+ ( dbei.eventType == dbeiExisting.eventType ) &&
+ ( dbei.cbBlob == dbeiExisting.cbBlob ) )
+ {
+ if( !strcmp( dbei.pBlob, dbeiExisting.pBlob ) )
+ {
+ free( blob );
+ return hExistingDbEvent;
+ }
+ }
+ free( blob );
+ // Get next event in chain
+ hExistingDbEvent = (HANDLE)CallService( MS_DB_EVENT_FINDNEXT, (WPARAM)hExistingDbEvent, 0 );
+ }
+ return INVALID_HANDLE_VALUE;
+}
+
+HANDLE AddNumericContact( char* pszProtoName, char* pszUniqueSetting, DWORD dwID, char* pzsNick )
+{
+ HANDLE hContact = INVALID_HANDLE_VALUE;
+ hContact = (HANDLE)CallService( MS_DB_CONTACT_ADD, 0, 0 );
+ if( CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName ) != 0 )
+ {
+ CallService( MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0 );
+ return INVALID_HANDLE_VALUE;
+ }
+ DBWriteContactSettingDword( hContact, pszProtoName, pszUniqueSetting, dwID );
+ if( pzsNick && pzsNick[0] )
+ DBWriteContactSettingString( hContact, "CList", "MyHandle", pzsNick );
+ return hContact;
+}
+
+HANDLE AddContact( char* pszProtoName, char* pszUniqueSetting, char* pszID, char* pzsNick )
+{
+ HANDLE hContact = INVALID_HANDLE_VALUE;
+ hContact = (HANDLE)CallService( MS_DB_CONTACT_ADD, 0, 0 );
+ if( CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)pszProtoName ) != 0 )
+ {
+ CallService( MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0 );
+ return INVALID_HANDLE_VALUE;
+ }
+ DBWriteContactSettingString( hContact, pszProtoName, pszUniqueSetting, pszID );
+ if( pzsNick && pzsNick[0] )
+ DBWriteContactSettingString( hContact, "CList", "MyHandle", pzsNick );
+ return hContact;
+}
+
+// szIn, pointer to source string
+// szOut, pointer to destination buffer
+// cchOut, size of destination buffer
+void Utf8ToAnsi( const char *szIn, char *szOut, int cchOut )
+{
+ if( GetVersion( ) != 4 || !( GetVersion( ) & 0x80000000 ) )
+ {
+ WCHAR *wszTemp;
+ int inlen;
+ inlen = (int)strlen(szIn);
+ wszTemp = (WCHAR *)malloc( sizeof(WCHAR) * (inlen + 1) );
+ MultiByteToWideChar( CP_UTF8, 0, szIn, -1, wszTemp, inlen + 1 );
+ WideCharToMultiByte( CP_ACP, 0, wszTemp, -1, szOut, cchOut, NULL, NULL );
+ free(wszTemp);
+ }
+ else
+ {
+ for( ; *szIn && cchOut > 1; szIn++ )
+ {
+ if( *szIn >= 0 )
+ {
+ *szOut++ = *szIn;
+ cchOut--;
+ }
+ else
+ {
+ unsigned short wideChar;
+ if( (unsigned char)*szIn >= 0xe0 )
+ {
+ wideChar = ((szIn[0]&0x0f) << 12)
+ | ((szIn[1]&0x3f) << 6)
+ | (szIn[2]&0x3f);
+ szIn += 2;
+ }
+ else
+ {
+ wideChar = ( (szIn[0]&0x1f) << 6 ) | ( szIn[1]&0x3f );
+ szIn++;
+ }
+ if( wideChar >= 0x100 ) *szOut++ = '?';
+ else *szOut++ = (char)wideChar;
+ cchOut--;
+ }
+ }
+ *szOut = '\0';
+ }
+}
+//*****************************************
+// END CODE FROM THE IMPORT.DLL PLUGIN!
+//*****************************************
+
+BOOL importSingleHistory( char *logpath, HANDLE *hContact, char *prot, HWND *dlg, float overal )
+{
+ int i = 0, lineNr, lineTotal = 0, lastflag = 0, imp = 0;
+ char *time;
+ char *message;
+ DBEVENTINFO dbev;
+ HANDLE dup;
+ FILE *msg;
+ char other[256];
+ time_t startts, prev = 0;
+ struct tm starttime;
+ int hasTime = -1, timeType = 0;
+ int nameoffset[2][2] = { { 0, 8 }, { 0, 11 } };
+ BOOL doConversion = FALSE;
+ MSG pm;
+
+ msg = fopen( logpath, "r" );
+ lineTotal = 0;
+ startts = 0;
+ if( msg )
+ {
+ while( !feof( msg ) )
+ {
+ if( fgetc( msg ) == '\n' )
+ lineTotal++;
+ }
+ fseek( msg, 0, SEEK_SET );
+
+ lineNr = 0;
+ imp = FALSE;
+ }
+ lineTotal = max( 1, lineTotal );
+ while( msg && readLine( msg ) )
+ {
+ if( aborting )
+ return FALSE;
+ lineNr++;
+ ZeroMemory( &dbev, sizeof( dbev ) );
+ dbev.cbSize = sizeof(dbev);
+ dbev.eventType = EVENTTYPE_MESSAGE;
+ dbev.szModule = prot;
+
+ if( !( lineNr % 10 ) )
+ {
+ SendMessage( *dlg, DLG_UPDATE, 100 * lineNr / lineTotal, (LPARAM)overal );
+ wsprintf( status, "%s: %s %d/~%d", logpath, Translate( "line" ), lineNr, lineTotal );
+ }
+
+ if( !strlen( line ) )
+ {
+ }
+ // Inefficient but quite save.
+ else if( strstr( line, SESS_START1 )
+ || strstr( line, SESS_START2 )
+ || strstr( line, SESS_START3 )
+ || strstr( line, SESS_START4 )
+ || strstr( line, SESS_START5 ) )
+ {
+ if( !strrchr( line, ')' ) )
+ continue;
+ time = strrchr( line, ')' ) + 7;
+ starttime = string2Tm( time );
+ startts = mktime( &starttime );
+
+ hasTime = -1;
+
+ strncpy( other, strchr( line, ':' ) + 1, 255 );
+ if( strrchr( other, ')' ) )
+ *strrchr( other, ')' ) = '\0';
+ strcpy( lastNick, other );
+ }
+ else if( strstr( line, SESS_STOP ) )
+ {
+ }
+ else if( startts )
+ {
+ //FILE *f;
+ if( hasTime == -1 )
+ {
+ hasTime = 0;
+ if( line[0] == '[' && strncmp( line, other, strlen(other) ) )
+ {
+ int timelen = ( (int)strchr( line, ']' ) - (int)line );
+ if( timelen == 9 )
+ {
+ hasTime = 1;
+ timeType = 1;
+ }
+ else if( timelen == 6 )
+ {
+ hasTime = 1;
+ timeType = 0;
+ }
+ }
+ }
+
+ /*f = fopen( "test.log", "w" );
+ fprintf( f, "%s\n%s", &line[nameoffset[timeType][hasTime]], other );
+ fclose( f );*/
+ if( hasTime && line[0] != '[' )
+ {
+ if( !importMsg )
+ continue;
+ message = line;
+ dbev.flags = lastflag;
+ }
+ else if( !strncmp( &line[nameoffset[timeType][hasTime]], other, strlen(other) ) )
+ {
+ if( !importMsg )
+ continue;
+ dbev.flags = DBEF_READ;
+ message = line + nameoffset[timeType][hasTime] + strlen( other ) + 2;
+ }
+ else if( !strncmp( &line[nameoffset[timeType][hasTime]], "*** ", 4 ) )
+ {
+ if( !importStat )
+ continue;
+ dbev.flags = DBEF_READ;
+ message = line + nameoffset[timeType][hasTime];
+ }
+ else
+ {
+ if( !importMsg )
+ continue;
+ message = strchr( line + nameoffset[timeType][hasTime], ':' ) + 2;
+ if( (int)message == 2 )
+ message = line + nameoffset[timeType][hasTime] + 1;
+ dbev.flags = DBEF_SENT | DBEF_READ;
+ }
+
+ if( hasTime && line[0] == '[' && line[3] == ':')
+ {
+ int hr, min, sec;
+ if( timeType == 1 )
+ {
+ sscanf( line, "[%d:%d:%d", &hr, &min, &sec );
+ starttime.tm_sec = sec;
+ }
+ else
+ {
+ sscanf( line, "[%d:%d", &hr, &min );
+ starttime.tm_sec = 0;
+ }
+ starttime.tm_hour = hr;
+ starttime.tm_min = min;
+ startts = mktime( &starttime );
+ }
+ //if( startts == prev )
+ // startts += 4;
+
+ doConversion = FALSE;
+ if( utf8AutoDetect )
+ {
+ //Whatever :)
+ if( strstr( message, "ä" )
+ || strstr( message, "ö" )
+ || strstr( message, "ü" )
+ || strstr( message, "Ä" )
+ || strstr( message, "Ö" )
+ || strstr( message, "Ü" )
+ || strstr( message, "ß" )
+ || strstr( message, "é" )
+ || strstr( message, "à" )
+ || strstr( message, "è" )
+ || strstr( message, "É" )
+ || strstr( message, "À" )
+ || strstr( message, "È" )
+ || strstr( message, "ç" ) )
+ doConversion = TRUE;
+ }
+ else if( utf8DoAlways )
+ doConversion = TRUE;
+ if( doConversion )
+ Utf8ToAnsi( message, message, (int)strlen(message) );
+ imp = TRUE;
+
+ lastflag = dbev.flags;
+ dbev.timestamp = (DWORD)startts;
+ dbev.cbBlob = (DWORD)strlen( message ) + 1;
+ dbev.pBlob = (PBYTE)malloc( dbev.cbBlob );
+ CopyMemory( dbev.pBlob, message, dbev.cbBlob );
+ dbev.pBlob[dbev.cbBlob - 1] = 0;
+ if( ( dup = IsDuplicateEvent( *hContact, dbev ) ) == INVALID_HANDLE_VALUE )
+ CallService( MS_DB_EVENT_ADD, (WPARAM)*hContact, (LPARAM)&dbev );
+ else if( repDup )
+ {
+ CallService( MS_DB_EVENT_DELETE, (WPARAM)*hContact, (LPARAM)dup );
+ CallService( MS_DB_EVENT_ADD, (WPARAM)*hContact, (LPARAM)&dbev );
+ }
+ else
+ wsprintf( status, "Skipping dublicate entries..." );
+
+ prev = startts;
+ free( dbev.pBlob );
+ }
+ if( PeekMessage( &pm, NULL, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &pm );
+ DispatchMessage( &pm );
+ }
+ }
+ if( msg )
+ fclose( msg );
+ return imp;
+}
+
+struct import
+{
+ char prot[8];
+ char id[8];
+ int num;
+};
+
+int numFiles( char *path )
+{
+ struct _finddata_t fl;
+ long curFl;
+ int num = 0;
+
+ if( ( curFl = (long)_findfirst( path, &fl ) ) == -1L )
+ return num;
+
+ while( _findnext( curFl, &fl ) == 0 )
+ {
+ num++;
+ }
+ _findclose( curFl );
+ return num;
+}
+
+struct import importList[6] =
+{
+ { "ICQ", "UIN", 1 },
+ { "MSN", "e-mail", 0 },
+ { "AIM", "SN", 0 },
+ { "YAHOO", "yahoo_id", 0 },
+ { "IRC", "Nick", 0 },
+ { "", "", 0 }
+};
+
+static int ImportMessages( )
+{
+ int i = 0, numImp = 0, contTotal = 0, contNr = 0, o;
+ HANDLE hContact;
+ char msgpath[128];
+ char id[64];
+ HWND dlg;
+ MSG pm;
+ struct _finddata_t fl;
+ long curFl;
+ int len, first = 1;
+
+ aborting = 0;
+ finished = 0;
+
+ dlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_TRILLIAN), NULL, (DLGPROC)ProgressDialogProc );
+ //contTotal = (int)CallService( MS_DB_CONTACT_GETCOUNT, 0, 0 );
+
+ if( speedMode )
+ CallService( MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0 );
+
+ while( !aborting && strlen( importList[i].prot ) )
+ {
+ if( !importProt[i] )
+ {
+ i++;
+ continue;
+ }
+ for( o = 0; o < 2; o++ )
+ {
+ first = 1;
+ contNr = -1;
+ sprintf( msgpath, "%s\\%s%s\\*.log", file, importList[i].prot, o == 0 ? "" : "\\Query" );
+ contTotal = numFiles( msgpath );
+
+ curFl = (long)_findfirst( msgpath, &fl );
+ //if( ( curFl = (long)_findfirst( msgpath, &fl ) ) == -1L )
+ // MessageBox( dlg, Translate( "No logs found for this protocol." ), importList[i].prot, 0 );
+
+ while( !aborting && ( ( first && curFl != -1 ) || ( _findnext( curFl, &fl ) == 0 ) ) )
+ {
+ first = 0;
+ contNr++;
+ if( !strncmp( fl.name, importList[i].prot, strlen( importList[i].prot ) ) )
+ continue;
+ if( !strcmp( importList[i].prot, "IRC" ) )
+ {
+ if( strchr( fl.name, '#' ) )
+ {
+ if( !importCha )
+ continue;
+ }
+ else if( !importNic )
+ continue;
+ }
+ len = (long)strrchr( fl.name, '.' ) - (long)fl.name;
+ strncpy( id, fl.name, len );
+ id[len] = '\0';
+ getNick = FALSE;
+
+ hContact = GetContactByID( importList[i].prot, importList[i].id, id );
+
+ sprintf( msgpath, "%s\\%s%s\\%s.log", file, importList[i].prot, o == 0 ? "" : "\\Query", id );
+ if( ( hContact == INVALID_HANDLE_VALUE ) && importAdd )
+ {
+ if( importList[i].num )
+ hContact = AddNumericContact( importList[i].prot, importList[i].id, atol(id), 0 );
+ else
+ hContact = AddContact( importList[i].prot, importList[i].id, id, 0 );
+ getNick = TRUE;
+ }
+ else if( !importEx )
+ continue;
+ if( delBefore )
+ DeleteContactEventsBefore( hContact, delBeforeTS );
+ if( ( hContact != INVALID_HANDLE_VALUE ) && importSingleHistory( msgpath, &hContact, importList[i].prot, &dlg, 100.0f * contNr / contTotal ) )
+ numImp++;
+ if( getNick )
+ DBWriteContactSettingString( hContact, "CList", "MyHandle", lastNick );
+ }
+ _findclose( curFl );
+ }
+ i++;
+ }
+
+ if( speedMode )
+ CallService( MS_DB_SETSAFETYMODE, (WPARAM)TRUE, 0 );
+
+ finished = 1;
+
+ wsprintf( status, Translate( "Done importing %d contact history files!" ), numImp );
+ if( numImp == 0 )
+ strcat( status, Translate( "\nCheck your UIN and path settings. Path musst end with \\logs" ) );
+ SendMessage( dlg, DLG_UPDATE, 100, 100 );
+
+ while( PeekMessage( &pm, NULL, 0, 0, PM_REMOVE ) )
+ {
+ TranslateMessage( &pm );
+ DispatchMessage( &pm );
+ }
+ return 0;
+}
+
+static int ImportCommand( WPARAM wParam,LPARAM lParam )
+{
+ HWND dlg;
+ strcpy( file, "C:\\Program Files\\Trillian\\users\\default\\logs" );
+ dlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_STARTUP), NULL, (DLGPROC)StartupDialogProc );
+ return 0;
+}
+
+__declspec(dllexport) PLUGININFO* MirandaPluginInfo( DWORD mirandaVersion )
+{
+ if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 1, 1, 0))
+ return NULL;
+
+ return &pluginInfo;
+}
+
+int __declspec(dllexport) Load( PLUGINLINK *link )
+{
+ CLISTMENUITEM mi;
+
+ pluginLink = link;
+ CreateServiceFunction( IMPORT_SERVICE, ImportCommand );
+
+ ZeroMemory( &mi, sizeof( mi ) );
+ mi.cbSize = sizeof( mi );
+ mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_IMPORT));
+ mi.pszName = Translate( Translate( "Import Trillian history/contacts..." ) );
+ mi.position = 500050000;
+ mi.pszService = IMPORT_SERVICE;
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi );
+ return 0;
+}
+
+
+int __declspec(dllexport) Unload( void )
+{
+ return 0;
+} \ No newline at end of file