[sword-svn] r2077 - in trunk: . include src/mgr utilities
scribe at www.crosswire.org
scribe at www.crosswire.org
Thu Sep 13 18:34:38 MST 2007
Author: scribe
Date: 2007-09-13 18:34:37 -0700 (Thu, 13 Sep 2007)
New Revision: 2077
Modified:
trunk/ChangeLog
trunk/include/installmgr.h
trunk/include/swmgr.h
trunk/src/mgr/ftptrans.cpp
trunk/src/mgr/installmgr.cpp
trunk/utilities/installmgr.cpp
Log:
Normalized all paths in installmgr to be safe
Added new getModuleStatus to installmgr to help
frontends know which modules are new/updated
Added a const SWModule *getModule method to SWMgr
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2007-09-09 01:20:11 UTC (rev 2076)
+++ trunk/ChangeLog 2007-09-14 01:34:37 UTC (rev 2077)
@@ -1,6 +1,10 @@
-API ChangeLog (see the ChangeLog in each 'apps' directory for
- app specific changes)
+API ChangeLog
+13-Sep-2007 Troy A. Griffitts <scribe at crosswire.org>
+ Added InstallMgr::getModuleStatus to return a list
+ of differences between the modules of two SWMgr
+ objects
+
03-Mar-2007 Joachim Ansorg <jansorg at crosswire.org>
Added osis morph segments filter include file to the dist
Fixed wrong stricmp in SWObject
@@ -25,7 +29,7 @@
Added recognition of additional greek accent ~
in UTF8GreekAccents filter
Fixed bug in RawGenBook::setText where default size
- is < 0, not false.
+ is < 0, not false
Changed lucene indexing to actually index the key field. This
allows searching within key field (e.g. key:word)
Fixed divineName logic
Modified: trunk/include/installmgr.h
===================================================================
--- trunk/include/installmgr.h 2007-09-09 01:20:11 UTC (rev 2076)
+++ trunk/include/installmgr.h 2007-09-14 01:34:37 UTC (rev 2077)
@@ -9,6 +9,7 @@
SWORD_NAMESPACE_START
class SWMgr;
+class SWModule;
class SWConfig;
class FTPTransport;
class StatusReporter;
@@ -53,6 +54,14 @@
FTPTransport *transport;
public:
+
+ const static int MODSTAT_OLDER;
+ const static int MODSTAT_SAMEVERSION;
+ const static int MODSTAT_UPDATED;
+ const static int MODSTAT_NEW;
+ const static int MODSTAT_CIPHERED;
+ const static int MODSTAT_CIPHERKEYPRESENT;
+
SWConfig *installConf;
InstallSourceMap sources;
bool term;
@@ -70,6 +79,12 @@
void terminate();
/************************************************************************
+ * getModuleStatus - compare the modules of two SWMgrs and return a
+ * vector describing the status of each. See MODSTAT_*
+ */
+ static std::map<SWModule *, int> getModuleStatus(const SWMgr &base, const SWMgr &other);
+
+ /************************************************************************
* isDefaultModule - allows an installation to provide a set of modules
* in installMgr.conf like:
* [General]
Modified: trunk/include/swmgr.h
===================================================================
--- trunk/include/swmgr.h 2007-09-09 01:20:11 UTC (rev 2076)
+++ trunk/include/swmgr.h 2007-09-14 01:34:37 UTC (rev 2077)
@@ -209,6 +209,7 @@
* @return the module, if found, otherwise 0
*/
SWModule *getModule(const char *modName) { ModMap::iterator it = Modules.find(modName); return ((it != Modules.end()) ? it->second : 0); }
+ const SWModule *getModule(const char *modName) const { ModMap::const_iterator it = Modules.find(modName); return ((it != Modules.end()) ? it->second : 0); }
/** Constructs an instance of SWMgr
Modified: trunk/src/mgr/ftptrans.cpp
===================================================================
--- trunk/src/mgr/ftptrans.cpp 2007-09-09 01:20:11 UTC (rev 2076)
+++ trunk/src/mgr/ftptrans.cpp 2007-09-14 01:34:37 UTC (rev 2077)
@@ -18,6 +18,18 @@
SWORD_NAMESPACE_START
+namespace {
+
+void removeTrailingSlash(SWBuf &buf) {
+ int len = buf.size();
+ if ((buf[len-1] == '/')
+ || (buf[len-1] == '\\'))
+ buf.size(len-1);
+}
+
+};
+
+
void StatusReporter::preStatus(long totalBytes, long completedBytes, const char *message) {
}
@@ -90,9 +102,8 @@
int retVal = 0;
SWBuf url = SWBuf(urlPrefix) + SWBuf(dir);
- if (url[url.length()-1] != '/') {
- url.append('/'); //don't forget the final slash if it's not yet at the end
- }
+ removeTrailingSlash(url);
+ url += '/';
SWLog::getSystemLog()->logWarning("FTPCopy: getting dir %s\n", url.c_str());
vector<struct ftpparse> dirList = getDirList(url.c_str());
@@ -108,7 +119,9 @@
long completedBytes = 0;
for (i = 0; i < dirList.size(); i++) {
struct ftpparse &dirEntry = dirList[i];
- SWBuf buffer = (SWBuf)dest + "/" + (dirEntry.name);
+ SWBuf buffer = (SWBuf)dest;
+ removeTrailingSlash(buffer);
+ buffer += (SWBuf)"/" + (dirEntry.name);
if (!strcmp(&buffer.c_str()[buffer.length()-strlen(suffix)], suffix)) {
SWBuf buffer2 = "Downloading (";
buffer2.appendFormatted("%d", i+1);
@@ -120,7 +133,9 @@
statusReporter->preStatus(totalBytes, completedBytes, buffer2.c_str());
FileMgr::createParent(buffer.c_str()); // make sure parent directory exists
SWTRY {
- SWBuf url = (SWBuf)urlPrefix + (SWBuf)dir + "/" + dirEntry.name; //dont forget the final slash
+ SWBuf url = (SWBuf)urlPrefix + (SWBuf)dir;
+ removeTrailingSlash(url);
+ url += (SWBuf)"/" + dirEntry.name; //dont forget the final slash
if (dirEntry.flagtrycwd != 1) {
if (getURL(buffer.c_str(), url.c_str())) {
SWLog::getSystemLog()->logWarning("FTPCopy: failed to get file %s\n", url.c_str());
@@ -129,7 +144,9 @@
completedBytes += dirEntry.size;
}
else {
- SWBuf subdir = (SWBuf)dir + "/" + dirEntry.name;
+ SWBuf subdir = (SWBuf)dir;
+ removeTrailingSlash(subdir);
+ subdir += (SWBuf)"/" + dirEntry.name;
if (copyDirectory(urlPrefix, subdir, buffer.c_str(), suffix)) {
SWLog::getSystemLog()->logWarning("FTPCopy: failed to get file %s\n", subdir.c_str());
return -2;
Modified: trunk/src/mgr/installmgr.cpp
===================================================================
--- trunk/src/mgr/installmgr.cpp 2007-09-09 01:20:11 UTC (rev 2076)
+++ trunk/src/mgr/installmgr.cpp 2007-09-14 01:34:37 UTC (rev 2077)
@@ -18,9 +18,12 @@
#include <fcntl.h>
#include <swmgr.h>
+#include <swmodule.h>
+#include <swversion.h>
#include <dirent.h>
#include <stdio.h>
+#include <map>
#ifdef CURLAVAILABLE
#include <curlftpt.h>
@@ -28,10 +31,29 @@
#include <ftplibftpt.h>
#endif
-
SWORD_NAMESPACE_START
+namespace {
+void removeTrailingSlash(SWBuf &buf) {
+ int len = buf.size();
+ if ((buf[len-1] == '/')
+ || (buf[len-1] == '\\'))
+ buf.size(len-1);
+}
+
+};
+
+
+using std::map;
+
+const int InstallMgr::MODSTAT_OLDER = 0x001;
+const int InstallMgr::MODSTAT_SAMEVERSION = 0x002;
+const int InstallMgr::MODSTAT_UPDATED = 0x004;
+const int InstallMgr::MODSTAT_NEW = 0x008;
+const int InstallMgr::MODSTAT_CIPHERED = 0x010;
+const int InstallMgr::MODSTAT_CIPHERKEYPRESENT = 0x020;
+
// override this method and provide your own custom FTPTransport subclass
// here we try a couple defaults if sword was compiled with support for them.
// see these classes for examples of how to make your own
@@ -51,6 +73,12 @@
this->privatePath = 0;
this->transport = 0;
stdstr(&(this->privatePath), privatePath);
+ if (this->privatePath) {
+ int len = strlen(this->privatePath);
+ if ((this->privatePath[len-1] == '/')
+ || (this->privatePath[len-1] == '\\'))
+ this->privatePath[len-1] = 0;
+ }
SWBuf confPath = (SWBuf)privatePath + "/InstallMgr.conf";
FileMgr::createParent(confPath.c_str());
@@ -127,6 +155,7 @@
SWBuf modDir;
entry = module->second.find("AbsoluteDataPath");
modDir = entry->second.c_str();
+ removeTrailingSlash(modDir);
if (fileBegin != fileEnd) { // remove each file
while (fileBegin != fileEnd) {
modFile = modDir;
@@ -150,6 +179,7 @@
while ((ent = readdir(dir))) {
if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
modFile = manager->configPath;
+ removeTrailingSlash(modFile);
modFile += "/";
modFile += ent->d_name;
SWConfig *config = new SWConfig(modFile.c_str());
@@ -169,45 +199,6 @@
}
-
-InstallSource::InstallSource(const char *type, const char *confEnt) {
- this->type = type;
- mgr = 0;
- userData = 0;
- if (confEnt) {
- char *buf = 0;
- stdstr(&buf, confEnt);
-
- caption = strtok(buf, "|");
- source = strtok(0, "|");
- directory = strtok(0, "|");
- delete [] buf;
- }
-}
-
-
-InstallSource::~InstallSource() {
- if (mgr)
- delete mgr;
-}
-
-
-void InstallSource::flush() {
- if (mgr) {
- delete mgr;
- mgr = 0;
- }
-}
-
-
-SWMgr *InstallSource::getMgr() {
- if (!mgr)
- // ..., false = don't augment ~home directory.
- mgr = new SWMgr(localShadow.c_str(), true, 0, false, false);
- return mgr;
-}
-
-
int InstallMgr::ftpCopy(InstallSource *is, const char *src, const char *dest, bool dirTransfer, const char *suffix) {
int retVal = 0;
FTPTransport *trans = createFTPTransport(is->source, statusReporter);
@@ -225,7 +216,9 @@
if (dirTransfer) {
- SWBuf dir = (SWBuf)is->directory.c_str() + "/" + src; //dont forget the final slash
+ SWBuf dir = (SWBuf)is->directory.c_str();
+ removeTrailingSlash(dir);
+ dir += (SWBuf)"/" + src; //dont forget the final slash
retVal = trans->copyDirectory(urlPrefix, dir, dest, suffix);
@@ -233,7 +226,9 @@
}
else {
SWTRY {
- SWBuf url = urlPrefix + is->directory.c_str() + "/" + src; //dont forget the final slash
+ SWBuf url = urlPrefix + is->directory.c_str();
+ removeTrailingSlash(url);
+ url += (SWBuf)"/" + src; //dont forget the final slash
if (trans->getURL(dest, url.c_str())) {
fprintf(stderr, "FTPCopy: failed to get file %s", url.c_str());
retVal = -1;
@@ -273,8 +268,8 @@
sourceDir = (SWBuf)privatePath + "/" + is->source;
else sourceDir = fromLocation;
- if (sourceDir[sourceDir.length()-1] != '/')
- sourceDir += '/';
+ removeTrailingSlash(sourceDir);
+ sourceDir += '/';
SWMgr mgr(sourceDir.c_str());
@@ -296,7 +291,7 @@
if (fileBegin != fileEnd) { // copy each file
if (is) {
while (fileBegin != fileEnd) { // ftp each file first
- buffer = sourceDir + "/" + fileBegin->second.c_str();
+ buffer = sourceDir + fileBegin->second.c_str();
if (ftpCopy(is, fileBegin->second.c_str(), buffer.c_str())) {
aborted = true;
break; // user aborted
@@ -312,8 +307,8 @@
SWBuf sourcePath = sourceDir;
sourcePath += fileBegin->second.c_str();
SWBuf dest = destMgr->prefixPath;
- if ((destMgr->prefixPath[strlen(destMgr->prefixPath)-1] != '\\') && (destMgr->prefixPath[strlen(destMgr->prefixPath)-1] != '/'))
- dest += "/";
+ removeTrailingSlash(dest);
+ dest += '/';
dest += fileBegin->second.c_str();
FileMgr::copyFile(sourcePath.c_str(), dest.c_str());
@@ -325,7 +320,7 @@
if (is) {
fileBegin = module->second.lower_bound("File");
while (fileBegin != fileEnd) { // delete each tmp ftp file
- buffer = sourceDir + "/" + fileBegin->second.c_str();
+ buffer = sourceDir + fileBegin->second.c_str();
FileMgr::removeFile(buffer.c_str());
fileBegin++;
}
@@ -362,7 +357,7 @@
}
}
if (!aborted) {
- SWBuf confDir = sourceDir + "/mods.d/";
+ SWBuf confDir = sourceDir + "mods.d/";
if ((dir = opendir(confDir.c_str()))) { // find and copy .conf file
rewinddir(dir);
while ((ent = readdir(dir))) {
@@ -372,6 +367,7 @@
SWConfig *config = new SWConfig(modFile.c_str());
if (config->Sections.find(modName) != config->Sections.end()) {
SWBuf targetFile = destMgr->configPath; //"./mods.d/";
+ removeTrailingSlash(targetFile);
targetFile += "/";
targetFile += ent->d_name;
FileMgr::copyFile(modFile.c_str(), targetFile.c_str());
@@ -441,6 +437,7 @@
int InstallMgr::refreshRemoteSource(InstallSource *is) {
SWBuf root = (SWBuf)privatePath + (SWBuf)"/" + is->source.c_str();
+ removeTrailingSlash(root);
SWBuf target = root + "/mods.d";
int errorCode = -1; //0 means successful
@@ -471,6 +468,97 @@
return defaultMods.count(modName);
}
+/************************************************************************
+ * getModuleStatus - compare the modules of two SWMgrs and return a
+ * vector describing the status of each. See MODSTAT_*
+ */
+map<SWModule *, int> InstallMgr::getModuleStatus(const SWMgr &base, const SWMgr &other) {
+ map<SWModule *, int> retVal;
+ SWBuf targetVersion;
+ SWBuf sourceVersion;
+ SWBuf softwareVersion;
+ bool cipher;
+ bool keyPresent;
+ int modStat;
+
+ for (ModMap::const_iterator mod = other.Modules.begin(); mod != other.Modules.end(); mod++) {
+
+ modStat = 0;
+ cipher = false;
+ keyPresent = false;
+
+ const char *v = mod->second->getConfigEntry("CipherKey");
+ if (v) {
+ cipher = true;
+ keyPresent = *v;
+ }
+
+ targetVersion = "0.0";
+ sourceVersion = "1.0";
+ softwareVersion = (const char *)SWVersion::currentVersion;
+
+ v = mod->second->getConfigEntry("Version");
+ if (v) sourceVersion = v;
+
+ v = mod->second->getConfigEntry("MinimumVersion");
+ if (v) softwareVersion = v;
+
+ const SWModule *baseMod = base.getModule(mod->first);
+ if (baseMod) {
+ targetVersion = "1.0";
+ v = baseMod->getConfigEntry("Version");
+ if (v) targetVersion = v;
+ modStat |= (SWVersion(sourceVersion.c_str()) > SWVersion(targetVersion.c_str())) ? MODSTAT_UPDATED : (SWVersion(sourceVersion.c_str()) < SWVersion(targetVersion.c_str())) ? MODSTAT_OLDER : MODSTAT_SAMEVERSION;
+ }
+ else modStat |= MODSTAT_NEW;
+
+ if (cipher) modStat |= MODSTAT_CIPHERED;
+ if (keyPresent) modStat |= MODSTAT_CIPHERKEYPRESENT;
+ retVal[mod->second] = modStat;
+ }
+ return retVal;
+}
+
+
+InstallSource::InstallSource(const char *type, const char *confEnt) {
+ this->type = type;
+ mgr = 0;
+ userData = 0;
+ if (confEnt) {
+ char *buf = 0;
+ stdstr(&buf, confEnt);
+
+ caption = strtok(buf, "|");
+ source = strtok(0, "|");
+ directory = strtok(0, "|");
+ removeTrailingSlash(directory);
+ delete [] buf;
+ }
+}
+
+
+InstallSource::~InstallSource() {
+ if (mgr)
+ delete mgr;
+}
+
+
+void InstallSource::flush() {
+ if (mgr) {
+ delete mgr;
+ mgr = 0;
+ }
+}
+
+
+SWMgr *InstallSource::getMgr() {
+ if (!mgr)
+ // ..., false = don't augment ~home directory.
+ mgr = new SWMgr(localShadow.c_str(), true, 0, false, false);
+ return mgr;
+}
+
+
SWORD_NAMESPACE_END
Modified: trunk/utilities/installmgr.cpp
===================================================================
--- trunk/utilities/installmgr.cpp 2007-09-09 01:20:11 UTC (rev 2076)
+++ trunk/utilities/installmgr.cpp 2007-09-14 01:34:37 UTC (rev 2077)
@@ -2,14 +2,14 @@
#include <installmgr.h>
#include <filemgr.h>
#include <iostream>
-#include <string>
+#include <map>
#include <swmodule.h>
#include <stdio.h>
using namespace sword;
using std::cout;
using std::cin;
-using std::string;
+using std::map;
SWMgr *mgr;
@@ -33,6 +33,7 @@
"\t-s\t\t\t\tlist remote sources\n"
"\t-r <remoteSrcName>\t\trefresh remote source\n"
"\t-rl <remoteSrcName>\t\tlist available modules from remote source\n"
+ "\t-rd <remoteSrcName>\t\tlist new/updated modules from remote source\n"
"\t-ri <remoteSrcName> <modName>\tinstall module from remote source\n"
"\t-ll <path>\t\t\tlist available modules at local path\n"
"\t-li <path> <modName>\t\tinstall module from local path\n"
@@ -123,6 +124,28 @@
}
+void remoteNewModules(const SWMgr *base, const char *sourceName) {
+ cout << "Updated and New Modules:\n(be sure to refresh remote source (-r) first for most current list)\n\n";
+ InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
+ if (source == installMgr->sources.end()) {
+ fprintf(stderr, "Couldn't find remote source [%s]\n", sourceName);
+ finish(-3);
+ }
+ map<SWModule *, int> modStats = installMgr->getModuleStatus(*base, *source->second->getMgr());
+ SWModule *module;
+ int status;
+ bool updated;
+ for (map<SWModule *, int>::iterator it = modStats.begin(); it != modStats.end(); it++) {
+ module = it->first;
+ status = it->second;
+ updated = (status & InstallMgr::MODSTAT_UPDATED);
+ if ((status & InstallMgr::MODSTAT_NEW) || (updated)) {
+ cout << ((updated)?"U":"N") << " [" << module->Name() << "] \t- " << module->Description() << "\n";
+ }
+ }
+}
+
+
void remoteListModules(const char *sourceName) {
cout << "Available Modules:\n(be sure to refresh remote source (-r) first for most current list)\n\n";
InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
@@ -156,8 +179,10 @@
finish(-4);
}
module = it->second;
- installMgr->installModule(mgr, 0, module->Name(), is);
- cout << "Installed module: [" << module->Name() << "]\n";
+ int error = installMgr->installModule(mgr, 0, module->Name(), is);
+ if (error) {
+ cout << "Error installing module: [" << module->Name() << "] (write permissions?)\n";
+ } else cout << "Installed module: [" << module->Name() << "]\n";
}
@@ -170,8 +195,10 @@
finish(-4);
}
module = it->second;
- installMgr->installModule(mgr, dir, module->Name());
- cout << "Installed module: [" << module->Name() << "]\n";
+ int error = installMgr->installModule(mgr, dir, module->Name());
+ if (error) {
+ cout << "Error installing module: [" << module->Name() << "] (write permissions?)\n";
+ } else cout << "Installed module: [" << module->Name() << "]\n";
}
@@ -233,6 +260,11 @@
usage(*argv);
remoteListModules(argv[2]);
break;
+ case 'd': // -rl remote list
+ if (argc < 3)
+ usage(*argv);
+ remoteNewModules(mgr, argv[2]);
+ break;
case 'i': // -ri remote install
if (argc < 4)
usage(*argv);
More information about the sword-cvs
mailing list