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