kpilot

mal-conduit.cc

Go to the documentation of this file.
00001 /*
00002 ** MAL conduit for KPilot
00003 **
00004 ** Copyright (C) 2002 by Reinhold Kainhofer
00005 */
00006 
00007 /*
00008 ** This program is free software; you can redistribute it and/or modify
00009 ** it under the terms of the GNU General Public License as published by
00010 ** the Free Software Foundation; either version 2 of the License, or
00011 ** (at your option) any later version.
00012 **
00013 ** This program is distributed in the hope that it will be useful,
00014 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016 ** GNU General Public License for more details.
00017 **
00018 ** You should have received a copy of the GNU General Public License
00019 ** along with this program in a file called COPYING; if not, write to
00020 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00021 ** MA 02110-1301, USA.
00022 **
00023 **
00024 ** Specific permission is granted for this code to be linked to libmal
00025 ** (this is necessary because the libmal license is not GPL-compatible).
00026 */
00027  
00028 /*
00029 ** Bug reports and questions can be sent to kde-pim@kde.org
00030 */
00031  
00032 
00033 
00034 
00035 #include "options.h"
00036 
00037 #include <qregexp.h>
00038 #include <kconfig.h>
00039 #include <kdebug.h>
00040 
00041 #include "mal-factory.h"
00042 #include "mal-conduit.moc"
00043 #include <libmal.h>
00044 #include "malconduitSettings.h"
00045 
00046 
00047 static MALConduit *conduitInstance=0L;
00048 
00049 int malconduit_logf(const char *, ...) __attribute__ ((format (printf, 1, 2)));
00050 
00051 int malconduit_logf(const char *format, ...)
00052 {
00053     FUNCTIONSETUP;
00054     va_list val;
00055     int rval;
00056     va_start(val, format);
00057 #define WRITE_MAX_BUF   4096
00058     char msg[WRITE_MAX_BUF];
00059     msg[0]='\0';
00060     rval=vsnprintf(&msg[0], sizeof(msg), format, val);
00061     va_end(val);
00062     if (rval == -1) {
00063         msg[WRITE_MAX_BUF-1] = '\0';
00064         rval=WRITE_MAX_BUF-1;
00065     }
00066     if (conduitInstance)
00067     {
00068         conduitInstance->printLogMessage(msg);
00069     }
00070     else
00071     {
00072         // write out to stderr
00073         WARNINGKPILOT<< msg << endl;
00074     }
00075     return rval;
00076 }
00077  
00078 #ifndef LIBMAL20
00079 int32 cbTask (void * /*out*/,
00080         int32 * /*returnErrorCode*/,
00081         char *currentTask,
00082         AGBool /*bufferable*/)
00083 {
00084     if (currentTask) {
00085         malconduit_logf ("%s\n", currentTask);
00086     }
00087 
00088     return AGCLIENT_CONTINUE;
00089 }
00090 
00091 static int32 cbItem (void */*out*/,
00092         int32 * /*returnErrorCode*/,
00093         int32   /*currentItemNumber*/,
00094         int32   /*totalItemCount*/,
00095         char *  /*currentItem*/)
00096 {
00097 //  The log widget only supports writing out whole lines. You just can't add a single character 
00098 //  to the last line. Thus I completely remove the pseudo-percentbar.
00099 /*    malconduit_logf (".");
00100 
00101     if (currentItemNumber == totalItemCount) {
00102         malconduit_logf ("\n");
00103     }
00104 */
00105     return AGCLIENT_CONTINUE;
00106 }
00107 #endif
00108 
00109  
00110 MALConduit::MALConduit(KPilotLink * o,
00111     const char *n, 
00112     const QStringList & a) :
00113     ConduitAction(o, n, a)
00114 {
00115     FUNCTIONSETUP;
00116 #ifdef LIBMAL20
00117     register_printStatusHook(malconduit_logf);
00118     register_printErrorHook(malconduit_logf);
00119 #endif
00120     conduitInstance=this;
00121     fConduitName=i18n("MAL");
00122 }
00123 
00124 
00125 
00126 MALConduit::~MALConduit()
00127 {
00128     FUNCTIONSETUP;
00129 }
00130 
00131 
00132 
00133 void MALConduit::readConfig()
00134 {
00135     FUNCTIONSETUP;
00136     MALConduitSettings::self()->readConfig();
00137 #ifdef DEBUG
00138     DEBUGKPILOT<<"Last sync was "<<MALConduitSettings::lastMALSync().toString()<<endl;
00139 #endif
00140 }
00141 
00142 
00143 
00144 void MALConduit::saveConfig()
00145 {
00146     FUNCTIONSETUP;
00147     MALConduitSettings::setLastMALSync( QDateTime::currentDateTime() );
00148     MALConduitSettings::self()->writeConfig();
00149 }
00150 
00151 
00152 
00153 bool MALConduit::skip() 
00154 {
00155     QDateTime now=QDateTime::currentDateTime();
00156     QDateTime lastSync=MALConduitSettings::lastMALSync();
00157     
00158     if (!lastSync.isValid() || !now.isValid()) return false;
00159     
00160     switch ( MALConduitSettings::syncFrequency() ) 
00161     {
00162         case MALConduitSettings::eEveryHour:
00163             if ( (lastSync.secsTo(now)<=3600) && (lastSync.time().hour()==now.time().hour()) ) return true;
00164             else return false;
00165         case MALConduitSettings::eEveryDay:
00166             if ( lastSync.date() == now.date() ) return true;
00167             else return false;
00168         case MALConduitSettings::eEveryWeek:
00169             if ( (lastSync.daysTo(now)<=7)  && ( lastSync.date().dayOfWeek()<=now.date().dayOfWeek()) ) return true;
00170             else return false;
00171         case MALConduitSettings::eEveryMonth:
00172             if ( (lastSync.daysTo(now)<=31) && (lastSync.date().month()==now.date().month()) ) return true;
00173             else return false;
00174         case MALConduitSettings::eEverySync:
00175         default:
00176             return false;
00177     }
00178     return false;
00179 }
00180 
00181 
00182 
00183 /* virtual */ bool MALConduit::exec()
00184 {
00185     FUNCTIONSETUP;
00186 
00187     readConfig();
00188     
00189     // TODO: set the log/error message hooks of libmal here!!!
00190 
00191     if (skip()) 
00192     {
00193         emit logMessage(i18n("Skipping MAL sync, because last synchronization was not long enough ago."));
00194         emit syncDone(this);
00195         return true;
00196     }
00197     
00198     // Now initiate the sync.
00199     PalmSyncInfo* pInfo=syncInfoNew();
00200     if (!pInfo) {
00201         WARNINGKPILOT << "Could not allocate SyncInfo!" << endl;
00202         emit logError(i18n("MAL synchronization failed (no SyncInfo)."));
00203         return false;
00204     }
00205 
00206     QString proxyServer( MALConduitSettings::proxyServer() );
00207     int proxyPort( MALConduitSettings::proxyPort() );
00208     QString syncMessage;
00209     bool canContinue = true;
00210     // Set all proxy settings
00211     switch (MALConduitSettings::proxyType()) 
00212     {
00213         case MALConduitSettings::eProxyHTTP:
00214             if (proxyServer.isEmpty()) 
00215             {
00216                 canContinue = false;
00217                 syncMessage = i18n("No proxy server is set.");
00218                 break;
00219             }
00220             syncMessage = i18n("Using proxy server: %1").arg(proxyServer);
00221 
00222 #ifdef DEBUG
00223             DEBUGKPILOT<<" Using HTTP proxy server \""<<proxyServer<<
00224                 "\", Port "<<proxyPort<<", User "<<MALConduitSettings::proxyUser()<<
00225                 ", Password "<<( (MALConduitSettings::proxyPassword().isEmpty())?QString("not "):QString())<<"set"
00226                 <<endl;
00227 #endif
00228 #ifdef LIBMAL20
00229             setHttpProxy(const_cast<char *>(proxyServer.latin1()));
00230             if (proxyPort>0 && proxyPort<65536) setHttpProxyPort( proxyPort );
00231             else setHttpProxyPort(80);
00232 #else
00233             pInfo->httpProxy = new char[ proxyServer.length() + 1 ];
00234             strlcpy( pInfo->httpProxy, proxyServer.latin1(), proxyServer.length() + 1);
00235             if (proxyPort>0 && proxyPort<65536) pInfo->httpProxyPort = proxyPort;
00236             else pInfo->httpProxyPort = 80;
00237 #endif
00238             
00239             if (!MALConduitSettings::proxyUser().isEmpty()) 
00240             {
00241 #ifdef LIBMAL20
00242                 setProxyUsername( const_cast<char *>(MALConduitSettings::proxyUser().latin1()) );
00243                 if (!MALConduitSettings::proxyPassword().isEmpty()) setProxyPassword( const_cast<char *>(MALConduitSettings::proxyPassword().latin1()) );
00244 #else
00245                 pInfo->proxyUsername = new char[ MALConduitSettings::proxyUser().length() + 1 ];
00246                 strlcpy( pInfo->proxyUsername, MALConduitSettings::proxyUser().latin1(), MALConduitSettings::proxyUser().length() + 1);
00247                 if (!MALConduitSettings::proxyPassword().isEmpty()) {
00248 //                      pInfo->proxyPassword = MALConduitSettings::proxyPassword().latin1();
00249                     pInfo->proxyPassword = new char[ MALConduitSettings::proxyPassword().length() + 1 ];
00250                     strlcpy( pInfo->proxyPassword, MALConduitSettings::proxyPassword().latin1(), MALConduitSettings::proxyPassword().length() + 1);
00251                 }
00252 #endif
00253             }
00254             break;
00255         case MALConduitSettings::eProxySOCKS:
00256             if (proxyServer.isEmpty()) 
00257             {
00258                 canContinue = false;
00259                 syncMessage = i18n("No SOCKS proxy is set.");
00260                 break;
00261             }
00262             syncMessage = i18n("Using SOCKS proxy: %1").arg(proxyServer);
00263 #ifdef DEBUG
00264             DEBUGKPILOT<<" Using SOCKS proxy server \""<<proxyServer<<"\",  Port "<<proxyPort<<", User "<<MALConduitSettings::proxyUser()<<", Password "<<( (MALConduitSettings::proxyPassword().isEmpty())?QString("not "):QString() )<<"set"<<endl;
00265 #endif
00266 #ifdef LIBMAL20
00267             setSocksProxy( const_cast<char *>(proxyServer.latin1()) );
00268             if (proxyPort>0 && proxyPort<65536) setSocksProxyPort( proxyPort );
00269             else setSocksProxyPort(1080);
00270 #else
00271 //          pInfo->socksProxy = proxyServer.latin1();
00272             pInfo->socksProxy = new char[ proxyServer.length() + 1 ];
00273             strlcpy( pInfo->socksProxy, proxyServer.latin1(), proxyServer.length() + 1);
00274             if (proxyPort>0 && proxyPort<65536) pInfo->socksProxyPort = proxyPort;
00275             else pInfo->socksProxyPort = 1080;
00276 #endif
00277             break; 
00278         default:
00279             break;
00280     }
00281 
00282     logMessage(syncMessage);
00283 
00284     if (!canContinue)
00285     {
00286         return false;
00287     }
00288 
00289 #ifdef LIBMAL20
00290     malsync( pilotSocket(), pInfo);
00291 #else
00292     pInfo->sd = pilotSocket();
00293     pInfo->taskFunc = cbTask;
00294     pInfo->itemFunc = cbItem;
00295     malsync( pInfo );
00296     delete[] pInfo->httpProxy;
00297     delete[] pInfo->proxyUsername;
00298     delete[] pInfo->proxyPassword;
00299     delete[] pInfo->socksProxy;
00300     syncInfoFree(pInfo);
00301 #endif
00302 
00303     saveConfig();
00304     return delayDone();
00305 }
00306 
00307 void MALConduit::printLogMessage(QString msg)
00308 {
00309     FUNCTIONSETUP;
00310     // Remove the pseudo-progressbar:
00311     QString newmsg(msg);
00312     newmsg.replace( QRegExp("^\\s*\\.*\\s*"), "");
00313     newmsg.replace( QRegExp("\\s*\\.*\\s*$"), "");
00314     if (newmsg.length()>0)
00315     {
00316         emit logMessage(newmsg);
00317     }
00318 }
00319