kpilot Library API Documentation

hotSync.cc

00001 /* hotSync.cc                           KPilot
00002 **
00003 ** Copyright (C) 2001 by Dan Pilone
00004 **
00005 ** This file defines SyncActions, which are used to perform some specific
00006 ** task during a HotSync. Conduits are not included here, nor are 
00007 ** sync actions requiring user interaction. Those can be found in the
00008 ** conduits subdirectory or interactiveSync.h.
00009 */
00010 
00011 /*
00012 ** This program is free software; you can redistribute it and/or modify
00013 ** it under the terms of the GNU General Public License as published by
00014 ** the Free Software Foundation; either version 2 of the License, or
00015 ** (at your option) any later version.
00016 **
00017 ** This program is distributed in the hope that it will be useful,
00018 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00020 ** GNU General Public License for more details.
00021 **
00022 ** You should have received a copy of the GNU General Public License
00023 ** along with this program in a file called COPYING; if not, write to
00024 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00025 ** MA 02111-1307, USA.
00026 */
00027 
00028 /*
00029 ** Bug reports and questions can be sent to kde-pim@kde.org.
00030 */
00031 
00032 static const char *hotsync_id =
00033         "$Id: hotSync.cc,v 1.18.4.7 2003/03/12 23:31:14 adridg Exp $";
00034 
00035 #include "options.h"
00036 
00037 #include <time.h>
00038 #include <unistd.h>
00039 
00040 #include <pi-file.h>
00041 
00042 #include <qtimer.h>
00043 #include <qfile.h>
00044 #include <qfileinfo.h>
00045 #include <qdir.h>
00046 #include <qvaluelist.h>
00047 #include <qregexp.h>
00048 #include <qtextcodec.h>
00049 
00050 #include <kglobal.h>
00051 #include <kstandarddirs.h>
00052 #include <kapplication.h>
00053 
00054 #include "pilotUser.h"
00055 #include "pilotAppCategory.h"
00056 
00057 #include "hotSync.moc"
00058 
00059 TestLink::TestLink(KPilotDeviceLink * p) :
00060         SyncAction(p, "testLink")
00061 {
00062         FUNCTIONSETUP;
00063 
00064         (void) hotsync_id;
00065 }
00066 
00067 /* virtual */ bool TestLink::exec()
00068 {
00069         FUNCTIONSETUP;
00070 
00071         int i;
00072         int dbindex = 0;
00073         int count = 0;
00074         struct DBInfo db;
00075 
00076         addSyncLogEntry(i18n("Testing.\n"));
00077 
00078 #ifdef BRUTE_FORCE
00079         for (i=0; i<32; i++)
00080 #else
00081         while ((i = fHandle->getNextDatabase(dbindex,&db)) > 0)
00082 #endif
00083         {
00084 #ifdef BRUTE_FORCE
00085                 if (fHandle->getNextDatabase(i,&db) < 1)
00086                 {
00087                         DEBUGKPILOT << fname << ": No database index " << i << endl;
00088                         continue;
00089                 }
00090 #endif
00091 
00092                 count++;
00093                 dbindex = db.index + 1;
00094 
00095 #ifdef DEBUG
00096                 DEBUGKPILOT << fname << ": Read database " << db.name << endl;
00097 #endif
00098 
00099                 // Let the Pilot User know what's happening
00100                 openConduit();
00101                 // Let the KDE User know what's happening
00102                 // Pretty sure all database names are in latin1.
00103                 emit logMessage(i18n("Syncing database %1...")
00104                         .arg(QString::fromLatin1(db.name)));
00105 
00106                 kapp->processEvents();
00107         }
00108 
00109         emit logMessage(i18n("HotSync finished."));
00110         emit syncDone(this);
00111         return true;
00112 }
00113 
00114 BackupAction::BackupAction(KPilotDeviceLink * p) :
00115         SyncAction(p, "backupAction")
00116 {
00117         FUNCTIONSETUP;
00118 
00119         fDatabaseDir = KGlobal::dirs()->saveLocation("data",
00120                 CSL1("kpilot/DBBackup/"));
00121 }
00122 
00123 /* virtual */ QString BackupAction::statusString() const
00124 {
00125         FUNCTIONSETUP;
00126         QString s(CSL1("BackupAction="));
00127 
00128         switch (status())
00129         {
00130         case Init:
00131                 s.append(CSL1("Init"));
00132                 break;
00133         case Error:
00134                 s.append(CSL1("Error"));
00135                 break;
00136         case FullBackup:
00137                 s.append(CSL1("FullBackup"));
00138                 break;
00139         case BackupEnded:
00140                 s.append(CSL1("BackupEnded"));
00141                 break;
00142         default:
00143                 s.append(CSL1("(unknown "));
00144                 s.append(QString::number(status()));
00145                 s.append(CSL1(")"));
00146         }
00147 
00148         return s;
00149 }
00150 
00151 
00152 /* virtual */ bool BackupAction::exec()
00153 {
00154         FUNCTIONSETUP;
00155 
00156 #ifdef DEBUG
00157         DEBUGDAEMON << fname
00158                 << ": This Pilot user's name is \""
00159                 << fHandle->getPilotUser()->getUserName() << "\"" << endl;
00160 #endif
00161 
00162         addSyncLogEntry(i18n("Full backup started."));
00163 
00164         // ASSERT(!fTimer);
00165 
00166         fTimer = new QTimer(this);
00167         QObject::connect(fTimer, SIGNAL(timeout()),
00168                 this, SLOT(backupOneDB()));
00169 
00170         fDBIndex = 0;
00171         fStatus = FullBackup;
00172 
00173         fTimer->start(0, false);
00174         return true;
00175 }
00176 
00177 /* slot */ void BackupAction::backupOneDB()
00178 {
00179         FUNCTIONSETUP;
00180 
00181         struct DBInfo info;
00182 
00183         emit logProgress(QString::null, fDBIndex);
00184 
00185         if (openConduit() < 0)
00186         {
00187 #ifdef DEBUG
00188                 DEBUGDAEMON << fname
00189                         << ": openConduit failed. User cancel?" << endl;
00190 #endif
00191 
00192                 addSyncLogEntry(i18n("Exiting on cancel."));
00193                 endBackup();
00194                 fStatus = BackupIncomplete;
00195                 return;
00196         }
00197 
00198         if (fHandle->getNextDatabase(fDBIndex, &info) < 0)
00199         {
00200 #ifdef DEBUG
00201                 DEBUGDAEMON << fname << ": Backup complete." << endl;
00202 #endif
00203 
00204                 addSyncLogEntry(i18n("Full backup complete."));
00205                 endBackup();
00206                 fStatus = BackupComplete;
00207                 return;
00208         }
00209 
00210         fDBIndex = info.index + 1;
00211 
00212         // Pretty sure all database names are latin1.
00213         QString s = i18n("Backing up: %1")
00214                 .arg(QString::fromLatin1(info.name));
00215         addSyncLogEntry(s);
00216 
00217         if (!createLocalDatabase(&info))
00218         {
00219                 kdError() << k_funcinfo
00220                         << ": Couldn't create local database for "
00221                         << info.name << endl;
00222                 addSyncLogEntry(i18n("Backup of %1 failed.\n")
00223                         .arg(QString::fromLatin1(info.name)));
00224         }
00225         else
00226         {
00227                 addSyncLogEntry(i18n(" .. OK\n"),false); // Not in kpilot log.
00228         }
00229 }
00230 
00231 bool BackupAction::createLocalDatabase(DBInfo * info)
00232 {
00233         FUNCTIONSETUP;
00234 
00235         QString fullBackupDir =
00236                 fDatabaseDir + 
00237                 PilotAppCategory::codec()->toUnicode(fHandle->getPilotUser()->getUserName()) +
00238                 CSL1("/");
00239 
00240 #ifdef DEBUG
00241         DEBUGDAEMON << fname
00242                 << ": Looking in directory " << fullBackupDir << endl;
00243 #endif
00244 
00245         QFileInfo fi(fullBackupDir);
00246 
00247         if (!(fi.exists() && fi.isDir()))
00248         {
00249 #ifdef DEBUG
00250                 DEBUGDAEMON << fname
00251                         << ": Need to create backup directory for user "
00252                         << fHandle->getPilotUser()->getUserName() << endl;
00253 #endif
00254 
00255                 fi = QFileInfo(fDatabaseDir);
00256                 if (!(fi.exists() && fi.isDir()))
00257                 {
00258                         kdError() << k_funcinfo
00259                                 << ": Database backup directory "
00260                                 << "doesn't exist."
00261                                 << endl;
00262                         return false;
00263                 }
00264 
00265                 QDir databaseDir(fDatabaseDir);
00266 
00267                 if (!databaseDir.mkdir(fullBackupDir, true))
00268                 {
00269                         kdError() << k_funcinfo
00270                                 << ": Can't create backup directory." << endl;
00271                         return false;
00272                 }
00273         }
00274 
00275         QString databaseName(QString::fromLatin1(info->name));
00276 
00277 #if QT_VERSION < 0x30100
00278         databaseName.replace(QRegExp(CSL1("/")), CSL1("_"));
00279 #else
00280         databaseName.replace('/', CSL1("_"));
00281 #endif
00282 
00283         QString fullBackupName = fullBackupDir + databaseName;
00284 
00285         if (info->flags & dlpDBFlagResource)
00286         {
00287                 fullBackupName.append(CSL1(".prc"));
00288         }
00289         else
00290         {
00291                 fullBackupName.append(CSL1(".pdb"));
00292         }
00293 
00294 #ifdef DEBUG
00295         DEBUGDB << fname
00296                 << ": Creating local database " << fullBackupName << endl;
00297 #endif
00298 
00299         /* Ensure that DB-open flag is not kept */
00300         info->flags &= ~dlpDBFlagOpen;
00301 
00302         return fHandle->retrieveDatabase(fullBackupName,info);
00303 }
00304 
00305 void BackupAction::endBackup()
00306 {
00307         FUNCTIONSETUP;
00308 
00309         KPILOT_DELETE(fTimer);
00310         fDBIndex = (-1);
00311         fStatus = BackupEnded;
00312 
00313         emit syncDone(this);
00314 }
00315 
00316 FileInstallAction::FileInstallAction(KPilotDeviceLink * p,
00317         const QString & d,
00318         const QStringList & l) :
00319         SyncAction(p, "fileInstall"),
00320         fDBIndex(-1),
00321         fTimer(0L),
00322         fDir(d),
00323         fList(l)
00324 {
00325         FUNCTIONSETUP;
00326 
00327 #ifdef DEBUG
00328         DEBUGDAEMON << fname << ": File list has "
00329                 << fList.  count() << " entries" << endl;
00330 
00331         QStringList::ConstIterator i;
00332 
00333         for (i = fList.begin(); i != fList.end(); ++i)
00334         {
00335                 DEBUGDAEMON << fname << ": " << *i << endl;
00336         }
00337 #endif
00338 }
00339 
00340 FileInstallAction::~FileInstallAction()
00341 {
00342         FUNCTIONSETUP;
00343 
00344         KPILOT_DELETE(fTimer);
00345 }
00346 
00347 /* virtual */ bool FileInstallAction::exec()
00348 {
00349         FUNCTIONSETUP;
00350 
00351         fDBIndex = 0;
00352 
00353 #ifdef DEBUG
00354         DEBUGDAEMON << fname
00355                 << ": Installing " << fList.count() << " files" << endl;
00356 #endif
00357 
00358         // Possibly no files to install?
00359         if (!fList.count())
00360         {
00361                 emit logMessage(i18n("No Files to install"));
00362                 emit syncDone(this);
00363 
00364                 return true;
00365         }
00366 
00367         fTimer = new QTimer(this);
00368         QObject::connect(fTimer, SIGNAL(timeout()),
00369                 this, SLOT(installNextFile()));
00370 
00371         fTimer->start(0, false);
00372 
00373         emit logProgress(i18n("Installing Files"), 0);
00374         return true;
00375 }
00376 
00377 /* slot */ void FileInstallAction::installNextFile()
00378 {
00379         FUNCTIONSETUP;
00380 
00381         ASSERT(fDBIndex >= 0);
00382         ASSERT((unsigned) fDBIndex <= fList.count());
00383 
00384 #ifdef DEBUG
00385         DEBUGDAEMON << fname
00386                 << ": Installing file index "
00387                 << fDBIndex << " (of " << fList.count() << ")" << endl;
00388 #endif
00389 
00390         if ((!fList.count()) || ((unsigned) fDBIndex >= fList.count()))
00391         {
00392 #ifdef DEBUG
00393                 DEBUGDAEMON << fname
00394                         << ": Peculiar file index, bailing out." << endl;
00395 #endif
00396                 KPILOT_DELETE(fTimer);
00397                 fDBIndex = (-1);
00398                 emit logProgress(i18n("Done Installing Files"), 100);
00399                 emit syncDone(this);
00400                 return;
00401         }
00402 
00403         const QString filePath = fDir + fList[fDBIndex];
00404         const QString fileName = fList[fDBIndex];
00405 
00406         fDBIndex++;
00407 
00408 #ifdef DEBUG
00409         DEBUGDAEMON << fname << ": Installing file " << filePath << endl;
00410 #endif
00411 
00412         QString m = i18n("Installing %1").arg(fileName);
00413         emit logProgress(m,(100 * fDBIndex) / (fList.count()+1));
00414         m+=QString::fromLatin1("\n");
00415         emit addSyncLogEntry(m,true /* Don't print in KPilot's log. */ );
00416 
00417 
00418         struct pi_file *f = 0L;
00419 
00420         f = pi_file_open(const_cast <char *>
00421                 ((const char *) QFile::encodeName(filePath)));
00422 
00423         if (!f)
00424         {
00425                 kdWarning() << k_funcinfo
00426                         << ": Unable to open file." << endl;
00427 
00428                 emit logError(i18n("Unable to open file &quot;%1&quot;!").
00429                         arg(fileName));
00430                 goto nextFile;
00431         }
00432 
00433         if (pi_file_install(f, pilotSocket(), 0) < 0)
00434         {
00435                 kdWarning() << k_funcinfo << ": failed to install." << endl;
00436 
00437 
00438                 emit logError(i18n("Cannot install file &quot;%1&quot;!").
00439                         arg(fileName));
00440         }
00441         else
00442         {
00443                 QFile::remove(filePath);
00444         }
00445 
00446 
00447 nextFile:
00448         if (f) pi_file_close(f);
00449         if (fDBIndex == -1)
00450         {
00451                 emit syncDone(this);
00452         }
00453 }
00454 
00455 /* virtual */ QString FileInstallAction::statusString() const
00456 {
00457         FUNCTIONSETUP;
00458         if (fDBIndex < 0)
00459         {
00460                 return QString(CSL1("Idle"));
00461         }
00462         else
00463         {
00464                 if ((unsigned) fDBIndex >= fList.count())
00465                 {
00466                         return QString(CSL1("Index out of range"));
00467                 }
00468                 else
00469                 {
00470                         return QString(CSL1("Installing %1")).arg(fList[fDBIndex]);
00471                 }
00472         }
00473 }
00474 
00475 CleanupAction::CleanupAction(KPilotDeviceLink *p)  : SyncAction(p,"cleanupAction")
00476 {
00477         FUNCTIONSETUP;
00478 }
00479 
00480 CleanupAction::~CleanupAction()
00481 {
00482 #ifdef DEBUG
00483         FUNCTIONSETUP;
00484         DEBUGDAEMON << fname
00485                 << ": Deleting @" << (int)this << endl;
00486 #endif
00487 }
00488 
00489 /* virtual */ bool CleanupAction::exec()
00490 {
00491         FUNCTIONSETUP;
00492 
00493         fHandle->finishSync();
00494         emit syncDone(this);
00495         return true;
00496 }
00497 
00498 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sat Oct 18 02:47:14 2003 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001