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 static const char *kpilotlink_id = "$Id: kpilotlink.cc 444649 2005-08-10 13:21:07Z mlaurent $";
00029
00030 #include "options.h"
00031
00032
00033
00034 #include <sys/stat.h>
00035 #include <sys/types.h>
00036 #include <stdio.h>
00037 #include <unistd.h>
00038 #include <fcntl.h>
00039 #include <errno.h>
00040
00041 #include <iostream>
00042
00043 #include <pi-source.h>
00044 #include <pi-socket.h>
00045 #include <pi-dlp.h>
00046 #include <pi-file.h>
00047 #if !(PILOT_LINK_NUMBER < PILOT_LINK_0_12_0)
00048 #include <pi-buffer.h>
00049 #endif
00050
00051 #include <qdir.h>
00052 #include <qtimer.h>
00053 #include <qdatetime.h>
00054 #include <qsocketnotifier.h>
00055 #include <qthread.h>
00056 #include <qtextcodec.h>
00057
00058 #include <kconfig.h>
00059 #include <kmessagebox.h>
00060 #include <kstandarddirs.h>
00061
00062 #include "pilotUser.h"
00063 #include "pilotSysInfo.h"
00064 #include "pilotCard.h"
00065 #include "pilotAppCategory.h"
00066
00067 #include "kpilotlink.moc"
00068
00069
00070
00071 class KPilotDeviceLink::KPilotDeviceLinkPrivate
00072 {
00073 public:
00074 static KPilotDeviceLinkPrivate*self()
00075 {
00076 if (!mThis) mThis = new KPilotDeviceLinkPrivate();
00077 return mThis;
00078 }
00079
00080 bool canBind( QString device )
00081 {
00082 showList();
00083 return !mBoundDevices.contains( device );
00084 }
00085
00086 void bindDevice( QString device )
00087 {
00088 mBoundDevices.append( device );
00089 showList();
00090 }
00091
00092 void unbindDevice( QString device )
00093 {
00094 mBoundDevices.remove( device );
00095 showList();
00096 }
00097
00098 protected:
00099 KPilotDeviceLinkPrivate() {}
00100 ~KPilotDeviceLinkPrivate() {}
00101
00102 QStringList mBoundDevices;
00103 static KPilotDeviceLinkPrivate*mThis;
00104
00105 private:
00106 inline void showList() const
00107 {
00108 #ifdef DEBUG
00109 FUNCTIONSETUPL(3);
00110 DEBUGDAEMON << fname << "Bound devices: "
00111 << ((mBoundDevices.count() > 0) ? mBoundDevices.join(CSL1(", ")) : CSL1("<none>")) << endl;
00112 #endif
00113 }
00114 } ;
00115
00116 KPilotDeviceLink::KPilotDeviceLinkPrivate *KPilotDeviceLink::KPilotDeviceLinkPrivate::mThis = 0L;
00117
00118
00119 KPilotDeviceLink::KPilotDeviceLink(QObject * parent, const char *name, const QString &tempDevice) :
00120 QObject(parent, name),
00121 fLinkStatus(Init),
00122 fTickleDone(true),
00123 fTickleThread(0L),
00124 fWorkaroundUSB(false),
00125 fWorkaroundUSBTimer(0L),
00126 fPilotPath(QString::null),
00127 fRetries(0),
00128 fOpenTimer(0L),
00129 fSocketNotifier(0L),
00130 fSocketNotifierActive(false),
00131 fPilotMasterSocket(-1),
00132 fCurrentPilotSocket(-1),
00133 fTempDevice(tempDevice),
00134 fPilotUser(0L),
00135 fPilotSysInfo(0L)
00136 {
00137 FUNCTIONSETUP;
00138
00139 #ifdef DEBUG
00140 DEBUGDAEMON << fname
00141 << ": Pilot-link version " << PILOT_LINK_NUMBER
00142 << endl;
00143 #endif
00144
00145 messagesMask=0xffffffff;
00146
00147 (void) kpilotlink_id;
00148 }
00149
00150 KPilotDeviceLink::~KPilotDeviceLink()
00151 {
00152 FUNCTIONSETUP;
00153 close();
00154 KPILOT_DELETE(fWorkaroundUSBTimer);
00155 KPILOT_DELETE(fPilotSysInfo);
00156 KPILOT_DELETE(fPilotUser);
00157 }
00158
00159 void KPilotDeviceLink::close()
00160 {
00161 FUNCTIONSETUP;
00162
00163 KPILOT_DELETE(fWorkaroundUSBTimer);
00164 KPILOT_DELETE(fOpenTimer);
00165 KPILOT_DELETE(fSocketNotifier);
00166 fSocketNotifierActive=false;
00167 #ifdef DEBUG
00168 DEBUGDAEMON << fname
00169 << ": Closing sockets "
00170 << fCurrentPilotSocket
00171 << " and "
00172 << fPilotMasterSocket
00173 << endl;
00174 #endif
00175 if (fCurrentPilotSocket != -1)
00176 {
00177 pi_close(fCurrentPilotSocket);
00178
00179
00180 ::close(fCurrentPilotSocket);
00181 }
00182 if (fPilotMasterSocket != -1)
00183 {
00184 pi_close(fPilotMasterSocket);
00185 ::close(fPilotMasterSocket);
00186 }
00187 KPilotDeviceLinkPrivate::self()->unbindDevice( fRealPilotPath );
00188 fPilotMasterSocket = (-1);
00189 fCurrentPilotSocket = (-1);
00190 }
00191
00192 void KPilotDeviceLink::reset(const QString & dP)
00193 {
00194 FUNCTIONSETUP;
00195
00196 fLinkStatus = Init;
00197 fRetries = 0;
00198
00199
00200
00201 close();
00202 fPilotPath = QString::null;
00203
00204 fPilotPath = dP;
00205 if (fPilotPath.isEmpty())
00206 fPilotPath = fTempDevice;
00207 if (fPilotPath.isEmpty())
00208 return;
00209
00210 reset();
00211 }
00212
00213 static inline void startOpenTimer(KPilotDeviceLink *dev, QTimer *&t)
00214 {
00215 if ( !t ){
00216 t = new QTimer(dev);
00217 QObject::connect(t, SIGNAL(timeout()),
00218 dev, SLOT(openDevice()));
00219 }
00220 t->start(1000, false);
00221 }
00222
00223 void KPilotDeviceLink::reset()
00224 {
00225 FUNCTIONSETUP;
00226
00227 messages=0;
00228 close();
00229
00230 checkDevice();
00231
00232
00233 startOpenTimer(this,fOpenTimer);
00234
00235 fLinkStatus = WaitingForDevice;
00236 }
00237
00238 void KPilotDeviceLink::checkDevice()
00239 {
00240
00241
00242
00243 QFileInfo fi(fPilotPath);
00244 if (fi.exists())
00245 {
00246
00247
00248 if (!(fi.isReadable() && fi.isWritable()))
00249 {
00250 emit logError(i18n("Pilot device %1 is not read-write.")
00251 .arg(fPilotPath));
00252 }
00253 }
00254 else
00255 {
00256
00257
00258
00259 emit logError(i18n("Pilot device %1 does not exist. "
00260 "Probably it is a USB device and will appear during a HotSync.")
00261 .arg(fPilotPath));
00262 messages |= (OpenMessage | OpenFailMessage);
00263 }
00264 }
00265
00266 void KPilotDeviceLink::setTempDevice( const QString &d )
00267 {
00268 fTempDevice = d;
00269 KPilotDeviceLinkPrivate::self()->bindDevice( fTempDevice );
00270 }
00271
00272 void KPilotDeviceLink::openDevice()
00273 {
00274 FUNCTIONSETUPL(2);
00275
00276
00277
00278
00279 if (fLinkStatus == WaitingForDevice)
00280 {
00281 fLinkStatus = FoundDevice;
00282 }
00283
00284 shouldPrint(OpenMessage,i18n("Trying to open device %1...")
00285 .arg(fPilotPath));
00286
00287 if (open())
00288 {
00289 emit logMessage(i18n("Device link ready."));
00290 }
00291 else if (open(fTempDevice))
00292 {
00293 emit logMessage(i18n("Device link ready."));
00294 }
00295 else
00296 {
00297 shouldPrint(OpenFailMessage,i18n("Could not open device: %1 "
00298 "(will retry)").
00299 arg(fPilotPath));
00300
00301 if (fLinkStatus != PilotLinkError)
00302 {
00303 startOpenTimer(this,fOpenTimer);
00304 }
00305 }
00306 }
00307
00308 bool KPilotDeviceLink::open(QString device)
00309 {
00310 FUNCTIONSETUPL(2);
00311
00312 int ret;
00313 int e = 0;
00314 QString msg;
00315
00316 if (fCurrentPilotSocket != -1)
00317 {
00318
00319 pi_close(fCurrentPilotSocket);
00320 ::close(fCurrentPilotSocket);
00321 }
00322 fCurrentPilotSocket = (-1);
00323
00324 if ( device.isEmpty() )
00325 {
00326 device = pilotPath();
00327 }
00328 if (device.isEmpty())
00329 {
00330 kdWarning() << k_funcinfo
00331 << ": No point in trying empty device."
00332 << endl;
00333
00334 msg = i18n("The Pilot device is not configured yet.");
00335 e = 0;
00336 goto errInit;
00337 }
00338 fRealPilotPath = KStandardDirs::realPath ( device );
00339
00340 if ( !KPilotDeviceLinkPrivate::self()->canBind( fRealPilotPath ) ) {
00341 msg = i18n("Already listening on that device");
00342 e=0;
00343 kdWarning() << k_funcinfo <<": Pilot Path " << pilotPath().latin1() << " already connected." << endl;
00344 goto errInit;
00345 }
00346
00347
00348 if (fPilotMasterSocket == -1)
00349 {
00350 #ifdef DEBUG
00351 DEBUGDAEMON << fname << ": Typing to open " << fRealPilotPath << endl;
00352 #endif
00353
00354 #if PILOT_LINK_NUMBER < PILOT_LINK_0_10_0
00355 fPilotMasterSocket = pi_socket(PI_AF_SLP,
00356 PI_SOCK_STREAM, PI_PF_PADP);
00357 #else
00358 fPilotMasterSocket = pi_socket(PI_AF_PILOT,
00359 PI_SOCK_STREAM, PI_PF_DLP);
00360 #endif
00361
00362 if (fPilotMasterSocket<1)
00363 {
00364 e = errno;
00365 msg = i18n("Cannot create socket for communicating "
00366 "with the Pilot");
00367 goto errInit;
00368 }
00369
00370 #ifdef DEBUG
00371 DEBUGDAEMON << fname
00372 << ": Got master " << fPilotMasterSocket << endl;
00373 #endif
00374
00375 fLinkStatus = CreatedSocket;
00376 }
00377
00378 Q_ASSERT(fLinkStatus == CreatedSocket);
00379
00380 #ifdef DEBUG
00381 DEBUGDAEMON << fname << ": Binding to path " << fPilotPath << endl;
00382 #endif
00383
00384 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
00385 struct pi_sockaddr addr;
00386 #if PILOT_LINK_NUMBER < PILOT_LINK_0_10_0
00387 addr.pi_family = PI_AF_SLP;
00388 #else
00389 addr.pi_family = PI_AF_PILOT;
00390 #endif
00391 strlcpy(addr.pi_device, QFile::encodeName(device),sizeof(addr.pi_device));
00392
00393 ret = pi_bind(fPilotMasterSocket,
00394 (struct sockaddr *) &addr, sizeof(addr));
00395 #else
00396 ret = pi_bind(fPilotMasterSocket, QFile::encodeName(device));
00397 #endif
00398
00399 if (ret >= 0)
00400 {
00401 fLinkStatus = DeviceOpen;
00402 if( fOpenTimer)
00403 fOpenTimer->stop();
00404
00405 KPilotDeviceLinkPrivate::self()->bindDevice( fRealPilotPath );
00406 fSocketNotifier = new QSocketNotifier(fPilotMasterSocket,
00407 QSocketNotifier::Read, this);
00408 QObject::connect(fSocketNotifier, SIGNAL(activated(int)),
00409 this, SLOT(acceptDevice()));
00410 fSocketNotifierActive=true;
00411
00412 if (fWorkaroundUSB)
00413 {
00414 #ifdef DEBUG
00415 DEBUGDAEMON << fname << ": Adding Z31 workaround." << endl;
00416 #endif
00417
00418
00419
00420
00421 fWorkaroundUSBTimer = new QTimer(this);
00422 connect(fWorkaroundUSBTimer,SIGNAL(timeout()),
00423 this,SLOT(workaroundUSB()));
00424 fWorkaroundUSBTimer->start(5000,true);
00425 }
00426
00427 return true;
00428 }
00429 else
00430 {
00431 #ifdef DEBUG
00432 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
00433 DEBUGDAEMON << fname
00434 << ": Tried "
00435 << addr.pi_device
00436 << " and got "
00437 << strerror(errno)
00438 << endl;
00439 #else
00440 DEBUGDAEMON << fname
00441 << ": Tried " << device << " and got " << strerror(errno) << endl;
00442 #endif
00443 #endif
00444
00445 if (fRetries < 5)
00446 {
00447 return false;
00448 }
00449 e = errno;
00450 msg = i18n("Cannot open Pilot port \"%1\". ");
00451 if (fOpenTimer )
00452 fOpenTimer->stop();
00453
00454
00455 }
00456
00457
00458
00459
00460
00461
00462
00463 errInit:
00464 close();
00465
00466 if (msg.find('%'))
00467 {
00468 if (fPilotPath.isEmpty())
00469 {
00470 msg = msg.arg(i18n("(empty)"));
00471 }
00472 else
00473 {
00474 msg = msg.arg(fPilotPath);
00475 }
00476 }
00477 switch (e)
00478 {
00479 case ENOENT:
00480 msg += i18n(" The port does not exist.");
00481 break;
00482 case ENODEV:
00483 msg += i18n(" These is no such device.");
00484 break;
00485 case EPERM:
00486 msg += i18n(" You do not have permission to open the "
00487 "Pilot device.");
00488 break;
00489 default:
00490 msg += i18n(" Check Pilot path and permissions.");
00491 }
00492
00493
00494
00495
00496
00497
00498 kdError() << k_funcinfo << ": " << msg << endl;
00499 if (e)
00500 {
00501 kdError() << k_funcinfo
00502 << ": (" << strerror(e) << ")" << endl;
00503 }
00504
00505 fLinkStatus = PilotLinkError;
00506 emit logError(msg);
00507 return false;
00508 }
00509
00510 void KPilotDeviceLink::acceptDevice()
00511 {
00512 FUNCTIONSETUP;
00513
00514 int ret;
00515
00516 if (!fSocketNotifierActive)
00517 {
00518 if (!fAcceptedCount)
00519 {
00520 kdWarning() << k_funcinfo << ": Accidentally in acceptDevice()"
00521 << endl;
00522 }
00523 fAcceptedCount++;
00524 if (fAcceptedCount>10)
00525 {
00526
00527 KPILOT_DELETE(fSocketNotifier);
00528 }
00529 return;
00530 }
00531
00532 if (fSocketNotifier)
00533 {
00534
00535 fSocketNotifierActive=false;
00536 }
00537
00538 #ifdef DEBUG
00539 DEBUGDAEMON << fname
00540 << ": Found connection on device "<<pilotPath().latin1()<<endl;
00541 DEBUGDAEMON << fname
00542 << ": Current status "
00543 << statusString()
00544 << " and master " << fPilotMasterSocket << endl;
00545 #endif
00546
00547 ret = pi_listen(fPilotMasterSocket, 1);
00548 if (ret == -1)
00549 {
00550 char *s = strerror(errno);
00551
00552 kdWarning() << "pi_listen: " << s << endl;
00553
00554
00555
00556 emit logError(i18n("Cannot listen on Pilot socket (%1)").
00557 arg(QString::fromLocal8Bit(s)));
00558
00559 close();
00560 return;
00561 }
00562
00563 KPILOT_DELETE(fWorkaroundUSBTimer);
00564
00565 emit logProgress(QString::null,10);
00566
00567 fCurrentPilotSocket = pi_accept(fPilotMasterSocket, 0, 0);
00568 if (fCurrentPilotSocket == -1)
00569 {
00570 char *s = strerror(errno);
00571
00572 kdWarning() << "pi_accept: " << s << endl;
00573
00574 emit logError(i18n("Cannot accept Pilot (%1)")
00575 .arg(QString::fromLocal8Bit(s)));
00576
00577 fLinkStatus = PilotLinkError;
00578 close();
00579 return;
00580 }
00581
00582 if ((fLinkStatus != DeviceOpen) || (fPilotMasterSocket == -1))
00583 {
00584 fLinkStatus = PilotLinkError;
00585 kdError() << k_funcinfo
00586 << ": Already connected or unable to connect!"
00587 << endl;
00588 emit logError(i18n("Cannot accept Pilot (%1)")
00589 .arg(i18n("already connected")));
00590 close();
00591 return;
00592 }
00593
00594 emit logProgress(QString::null, 30);
00595
00596 KPILOT_DELETE(fPilotSysInfo);
00597 fPilotSysInfo = new KPilotSysInfo;
00598 if (dlp_ReadSysInfo(fCurrentPilotSocket, fPilotSysInfo->sysInfo()) < 0)
00599 {
00600 emit logError(i18n("Unable to read system information from Pilot"));
00601 fLinkStatus=PilotLinkError;
00602 return;
00603 }
00604 #ifdef DEBUG
00605 else
00606 {
00607 DEBUGDAEMON << fname
00608 << ": RomVersion=" << fPilotSysInfo->getRomVersion()
00609 << " Locale=" << fPilotSysInfo->getLocale()
00610 #if PILOT_LINK_NUMBER < PILOT_LINK_0_10_0
00611
00612 #else
00613 << " Product=" << fPilotSysInfo->getProductID()
00614 #endif
00615 << endl;
00616 }
00617 #endif
00618 fPilotSysInfo->boundsCheck();
00619
00620 emit logProgress(QString::null, 60);
00621 KPILOT_DELETE(fPilotUser);
00622 fPilotUser = new KPilotUser;
00623
00624
00625 #ifdef DEBUG
00626 DEBUGDAEMON << fname << ": Reading user info @"
00627 << (long) fPilotUser << endl;
00628 DEBUGDAEMON << fname << ": Buffer @"
00629 << (long) fPilotUser->pilotUser() << endl;
00630 #endif
00631
00632 dlp_ReadUserInfo(fCurrentPilotSocket, fPilotUser->pilotUser());
00633
00634 #ifdef DEBUG
00635 DEBUGDAEMON << fname
00636 << ": Read user name " << fPilotUser->getUserName() << endl;
00637 #endif
00638
00639 emit logProgress(i18n("Checking last PC..."), 90);
00640
00641
00642 if ((ret=dlp_OpenConduit(fCurrentPilotSocket)) < 0)
00643 {
00644 #ifdef DEBUG
00645 DEBUGDAEMON << k_funcinfo
00646 << ": dlp_OpenConduit returned " << ret << endl;
00647 #endif
00648
00649 #if 0
00650 fLinkStatus = SyncDone;
00651 emit logMessage(i18n
00652 ("Exiting on cancel. All data not restored."));
00653 return;
00654 #endif
00655 emit logError(i18n("Could not read user information from the Pilot. "
00656 "Perhaps you have a password set on the device?"));
00657 }
00658 fLinkStatus = AcceptedDevice;
00659
00660
00661 emit logProgress(QString::null, 100);
00662 emit deviceReady( this );
00663 }
00664
00665 void KPilotDeviceLink::workaroundUSB()
00666 {
00667 FUNCTIONSETUP;
00668
00669 Q_ASSERT((fLinkStatus == DeviceOpen) || (fLinkStatus == WorkaroundUSB));
00670 if (fLinkStatus == DeviceOpen)
00671 {
00672 reset();
00673 }
00674 fLinkStatus = WorkaroundUSB;
00675
00676 if (!QFile::exists(fRealPilotPath))
00677 {
00678
00679
00680 startOpenTimer(this,fOpenTimer);
00681 return;
00682 }
00683 if (fOpenTimer)
00684 {
00685 fOpenTimer->stop();
00686 }
00687 KPILOT_DELETE(fWorkaroundUSBTimer);
00688 QTimer::singleShot(1000,this,SLOT(workaroundUSB()));
00689 }
00690
00691 bool KPilotDeviceLink::tickle() const
00692 {
00693
00694
00695 return pi_tickle(pilotSocket()) >= 0;
00696 }
00697
00698 class TickleThread : public QThread
00699 {
00700 public:
00701 TickleThread(KPilotDeviceLink *d, bool *done, int timeout) :
00702 QThread(),
00703 fHandle(d),
00704 fDone(done),
00705 fTimeout(timeout)
00706 { };
00707 virtual ~TickleThread();
00708
00709 virtual void run();
00710
00711 static const int ChecksPerSecond = 5;
00712 static const int SecondsPerTickle = 5;
00713
00714 private:
00715 KPilotDeviceLink *fHandle;
00716 bool *fDone;
00717 int fTimeout;
00718 } ;
00719
00720 TickleThread::~TickleThread()
00721 {
00722 }
00723
00724 void TickleThread::run()
00725 {
00726 FUNCTIONSETUP;
00727 int subseconds = ChecksPerSecond;
00728 int ticktock = SecondsPerTickle;
00729 int timeout = fTimeout;
00730 #ifdef DEBUG_CERR
00731 DEBUGDAEMON << fname << ": Running for " << timeout << " seconds." << endl;
00732 DEBUGDAEMON << fname << ": Done @" << (void *) fDone << endl;
00733 #endif
00734 while (!(*fDone))
00735 {
00736 QThread::msleep(1000/ChecksPerSecond);
00737 if (!(--subseconds))
00738 {
00739 #ifdef DEBUG_CERR
00740
00741 DEBUGDAEMON << fname << ": One second." << endl;
00742 #endif
00743 if (timeout)
00744 {
00745 if (!(--timeout))
00746 {
00747 QApplication::postEvent(fHandle, new QEvent((QEvent::Type)(KPilotDeviceLink::TickleTimeoutEvent)));
00748 break;
00749 }
00750 }
00751 subseconds=ChecksPerSecond;
00752 if (!(--ticktock))
00753 {
00754 #ifdef DEBUG_CERR
00755 DEBUGDAEMON << fname << ": Kietel kietel!." << endl;
00756 #endif
00757 ticktock=SecondsPerTickle;
00758 fHandle->tickle();
00759 }
00760 }
00761 }
00762 #ifdef DEBUG_CERR
00763 DEBUGDAEMON << fname << ": Finished." << endl;
00764 #endif
00765 }
00766
00767
00768
00769
00770
00771
00772 bool KPilotDeviceLink::event(QEvent *e)
00773 {
00774 if (e->type() == TickleTimeoutEvent)
00775 {
00776 stopTickle();
00777 emit timeout();
00778 return true;
00779 }
00780 else return QObject::event(e);
00781 }
00782
00783
00784
00785
00786 void KPilotDeviceLink::startTickle(unsigned int timeout)
00787 {
00788 FUNCTIONSETUP;
00789
00790 Q_ASSERT(fTickleDone);
00791
00792
00793
00794
00795
00796
00797 if (fTickleDone && fTickleThread)
00798 {
00799 fTickleThread->wait();
00800 KPILOT_DELETE(fTickleThread);
00801 }
00802
00803 #ifdef DEBUG
00804 DEBUGDAEMON << fname << ": Done @" << (void *) (&fTickleDone) << endl;
00805 #endif
00806 fTickleDone = false;
00807 fTickleThread = new TickleThread(this,&fTickleDone,timeout);
00808 fTickleThread->start();
00809 }
00810
00811 void KPilotDeviceLink::stopTickle()
00812 {
00813 FUNCTIONSETUP;
00814 fTickleDone = true;
00815 if (fTickleThread)
00816 {
00817 fTickleThread->wait();
00818 KPILOT_DELETE(fTickleThread);
00819 }
00820 }
00821
00822
00823 int KPilotDeviceLink::installFiles(const QStringList & l, const bool deleteFiles)
00824 {
00825 FUNCTIONSETUP;
00826
00827 QStringList::ConstIterator i;
00828 int k = 0;
00829 int n = 0;
00830
00831 for (i = l.begin(); i != l.end(); ++i)
00832 {
00833 emit logProgress(QString::null,
00834 (int) ((100.0 / l.count()) * (float) n));
00835
00836 if (installFile(*i, deleteFiles))
00837 k++;
00838 n++;
00839 }
00840 emit logProgress(QString::null, 100);
00841
00842 return k;
00843 }
00844
00845 bool KPilotDeviceLink::installFile(const QString & f, const bool deleteFile)
00846 {
00847 FUNCTIONSETUP;
00848
00849 #ifdef DEBUG
00850 DEBUGDAEMON << fname << ": Installing file " << f << endl;
00851 #endif
00852
00853 if (!QFile::exists(f))
00854 return false;
00855
00856 char buffer[PATH_MAX];
00857 memset(buffer,0,PATH_MAX);
00858 strlcpy(buffer,QFile::encodeName(f),PATH_MAX);
00859 struct pi_file *pf =
00860 pi_file_open(buffer);
00861
00862 if (!f)
00863 {
00864 kdWarning() << k_funcinfo
00865 << ": Cannot open file " << f << endl;
00866 emit logError(i18n
00867 ("<qt>Cannot install the file "%1".</qt>").
00868 arg(f));
00869 return false;
00870 }
00871
00872 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
00873 if (pi_file_install(pf, fCurrentPilotSocket, 0) < 0)
00874 #else
00875 if (pi_file_install(pf, fCurrentPilotSocket, 0, 0L) < 0)
00876 #endif
00877 {
00878 kdWarning() << k_funcinfo
00879 << ": Cannot pi_file_install " << f << endl;
00880 emit logError(i18n
00881 ("<qt>Cannot install the file "%1".</qt>").
00882 arg(f));
00883 return false;
00884 }
00885
00886 pi_file_close(pf);
00887 if (deleteFile) QFile::remove(f);
00888
00889 return true;
00890 }
00891
00892
00893 void KPilotDeviceLink::addSyncLogEntry(const QString & entry, bool log)
00894 {
00895 FUNCTIONSETUP;
00896 if (entry.isEmpty()) return;
00897
00898 QString t(entry);
00899
00900 #if PILOT_LINK_NUMBER < PILOT_LINK_0_11_0
00901 t.append("X");
00902 #endif
00903
00904 dlp_AddSyncLogEntry(fCurrentPilotSocket,
00905 const_cast<char *>((const char *)PilotAppCategory::codec()->fromUnicode(entry)));
00906 if (log)
00907 {
00908 emit logMessage(entry);
00909 }
00910 }
00911
00912 int KPilotDeviceLink::openConduit()
00913 {
00914 return dlp_OpenConduit(fCurrentPilotSocket);
00915 }
00916
00917 QString KPilotDeviceLink::statusString(LinkStatus l)
00918 {
00919 FUNCTIONSETUP;
00920 QString s = CSL1("KPilotDeviceLink=");
00921
00922 switch (l)
00923 {
00924 case Init:
00925 s.append(CSL1("Init"));
00926 break;
00927 case WaitingForDevice:
00928 s.append(CSL1("WaitingForDevice"));
00929 break;
00930 case FoundDevice:
00931 s.append(CSL1("FoundDevice"));
00932 break;
00933 case CreatedSocket:
00934 s.append(CSL1("CreatedSocket"));
00935 break;
00936 case DeviceOpen:
00937 s.append(CSL1("DeviceOpen"));
00938 break;
00939 case AcceptedDevice:
00940 s.append(CSL1("AcceptedDevice"));
00941 break;
00942 case SyncDone:
00943 s.append(CSL1("SyncDone"));
00944 break;
00945 case PilotLinkError:
00946 s.append(CSL1("PilotLinkError"));
00947 break;
00948 case WorkaroundUSB:
00949 s.append(CSL1("WorkaroundUSB"));
00950 break;
00951 }
00952
00953 return s;
00954 }
00955
00956 QString KPilotDeviceLink::statusString() const
00957 {
00958 return statusString( status() );
00959 }
00960
00961 void KPilotDeviceLink::endOfSync()
00962 {
00963 dlp_EndOfSync(pilotSocket(), 0);
00964 KPILOT_DELETE(fPilotSysInfo);
00965 KPILOT_DELETE(fPilotUser);
00966 }
00967
00968 void KPilotDeviceLink::finishSync()
00969 {
00970 FUNCTIONSETUP ;
00971
00972 getPilotUser()->setLastSyncPC((unsigned long) gethostid());
00973 getPilotUser()->setLastSyncDate(time(0));
00974
00975
00976 #ifdef DEBUG
00977 DEBUGDAEMON << fname << ": Writing username " << getPilotUser()->getUserName() << endl;
00978 #endif
00979 dlp_WriteUserInfo(pilotSocket(),getPilotUser()->pilotUser());
00980 addSyncLogEntry(i18n("End of HotSync\n"));
00981 endOfSync();
00982 }
00983
00984 int KPilotDeviceLink::getNextDatabase(int index,struct DBInfo *dbinfo)
00985 {
00986 FUNCTIONSETUP;
00987
00988 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
00989 return dlp_ReadDBList(pilotSocket(),0,dlpDBListRAM,index,dbinfo);
00990 #else
00991 pi_buffer_t buf = { 0,0,0 };
00992 int r = dlp_ReadDBList(pilotSocket(),0,dlpDBListRAM,index,&buf);
00993 if (r >= 0)
00994 {
00995 memcpy(dbinfo,buf.data,sizeof(struct DBInfo));
00996 }
00997 return r;
00998 #endif
00999 }
01000
01001
01002 int KPilotDeviceLink::findDatabase(const char *name, struct DBInfo *dbinfo,
01003 int index, long type, long creator)
01004 {
01005 FUNCTIONSETUP;
01006 return dlp_FindDBInfo(pilotSocket(), 0, index,
01007 const_cast<char *>(name), type, creator, dbinfo);
01008 }
01009
01010 bool KPilotDeviceLink::retrieveDatabase(const QString &fullBackupName,
01011 DBInfo *info)
01012 {
01013 FUNCTIONSETUP;
01014
01015 #ifdef DEBUG
01016 DEBUGDAEMON << fname << ": Writing DB <" << info->name << "> "
01017 << " to " << fullBackupName << endl;
01018 #endif
01019
01020 struct pi_file *f;
01021 if (fullBackupName.isEmpty())
01022 {
01023
01024 return false;
01025 }
01026 QCString encodedName = QFile::encodeName(fullBackupName);
01027 char filenameBuf[PATH_MAX];
01028 memset(filenameBuf,0,PATH_MAX);
01029 strlcpy(filenameBuf,(const char *)encodedName,PATH_MAX);
01030 f = pi_file_create(filenameBuf,info);
01031
01032 if (f == 0)
01033 {
01034 kdWarning() << k_funcinfo
01035 << ": Failed, unable to create file" << endl;
01036 return false;
01037 }
01038
01039 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
01040 if (pi_file_retrieve(f, pilotSocket(), 0) < 0)
01041 #else
01042 if (pi_file_retrieve(f, pilotSocket(), 0, 0L) < 0)
01043 #endif
01044 {
01045 kdWarning() << k_funcinfo
01046 << ": Failed, unable to back up database" << endl;
01047
01048 pi_file_close(f);
01049 return false;
01050 }
01051
01052 pi_file_close(f);
01053 return true;
01054 }
01055
01056
01057 QPtrList<DBInfo> KPilotDeviceLink::getDBList(int cardno, int flags)
01058 {
01059 bool cont=true;
01060 QPtrList<DBInfo>dbs;
01061 int index=0;
01062 while (cont)
01063 {
01064 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
01065 DBInfo*dbi=new DBInfo();
01066 if (dlp_ReadDBList(pilotSocket(), cardno, flags, index, dbi)<0)
01067 {
01068 KPILOT_DELETE(dbi);
01069 cont=false;
01070 }
01071 else
01072 {
01073 index=dbi->index+1;
01074 dbs.append(dbi);
01075 }
01076 #else
01077 pi_buffer_t buf = { 0,0,0 };
01078 pi_buffer_clear(&buf);
01079
01080 if (dlp_ReadDBList(pilotSocket(), cardno, flags | dlpDBListMultiple, index, &buf)<0)
01081 {
01082 cont=false;
01083 }
01084 else
01085 {
01086 DBInfo *db_n = 0L;
01087 DBInfo *db_it = (DBInfo *)buf.data;
01088 int info_count = buf.used / sizeof(struct DBInfo);
01089
01090 while(info_count>0)
01091 {
01092 db_n = new DBInfo();
01093 memcpy(db_n,db_it,sizeof(struct DBInfo));
01094 ++db_it;
01095 info_count--;
01096 dbs.append(db_n);
01097 }
01098 if (db_n)
01099 {
01100 index=db_n->index+1;
01101 }
01102 }
01103 #endif
01104 }
01105 return dbs;
01106 }
01107
01108 KPilotCard *KPilotDeviceLink::getCardInfo(int card)
01109 {
01110 KPilotCard *cardinfo=new KPilotCard();
01111 if (dlp_ReadStorageInfo(pilotSocket(), card, cardinfo->cardInfo())<0)
01112 {
01113 kdWarning() << k_funcinfo << ": Could not get info for card "
01114 << card << endl;
01115
01116 KPILOT_DELETE(cardinfo);
01117 return 0L;
01118 };
01119 return cardinfo;
01120 }
01121
01122 QDateTime KPilotDeviceLink::getTime()
01123 {
01124 QDateTime time;
01125 time_t palmtime;
01126 if (dlp_GetSysDateTime(pilotSocket(), &palmtime))
01127 {
01128 time.setTime_t(palmtime);
01129 }
01130 return time;
01131 }
01132
01133 bool KPilotDeviceLink::setTime(const time_t &pctime)
01134 {
01135
01136
01137 return dlp_SetSysDateTime(pilotSocket(), pctime);
01138 }
01139
01140
01141
01142 unsigned long KPilotDeviceLink::ROMversion() const
01143 {
01144 unsigned long rom;
01145 dlp_ReadFeature(pilotSocket(),
01146 makelong(const_cast<char *>("psys")), 1, &rom);
01147 return rom;
01148 }
01149 unsigned long KPilotDeviceLink::majorVersion() const
01150 {
01151 unsigned long rom=ROMversion();
01152 return (((rom >> 28) & 0xf) * 10)+ ((rom >> 24) & 0xf);
01153 }
01154 unsigned long KPilotDeviceLink::minorVersion() const
01155 {
01156 unsigned long int rom=ROMversion();
01157 return (((rom >> 20) & 0xf) * 10)+ ((rom >> 16) & 0xf);
01158 }
01159
01160 const int KPilotDeviceLink::messagesType=
01161 (int)OpenFailMessage ;
01162
01163 void KPilotDeviceLink::shouldPrint(int m,const QString &s)
01164 {
01165 if (!(messages & m))
01166 {
01167 if (messagesType & m) { emit logError(s); }
01168 else { emit logMessage(s); }
01169 messages |= (m & messagesMask);
01170 }
01171 }
01172
01173 bool operator < (const db & a, const db & b) {
01174 if (a.creator == b.creator)
01175 {
01176 if (a.type != b.type)
01177 {
01178 if (a.type == pi_mktag('a', 'p', 'p', 'l'))
01179 return false;
01180 else
01181 return true;
01182 }
01183 }
01184
01185 return a.maxblock < b.maxblock;
01186 }