aboutsummaryrefslogtreecommitdiffstats
path: root/sisinstall
diff options
context:
space:
mode:
authorDaniel Brahneborg <basic@chello.se>2002-03-19 13:34:53 +0000
committerDaniel Brahneborg <basic@chello.se>2002-03-19 13:34:53 +0000
commit89a3d9a86c9f948829ab173b811709f74685bfe6 (patch)
treebeb4e5806d47b4f4c7d4335deecaf205b4e9634a /sisinstall
parenta7f48478e5126a8cd4b729109ab7aacabc615c66 (diff)
downloadplptools-89a3d9a86c9f948829ab173b811709f74685bfe6.tar.gz
plptools-89a3d9a86c9f948829ab173b811709f74685bfe6.tar.bz2
plptools-89a3d9a86c9f948829ab173b811709f74685bfe6.zip
Remove the previous version (unconditionally) before installing the new
version.
Diffstat (limited to 'sisinstall')
-rw-r--r--sisinstall/fakepsion.cpp5
-rw-r--r--sisinstall/fakepsion.h2
-rw-r--r--sisinstall/psion.cpp11
-rw-r--r--sisinstall/psion.h2
-rw-r--r--sisinstall/sisinstaller.cpp156
-rw-r--r--sisinstall/sisinstaller.h28
6 files changed, 186 insertions, 18 deletions
diff --git a/sisinstall/fakepsion.cpp b/sisinstall/fakepsion.cpp
index 3de2967..61ca210 100644
--- a/sisinstall/fakepsion.cpp
+++ b/sisinstall/fakepsion.cpp
@@ -57,3 +57,8 @@ FakePsion::mkdir(const char* dir)
return rfsv::E_PSI_GEN_NONE;
}
+void
+FakePsion::remove(const char* name)
+{
+}
+
diff --git a/sisinstall/fakepsion.h b/sisinstall/fakepsion.h
index f1b965c..dfd741f 100644
--- a/sisinstall/fakepsion.h
+++ b/sisinstall/fakepsion.h
@@ -30,6 +30,8 @@ public:
virtual Enum<rfsv::errs> mkdir(const char* dir);
+ virtual void remove(const char* name);
+
};
#endif
diff --git a/sisinstall/psion.cpp b/sisinstall/psion.cpp
index d3abdf4..66c7cfc 100644
--- a/sisinstall/psion.cpp
+++ b/sisinstall/psion.cpp
@@ -73,7 +73,10 @@ Enum<rfsv::errs>
Psion::copyToPsion(const char * const from, const char * const to,
void *, cpCallback_t func)
{
- return m_rfsv->copyToPsion(from, to, NULL, func);
+ Enum<rfsv::errs> res;
+ res = m_rfsv->copyToPsion(from, to, NULL, func);
+// printf("Returned to Psion\n");
+ return res;
}
Enum<rfsv::errs>
@@ -126,3 +129,9 @@ Psion::mkdir(const char* dir)
return m_rfsv->mkdir(dir);
}
+void
+Psion::remove(const char* name)
+{
+ m_rfsv->remove(name);
+}
+
diff --git a/sisinstall/psion.h b/sisinstall/psion.h
index c305173..83893af 100644
--- a/sisinstall/psion.h
+++ b/sisinstall/psion.h
@@ -39,6 +39,8 @@ public:
virtual Enum<rfsv::errs> mkdir(const char* dir);
+ virtual void remove(const char* name);
+
private:
ppsocket* m_skt;
diff --git a/sisinstall/sisinstaller.cpp b/sisinstall/sisinstaller.cpp
index 80d2ce2..334d340 100644
--- a/sisinstall/sisinstaller.cpp
+++ b/sisinstall/sisinstaller.cpp
@@ -27,6 +27,22 @@ checkAbortHash(void *, u_int32_t)
SISInstaller::SISInstaller()
{
m_installed = 0;
+ m_ownInstalled = false;
+}
+
+SISInstaller::~SISInstaller()
+{
+ if (m_ownInstalled)
+ {
+ SISFileLink* curr = m_installed;
+ while (curr)
+ {
+ delete curr->m_file;
+ SISFileLink* next = curr->m_next;
+ delete curr;
+ curr = next;
+ }
+ }
}
void
@@ -66,20 +82,23 @@ SISInstaller::copyFile(SISFileRecord* fileRecord)
m_file->setDrive(m_drive);
}
int len = fileRecord->m_destLength;
- char* dest = new char[len + 1];
+ char dest[256];
memcpy(dest, m_buf + fileRecord->m_destPtr, len);
dest[len] = 0;
if (dest[0] == '!')
{
dest[0] = m_drive;
- m_buf[fileRecord->m_destPtr] = m_drive;
+ fileRecord->setMainDrive(m_drive);
+ if (logLevel >= 2)
+ printf("Setting drive at index %d to %c\n",
+ fileRecord->m_destPtr, m_drive);
+// m_buf[fileRecord->m_destPtr] = m_drive;
}
printf("Copying %d bytes to %s\n",
fileRecord->m_fileLengths[m_fileNo], dest);
copyBuf(m_buf + fileRecord->m_filePtrs[m_fileNo],
fileRecord->m_fileLengths[m_fileNo],
dest);
- delete[] dest;
}
void
@@ -115,7 +134,7 @@ SISInstaller::copyBuf(const uint8_t* buf, int len, char* name)
int
SISInstaller::installFile(SISFileRecord* fileRecord)
{
- char readbuf[2];
+ char readbuf[8];
switch (fileRecord->m_fileType)
{
case 0:
@@ -129,11 +148,11 @@ SISInstaller::installFile(SISFileRecord* fileRecord)
{
case 0:
printf("Continue\n");
- fgets(readbuf, 2, stdin);
+ fgets(readbuf, sizeof(readbuf), stdin);
break;
case 1:
printf("(Install next file?) [Y]es/No\n");
- fgets(readbuf, 2, stdin);
+ fgets(readbuf, sizeof(readbuf), stdin);
if (strchr("Nn", readbuf[0]))
{
return FILE_SKIP;
@@ -141,7 +160,7 @@ SISInstaller::installFile(SISFileRecord* fileRecord)
break;
case 2:
printf("(Continue installation?) [Y]es/No\n");
- fgets(readbuf, 2, stdin);
+ fgets(readbuf, sizeof(readbuf), stdin);
if (strchr("Nn", readbuf[0]))
{
// Watch out if we have copied any files
@@ -157,8 +176,11 @@ SISInstaller::installFile(SISFileRecord* fileRecord)
if (logLevel >= 1)
printf("Recursive sis file...\n");
SISFile sisFile;
- uint8_t* buf2 = m_buf + fileRecord->m_filePtrs[m_fileNo];
+ int fileptr = fileRecord->m_filePtrs[m_fileNo];
+ uint8_t* buf2 = m_buf + fileptr;
off_t len = fileRecord->m_fileLengths[m_fileNo];
+ if (m_lastSisFile < fileptr + len)
+ m_lastSisFile = fileptr + len;
SisRC rc = sisFile.fillFrom(buf2, len);
if (rc != SIS_OK)
{
@@ -254,11 +276,31 @@ SISInstaller::loadPsionSis(const char* name)
printf(" Ok.\n");
SISFileLink* link = new SISFileLink(sisFile);
link->m_next = m_installed;
+ m_ownInstalled = true;
m_installed = link;
+ sisFile->ownBuffer();
+ }
+ else
+ {
+ delete sisFile;
+ delete[] sisbuf;
}
}
}
close(fd);
+ unlink(srcName);
+}
+
+void
+SISInstaller::removeFile(SISFileRecord* fileRecord)
+{
+ int len = fileRecord->m_destLength;
+ char dest[256];
+ memcpy(dest, fileRecord->getDestPtr(), len);
+ dest[len] = 0;
+ if (logLevel >= 1)
+ printf("Removing file component %s.\n", dest);
+ m_psion->remove(dest);
}
SisRC
@@ -334,8 +376,9 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent)
m_file->m_header.m_major,
m_file->m_header.m_minor);
- bool uninstallFirst;
+ bool uninstallFirst = false;
SISFileLink* curr = m_installed;
+ SISFile* oldFile = 0;
while (curr)
{
SISFile* sisFile = curr->m_file;
@@ -343,16 +386,19 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent)
{
case SIS_VER_EARLIER:
uninstallFirst = true;
+ oldFile = sisFile;
break;
case SIS_SAME_OR_LATER:
// Ask for confirmation.
uninstallFirst = true;
+ oldFile = sisFile;
break;
case SIS_OTHER_VARIANT:
// Ask for confirmation.
uninstallFirst = true;
+ oldFile = sisFile;
break;
}
curr = curr->m_next;
@@ -360,10 +406,15 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent)
if (uninstallFirst)
{
- printf("You should uninstall the previous version first.\n");
- return SIS_ABORTED;
- // Not yet...
- // uninstall(&sisFile);
+// printf("You should uninstall the previous version first.\n");
+// if (!m_forced)
+// return SIS_ABORTED;
+// printf("Forced mode... Installing anyway!\n");
+ printf("Uninstalling the previous version first.\n");
+ if (oldFile == 0)
+ printf("Already installed, but 0?\n");
+ else
+ uninstall(oldFile);
}
// Install file components.
@@ -374,6 +425,7 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent)
m_drive = (parent == 0) ? 0 : parent->m_header.m_installationDrive;
int nCopiedFiles = 0;
int firstFile = -1;
+ m_lastSisFile = 0;
bool skipnext = false;
bool aborted = false;
while (!aborted && (n-- > 0))
@@ -417,10 +469,12 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent)
}
m_file->setFiles(nCopiedFiles);
if (logLevel >= 1)
- printf("Installed %d files of %d, cutting at offset %d\n",
+ printf("Installed %d files of %d, cutting at offset max(%d,%d)\n",
m_file->m_header.m_installationFiles,
m_file->m_header.m_nfiles,
- firstFile);
+ firstFile, m_lastSisFile);
+ if (firstFile < m_lastSisFile)
+ firstFile = m_lastSisFile;
if (nCopiedFiles == 0)
{
// There is no need to copy any uninstall information to the
@@ -431,7 +485,7 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent)
// Copy the updated sis file to the epoc machine.
//
- char* resname = new char[256];
+ char resname[256];
int namelen = 0;
while (compName[namelen] != 0)
{
@@ -442,7 +496,6 @@ SISInstaller::run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent)
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;
@@ -515,3 +568,72 @@ SISInstaller::setPsion(Psion* psion)
m_psion = psion;
}
+void
+SISInstaller::uninstall(SISFile* file)
+{
+ int n = file->m_header.m_nfiles;
+ int fileix = n - file->m_header.m_installationFiles;
+ if (logLevel >= 1)
+ printf("Uninstalling %d files, from a total of %d.\n",
+ file->m_header.m_installationFiles,
+ file->m_header.m_nfiles);
+ int lang = file->getLanguage();
+ while (fileix < n)
+ {
+ SISFileRecord* fileRecord = &file->m_fileRecords[fileix];
+ m_fileNo = (fileRecord->m_flags & 1) ? lang : 0;
+ char drive = file->m_header.m_installationDrive;
+ fileRecord->setMainDrive(drive);
+ uninstallFile(fileRecord);
+ ++fileix;
+ }
+}
+
+void
+SISInstaller::uninstallFile(SISFileRecord* fileRecord)
+{
+ switch (fileRecord->m_fileType)
+ {
+ case 0:
+ case 4:
+ removeFile(fileRecord);
+ break;
+ case 2:
+ {
+#if 0
+ // This is messy... We can't remove the sis component unless
+ // we've stored the entire component in the residual sis
+ // file no the target machine.
+ //
+ if (logLevel >= 1)
+ printf("Recursive sis file...\n");
+ SISFile sisFile;
+ int fileptr = fileRecord->m_filePtrs[m_fileNo];
+ uint8_t* buf2 = m_buf + fileptr;
+ off_t len = fileRecord->m_fileLengths[m_fileNo];
+ if (m_lastSisFile < fileptr + len)
+ m_lastSisFile = fileptr + len;
+ SisRC rc = sisFile.fillFrom(buf2, len);
+ if (rc != SIS_OK)
+ {
+ printf("Could not read contained sis file, rc = %d\n", rc);
+ break;
+ }
+ SISInstaller installer;
+ installer.setPsion(m_psion);
+ installer.setInstalled(m_installed);
+ rc = installer.run(&sisFile, buf2, len, m_file);
+ if (0 == m_drive)
+ {
+ m_drive = sisFile.m_header.m_installationDrive;
+ m_file->setDrive(m_drive);
+ if (logLevel >= 1)
+ printf("Updated drive to %c from recursive sis file\n",
+ m_drive);
+ }
+#endif
+ break;
+ }
+ }
+}
+
diff --git a/sisinstall/sisinstaller.h b/sisinstall/sisinstaller.h
index ff9845e..bb50c6e 100644
--- a/sisinstall/sisinstaller.h
+++ b/sisinstall/sisinstaller.h
@@ -20,6 +20,8 @@ public:
SISInstaller();
+ virtual ~SISInstaller();
+
SisRC run(SISFile* file, uint8_t* buf, off_t len);
SisRC run(SISFile* file, uint8_t* buf, off_t len, SISFile* parent);
@@ -29,6 +31,20 @@ public:
*/
void selectDrive();
+ /**
+ * Set forced mode, which means that it ignores any earlier versions
+ * of the same application.
+ */
+ void setForced(bool f)
+ {
+ m_forced = f;
+ }
+
+ /**
+ * Set the base pointer to the list of already installed
+ * applications, so we don't have to scan it for every sis
+ * component.
+ */
void setInstalled(SISFileLink* installed)
{
m_installed = installed;
@@ -53,6 +69,14 @@ private:
SISFileLink* m_installed;
+ int m_lastSisFile;
+
+ bool m_forced;
+
+ bool m_ownBuffer;
+
+ bool m_ownInstalled;
+
enum {
FILE_OK,
FILE_SKIP,
@@ -77,8 +101,12 @@ private:
void loadPsionSis(const char* name);
+ void removeFile(SISFileRecord* fileRecord);
+
void uninstall(SISFile* sisFile);
+ void uninstallFile(SISFileRecord* fileRecord);
+
};
#endif