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