aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/sisfile.cpp13
-rw-r--r--lib/sisfile.h13
-rw-r--r--lib/sisfilerecord.cpp8
-rw-r--r--lib/sisfilerecord.h16
-rw-r--r--po/sv.po4
-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
11 files changed, 238 insertions, 20 deletions
diff --git a/lib/sisfile.cpp b/lib/sisfile.cpp
index c5d7139..62a2ce1 100644
--- a/lib/sisfile.cpp
+++ b/lib/sisfile.cpp
@@ -28,6 +28,18 @@
#include <stdio.h>
+SISFile::SISFile()
+{
+ m_buf = 0;
+ m_ownBuffer = false;
+}
+
+SISFile::~SISFile()
+{
+ if (m_ownBuffer)
+ delete[] m_buf;
+}
+
SisRC
SISFile::compareApp(SISFile* other)
{
@@ -38,6 +50,7 @@ SisRC
SISFile::fillFrom(uint8_t* buf, off_t len)
{
int ix = 0;
+ m_buf = buf;
SisRC rc = m_header.fillFrom(buf, &ix, len);
if (rc != SIS_OK)
{
diff --git a/lib/sisfile.h b/lib/sisfile.h
index 2bfcea5..d74cc1c 100644
--- a/lib/sisfile.h
+++ b/lib/sisfile.h
@@ -39,6 +39,10 @@ class SISFile
{
public:
+ SISFile();
+
+ virtual ~SISFile();
+
/**
* Compare uid and version number of this file, with another.
*
@@ -70,6 +74,11 @@ public:
*/
uint8_t* getName();
+ void ownBuffer()
+ {
+ m_ownBuffer = true;
+ }
+
/**
* Is this the same application?
*/
@@ -99,6 +108,10 @@ private:
SISComponentNameRecord m_componentRecord;
+ bool m_ownBuffer;
+
+ uint8_t* m_buf;
+
};
#endif
diff --git a/lib/sisfilerecord.cpp b/lib/sisfilerecord.cpp
index 24650da..95e75ed 100644
--- a/lib/sisfilerecord.cpp
+++ b/lib/sisfilerecord.cpp
@@ -32,6 +32,7 @@ SISFileRecord::fillFrom(uint8_t* buf, int* base, off_t len, SISFile* sisFile)
if (*base + 28 + 4 * 2 > len)
return SIS_TRUNCATED;
+ m_buf = buf;
uint8_t* p = buf + *base;
int size = 0;
m_flags = read32(p);
@@ -124,3 +125,10 @@ SISFileRecord::fillFrom(uint8_t* buf, int* base, off_t len, SISFile* sisFile)
return SIS_OK;
}
+void
+SISFileRecord::setMainDrive(char drive)
+{
+ if (m_buf[m_destPtr] == '!')
+ m_buf[m_destPtr] = drive;
+}
+
diff --git a/lib/sisfilerecord.h b/lib/sisfilerecord.h
index dbbbc49..d0ccced 100644
--- a/lib/sisfilerecord.h
+++ b/lib/sisfilerecord.h
@@ -48,6 +48,13 @@ public:
*/
SisRC fillFrom(uint8_t* buf, int* base, off_t len, SISFile* sisFile);
+ uint8_t* getDestPtr()
+ {
+ return &m_buf[m_destPtr];
+ }
+
+ void setMainDrive(char drive);
+
/**
* 1 if multiple language versions, otherwise 0.
*/
@@ -86,6 +93,15 @@ public:
uint32_t m_destPtr;
uint32_t* m_fileLengths;
uint32_t* m_filePtrs;
+
+private:
+
+ /**
+ * The buffer we belong to.
+ * Used for updating the destination file name.
+ */
+ uint8_t* m_buf;
+
};
#endif
diff --git a/po/sv.po b/po/sv.po
index edbd604..09e8fb9 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -1162,7 +1162,7 @@ msgstr " Använt: "
#: plpftp/ftp.cc:854 plpftp/ftp.cc:858
msgid " Voltage: "
-msgstr ""
+msgstr " Spänning: "
#: plpftp/ftp.cc:855 plpftp/ftp.cc:859
msgid " Max. voltage: "
@@ -1174,7 +1174,7 @@ msgstr "Backupbatteri: "
#: plpftp/ftp.cc:860
msgid "External power:"
-msgstr ""
+msgstr "Extern ström: "
#: plpftp/ftp.cc:861
#, fuzzy
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