From 7378f5ddf46ef0317343ad310d703c4f4ff8d703 Mon Sep 17 00:00:00 2001 From: Daniel Brahneborg Date: Fri, 8 Mar 2002 19:44:37 +0000 Subject: Initial stuff for checking requisites and previous versions. --- lib/sisfile.cpp | 6 +++ lib/sisfile.h | 13 ++++++ lib/sisfileheader.cpp | 16 +++++++ lib/sisfileheader.h | 5 +++ lib/sistypes.h | 6 +++ sisinstall/psion.cpp | 7 +++ sisinstall/psion.h | 3 ++ sisinstall/sisinstaller.cpp | 105 ++++++++++++++++++++++++++++++++++++++------ sisinstall/sisinstaller.h | 2 + 9 files changed, 150 insertions(+), 13 deletions(-) diff --git a/lib/sisfile.cpp b/lib/sisfile.cpp index ec8adb8..634266f 100644 --- a/lib/sisfile.cpp +++ b/lib/sisfile.cpp @@ -27,6 +27,12 @@ #include +SisRC +SISFile::compareApp(SISFile* other) +{ + return m_header.compareApp(&other->m_header); +} + SisRC SISFile::fillFrom(uint8_t* buf, off_t len) { diff --git a/lib/sisfile.h b/lib/sisfile.h index cae00ee..2bfcea5 100644 --- a/lib/sisfile.h +++ b/lib/sisfile.h @@ -38,6 +38,14 @@ class SISReqRecord; class SISFile { public: + + /** + * Compare uid and version number of this file, with another. + * + * @see SISFileHeader::compareApp() + */ + SisRC compareApp(SISFile* other); + /** * Populate the fields. * @@ -62,6 +70,11 @@ public: */ uint8_t* getName(); + /** + * Is this the same application? + */ + bool sameApp(SISFile* other); + /** * Set the installed drive. */ diff --git a/lib/sisfileheader.cpp b/lib/sisfileheader.cpp index 19724c3..97e0687 100644 --- a/lib/sisfileheader.cpp +++ b/lib/sisfileheader.cpp @@ -28,6 +28,22 @@ const int OFF_NUMBER_OF_FILES = 26; const int OFF_INSTALLATION_DRIVE = 28; +SisRC +SISFileHeader::compareApp(SISFileHeader* other) +{ + if (m_uid1 != other->m_uid1) + return SIS_DIFFERENT_APP; + if ((m_major < other->m_major) || + ((m_major == other->m_major) && + (m_minor < other->m_minor))) + return SIS_VER_EARLIER; + if ((m_major == other->m_major) && + (m_minor == other->m_minor) && + (m_variant != other->m_variant)) + return SIS_OTHER_VARIANT; + return SIS_SAME_OR_LATER; +} + SisRC SISFileHeader::fillFrom(uint8_t* buf, int* base, off_t len) { diff --git a/lib/sisfileheader.h b/lib/sisfileheader.h index 6b5fa3f..0c2d635 100644 --- a/lib/sisfileheader.h +++ b/lib/sisfileheader.h @@ -35,6 +35,11 @@ class SISFileHeader { public: + /** + * Compare uid and version number of this file, with another. + */ + SisRC compareApp(SISFileHeader* other); + /** * Populate the fields. * diff --git a/lib/sistypes.h b/lib/sistypes.h index 12f237b..a5d008f 100644 --- a/lib/sistypes.h +++ b/lib/sistypes.h @@ -32,6 +32,12 @@ enum SisRC { SIS_OK = 0, SIS_TRUNCATED, SIS_CORRUPTED, + SIS_FAILED, + SIS_ABORTED, + SIS_DIFFERENT_APP, + SIS_VER_EARLIER, + SIS_SAME_OR_LATER, + SIS_OTHER_VARIANT, }; extern uint16_t read16(uint8_t* p); diff --git a/sisinstall/psion.cpp b/sisinstall/psion.cpp index 287ea76..c068b1c 100644 --- a/sisinstall/psion.cpp +++ b/sisinstall/psion.cpp @@ -62,6 +62,13 @@ Psion::connect() return false; } +Enum +Psion::copyFromPsion(const char * const from, int fd, + cpCallback_t func) +{ + return m_rfsv->copyFromPsion(from, fd, func); +} + Enum Psion::copyToPsion(const char * const from, const char * const to, void *, cpCallback_t func) diff --git a/sisinstall/psion.h b/sisinstall/psion.h index 4336bb0..d01c70b 100644 --- a/sisinstall/psion.h +++ b/sisinstall/psion.h @@ -20,6 +20,9 @@ public: virtual bool connect(); + virtual Enum copyFromPsion(const char * const from, int fd, + cpCallback_t func); + virtual Enum copyToPsion(const char * const from, const char * const to, void *, cpCallback_t func); diff --git a/sisinstall/sisinstaller.cpp b/sisinstall/sisinstaller.cpp index 27fd9bd..263b2ea 100644 --- a/sisinstall/sisinstaller.cpp +++ b/sisinstall/sisinstaller.cpp @@ -136,7 +136,7 @@ SISInstaller::installFile(SISFileRecord* fileRecord) case 2: printf("(Continue installation?) [Y]es/No\n"); fgets(readbuf, 2, stdin); - if (!strchr("Nn", readbuf[0])) + if (strchr("Nn", readbuf[0])) { // Watch out if we have copied any files // already. @@ -234,6 +234,13 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent) uint8_t* compName = m_file->getName(); printf("Installing component: `%s'\n", compName); + // In order to check requisites and previous versions, we need to + // load all sis files from the c:/system/install directory. + // This is the only way to find out if a specific application or + // library has been loaded, since the sis file names could be just + // about anything. + // + // Check Requisites. // n = m_file->m_header.m_nreqs; @@ -255,6 +262,76 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent) m_file->m_header.m_uid1, m_file->m_header.m_major, m_file->m_header.m_minor); + char* resname = new char[256]; + int namelen = 0; + while (compName[namelen] != 0) + { + if (compName[namelen] == ' ') + break; + namelen++; + } + sprintf(resname, "C:\\System\\Install\\%.*s.sis", namelen, compName); + +#if 0 + char srcName[32]; + strcpy(srcName, "/tmp/plptools-sis-XXXXXX"); + int fd = mkstemp(srcName); + if (-1 == fd) + { + printf("Couldn't create temp file: %s\n", strerror(errno)); + return SIS_FAILED; + } + Enum res; + continueRunning = 1; + printf("Copying from %s to temp file %s\n", resname, srcName); + res = m_psion->copyFromPsion(resname, fd, checkAbortHash); + if (res == rfsv::E_PSI_GEN_NONE) + { + off_t fileLen = lseek(fd, SEEK_END, 0); + if (logLevel >= 2) + printf("Read %d bytes from the Psion file %s\n", + fileLen, resname); + lseek(fd, SEEK_SET, 0); + uint8_t* sisbuf = new uint8_t[fileLen]; + int rc = read(fd, sisbuf, fileLen); + if (rc == fileLen) + { + bool uninstallFirst = false; + SISFile sisFile; + SisRC rc2 = sisFile.fillFrom(sisbuf, fileLen); + if (rc2 == SIS_OK) + { + switch (sisFile.compareApp(m_file)) + { + case SIS_DIFFERENT_APP: + // NOW WHAT? + return SIS_DIFFERENT_APP; + + case SIS_VER_EARLIER: + uninstallFirst = true; + break; + + case SIS_SAME_OR_LATER: + // Ask for confirmation. + uninstallFirst = true; + break; + + case SIS_OTHER_VARIANT: + // Ask for confirmation. + uninstallFirst = true; + break; + + } + if (uninstallFirst) + { + // Not yet... + // uninstall(&sisFile); + } + } + } + } + close(fd); +#endif // Install file components. // @@ -265,7 +342,8 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent) int nCopiedFiles = 0; int firstFile = -1; bool skipnext = false; - while (n-- > 0) + bool aborted = false; + while (!aborted && (n-- > 0)) { SISFileRecord* fileRecord = &m_file->m_fileRecords[n]; m_fileNo = (fileRecord->m_flags & 1) ? lang : 0; @@ -297,11 +375,12 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent) skipnext = true; break; case FILE_ABORT: + aborted = true; break; } } - - nCopiedFiles++; + if (!aborted) + nCopiedFiles++; } m_file->setFiles(nCopiedFiles); if (logLevel >= 1) @@ -309,21 +388,21 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent) m_file->m_header.m_installationFiles, m_file->m_header.m_nfiles, firstFile); + if (nCopiedFiles == 0) + { + // There is no need to copy any uninstall information to the + // psion, unless we've actually copied anything there. + // + return SIS_ABORTED; + } // Copy the updated sis file to the epoc machine. // - char* resname = new char[256]; - int namelen = 0; - while (compName[namelen] != 0) - { - if (compName[namelen] == ' ') - break; - namelen++; - } - sprintf(resname, "C:\\System\\Install\\%.*s.sis", namelen, compName); printf("Creating residual sis file %s\n", resname); copyBuf(buf, firstFile, resname); delete[] resname; + if (aborted) + return SIS_ABORTED; return SIS_OK; } diff --git a/sisinstall/sisinstaller.h b/sisinstall/sisinstaller.h index a822baf..bca7117 100644 --- a/sisinstall/sisinstaller.h +++ b/sisinstall/sisinstaller.h @@ -63,6 +63,8 @@ private: int installFile(SISFileRecord* fileRecord); + void uninstall(SISFile* sisFile); + }; #endif -- cgit v1.2.3