aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/sisfile.cpp6
-rw-r--r--lib/sisfile.h13
-rw-r--r--lib/sisfileheader.cpp16
-rw-r--r--lib/sisfileheader.h5
-rw-r--r--lib/sistypes.h6
-rw-r--r--sisinstall/psion.cpp7
-rw-r--r--sisinstall/psion.h3
-rw-r--r--sisinstall/sisinstaller.cpp105
-rw-r--r--sisinstall/sisinstaller.h2
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
@@ -28,6 +28,12 @@
#include <stdio.h>
SisRC
+SISFile::compareApp(SISFile* other)
+{
+ return m_header.compareApp(&other->m_header);
+}
+
+SisRC
SISFile::fillFrom(uint8_t* buf, off_t len)
{
int ix = 0;
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.
*
@@ -63,6 +71,11 @@ public:
uint8_t* getName();
/**
+ * Is this the same application?
+ */
+ bool sameApp(SISFile* other);
+
+ /**
* Set the installed drive.
*/
void setDrive(char drive);
diff --git a/lib/sisfileheader.cpp b/lib/sisfileheader.cpp
index 19724c3..97e0687 100644
--- a/lib/sisfileheader.cpp
+++ b/lib/sisfileheader.cpp
@@ -29,6 +29,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)
{
if (*base + 68 > len)
diff --git a/lib/sisfileheader.h b/lib/sisfileheader.h
index 6b5fa3f..0c2d635 100644
--- a/lib/sisfileheader.h
+++ b/lib/sisfileheader.h
@@ -36,6 +36,11 @@ class SISFileHeader
public:
/**
+ * Compare uid and version number of this file, with another.
+ */
+ SisRC compareApp(SISFileHeader* other);
+
+ /**
* Populate the fields.
*
* @param buf The buffer to read from.
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
@@ -63,6 +63,13 @@ Psion::connect()
}
Enum<rfsv::errs>
+Psion::copyFromPsion(const char * const from, int fd,
+ cpCallback_t func)
+{
+ return m_rfsv->copyFromPsion(from, fd, func);
+}
+
+Enum<rfsv::errs>
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<rfsv::errs> copyFromPsion(const char * const from, int fd,
+ cpCallback_t func);
+
virtual Enum<rfsv::errs> 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<rfsv::errs> 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