aboutsummaryrefslogtreecommitdiffstats
path: root/src/mgr
diff options
context:
space:
mode:
Diffstat (limited to 'src/mgr')
-rw-r--r--src/mgr/Makefile.am26
-rw-r--r--src/mgr/encfiltmgr.cpp148
-rw-r--r--src/mgr/filemgr.cpp266
-rw-r--r--src/mgr/localemgr.cpp184
-rw-r--r--src/mgr/markupfiltmgr.cpp236
-rw-r--r--src/mgr/swcacher.cpp43
-rw-r--r--src/mgr/swconfig.cpp163
-rw-r--r--src/mgr/swfiltermgr.cpp90
-rw-r--r--src/mgr/swlocale.cpp140
-rw-r--r--src/mgr/swmgr.cpp1084
10 files changed, 2380 insertions, 0 deletions
diff --git a/src/mgr/Makefile.am b/src/mgr/Makefile.am
new file mode 100644
index 0000000..c648032
--- /dev/null
+++ b/src/mgr/Makefile.am
@@ -0,0 +1,26 @@
+mgrdir = $(top_srcdir)/src/mgr
+
+if CONFDEF
+globdef = -DGLOBCONFPATH=\"${globalconfdir}/sword.conf\"
+else
+globdef =
+endif
+
+if ICU
+icudatadir = -DICUDATA=\"${pkglibdir}\"
+else
+icudatadir =
+endif
+
+
+DEFS += $(globdef) $(icudatadir)
+
+libsword_la_SOURCES += $(mgrdir)/swconfig.cpp
+libsword_la_SOURCES += $(mgrdir)/swmgr.cpp
+libsword_la_SOURCES += $(mgrdir)/swfiltermgr.cpp
+libsword_la_SOURCES += $(mgrdir)/encfiltmgr.cpp
+libsword_la_SOURCES += $(mgrdir)/markupfiltmgr.cpp
+libsword_la_SOURCES += $(mgrdir)/filemgr.cpp
+libsword_la_SOURCES += $(mgrdir)/swlocale.cpp
+libsword_la_SOURCES += $(mgrdir)/localemgr.cpp
+libsword_la_SOURCES += $(mgrdir)/swcacher.cpp
diff --git a/src/mgr/encfiltmgr.cpp b/src/mgr/encfiltmgr.cpp
new file mode 100644
index 0000000..ab55de9
--- /dev/null
+++ b/src/mgr/encfiltmgr.cpp
@@ -0,0 +1,148 @@
+/******************************************************************************
+ * swencodingmgr.cpp - implementaion of class EncodingFilterMgr, subclass of
+ * used to transcode all module text to a requested
+ * encoding.
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <encfiltmgr.h>
+
+#include <scsuutf8.h>
+#include <latin1utf8.h>
+
+#include <unicodertf.h>
+#include <utf8latin1.h>
+#include <utf8utf16.h>
+#include <utf8html.h>
+
+#include <swmgr.h>
+
+/******************************************************************************
+ * EncodingFilterMgr Constructor - initializes instance of EncodingFilterMgr
+ *
+ * ENT:
+ * enc - Encoding format to emit
+ */
+
+EncodingFilterMgr::EncodingFilterMgr (char enc)
+ : SWFilterMgr() {
+
+ scsuutf8 = new SCSUUTF8();
+ latin1utf8 = new Latin1UTF8();
+
+ encoding = enc;
+
+ switch (encoding) {
+ case ENC_LATIN1:
+ targetenc = new UTF8Latin1();
+ break;
+ case ENC_UTF16:
+ targetenc = new UTF8UTF16();
+ break;
+ case ENC_RTF:
+ targetenc = new UnicodeRTF();
+ break;
+ case ENC_HTML:
+ targetenc = new UTF8HTML();
+ break;
+ default: // i.e. case ENC_UTF8
+ targetenc = NULL;
+ }
+}
+
+/******************************************************************************
+ * EncodingFilterMgr Destructor - Cleans up instance of EncodingFilterMgr
+ */
+EncodingFilterMgr::~EncodingFilterMgr() {
+ if (scsuutf8)
+ delete scsuutf8;
+ if (latin1utf8)
+ delete latin1utf8;
+ if (targetenc)
+ delete targetenc;
+}
+
+void EncodingFilterMgr::AddRawFilters(SWModule *module, ConfigEntMap &section) {
+
+ ConfigEntMap::iterator entry;
+
+ string encoding = ((entry = section.find("Encoding")) != section.end()) ? (*entry).second : (string)"";
+ if (encoding.empty() || !stricmp(encoding.c_str(), "Latin-1")) {
+ module->AddRawFilter(latin1utf8);
+ }
+ else if (!stricmp(encoding.c_str(), "SCSU")) {
+ module->AddRawFilter(scsuutf8);
+ }
+}
+
+void EncodingFilterMgr::AddEncodingFilters(SWModule *module, ConfigEntMap &section) {
+ if (targetenc)
+ module->AddEncodingFilter(targetenc);
+}
+
+/******************************************************************************
+ * EncodingFilterMgr::Encoding - sets/gets encoding
+ *
+ * ENT: enc - new encoding or 0 to simply get the current encoding
+ *
+ * RET: encoding
+ */
+char EncodingFilterMgr::Encoding(char enc) {
+ if (enc && enc != encoding) {
+ encoding = enc;
+ SWFilter * oldfilter = targetenc;
+
+ switch (encoding) {
+ case ENC_LATIN1:
+ targetenc = new UTF8Latin1();
+ break;
+ case ENC_UTF16:
+ targetenc = new UTF8UTF16();
+ break;
+ case ENC_RTF:
+ targetenc = new UnicodeRTF();
+ break;
+ case ENC_HTML:
+ targetenc = new UTF8HTML();
+ break;
+ default: // i.e. case ENC_UTF8
+ targetenc = NULL;
+ }
+
+ ModMap::const_iterator module;
+
+ if (oldfilter != targetenc) {
+ if (oldfilter) {
+ if (!targetenc) {
+ for (module = getParentMgr()->Modules.begin(); module != getParentMgr()->Modules.end(); module++)
+ module->second->RemoveRenderFilter(oldfilter);
+ }
+ else {
+ for (module = getParentMgr()->Modules.begin(); module != getParentMgr()->Modules.end(); module++)
+ module->second->ReplaceRenderFilter(oldfilter, targetenc);
+ }
+ delete oldfilter;
+ }
+ else if (targetenc) {
+ for (module = getParentMgr()->Modules.begin(); module != getParentMgr()->Modules.end(); module++)
+ module->second->AddRenderFilter(targetenc);
+ }
+ }
+
+ }
+ return encoding;
+}
diff --git a/src/mgr/filemgr.cpp b/src/mgr/filemgr.cpp
new file mode 100644
index 0000000..0b31576
--- /dev/null
+++ b/src/mgr/filemgr.cpp
@@ -0,0 +1,266 @@
+/******************************************************************************
+ * filemgr.cpp - implementation of class FileMgr used for pooling file
+ * handles
+ *
+ * $Id: filemgr.cpp,v 1.22 2002/07/31 20:26:38 scribe Exp $
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <filemgr.h>
+#include <utilstr.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef __GNUC__
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+// ---------------- statics -----------------
+FileMgr FileMgr::systemFileMgr;
+
+// --------------- end statics --------------
+
+
+FileDesc::FileDesc(FileMgr *parent, char *path, int mode, int perms, bool tryDowngrade) {
+ this->parent = parent;
+ this->path = 0;
+ stdstr(&this->path, path);
+ this->mode = mode;
+ this->perms = perms;
+ this->tryDowngrade = tryDowngrade;
+ offset = 0;
+ fd = -77;
+}
+
+
+FileDesc::~FileDesc() {
+ if (fd > 0)
+ close(fd);
+
+ if (path)
+ delete [] path;
+}
+
+
+int FileDesc::getFd() {
+ if (fd == -77)
+ fd = parent->sysOpen(this);
+ return fd;
+}
+
+
+FileMgr::FileMgr(int maxFiles) {
+ this->maxFiles = maxFiles; // must be at least 2
+ files = 0;
+}
+
+
+FileMgr::~FileMgr() {
+ FileDesc *tmp;
+
+ while(files) {
+ tmp = files->next;
+ delete files;
+ files = tmp;
+ }
+}
+
+
+FileDesc *FileMgr::open(char *path, int mode, bool tryDowngrade) {
+ return open(path, mode, S_IREAD | S_IWRITE, tryDowngrade);
+}
+
+FileDesc *FileMgr::open(char *path, int mode, int perms, bool tryDowngrade) {
+ FileDesc **tmp, *tmp2;
+
+ for (tmp = &files; *tmp; tmp = &((*tmp)->next)) {
+ if ((*tmp)->fd < 0) // insert as first non-system_open file
+ break;
+ }
+
+ tmp2 = new FileDesc(this, path, mode, perms, tryDowngrade);
+ tmp2->next = *tmp;
+ *tmp = tmp2;
+
+ return tmp2;
+}
+
+
+void FileMgr::close(FileDesc *file) {
+ FileDesc **loop;
+
+ for (loop = &files; *loop; loop = &((*loop)->next)) {
+ if (*loop == file) {
+ *loop = (*loop)->next;
+ delete file;
+ break;
+ }
+ }
+}
+
+
+// to truncate a file at its current position
+// leaving byte at current possition intact
+// deleting everything afterward.
+signed char FileMgr::trunc(FileDesc *file) {
+
+ static const char *writeTest = "x";
+ long size = lseek(file->getFd(), 1, SEEK_CUR);
+ if (size == 1) // was empty
+ size = 0;
+ char nibble [ 32767 ];
+ bool writable = write(file->getFd(), writeTest, 1);
+ int bytes = 0;
+
+ if (writable) {
+ // get tmpfilename
+ char *buf = new char [ strlen(file->path) + 10 ];
+ int i;
+ for (i = 0; i < 9999; i++) {
+ sprintf(buf, "%stmp%.4d", file->path, i);
+ if (!existsFile(buf))
+ break;
+ }
+ if (i == 9999)
+ return -2;
+
+ int fd = ::open(buf, O_CREAT|O_RDWR, S_IREAD|S_IWRITE);
+ if (fd < 0)
+ return -3;
+
+ lseek(file->getFd(), 0, SEEK_SET);
+ while (size > 0) {
+ bytes = read(file->getFd(), nibble, 32767);
+ write(fd, nibble, (bytes < size)?bytes:size);
+ size -= bytes;
+ }
+ // zero out the file
+ ::close(file->fd);
+ file->fd = ::open(file->path, O_TRUNC, S_IREAD|S_IWRITE);
+ ::close(file->fd);
+ file->fd = -77; // force file open by filemgr
+ // copy tmp file back (dumb, but must preserve file permissions)
+ lseek(fd, 0, SEEK_SET);
+ do {
+ bytes = read(fd, nibble, 32767);
+ write(file->getFd(), nibble, bytes);
+ } while (bytes == 32767);
+
+ ::close(fd);
+ ::close(file->fd);
+ unlink(buf); // remove our tmp file
+ file->fd = -77; // causes file to be swapped out forcing open on next call to getFd()
+ }
+ else { // put offset back and return failure
+ lseek(file->getFd(), -1, SEEK_CUR);
+ return -1;
+ }
+ return 0;
+}
+
+
+int FileMgr::sysOpen(FileDesc *file) {
+ FileDesc **loop;
+ int openCount = 1; // because we are presently opening 1 file, and we need to be sure to close files to accomodate, if necessary
+
+ for (loop = &files; *loop; loop = &((*loop)->next)) {
+
+ if ((*loop)->fd > 0) {
+ if (++openCount > maxFiles) {
+ (*loop)->offset = lseek((*loop)->fd, 0, SEEK_CUR);
+ ::close((*loop)->fd);
+ (*loop)->fd = -77;
+ }
+ }
+
+ if (*loop == file) {
+ if (*loop != files) {
+ *loop = (*loop)->next;
+ file->next = files;
+ files = file;
+ }
+ if ((!access(file->path, 04)) || ((file->mode & O_CREAT) == O_CREAT)) { // check for at least file exists / read access before we try to open
+ char tries = (((file->mode & O_RDWR) == O_RDWR) && (file->tryDowngrade)) ? 2 : 1; // try read/write if possible
+ for (int i = 0; i < tries; i++) {
+ if (i > 0) {
+ file->mode = (file->mode & ~O_RDWR); // remove write access
+ file->mode = (file->mode | O_RDONLY);// add read access
+ }
+ file->fd = ::open(file->path, file->mode, file->perms);
+
+ if (file->fd >= 0)
+ break;
+ }
+
+ if (file->fd >= 0)
+ lseek(file->fd, file->offset, SEEK_SET);
+ }
+ else file->fd = -1;
+ if (!*loop)
+ break;
+ }
+ }
+ return file->fd;
+}
+
+
+signed char FileMgr::existsFile(const char *ipath, const char *ifileName)
+{
+ int len = strlen(ipath) + ((ifileName)?strlen(ifileName):0) + 3;
+ char *ch;
+ char *path = new char [ len ];
+ strcpy(path, ipath);
+
+ if ((path[strlen(path)-1] == '\\') || (path[strlen(path)-1] == '/'))
+ path[strlen(path)-1] = 0;
+
+ if (ifileName) {
+ ch = path + strlen(path);
+ sprintf(ch, "/%s", ifileName);
+ }
+ signed char retVal = !access(path, 04);
+ delete [] path;
+ return retVal;
+}
+
+
+signed char FileMgr::existsDir(const char *ipath, const char *idirName)
+{
+ char *ch;
+ int len = strlen(ipath) + ((idirName)?strlen(idirName):0) + 1;
+ if (idirName)
+ len += strlen(idirName);
+ char *path = new char [ len ];
+ strcpy(path, ipath);
+
+ if ((path[strlen(path)-1] == '\\') || (path[strlen(path)-1] == '/'))
+ path[strlen(path)-1] = 0;
+
+ if (idirName) {
+ ch = path + strlen(path);
+ sprintf(ch, "/%s", idirName);
+ }
+ signed char retVal = !access(path, 04);
+ delete [] path;
+ return retVal;
+}
diff --git a/src/mgr/localemgr.cpp b/src/mgr/localemgr.cpp
new file mode 100644
index 0000000..bc12f4c
--- /dev/null
+++ b/src/mgr/localemgr.cpp
@@ -0,0 +1,184 @@
+/******************************************************************************
+ * localemgr.cpp - implementation of class LocaleMgr used to interact with
+ * registered locales for a sword installation
+ *
+ * $Id: localemgr.cpp,v 1.12 2002/06/19 09:24:44 scribe Exp $
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#ifndef __GNUC__
+#include <io.h>
+#else
+#include <unistd.h>
+#include <unixstr.h>
+#endif
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include <swmgr.h>
+#include <utilfuns.h>
+
+#include <localemgr.h>
+#include <filemgr.h>
+
+
+LocaleMgr LocaleMgr::systemLocaleMgr;
+
+
+LocaleMgr::LocaleMgr(const char *iConfigPath) {
+ char *prefixPath = 0;
+ char *configPath = 0;
+ char configType = 0;
+ string path;
+
+ defaultLocaleName = 0;
+
+ char *lang = getenv ("LANG");
+ if (lang) {
+ if (strlen(lang) > 0)
+ setDefaultLocaleName(lang);
+ else setDefaultLocaleName("en_us");
+ }
+ else setDefaultLocaleName("en_us");
+
+ if (!iConfigPath)
+ SWMgr::findConfig(&configType, &prefixPath, &configPath);
+ else configPath = (char *)iConfigPath;
+
+ if (prefixPath) {
+ switch (configType) {
+ case 2:
+ int i;
+ for (i = strlen(configPath)-1; ((i) && (configPath[i] != '/') && (configPath[i] != '\\')); i--);
+ configPath[i] = 0;
+ path = configPath;
+ path += "/";
+ break;
+ default:
+ path = prefixPath;
+ if ((prefixPath[strlen(prefixPath)-1] != '\\') && (prefixPath[strlen(prefixPath)-1] != '/'))
+ path += "/";
+
+ break;
+ }
+ if (FileMgr::existsDir(path.c_str(), "locales.d")) {
+ path += "locales.d";
+ loadConfigDir(path.c_str());
+ }
+ }
+
+ if (prefixPath)
+ delete [] prefixPath;
+
+ if (configPath)
+ delete [] configPath;
+}
+
+
+LocaleMgr::~LocaleMgr() {
+ if (defaultLocaleName)
+ delete [] defaultLocaleName;
+ deleteLocales();
+}
+
+
+void LocaleMgr::loadConfigDir(const char *ipath) {
+ DIR *dir;
+ struct dirent *ent;
+ string newmodfile;
+ LocaleMap::iterator it;
+
+ if ((dir = opendir(ipath))) {
+ rewinddir(dir);
+ while ((ent = readdir(dir))) {
+ if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
+ newmodfile = ipath;
+ if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
+ newmodfile += "/";
+ newmodfile += ent->d_name;
+ SWLocale *locale = new SWLocale(newmodfile.c_str());
+ if (locale->getName()) {
+ it = locales.find(locale->getName());
+ if (it != locales.end()) {
+ *((*it).second) += *locale;
+ delete locale;
+ }
+ else locales.insert(LocaleMap::value_type(locale->getName(), locale));
+ }
+ else delete locale;
+ }
+ }
+ closedir(dir);
+ }
+}
+
+
+void LocaleMgr::deleteLocales() {
+
+ LocaleMap::iterator it;
+
+ for (it = locales.begin(); it != locales.end(); it++)
+ delete (*it).second;
+
+ locales.erase(locales.begin(), locales.end());
+}
+
+
+SWLocale *LocaleMgr::getLocale(const char *name) {
+ LocaleMap::iterator it;
+
+ it = locales.find(name);
+ if (it != locales.end())
+ return (*it).second;
+
+ return 0;
+}
+
+
+list <string> LocaleMgr::getAvailableLocales() {
+ list <string> retVal;
+ for (LocaleMap::iterator it = locales.begin(); it != locales.end(); it++)
+ retVal.push_back((*it).second->getName());
+
+ return retVal;
+}
+
+
+const char *LocaleMgr::translate(const char *text, const char *localeName) {
+ SWLocale *target;
+ if (!localeName) {
+ localeName = getDefaultLocaleName();
+ }
+ target = getLocale(localeName);
+ if (target)
+ return target->translate(text);
+ return text;
+}
+
+
+const char *LocaleMgr::getDefaultLocaleName() {
+ return defaultLocaleName;
+}
+
+
+void LocaleMgr::setDefaultLocaleName(const char *name) {
+ stdstr(&defaultLocaleName, name);
+}
diff --git a/src/mgr/markupfiltmgr.cpp b/src/mgr/markupfiltmgr.cpp
new file mode 100644
index 0000000..8dc68ea
--- /dev/null
+++ b/src/mgr/markupfiltmgr.cpp
@@ -0,0 +1,236 @@
+/******************************************************************************
+ * swmarkupmgr.cpp - implementaion of class MarkupFilterMgr, subclass of
+ * used to transcode all module text to a requested
+ * markup.
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <thmlplain.h>
+#include <gbfplain.h>
+#include <thmlgbf.h>
+#include <gbfthml.h>
+#include <thmlhtml.h>
+#include <gbfhtml.h>
+#include <plainhtml.h>
+#include <thmlhtmlhref.h>
+#include <gbfhtmlhref.h>
+#include <thmlrtf.h>
+#include <gbfrtf.h>
+#include <gbfosis.h>
+#include <thmlosis.h>
+
+#include <markupfiltmgr.h>
+
+#include <swmgr.h>
+
+
+/******************************************************************************
+ * MarkupFilterMgr Constructor - initializes instance of MarkupFilterMgr
+ *
+ * ENT:
+ * enc - Encoding format to emit
+ * mark - Markup format to emit
+ */
+
+MarkupFilterMgr::MarkupFilterMgr (char mark, char enc)
+ : EncodingFilterMgr(enc) {
+
+ markup = mark;
+
+ CreateFilters(markup);
+}
+
+
+/******************************************************************************
+ * MarkupFilterMgr Destructor - Cleans up instance of MarkupFilterMgr
+ */
+
+MarkupFilterMgr::~MarkupFilterMgr() {
+ if (fromthml)
+ delete (fromthml);
+ if (fromgbf)
+ delete (fromgbf);
+ if (fromplain)
+ delete (fromplain);
+ if (fromosis)
+ delete (fromosis);
+}
+
+/******************************************************************************
+ * MarkupFilterMgr::Markup - sets/gets markup
+ *
+ * ENT: mark - new encoding or 0 to simply get the current markup
+ *
+ * RET: markup
+ */
+char MarkupFilterMgr::Markup(char mark) {
+ if (mark && mark != markup) {
+ markup = mark;
+ ModMap::const_iterator module;
+
+ SWFilter * oldplain = fromplain;
+ SWFilter * oldthml = fromthml;
+ SWFilter * oldgbf = fromgbf;
+ SWFilter * oldosis = fromosis;
+
+ CreateFilters(markup);
+
+ for (module = getParentMgr()->Modules.begin(); module != getParentMgr()->Modules.end(); module++)
+ switch (module->second->Markup()) {
+ case FMT_THML:
+ if (oldthml != fromthml) {
+ if (oldthml) {
+ if (!fromthml) {
+ module->second->RemoveRenderFilter(oldthml);
+ }
+ else {
+ module->second->ReplaceRenderFilter(oldthml, fromthml);
+ }
+ }
+ else if (fromthml) {
+ module->second->AddRenderFilter(fromthml);
+ }
+ }
+ break;
+ case FMT_GBF:
+ if (oldgbf != fromgbf) {
+ if (oldgbf) {
+ if (!fromgbf) {
+ module->second->RemoveRenderFilter(oldgbf);
+ }
+ else {
+ module->second->ReplaceRenderFilter(oldgbf, fromgbf);
+ }
+ }
+ else if (fromgbf) {
+ module->second->AddRenderFilter(fromgbf);
+ }
+ break;
+ }
+ case FMT_PLAIN:
+ if (oldplain != fromplain) {
+ if (oldplain) {
+ if (!fromplain) {
+ module->second->RemoveRenderFilter(oldplain);
+ }
+ else {
+ module->second->ReplaceRenderFilter(oldplain, fromplain);
+ }
+ }
+ else if (fromplain) {
+ module->second->AddRenderFilter(fromplain);
+ }
+ break;
+ }
+ case FMT_OSIS:
+ if (oldosis != fromosis) {
+ if (oldosis) {
+ if (!fromosis) {
+ module->second->RemoveRenderFilter(oldosis);
+ }
+ else {
+ module->second->ReplaceRenderFilter(oldosis, fromosis);
+ }
+ }
+ else if (fromosis) {
+ module->second->AddRenderFilter(fromosis);
+ }
+ break;
+ }
+ }
+
+ if (oldthml)
+ delete oldthml;
+ if (oldgbf)
+ delete oldgbf;
+ if (oldplain)
+ delete oldplain;
+ if (oldosis)
+ delete oldosis;
+ }
+ return markup;
+}
+
+void MarkupFilterMgr::AddRenderFilters(SWModule *module, ConfigEntMap &section) {
+ switch (module->Markup()) {
+ case FMT_THML:
+ if (fromthml)
+ module->AddRenderFilter(fromthml);
+ break;
+ case FMT_GBF:
+ if (fromgbf)
+ module->AddRenderFilter(fromgbf);
+ break;
+ case FMT_PLAIN:
+ if (fromplain)
+ module->AddRenderFilter(fromplain);
+ break;
+ case FMT_OSIS:
+ if (fromosis)
+ module->AddRenderFilter(fromosis);
+ break;
+ }
+}
+
+void MarkupFilterMgr::CreateFilters(char markup) {
+
+ switch (markup) {
+ case FMT_PLAIN:
+ fromplain = NULL;
+ fromthml = new ThMLPlain();
+ fromgbf = new GBFPlain();
+ fromosis = NULL;
+ break;
+ case FMT_THML:
+ fromplain = NULL;
+ fromthml = NULL;
+ fromgbf = new GBFThML();
+ fromosis = NULL;
+ break;
+ case FMT_GBF:
+ fromplain = NULL;
+ fromthml = new ThMLGBF();
+ fromgbf = NULL;
+ fromosis = NULL;
+ break;
+ case FMT_HTML:
+ fromplain = new PLAINHTML();
+ fromthml = new ThMLHTML();
+ fromgbf = new GBFHTML();
+ fromosis = NULL;
+ break;
+ case FMT_HTMLHREF:
+ fromplain = NULL;
+ fromthml = new ThMLHTMLHREF();
+ fromgbf = new GBFHTMLHREF();
+ fromosis = NULL;
+ break;
+ case FMT_RTF:
+ fromplain = NULL;
+ fromthml = new ThMLRTF();
+ fromgbf = new GBFRTF();
+ fromosis = NULL;
+ break;
+ case FMT_OSIS:
+ fromplain = NULL;
+ fromthml = new ThMLOSIS();
+ fromgbf = new GBFOSIS();
+ fromosis = NULL;
+ break;
+ }
+
+}
diff --git a/src/mgr/swcacher.cpp b/src/mgr/swcacher.cpp
new file mode 100644
index 0000000..8128a70
--- /dev/null
+++ b/src/mgr/swcacher.cpp
@@ -0,0 +1,43 @@
+/******************************************************************************
+ * swcacher.h - definition of class SWCacher used to provide an interface for
+ * objects that cache and want a standard interface for cleaning up.
+ *
+ * $Id: swcacher.cpp,v 1.1 2002/03/16 01:12:37 scribe Exp $
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <swcacher.h>
+
+
+SWCacher::SWCacher() {
+}
+
+
+SWCacher::~SWCacher() {
+}
+
+
+void SWCacher::flush() {
+}
+
+long SWCacher::resourceConsumption() {
+ return 0;
+}
+
+long SWCacher::lastAccess() {
+ return 0;
+}
diff --git a/src/mgr/swconfig.cpp b/src/mgr/swconfig.cpp
new file mode 100644
index 0000000..d73d475
--- /dev/null
+++ b/src/mgr/swconfig.cpp
@@ -0,0 +1,163 @@
+/******************************************************************************
+ * swconfig.cpp - implementation of Class SWConfig used for saving and
+ * retrieval of configuration information
+ *
+ * $Id: swconfig.cpp,v 1.9 2002/07/28 01:48:38 scribe Exp $
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <swconfig.h>
+#include <utilfuns.h>
+
+
+SWConfig::SWConfig(const char * ifilename) {
+ filename = ifilename;
+ Load();
+}
+
+
+SWConfig::~SWConfig() {
+}
+
+
+char SWConfig::getline(FILE *fp, string &line)
+{
+ char retval = 0;
+ char buf[255];
+
+ line = "";
+
+ while (fgets(buf, 254, fp)) {
+ while (buf[strlen(buf)-1] == '\n' || buf[strlen(buf)-1] == '\r')
+ buf[strlen(buf)-1] = 0;
+
+ if (buf[strlen(buf)-1] == '\\') {
+ buf[strlen(buf)-1] = 0;
+ line += buf;
+ continue;
+ }
+ line += buf;
+
+ if (strlen(buf) < 253) {
+ retval = 1;
+ break;
+ }
+ }
+ return retval;
+}
+
+
+void SWConfig::Load() {
+ FILE *cfile;
+ char *buf, *data;
+ string line;
+ ConfigEntMap cursect;
+ string sectname;
+ bool first = true;
+
+ Sections.erase(Sections.begin(), Sections.end());
+
+ if ((cfile = fopen(filename.c_str(), "r"))) {
+ while (getline(cfile, line)) {
+ buf = new char [ line.length() + 1 ];
+ strcpy(buf, line.c_str());
+ if (*strstrip(buf) == '[') {
+ if (!first)
+ Sections.insert(SectionMap::value_type(sectname, cursect));
+ else first = false;
+
+ cursect.erase(cursect.begin(), cursect.end());
+
+ strtok(buf, "]");
+ sectname = buf+1;
+ }
+ else {
+ strtok(buf, "=");
+ if ((*buf) && (*buf != '=')) {
+ if ((data = strtok(NULL, "")))
+ cursect.insert(ConfigEntMap::value_type(buf, strstrip(data)));
+ else cursect.insert(ConfigEntMap::value_type(buf, ""));
+ }
+ }
+ delete [] buf;
+ }
+ if (!first)
+ Sections.insert(SectionMap::value_type(sectname, cursect));
+
+ fclose(cfile);
+ }
+}
+
+
+void SWConfig::Save() {
+ FILE *cfile;
+ string buf;
+ SectionMap::iterator sit;
+ ConfigEntMap::iterator entry;
+ string sectname;
+
+ if ((cfile = fopen(filename.c_str(), "w"))) {
+
+ for (sit = Sections.begin(); sit != Sections.end(); sit++) {
+ buf = "\n[";
+ buf += (*sit).first.c_str();
+ buf += "]\n";
+ fputs(buf.c_str(), cfile);
+ for (entry = (*sit).second.begin(); entry != (*sit).second.end(); entry++) {
+ buf = (*entry).first.c_str();
+ buf += "=";
+ buf += (*entry).second.c_str();
+ buf += "\n";
+ fputs(buf.c_str(), cfile);
+ }
+ }
+ fputs("\n", cfile); // so getline will find last line
+ fclose(cfile);
+ }
+}
+
+
+void SWConfig::augment(SWConfig &addFrom) {
+
+ SectionMap::iterator section;
+ ConfigEntMap::iterator entry, start, end;
+
+ for (section = addFrom.Sections.begin(); section != addFrom.Sections.end(); section++) {
+ for (entry = (*section).second.begin(); entry != (*section).second.end(); entry++) {
+ start = Sections[section->first].lower_bound(entry->first);
+ end = Sections[section->first].upper_bound(entry->first);
+ if (start != end) {
+ if (((++start) != end)
+ || ((++(addFrom.Sections[section->first].lower_bound(entry->first))) != addFrom.Sections[section->first].upper_bound(entry->first))) {
+ for (--start; start != end; start++) {
+ if (!strcmp(start->second.c_str(), entry->second.c_str()))
+ break;
+ }
+ if (start == end)
+ Sections[(*section).first].insert(ConfigEntMap::value_type((*entry).first, (*entry).second));
+ }
+ else Sections[section->first][entry->first.c_str()] = entry->second.c_str();
+ }
+ else Sections[section->first][entry->first.c_str()] = entry->second.c_str();
+ }
+ }
+}
+
+
+ConfigEntMap & SWConfig::operator [] (const char *section) {
+ return Sections[section];
+}
diff --git a/src/mgr/swfiltermgr.cpp b/src/mgr/swfiltermgr.cpp
new file mode 100644
index 0000000..264b5a6
--- /dev/null
+++ b/src/mgr/swfiltermgr.cpp
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * swfiltermgr.cpp - definition of class SWFilterMgr used as an interface to
+ * manage filters on a module
+ *
+ * $Id: swfiltermgr.cpp,v 1.2 2001/11/30 12:04:34 scribe Exp $
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <swfiltermgr.h>
+
+
+SWFilterMgr::SWFilterMgr() {
+}
+
+
+SWFilterMgr::~SWFilterMgr() {
+}
+
+
+void SWFilterMgr::setParentMgr(SWMgr *parentMgr) {
+ this->parentMgr = parentMgr;
+}
+
+
+SWMgr *SWFilterMgr::getParentMgr() {
+ return parentMgr;
+}
+
+
+void SWFilterMgr::AddGlobalOptions(SWModule * module, ConfigEntMap & section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) {
+}
+
+
+void SWFilterMgr::AddLocalOptions(SWModule * module, ConfigEntMap & section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) {
+}
+
+
+/**
+* Adds the encoding filters which are defined in "section" to the SWModule object "module".
+* @param module To this module the encoding filter(s) are added
+* @param section We use this section to get a list of filters we should apply to the module
+*/
+
+void SWFilterMgr::AddEncodingFilters(SWModule * module, ConfigEntMap & section) {
+}
+
+
+/**
+* Adds the render filters which are defined in "section" to the SWModule object "module".
+* @param module To this module the render filter(s) are added
+* @param section We use this section to get a list of filters we should apply to the module
+*/
+
+void SWFilterMgr::AddRenderFilters(SWModule * module, ConfigEntMap & section) {
+}
+
+
+/**
+* Adds the strip filters which are defined in "section" to the SWModule object "module".
+* @param module To this module the strip filter(s) are added
+* @param section We use this section to get a list of filters we should apply to the module
+*/
+
+void SWFilterMgr::AddStripFilters(SWModule * module, ConfigEntMap & section) {
+}
+
+
+/**
+* Adds the raw filters which are defined in "section" to the SWModule object "module".
+* @param module To this module the raw filter(s) are added
+* @param section We use this section to get a list of filters we should apply to the module
+*/
+
+void SWFilterMgr::AddRawFilters(SWModule * module, ConfigEntMap & section) {
+}
+
diff --git a/src/mgr/swlocale.cpp b/src/mgr/swlocale.cpp
new file mode 100644
index 0000000..d85d1eb
--- /dev/null
+++ b/src/mgr/swlocale.cpp
@@ -0,0 +1,140 @@
+/******************************************************************************
+ * swlocale.cpp - implementation of Class SWLocale used for retrieval
+ * of locale lookups
+ *
+ * $Id: swlocale.cpp,v 1.4 2002/07/28 01:48:38 scribe Exp $
+ *
+ * Copyright 2000 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <swlocale.h>
+#include <utilfuns.h>
+
+
+SWLocale::SWLocale(const char * ifilename) {
+ ConfigEntMap::iterator confEntry;
+
+ name = 0;
+ description = 0;
+ bookAbbrevs = 0;
+ BMAX = 0;
+ books = 0;
+ localeSource = new SWConfig(ifilename);
+
+ confEntry = localeSource->Sections["Meta"].find("Name");
+ if (confEntry != localeSource->Sections["Meta"].end())
+ stdstr(&name, (*confEntry).second.c_str());
+
+ confEntry = localeSource->Sections["Meta"].find("Description");
+ if (confEntry != localeSource->Sections["Meta"].end())
+ stdstr(&description, (*confEntry).second.c_str());
+}
+
+
+SWLocale::~SWLocale() {
+
+ delete localeSource;
+
+ if (description)
+ delete [] description;
+
+ if (name)
+ delete [] name;
+
+ if (bookAbbrevs)
+ delete [] bookAbbrevs;
+
+ if (BMAX) {
+ for (int i = 0; i < 2; i++)
+ delete [] books[i];
+ delete [] BMAX;
+ delete [] books;
+ }
+}
+
+
+const char *SWLocale::translate(const char *text) {
+ LookupMap::iterator entry;
+
+ entry = lookupTable.find(text);
+
+ if (entry == lookupTable.end()) {
+ ConfigEntMap::iterator confEntry;
+ confEntry = localeSource->Sections["Text"].find(text);
+ if (confEntry == localeSource->Sections["Text"].end())
+ lookupTable.insert(LookupMap::value_type(text, text));
+ else lookupTable.insert(LookupMap::value_type(text, (*confEntry).second.c_str()));
+ entry = lookupTable.find(text);
+ }
+ return (*entry).second.c_str();
+}
+
+
+const char *SWLocale::getName() {
+ return name;
+}
+
+
+const char *SWLocale::getDescription() {
+ return description;
+}
+
+
+void SWLocale::augment(SWLocale &addFrom) {
+ *localeSource += *addFrom.localeSource;
+}
+
+
+const struct abbrev *SWLocale::getBookAbbrevs() {
+ static const char *nullstr = "";
+ if (!bookAbbrevs) {
+ ConfigEntMap::iterator it;
+ int i;
+ int size = localeSource->Sections["Book Abbrevs"].size();
+ bookAbbrevs = new struct abbrev[size + 1];
+ for (i = 0, it = localeSource->Sections["Book Abbrevs"].begin(); it != localeSource->Sections["Book Abbrevs"].end(); it++, i++) {
+ bookAbbrevs[i].ab = (*it).first.c_str();
+ bookAbbrevs[i].book = atoi((*it).second.c_str());
+ }
+ bookAbbrevs[i].ab = nullstr;
+ bookAbbrevs[i].book = -1;
+ }
+
+ return bookAbbrevs;
+}
+
+
+void SWLocale::getBooks(char **iBMAX, struct sbook ***ibooks) {
+ if (!BMAX) {
+ BMAX = new char [2];
+ BMAX[0] = VerseKey::builtin_BMAX[0];
+ BMAX[1] = VerseKey::builtin_BMAX[1];
+
+ books = new struct sbook *[2];
+ books[0] = new struct sbook[BMAX[0]];
+ books[1] = new struct sbook[BMAX[1]];
+
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < BMAX[i]; j++) {
+ books[i][j] = VerseKey::builtin_books[i][j];
+ books[i][j].name = translate(VerseKey::builtin_books[i][j].name);
+ }
+ }
+ }
+
+ *iBMAX = BMAX;
+ *ibooks = books;
+}
diff --git a/src/mgr/swmgr.cpp b/src/mgr/swmgr.cpp
new file mode 100644
index 0000000..ff36acc
--- /dev/null
+++ b/src/mgr/swmgr.cpp
@@ -0,0 +1,1084 @@
+/******************************************************************************
+ * swmgr.cpp - implementaion of class SWMgr used to interact with an install
+ * base of sword modules.
+ *
+ * $Id: swmgr.cpp,v 1.79 2002/08/09 05:53:48 scribe Exp $
+ *
+ * Copyright 1998 CrossWire Bible Society (http://www.crosswire.org)
+ * CrossWire Bible Society
+ * P. O. Box 2528
+ * Tempe, AZ 85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#ifndef __GNUC__
+#include <io.h>
+#else
+#include <unistd.h>
+#include <unixstr.h>
+#endif
+#include <sys/stat.h>
+#ifndef _MSC_VER
+#include <iostream>
+#endif
+#include <dirent.h>
+
+#include <swmgr.h>
+#include <rawtext.h>
+#include <rawgenbook.h>
+#include <rawcom.h>
+#include <hrefcom.h>
+#include <rawld.h>
+#include <rawld4.h>
+#include <utilfuns.h>
+#include <gbfplain.h>
+#include <thmlplain.h>
+#include <gbfstrongs.h>
+#include <gbffootnotes.h>
+#include <gbfheadings.h>
+#include <gbfmorph.h>
+#include <thmlstrongs.h>
+#include <thmlfootnotes.h>
+#include <thmlheadings.h>
+#include <thmlmorph.h>
+#include <thmllemma.h>
+#include <thmlscripref.h>
+#include <cipherfil.h>
+#include <rawfiles.h>
+#include <ztext.h>
+#include <zld.h>
+#include <zcom.h>
+#include <lzsscomprs.h>
+#include <utf8greekaccents.h>
+#include <utf8cantillation.h>
+#include <utf8hebrewpoints.h>
+#include <greeklexattribs.h>
+#include <swfiltermgr.h>
+
+
+
+#ifdef _ICU_
+#include <utf8transliterator.h>
+bool SWMgr::isICU = true;
+#else
+bool SWMgr::isICU = false;
+#endif
+
+#ifndef EXCLUDEZLIB
+#include <zipcomprs.h>
+#endif
+
+bool SWMgr::debug = false;
+
+#ifdef GLOBCONFPATH
+const char *SWMgr::globalConfPath = GLOBCONFPATH;
+#else
+const char *SWMgr::globalConfPath = "/etc/sword.conf:/usr/local/etc/sword.conf";
+#endif
+
+void SWMgr::init() {
+ SWFilter *tmpFilter = 0;
+ configPath = 0;
+ prefixPath = 0;
+ configType = 0;
+ myconfig = 0;
+ mysysconfig = 0;
+ homeConfig = 0;
+
+
+ cipherFilters.clear();
+ optionFilters.clear();
+ cleanupFilters.clear();
+
+ tmpFilter = new GBFStrongs();
+ optionFilters.insert(FilterMap::value_type("GBFStrongs", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new GBFFootnotes();
+ optionFilters.insert(FilterMap::value_type("GBFFootnotes", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new GBFMorph();
+ optionFilters.insert(FilterMap::value_type("GBFMorph", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new GBFHeadings();
+ optionFilters.insert(FilterMap::value_type("GBFHeadings", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new ThMLStrongs();
+ optionFilters.insert(FilterMap::value_type("ThMLStrongs", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new ThMLFootnotes();
+ optionFilters.insert(FilterMap::value_type("ThMLFootnotes", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new ThMLMorph();
+ optionFilters.insert(FilterMap::value_type("ThMLMorph", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new ThMLHeadings();
+ optionFilters.insert(FilterMap::value_type("ThMLHeadings", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new ThMLLemma();
+ optionFilters.insert(FilterMap::value_type("ThMLLemma", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new ThMLScripref();
+ optionFilters.insert(FilterMap::value_type("ThMLScripref", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new UTF8GreekAccents();
+ optionFilters.insert(FilterMap::value_type("UTF8GreekAccents", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new UTF8HebrewPoints();
+ optionFilters.insert(FilterMap::value_type("UTF8HebrewPoints", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new UTF8Cantillation();
+ optionFilters.insert(FilterMap::value_type("UTF8Cantillation", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+ tmpFilter = new GreekLexAttribs();
+ optionFilters.insert(FilterMap::value_type("GreekLexAttribs", tmpFilter));
+ cleanupFilters.push_back(tmpFilter);
+
+// UTF8Transliterator needs to be handled differently because it should always available as an option, for all modules
+#ifdef _ICU_
+ transliterator = new UTF8Transliterator();
+ optionFilters.insert(FilterMap::value_type("UTF8Transliterator", transliterator));
+ options.push_back(transliterator->getOptionName());
+ cleanupFilters.push_back(transliterator);
+#endif
+
+ gbfplain = new GBFPlain();
+ cleanupFilters.push_back(gbfplain);
+
+ thmlplain = new ThMLPlain();
+ cleanupFilters.push_back(thmlplain);
+}
+
+
+SWMgr::SWMgr(SWFilterMgr *filterMgr) {
+ commonInit(0, 0, true, filterMgr);
+}
+
+
+SWMgr::SWMgr(SWConfig *iconfig, SWConfig *isysconfig, bool autoload, SWFilterMgr *filterMgr) {
+ commonInit(iconfig, isysconfig, autoload, filterMgr);
+}
+
+
+void SWMgr::commonInit(SWConfig * iconfig, SWConfig * isysconfig, bool autoload, SWFilterMgr *filterMgr) {
+ this->filterMgr = filterMgr;
+ if (filterMgr)
+ filterMgr->setParentMgr(this);
+
+ init();
+
+ if (iconfig) {
+ config = iconfig;
+ myconfig = 0;
+ }
+ else config = 0;
+ if (isysconfig) {
+ sysconfig = isysconfig;
+ mysysconfig = 0;
+ }
+ else sysconfig = 0;
+
+ if (autoload)
+ Load();
+}
+
+
+SWMgr::SWMgr(const char *iConfigPath, bool autoload, SWFilterMgr *filterMgr) {
+
+ string path;
+
+ this->filterMgr = filterMgr;
+ if (filterMgr)
+ filterMgr->setParentMgr(this);
+
+ init();
+
+ path = iConfigPath;
+ if ((iConfigPath[strlen(iConfigPath)-1] != '\\') && (iConfigPath[strlen(iConfigPath)-1] != '/'))
+ path += "/";
+ if (FileMgr::existsFile(path.c_str(), "mods.conf")) {
+ stdstr(&prefixPath, path.c_str());
+ path += "mods.conf";
+ stdstr(&configPath, path.c_str());
+ }
+ else {
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+ stdstr(&prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(&configPath, path.c_str());
+ configType = 1;
+ }
+ }
+
+ config = 0;
+ sysconfig = 0;
+
+ if (autoload && configPath)
+ Load();
+}
+
+
+SWMgr::~SWMgr() {
+
+ DeleteMods();
+
+ for (FilterList::iterator it = cleanupFilters.begin(); it != cleanupFilters.end(); it++)
+ delete (*it);
+
+ if (homeConfig)
+ delete homeConfig;
+
+ if (myconfig)
+ delete myconfig;
+
+ if (prefixPath)
+ delete [] prefixPath;
+
+ if (configPath)
+ delete [] configPath;
+
+ if (filterMgr)
+ delete filterMgr;
+}
+
+
+void SWMgr::findConfig(char *configType, char **prefixPath, char **configPath, list<string> *augPaths) {
+ string path;
+ ConfigEntMap::iterator entry;
+ ConfigEntMap::iterator lastEntry;
+
+ char *envsworddir = getenv ("SWORD_PATH");
+ char *envhomedir = getenv ("HOME");
+
+ *configType = 0;
+
+#ifndef _MSC_VER
+ // check working directory
+if (debug)
+ std::cerr << "Checking working directory for mods.conf...";
+#endif
+
+ if (FileMgr::existsFile(".", "mods.conf")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ stdstr(prefixPath, "./");
+ stdstr(configPath, "./mods.conf");
+ return;
+ }
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking working directory for mods.d...";
+#endif
+
+ if (FileMgr::existsDir(".", "mods.d")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ stdstr(prefixPath, "./");
+ stdstr(configPath, "./mods.d");
+ *configType = 1;
+ return;
+ }
+
+
+ // check environment variable SWORD_PATH
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking SWORD_PATH...";
+#endif
+
+ if (envsworddir != NULL) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found (" << envsworddir << ")\n";
+#endif
+
+ path = envsworddir;
+ if ((envsworddir[strlen(envsworddir)-1] != '\\') && (envsworddir[strlen(envsworddir)-1] != '/'))
+ path += "/";
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking $SWORD_PATH for mods.conf...";
+#endif
+
+ if (FileMgr::existsFile(path.c_str(), "mods.conf")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ stdstr(prefixPath, path.c_str());
+ path += "mods.conf";
+ stdstr(configPath, path.c_str());
+ return;
+ }
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking $SWORD_PATH for mods.d...";
+#endif
+
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ stdstr(prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(configPath, path.c_str());
+ *configType = 1;
+ return;
+ }
+ }
+
+
+ // check for systemwide globalConfPath
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nParsing " << globalConfPath << "...";
+#endif
+
+ char *globPaths = 0;
+ char *gfp;
+ stdstr(&globPaths, globalConfPath);
+ for (gfp = strtok(globPaths, ":"); gfp; gfp = strtok(0, ":")) {
+
+ #ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking for " << gfp << "...";
+#endif
+
+ if (FileMgr::existsFile(gfp))
+ break;
+ }
+
+ if (gfp) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ SWConfig etcconf(gfp);
+ if ((entry = etcconf.Sections["Install"].find("DataPath")) != etcconf.Sections["Install"].end()) {
+ path = (*entry).second;
+ if (((*entry).second.c_str()[strlen((*entry).second.c_str())-1] != '\\') && ((*entry).second.c_str()[strlen((*entry).second.c_str())-1] != '/'))
+ path += "/";
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "DataPath in " << gfp << " is set to: " << path;
+#endif
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking for mods.conf in DataPath ";
+#endif
+ if (FileMgr::existsFile(path.c_str(), "mods.conf")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ stdstr(prefixPath, path.c_str());
+ path += "mods.conf";
+ stdstr(configPath, path.c_str());
+ *configType = 1;
+ }
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking for mods.d in DataPath ";
+#endif
+
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ stdstr(prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(configPath, path.c_str());
+ *configType = 1;
+ }
+ }
+ if (augPaths) {
+ augPaths->clear();
+ entry = etcconf.Sections["Install"].lower_bound("AugmentPath");
+ lastEntry = etcconf.Sections["Install"].upper_bound("AugmentPath");
+ for (;entry != lastEntry; entry++) {
+ path = entry->second;
+ if ((entry->second.c_str()[strlen(entry->second.c_str())-1] != '\\') && (entry->second.c_str()[strlen(entry->second.c_str())-1] != '/'))
+ path += "/";
+ augPaths->push_back(path);
+ }
+ }
+ }
+
+ delete [] globPaths;
+ if (*configType)
+ return;
+
+ // check ~/.sword/
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking home directory for ~/.sword/mods.conf" << path;
+#endif
+
+ if (envhomedir != NULL) {
+ path = envhomedir;
+ if ((envhomedir[strlen(envhomedir)-1] != '\\') && (envhomedir[strlen(envhomedir)-1] != '/'))
+ path += "/";
+ path += ".sword/";
+ if (FileMgr::existsFile(path.c_str(), "mods.conf")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << " found\n";
+#endif
+
+ stdstr(prefixPath, path.c_str());
+ path += "mods.conf";
+ stdstr(configPath, path.c_str());
+ return;
+ }
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "\nChecking home directory for ~/.sword/mods.d" << path;
+#endif
+
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+
+#ifndef _MSC_VER
+if (debug)
+ std::cerr << "found\n";
+#endif
+
+ stdstr(prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(configPath, path.c_str());
+ *configType = 2;
+ return;
+ }
+ }
+}
+
+
+void SWMgr::loadConfigDir(const char *ipath)
+{
+ DIR *dir;
+ struct dirent *ent;
+ string newmodfile;
+
+ if ((dir = opendir(ipath))) {
+ rewinddir(dir);
+ while ((ent = readdir(dir))) {
+ if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
+ newmodfile = ipath;
+ if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
+ newmodfile += "/";
+ newmodfile += ent->d_name;
+ if (config) {
+ SWConfig tmpConfig(newmodfile.c_str());
+ *config += tmpConfig;
+ }
+ else config = myconfig = new SWConfig(newmodfile.c_str());
+ }
+ }
+ closedir(dir);
+ if (!config) { // if no .conf file exist yet, create a default
+ newmodfile = ipath;
+ if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
+ newmodfile += "/";
+ newmodfile += "globals.conf";
+ config = myconfig = new SWConfig(newmodfile.c_str());
+ }
+ }
+}
+
+
+void SWMgr::augmentModules(const char *ipath) {
+ string path = ipath;
+ if ((ipath[strlen(ipath)-1] != '\\') && (ipath[strlen(ipath)-1] != '/'))
+ path += "/";
+ if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+ char *savePrefixPath = 0;
+ char *saveConfigPath = 0;
+ SWConfig *saveConfig = 0;
+ stdstr(&savePrefixPath, prefixPath);
+ stdstr(&prefixPath, path.c_str());
+ path += "mods.d";
+ stdstr(&saveConfigPath, configPath);
+ stdstr(&configPath, path.c_str());
+ saveConfig = config;
+ config = myconfig = 0;
+ loadConfigDir(configPath);
+
+ CreateMods();
+
+ stdstr(&prefixPath, savePrefixPath);
+ delete []savePrefixPath;
+ stdstr(&configPath, saveConfigPath);
+ delete []saveConfigPath;
+ (*saveConfig) += *config;
+ homeConfig = myconfig;
+ config = myconfig = saveConfig;
+ }
+}
+
+
+/***********************************************************************
+ * SWMgr::Load - loads actual modules
+ *
+ * RET: status - 0 = ok; -1 no config found; 1 = no modules installed
+ *
+ */
+
+signed char SWMgr::Load() {
+ signed char ret = 0;
+
+ if (!config) { // If we weren't passed a config object at construction, find a config file
+ if (!configPath) // If we weren't passed a config path at construction...
+ findConfig(&configType, &prefixPath, &configPath, &augPaths);
+ if (configPath) {
+ if (configType)
+ loadConfigDir(configPath);
+ else config = myconfig = new SWConfig(configPath);
+ }
+ }
+
+ if (config) {
+ SectionMap::iterator Sectloop, Sectend;
+ ConfigEntMap::iterator Entryloop, Entryend;
+
+ DeleteMods();
+
+ for (Sectloop = config->Sections.lower_bound("Globals"), Sectend = config->Sections.upper_bound("Globals"); Sectloop != Sectend; Sectloop++) { // scan thru all 'Globals' sections
+ for (Entryloop = (*Sectloop).second.lower_bound("AutoInstall"), Entryend = (*Sectloop).second.upper_bound("AutoInstall"); Entryloop != Entryend; Entryloop++) // scan thru all AutoInstall entries
+ InstallScan((*Entryloop).second.c_str()); // Scan AutoInstall entry directory for new modules and install
+ }
+ if (configType) { // force reload on config object because we may have installed new modules
+ delete myconfig;
+ config = myconfig = 0;
+ loadConfigDir(configPath);
+ }
+ else config->Load();
+
+ CreateMods();
+
+ for (list<string>::iterator pathIt = augPaths.begin(); pathIt != augPaths.end(); pathIt++) {
+ augmentModules(pathIt->c_str());
+ }
+// augment config with ~/.sword/mods.d if it exists ---------------------
+ char *envhomedir = getenv ("HOME");
+ if (envhomedir != NULL && configType != 2) { // 2 = user only
+ string path = envhomedir;
+ if ((envhomedir[strlen(envhomedir)-1] != '\\') && (envhomedir[strlen(envhomedir)-1] != '/'))
+ path += "/";
+ path += ".sword/";
+ augmentModules(path.c_str());
+ }
+// -------------------------------------------------------------------------
+ if ( !Modules.size() ) // config exists, but no modules
+ ret = 1;
+
+ }
+ else {
+ SWLog::systemlog->LogError("SWMgr: Can't find 'mods.conf' or 'mods.d'. Try setting:\n\tSWORD_PATH=<directory containing mods.conf>\n\tOr see the README file for a full description of setup options (%s)", (configPath) ? configPath : "<configPath is null>");
+ ret = -1;
+ }
+
+ return ret;
+}
+
+SWModule *SWMgr::CreateMod(string name, string driver, ConfigEntMap &section)
+{
+ string description, datapath, misc1;
+ ConfigEntMap::iterator entry;
+ SWModule *newmod = 0;
+ string lang, sourceformat, encoding;
+ signed char direction, enc, markup;
+
+ description = ((entry = section.find("Description")) != section.end()) ? (*entry).second : (string)"";
+ lang = ((entry = section.find("Lang")) != section.end()) ? (*entry).second : (string)"en";
+ sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (string)"";
+ encoding = ((entry = section.find("Encoding")) != section.end()) ? (*entry).second : (string)"";
+ datapath = prefixPath;
+ if ((prefixPath[strlen(prefixPath)-1] != '\\') && (prefixPath[strlen(prefixPath)-1] != '/'))
+ datapath += "/";
+ misc1 += ((entry = section.find("DataPath")) != section.end()) ? (*entry).second : (string)"";
+ char *buf = new char [ strlen(misc1.c_str()) + 1 ];
+ char *buf2 = buf;
+ strcpy(buf, misc1.c_str());
+// for (; ((*buf2) && ((*buf2 == '.') || (*buf2 == '/') || (*buf2 == '\\'))); buf2++);
+ for (; ((*buf2) && ((*buf2 == '/') || (*buf2 == '\\'))); buf2++);
+ if (*buf2)
+ datapath += buf2;
+ delete [] buf;
+
+ section["AbsoluteDataPath"] = datapath;
+
+ if (!stricmp(sourceformat.c_str(), "GBF"))
+ markup = FMT_GBF;
+ else if (!stricmp(sourceformat.c_str(), "ThML"))
+ markup = FMT_THML;
+ else if (!stricmp(sourceformat.c_str(), "OSIS"))
+ markup = FMT_OSIS;
+ else
+ markup = FMT_PLAIN;
+
+ if (!stricmp(encoding.c_str(), "SCSU"))
+ enc = ENC_SCSU;
+ else if (!stricmp(encoding.c_str(), "UTF-8")) {
+ enc = ENC_UTF8;
+ }
+ else enc = ENC_LATIN1;
+
+ if ((entry = section.find("Direction")) == section.end()) {
+ direction = DIRECTION_LTR;
+ }
+ else if (!stricmp((*entry).second.c_str(), "rtol")) {
+ direction = DIRECTION_RTL;
+ }
+ else if (!stricmp((*entry).second.c_str(), "bidi")) {
+ direction = DIRECTION_BIDI;
+ }
+ else {
+ direction = DIRECTION_LTR;
+ }
+
+ if ((!stricmp(driver.c_str(), "zText")) || (!stricmp(driver.c_str(), "zCom"))) {
+ SWCompress *compress = 0;
+ int blockType = CHAPTERBLOCKS;
+ misc1 = ((entry = section.find("BlockType")) != section.end()) ? (*entry).second : (string)"CHAPTER";
+ if (!stricmp(misc1.c_str(), "VERSE"))
+ blockType = VERSEBLOCKS;
+ else if (!stricmp(misc1.c_str(), "CHAPTER"))
+ blockType = CHAPTERBLOCKS;
+ else if (!stricmp(misc1.c_str(), "BOOK"))
+ blockType = BOOKBLOCKS;
+
+ misc1 = ((entry = section.find("CompressType")) != section.end()) ? (*entry).second : (string)"LZSS";
+#ifndef EXCLUDEZLIB
+ if (!stricmp(misc1.c_str(), "ZIP"))
+ compress = new ZipCompress();
+ else
+#endif
+ if (!stricmp(misc1.c_str(), "LZSS"))
+ compress = new LZSSCompress();
+
+ if (compress) {
+ if (!stricmp(driver.c_str(), "zText"))
+ newmod = new zText(datapath.c_str(), name.c_str(), description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str());
+ else newmod = new zCom(datapath.c_str(), name.c_str(), description.c_str(), blockType, compress, 0, enc, direction, markup, lang.c_str());
+ }
+ }
+
+ if (!stricmp(driver.c_str(), "RawText")) {
+ newmod = new RawText(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str());
+ }
+
+ // backward support old drivers
+ if (!stricmp(driver.c_str(), "RawGBF")) {
+ newmod = new RawText(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str());
+ }
+
+ if (!stricmp(driver.c_str(), "RawCom")) {
+ newmod = new RawCom(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str());
+ }
+
+ if (!stricmp(driver.c_str(), "RawFiles")) {
+ newmod = new RawFiles(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str());
+ }
+
+ if (!stricmp(driver.c_str(), "HREFCom")) {
+ misc1 = ((entry = section.find("Prefix")) != section.end()) ? (*entry).second : (string)"";
+ newmod = new HREFCom(datapath.c_str(), misc1.c_str(), name.c_str(), description.c_str());
+ }
+
+ if (!stricmp(driver.c_str(), "RawLD"))
+ newmod = new RawLD(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str());
+
+ if (!stricmp(driver.c_str(), "RawLD4"))
+ newmod = new RawLD4(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str());
+
+ if (!stricmp(driver.c_str(), "zLD")) {
+ SWCompress *compress = 0;
+ int blockCount;
+ misc1 = ((entry = section.find("BlockCount")) != section.end()) ? (*entry).second : (string)"200";
+ blockCount = atoi(misc1.c_str());
+ blockCount = (blockCount) ? blockCount : 200;
+
+ misc1 = ((entry = section.find("CompressType")) != section.end()) ? (*entry).second : (string)"LZSS";
+#ifndef EXCLUDEZLIB
+ if (!stricmp(misc1.c_str(), "ZIP"))
+ compress = new ZipCompress();
+ else
+#endif
+ if (!stricmp(misc1.c_str(), "LZSS"))
+ compress = new LZSSCompress();
+
+ if (compress) {
+ newmod = new zLD(datapath.c_str(), name.c_str(), description.c_str(), blockCount, compress, 0, enc, direction, markup, lang.c_str());
+ }
+ }
+
+ if (!stricmp(driver.c_str(), "RawGenBook")) {
+ newmod = new RawGenBook(datapath.c_str(), name.c_str(), description.c_str(), 0, enc, direction, markup, lang.c_str());
+ }
+ // if a specific module type is set in the config, use this
+ if ((entry = section.find("Type")) != section.end())
+ newmod->Type(entry->second.c_str());
+
+ newmod->setConfig(&section);
+ return newmod;
+}
+
+
+void SWMgr::AddGlobalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) {
+ for (;start != end; start++) {
+ FilterMap::iterator it;
+ it = optionFilters.find((*start).second);
+ if (it != optionFilters.end()) {
+ module->AddOptionFilter((*it).second); // add filter to module and option as a valid option
+ OptionsList::iterator loop;
+ for (loop = options.begin(); loop != options.end(); loop++) {
+ if (!strcmp((*loop).c_str(), (*it).second->getOptionName()))
+ break;
+ }
+ if (loop == options.end()) // if we have not yet included the option
+ options.push_back((*it).second->getOptionName());
+ }
+ }
+ if (filterMgr)
+ filterMgr->AddGlobalOptions(module, section, start, end);
+#ifdef _ICU_
+ module->AddOptionFilter(transliterator);
+#endif
+}
+
+
+void SWMgr::AddLocalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end)
+{
+ for (;start != end; start++) {
+ FilterMap::iterator it;
+ it = optionFilters.find((*start).second);
+ if (it != optionFilters.end()) {
+ module->AddOptionFilter((*it).second); // add filter to module
+ }
+ }
+
+ if (filterMgr)
+ filterMgr->AddLocalOptions(module, section, start, end);
+}
+
+
+void SWMgr::AddRawFilters(SWModule *module, ConfigEntMap &section) {
+ string sourceformat, cipherKey;
+ ConfigEntMap::iterator entry;
+
+ cipherKey = ((entry = section.find("CipherKey")) != section.end()) ? (*entry).second : (string)"";
+ if (!cipherKey.empty()) {
+ SWFilter *cipherFilter = new CipherFilter(cipherKey.c_str());
+ cipherFilters.insert(FilterMap::value_type(module->Name(), cipherFilter));
+ cleanupFilters.push_back(cipherFilter);
+ module->AddRawFilter(cipherFilter);
+ }
+
+ if (filterMgr)
+ filterMgr->AddRawFilters(module, section);
+}
+
+
+void SWMgr::AddEncodingFilters(SWModule *module, ConfigEntMap &section) {
+
+ if (filterMgr)
+ filterMgr->AddEncodingFilters(module, section);
+}
+
+
+void SWMgr::AddRenderFilters(SWModule *module, ConfigEntMap &section) {
+ string sourceformat;
+ ConfigEntMap::iterator entry;
+
+ sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (string)"";
+
+ // Temporary: To support old module types
+ // TODO: Remove at 1.6.0 release?
+ if (sourceformat.empty()) {
+ sourceformat = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (string)"";
+ if (!stricmp(sourceformat.c_str(), "RawGBF"))
+ sourceformat = "GBF";
+ else sourceformat = "";
+ }
+
+// process module - eg. follows
+// if (!stricmp(sourceformat.c_str(), "GBF")) {
+// module->AddRenderFilter(gbftortf);
+// }
+
+ if (filterMgr)
+ filterMgr->AddRenderFilters(module, section);
+
+}
+
+
+void SWMgr::AddStripFilters(SWModule *module, ConfigEntMap &section)
+{
+ string sourceformat;
+ ConfigEntMap::iterator entry;
+
+ sourceformat = ((entry = section.find("SourceType")) != section.end()) ? (*entry).second : (string)"";
+ // Temporary: To support old module types
+ if (sourceformat.empty()) {
+ sourceformat = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (string)"";
+ if (!stricmp(sourceformat.c_str(), "RawGBF"))
+ sourceformat = "GBF";
+ else sourceformat = "";
+ }
+
+ if (!stricmp(sourceformat.c_str(), "GBF")) {
+ module->AddStripFilter(gbfplain);
+ }
+ else if (!stricmp(sourceformat.c_str(), "ThML")) {
+ module->AddStripFilter(thmlplain);
+ }
+
+ if (filterMgr)
+ filterMgr->AddStripFilters(module, section);
+
+}
+
+
+void SWMgr::CreateMods() {
+ SectionMap::iterator it;
+ ConfigEntMap::iterator start;
+ ConfigEntMap::iterator end;
+ ConfigEntMap::iterator entry;
+ SWModule *newmod;
+ string driver, misc1;
+ for (it = config->Sections.begin(); it != config->Sections.end(); it++) {
+ ConfigEntMap &section = (*it).second;
+ newmod = 0;
+
+ driver = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (string)"";
+ if (!driver.empty()) {
+ newmod = CreateMod((*it).first, driver, section);
+ if (newmod) {
+ start = (*it).second.lower_bound("GlobalOptionFilter");
+ end = (*it).second.upper_bound("GlobalOptionFilter");
+ AddGlobalOptions(newmod, section, start, end);
+
+ start = (*it).second.lower_bound("LocalOptionFilter");
+ end = (*it).second.upper_bound("LocalOptionFilter");
+ AddLocalOptions(newmod, section, start, end);
+
+ AddRawFilters(newmod, section);
+ AddStripFilters(newmod, section);
+ AddRenderFilters(newmod, section);
+ AddEncodingFilters(newmod, section);
+
+ Modules.insert(ModMap::value_type(newmod->Name(), newmod));
+ }
+ }
+ }
+}
+
+
+void SWMgr::DeleteMods() {
+
+ ModMap::iterator it;
+
+ for (it = Modules.begin(); it != Modules.end(); it++)
+ delete (*it).second;
+
+ Modules.clear();
+}
+
+
+void SWMgr::InstallScan(const char *dirname)
+{
+ DIR *dir;
+ struct dirent *ent;
+ int conffd = 0;
+ string newmodfile;
+ string targetName;
+
+ if (!access(dirname, 04)) {
+ if ((dir = opendir(dirname))) {
+ rewinddir(dir);
+ while ((ent = readdir(dir))) {
+ if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, ".."))) {
+ newmodfile = dirname;
+ if ((dirname[strlen(dirname)-1] != '\\') && (dirname[strlen(dirname)-1] != '/'))
+ newmodfile += "/";
+ newmodfile += ent->d_name;
+ if (configType) {
+ if (config > 0)
+ close(conffd);
+ targetName = configPath;
+ if ((configPath[strlen(configPath)-1] != '\\') && (configPath[strlen(configPath)-1] != '/'))
+ targetName += "/";
+ targetName += ent->d_name;
+ conffd = open(targetName.c_str(), O_WRONLY|O_CREAT, S_IREAD|S_IWRITE);
+ }
+ else {
+ if (conffd < 1) {
+ conffd = open(config->filename.c_str(), O_WRONLY|O_APPEND);
+ if (conffd > 0)
+ lseek(conffd, 0L, SEEK_END);
+ }
+ }
+ AddModToConfig(conffd, newmodfile.c_str());
+ unlink(newmodfile.c_str());
+ }
+ }
+ if (conffd > 0)
+ close(conffd);
+ closedir(dir);
+ }
+ }
+}
+
+
+char SWMgr::AddModToConfig(int conffd, const char *fname)
+{
+ int modfd;
+ char ch;
+
+ SWLog::systemlog->LogTimedInformation("Found new module [%s]. Installing...", fname);
+ modfd = open(fname, O_RDONLY);
+ ch = '\n';
+ write(conffd, &ch, 1);
+ while (read(modfd, &ch, 1) == 1)
+ write(conffd, &ch, 1);
+ ch = '\n';
+ write(conffd, &ch, 1);
+ close(modfd);
+ return 0;
+}
+
+
+void SWMgr::setGlobalOption(const char *option, const char *value)
+{
+ for (FilterMap::iterator it = optionFilters.begin(); it != optionFilters.end(); it++) {
+ if ((*it).second->getOptionName()) {
+ if (!stricmp(option, (*it).second->getOptionName()))
+ (*it).second->setOptionValue(value);
+ }
+ }
+}
+
+
+const char *SWMgr::getGlobalOption(const char *option)
+{
+ for (FilterMap::iterator it = optionFilters.begin(); it != optionFilters.end(); it++) {
+ if ((*it).second->getOptionName()) {
+ if (!stricmp(option, (*it).second->getOptionName()))
+ return (*it).second->getOptionValue();
+ }
+ }
+ return 0;
+}
+
+
+const char *SWMgr::getGlobalOptionTip(const char *option)
+{
+ for (FilterMap::iterator it = optionFilters.begin(); it != optionFilters.end(); it++) {
+ if ((*it).second->getOptionName()) {
+ if (!stricmp(option, (*it).second->getOptionName()))
+ return (*it).second->getOptionTip();
+ }
+ }
+ return 0;
+}
+
+
+OptionsList SWMgr::getGlobalOptions()
+{
+ return options;
+}
+
+
+OptionsList SWMgr::getGlobalOptionValues(const char *option)
+{
+ OptionsList options;
+ for (FilterMap::iterator it = optionFilters.begin(); it != optionFilters.end(); it++) {
+ if ((*it).second->getOptionName()) {
+ if (!stricmp(option, (*it).second->getOptionName())) {
+ options = (*it).second->getOptionValues();
+ break; // just find the first one. All option filters with the same option name should expect the same values
+ }
+ }
+ }
+ return options;
+}
+
+
+signed char SWMgr::setCipherKey(const char *modName, const char *key) {
+ FilterMap::iterator it;
+ ModMap::iterator it2;
+
+ // check for filter that already exists
+ it = cipherFilters.find(modName);
+ if (it != cipherFilters.end()) {
+ ((CipherFilter *)(*it).second)->getCipher()->setCipherKey(key);
+ return 0;
+ }
+ // check if module exists
+ else {
+ it2 = Modules.find(modName);
+ if (it2 != Modules.end()) {
+ SWFilter *cipherFilter = new CipherFilter(key);
+ cipherFilters.insert(FilterMap::value_type(modName, cipherFilter));
+ cleanupFilters.push_back(cipherFilter);
+ (*it2).second->AddRawFilter(cipherFilter);
+ return 0;
+ }
+ }
+ return -1;
+}