hotSync.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 static const char *hotsync_id =
00033 "$Id: hotSync.cc,v 1.27 2003/06/01 09:29:27 kainhofe 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 #include "syncStack.h"
00057 #include "pilotSerialDatabase.h"
00058 #include "pilotLocalDatabase.h"
00059 #include "pilotDatabase.h"
00060
00061 #include "hotSync.moc"
00062
00063 TestLink::TestLink(KPilotDeviceLink * p) :
00064 SyncAction(p, "testLink")
00065 {
00066 FUNCTIONSETUP;
00067
00068 (void) hotsync_id;
00069 }
00070
00071 bool TestLink::exec()
00072 {
00073 FUNCTIONSETUP;
00074
00075 int i;
00076 int dbindex = 0;
00077 int count = 0;
00078 struct DBInfo db;
00079
00080 addSyncLogEntry(i18n("Testing.\n"));
00081
00082 #ifdef BRUTE_FORCE
00083 for (i=0; i<32; i++)
00084 #else
00085 while ((i = fHandle->getNextDatabase(dbindex,&db)) > 0)
00086 #endif
00087 {
00088 #ifdef BRUTE_FORCE
00089 if (fHandle->getNextDatabase(i,&db) < 1)
00090 {
00091 DEBUGKPILOT << fname << ": No database index " << i << endl;
00092 continue;
00093 }
00094 #endif
00095
00096 count++;
00097 dbindex = db.index + 1;
00098
00099 #ifdef DEBUG
00100 DEBUGKPILOT << fname << ": Read database " << db.name << endl;
00101 #endif
00102
00103
00104 openConduit();
00105
00106
00107 emit logMessage(i18n("Syncing database %1...")
00108 .arg(QString::fromLatin1(db.name)));
00109
00110 kapp->processEvents();
00111 }
00112
00113 emit logMessage(i18n("HotSync finished."));
00114 emit syncDone(this);
00115 return true;
00116 }
00117
00118 BackupAction::BackupAction(KPilotDeviceLink * p, int mode) :
00119 SyncAction(p, "backupAction"), fMode(mode), fFullBackup(mode & ActionQueue::FlagFull)
00120 {
00121 FUNCTIONSETUP;
00122
00123 fDatabaseDir = KGlobal::dirs()->saveLocation("data",
00124 CSL1("kpilot/DBBackup/"));
00125 }
00126
00127 QString BackupAction::statusString() const
00128 {
00129 FUNCTIONSETUP;
00130 QString s(CSL1("BackupAction="));
00131
00132 switch (status())
00133 {
00134 case Init:
00135 s.append(CSL1("Init"));
00136 break;
00137 case Error:
00138 s.append(CSL1("Error"));
00139 break;
00140 case FullBackup:
00141 s.append(CSL1("FullBackup"));
00142 break;
00143 case FastBackup:
00144 s.append(CSL1("FastBackup"));
00145 break;
00146 case BackupEnded:
00147 s.append(CSL1("BackupEnded"));
00148 break;
00149 case BackupIncomplete:
00150 s.append(CSL1("BackupIncomplete"));
00151 break;
00152 case BackupComplete:
00153 s.append(CSL1("BackupComplete"));
00154 break;
00155 default:
00156 s.append(CSL1("(unknown "));
00157 s.append(QString::number(status()));
00158 s.append(CSL1(")"));
00159 }
00160
00161 return s;
00162 }
00163
00164
00165 bool BackupAction::exec()
00166 {
00167 FUNCTIONSETUP;
00168
00169 #ifdef DEBUG
00170 DEBUGDAEMON << fname
00171 << ": This Pilot user's name is \""
00172 << fHandle->getPilotUser()->getUserName() << "\"" << endl;
00173 #endif
00174
00175 fBackupDir =
00176 fDatabaseDir +
00177 PilotAppCategory::codec()->toUnicode(fHandle->getPilotUser()->getUserName()) +
00178 CSL1("/");
00179
00180 if (fFullBackup)
00181 {
00182 fStatus = FullBackup;
00183 addSyncLogEntry(i18n("Full backup started."));
00184 }
00185 else
00186 {
00187 fStatus = FastBackup;
00188 addSyncLogEntry(i18n("Fast backup started"));
00189 }
00190
00191 if (!checkBackupDirectory(fBackupDir))
00192 {
00193 fStatus=BackupIncomplete;
00194
00195
00196 return false;
00197 }
00198
00199 fTimer = new QTimer(this);
00200 QObject::connect(fTimer, SIGNAL(timeout()),
00201 this, SLOT(backupOneDB()));
00202
00203 fDBIndex = 0;
00204
00205 fTimer->start(0, false);
00206 return true;
00207 }
00208
00209 bool BackupAction::checkBackupDirectory(QString backupDir)
00210 {
00211 FUNCTIONSETUP;
00212 QFileInfo fi(backupDir);
00213
00214 if (!(fi.exists() && fi.isDir()))
00215 {
00216 #ifdef DEBUG
00217 DEBUGDAEMON << fname
00218 << ": Need to create backup directory for user "
00219 << fHandle->getPilotUser()->getUserName() << endl;
00220 #endif
00221
00222 fi = QFileInfo(fDatabaseDir);
00223 if (!(fi.exists() && fi.isDir()))
00224 {
00225 kdError() << k_funcinfo
00226 << ": Database backup directory "
00227 << "doesn't exist."
00228 << endl;
00229 return false;
00230 }
00231
00232 QDir databaseDir(backupDir);
00233
00234 if (!databaseDir.mkdir(backupDir, true))
00235 {
00236 kdError() << k_funcinfo
00237 << ": Can't create backup directory." << endl;
00238 return false;
00239 }
00240 }
00241 return true;
00242 }
00243
00244
00245 void BackupAction::backupOneDB()
00246 {
00247 FUNCTIONSETUP;
00248
00249 struct DBInfo info;
00250
00251 emit logProgress(QString::null, fDBIndex);
00252
00253 if (openConduit() < 0)
00254 {
00255 #ifdef DEBUG
00256 DEBUGDAEMON << fname
00257 << ": openConduit failed. User cancel?" << endl;
00258 #endif
00259
00260 addSyncLogEntry(i18n("Exiting on cancel."));
00261 endBackup();
00262 fStatus = BackupIncomplete;
00263 return;
00264 }
00265
00266
00267 int res=fHandle->getNextDatabase(fDBIndex, &info);
00268 if (res < 0)
00269 {
00270 #ifdef DEBUG
00271 DEBUGDAEMON << fname << ": Backup complete." << endl;
00272 #endif
00273
00274 if (fFullBackup)
00275 addSyncLogEntry(i18n("Full backup complete."));
00276 else
00277 addSyncLogEntry(i18n("Fast backup complete."));
00278 endBackup();
00279 fStatus = BackupComplete;
00280 return;
00281 }
00282
00283 fDBIndex = info.index + 1;
00284
00285
00286 QString s = i18n("Backing up: %1")
00287 .arg(QString::fromLatin1(info.name));
00288 addSyncLogEntry(s);
00289
00290 if (!createLocalDatabase(&info))
00291 {
00292 kdError() << k_funcinfo
00293 << ": Couldn't create local database for "
00294 << info.name << endl;
00295 addSyncLogEntry(i18n("Backup of %1 failed.\n")
00296 .arg(QString::fromLatin1(info.name)));
00297 }
00298 else
00299 {
00300 addSyncLogEntry(i18n(" .. OK\n"),false);
00301 }
00302 }
00303
00304 bool BackupAction::createLocalDatabase(DBInfo * info)
00305 {
00306 FUNCTIONSETUP;
00307
00308 #ifdef DEBUG
00309 DEBUGDAEMON << fname
00310 << ": Looking in directory " << fBackupDir << endl;
00311 #endif
00312
00313 QString databaseName(QString::fromLatin1(info->name));
00314 if (!fFullBackup)
00315 {
00316
00317
00318 PilotSerialDatabase*serial=new PilotSerialDatabase(pilotSocket(), databaseName);
00319 if (serial->isDBOpen())
00320 {
00321 PilotLocalDatabase*local=new PilotLocalDatabase(fBackupDir, databaseName);
00322 if (local->isDBOpen())
00323 {
00324
00325 int index=0;
00326 PilotRecord*rec=serial->readNextModifiedRec(&index);
00327 while (rec)
00328 {
00329 local->writeRecord(rec);
00330 KPILOT_DELETE(rec);
00331 rec=serial->readNextModifiedRec(&index);
00332 }
00333 KPILOT_DELETE(local);
00334 KPILOT_DELETE(serial);
00335 return true;
00336 }
00337 KPILOT_DELETE(local);
00338 }
00339 KPILOT_DELETE(serial);
00340 #ifdef DEBUG
00341 DEBUGCONDUIT<<"Fast backup not possible with database "<<info->name<<". Will do full backup on it"<<endl;
00342 #endif
00343 }
00344
00345
00346
00347 if (!checkBackupDirectory(fBackupDir)) return false;
00348
00349 #if QT_VERSION < 0x30100
00350 databaseName.replace(QRegExp(CSL1("/")), CSL1("_"));
00351 #else
00352 databaseName.replace('/', CSL1("_"));
00353 #endif
00354
00355 QString fullBackupName = fBackupDir + databaseName;
00356
00357 if (info->flags & dlpDBFlagResource)
00358 {
00359 fullBackupName.append(CSL1(".prc"));
00360 }
00361 else
00362 {
00363 fullBackupName.append(CSL1(".pdb"));
00364 }
00365
00366 #ifdef DEBUG
00367 DEBUGDB << fname
00368 << ": Creating local database " << fullBackupName << endl;
00369 #endif
00370
00371
00372 info->flags &= ~dlpDBFlagOpen;
00373
00374 return fHandle->retrieveDatabase(fullBackupName,info);
00375 }
00376
00377 void BackupAction::endBackup()
00378 {
00379 FUNCTIONSETUP;
00380
00381 KPILOT_DELETE(fTimer);
00382 fDBIndex = (-1);
00383 fStatus = BackupEnded;
00384
00385 emit syncDone(this);
00386 }
00387
00388 FileInstallAction::FileInstallAction(KPilotDeviceLink * p,
00389 const QString & d,
00390 const QStringList & l) :
00391 SyncAction(p, "fileInstall"),
00392 fDBIndex(-1),
00393 fTimer(0L),
00394 fDir(d),
00395 fList(l)
00396 {
00397 FUNCTIONSETUP;
00398
00399 #ifdef DEBUG
00400 DEBUGDAEMON << fname << ": File list has "
00401 << fList. count() << " entries" << endl;
00402
00403 QStringList::ConstIterator i;
00404
00405 for (i = fList.begin(); i != fList.end(); ++i)
00406 {
00407 DEBUGDAEMON << fname << ": " << *i << endl;
00408 }
00409 #endif
00410 }
00411
00412 FileInstallAction::~FileInstallAction()
00413 {
00414 FUNCTIONSETUP;
00415
00416 KPILOT_DELETE(fTimer);
00417 }
00418
00419 bool FileInstallAction::exec()
00420 {
00421 FUNCTIONSETUP;
00422
00423 fDBIndex = 0;
00424
00425 #ifdef DEBUG
00426 DEBUGDAEMON << fname
00427 << ": Installing " << fList.count() << " files" << endl;
00428 #endif
00429
00430 emit logMessage(i18n("[File Installer]"));
00431
00432
00433 if (!fList.count())
00434 {
00435 emit logMessage(i18n("No Files to install"));
00436 return delayDone();
00437 }
00438
00439 fTimer = new QTimer(this);
00440 QObject::connect(fTimer, SIGNAL(timeout()),
00441 this, SLOT(installNextFile()));
00442
00443 fTimer->start(0, false);
00444
00445 emit logProgress(i18n("Installing one file",
00446 "Installing %n Files",fList.count()), 0);
00447 return true;
00448 }
00449
00450 void FileInstallAction::installNextFile()
00451 {
00452 FUNCTIONSETUP;
00453
00454 Q_ASSERT(fDBIndex >= 0);
00455 Q_ASSERT((unsigned) fDBIndex <= fList.count());
00456
00457 #ifdef DEBUG
00458 DEBUGDAEMON << fname
00459 << ": Installing file index "
00460 << fDBIndex << " (of " << fList.count() << ")" << endl;
00461 #endif
00462
00463 if ((!fList.count()) || ((unsigned) fDBIndex >= fList.count()))
00464 {
00465 #ifdef DEBUG
00466 DEBUGDAEMON << fname
00467 << ": Peculiar file index, bailing out." << endl;
00468 #endif
00469 KPILOT_DELETE(fTimer);
00470 fDBIndex = (-1);
00471 emit logProgress(i18n("Done Installing Files"), 100);
00472 emit syncDone(this);
00473 return;
00474 }
00475
00476 const QString filePath = fDir + fList[fDBIndex];
00477 const QString fileName = fList[fDBIndex];
00478
00479 fDBIndex++;
00480
00481 #ifdef DEBUG
00482 DEBUGDAEMON << fname << ": Installing file " << filePath << endl;
00483 #endif
00484
00485 QString m = i18n("Installing %1").arg(fileName);
00486 emit logProgress(m,(100 * fDBIndex) / (fList.count()+1));
00487 m+=QString::fromLatin1("\n");
00488 emit addSyncLogEntry(m,true );
00489
00490
00491 struct pi_file *f = 0L;
00492
00493 f = pi_file_open(const_cast <char *>
00494 ((const char *) QFile::encodeName(filePath)));
00495
00496 if (!f)
00497 {
00498 kdWarning() << k_funcinfo
00499 << ": Unable to open file." << endl;
00500
00501 emit logError(i18n("Unable to open file "%1"!").
00502 arg(fileName));
00503 goto nextFile;
00504 }
00505
00506 if (pi_file_install(f, pilotSocket(), 0) < 0)
00507 {
00508 kdWarning() << k_funcinfo << ": failed to install." << endl;
00509
00510
00511 emit logError(i18n("Cannot install file "%1"!").
00512 arg(fileName));
00513 }
00514 else
00515 {
00516 QFile::remove(filePath);
00517 }
00518
00519
00520 nextFile:
00521 if (f) pi_file_close(f);
00522 if (fDBIndex == -1)
00523 {
00524 emit syncDone(this);
00525 }
00526 }
00527
00528 QString FileInstallAction::statusString() const
00529 {
00530 FUNCTIONSETUP;
00531 if (fDBIndex < 0)
00532 {
00533 return QString(CSL1("Idle"));
00534 }
00535 else
00536 {
00537 if ((unsigned) fDBIndex >= fList.count())
00538 {
00539 return QString(CSL1("Index out of range"));
00540 }
00541 else
00542 {
00543 return QString(CSL1("Installing %1")).arg(fList[fDBIndex]);
00544 }
00545 }
00546 }
00547
00548 CleanupAction::CleanupAction(KPilotDeviceLink *p) : SyncAction(p,"cleanupAction")
00549 {
00550 FUNCTIONSETUP;
00551 }
00552
00553 CleanupAction::~CleanupAction()
00554 {
00555 #ifdef DEBUG
00556 FUNCTIONSETUP;
00557 DEBUGDAEMON << fname
00558 << ": Deleting @" << (int)this << endl;
00559 #endif
00560 }
00561
00562 bool CleanupAction::exec()
00563 {
00564 FUNCTIONSETUP;
00565
00566 fHandle->finishSync();
00567 emit syncDone(this);
00568 return true;
00569 }
00570
00571
This file is part of the documentation for kpilot Library Version 3.2.1.