24 #pragma warning( disable: 4251 )
39 using namespace sword;
56 void usage(
const char *progName = 0,
const char *error = 0);
80 if (!userDisclaimerConfirmed) {
81 std::cout <<
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
82 std::cout <<
" -=+* WARNING *+=- -=+* WARNING *+=-\n\n\n";
83 std::cout <<
"Although Install Manager provides a convenient way for installing\n";
84 std::cout <<
"and upgrading SWORD components, it also uses a systematic method\n";
85 std::cout <<
"for accessing sites which gives packet sniffers a target to lock\n";
86 std::cout <<
"into for singling out users. \n\n\n";
87 std::cout <<
"IF YOU LIVE IN A PERSECUTED COUNTRY AND DO NOT WISH TO RISK DETECTION,\n";
88 std::cout <<
"YOU SHOULD *NOT* USE INSTALL MANAGER'S REMOTE SOURCE FEATURES.\n\n\n";
89 std::cout <<
"Also, Remote Sources other than CrossWire may contain less than\n";
90 std::cout <<
"quality modules, modules with unorthodox content, or even modules\n";
91 std::cout <<
"which are not legitimately distributable. Many repositories\n";
92 std::cout <<
"contain wonderfully useful content. These repositories simply\n";
93 std::cout <<
"are not reviewed or maintained by CrossWire and CrossWire\n";
94 std::cout <<
"cannot be held responsible for their content. CAVEAT EMPTOR.\n\n\n";
95 std::cout <<
"If you understand this and are willing to enable remote source features\n";
96 std::cout <<
"then type yes at the prompt\n\n";
97 std::cout <<
"enable? [no] ";
100 fgets(prompt, 9, stdin);
101 userDisclaimerConfirmed = (!strcmp(prompt,
"yes\n"));
104 return userDisclaimerConfirmed;
111 static bool allowed =
false;
118 cout <<
"While connecting to an encrypted install source, SWORD can allow\n";
119 cout <<
"unverified peers, e.g., self-signed certificates. While this is\n";
120 cout <<
"generally considered safe because SWORD only retrieves Bible content\n";
121 cout <<
"and does not send any data to the server, it could still possibly\n";
122 cout <<
"allow a malicious actor to sit between you and the server, as with\n";
123 cout <<
"unencrypted sources. Type no to turn this off.\n\n";
124 cout <<
"Would you like to allow unverified peers? [yes] ";
127 fgets(prompt, 9, stdin);
128 allowed = (strcmp(prompt,
"no\n"));
136 virtual void update(
unsigned long totalBytes,
unsigned long completedBytes) {
137 int p = (totalBytes > 0) ? (
int)(74.0 * ((double)completedBytes / (
double)totalBytes)) : 0;
138 for (;last < p; ++last) {
141 output.setFormatted(
"[ File Bytes: %ld", totalBytes);
142 while (output.size() < 75) output +=
" ";
144 cout << output.c_str() <<
"\n ";
150 virtual void preStatus(
long totalBytes,
long completedBytes,
const char *message) {
152 output.setFormatted(
"[ Total Bytes: %ld; Completed Bytes: %ld", totalBytes, completedBytes);
153 while (output.size() < 75) output +=
" ";
155 cout <<
"\n" << output.c_str() <<
"\n ";
156 int p = (int)(74.0 * (
double)completedBytes/totalBytes);
157 for (
int i = 0; i < p; ++i) { cout <<
"="; }
158 cout <<
"\n\n" << message <<
"\n";
169 usage(0,
"ERROR: SWORD configuration not found. Please configure SWORD before using this program.");
172 if (baseDir.length() < 1) baseDir =
".";
173 baseDir +=
"/.sword/InstallMgr";
174 confPath = baseDir +
"/InstallMgr.conf";
206 is.caption =
"CrossWire";
207 is.source =
"ftp.crosswire.org";
208 is.directory =
"/pub/sword/raw";
211 config[
"General"][
"PassiveFTP"] =
"true";
212 config[
"General"][
"TimeoutMillis"] =
"10000";
213 config[
"General"][
"UnverifiedPeerAllowed"] = (unverifiedPeerAllowed) ?
"true" :
"false";
215 config[
"Sources"][
"FTPSource"] = is.getConfEnt();
229 cout <<
"\n\nInitialized basic config file at [" <<
confPath <<
"]\n";
230 cout <<
"with remote source features " << ((enable) ?
"ENABLED" :
"DISABLED") <<
"\n";
231 cout <<
"with unverified peers " << ((allowed) ?
"ALLOWED" :
"DISALLOWED") <<
"\n";
239 cout <<
"\n\nDisclaimer not accepted. Aborting.";
251 cout <<
"\nSync'd config file with master remote source list.\n";
252 else cout <<
"\nFailed to sync config file with master remote source list.\n";
258 SWModule *
module =
mgr->getModule(modName);
260 fprintf(stderr,
"Couldn't find module [%s] to remove\n", modName);
264 cout <<
"Removed module: [" << modName <<
"]\n";
270 cout <<
"Remote Sources:\n\n";
272 cout <<
"[" << it->second->caption <<
"]\n";
273 cout <<
"\tType : " << it->second->type <<
"\n";
274 cout <<
"\tSource : " << it->second->source <<
"\n";
275 cout <<
"\tDirectory: " << it->second->directory <<
"\n";
284 fprintf(stderr,
"Couldn't find remote source [%s]\n", sourceName);
289 cout <<
"\nRemote Source Refreshed\n";
290 else cerr <<
"\nError Refreshing Remote Source\n";
294 void listModules(SWMgr *otherMgr = 0,
bool onlyNewAndUpdates =
false,
bool utilModules =
false) {
297 if (!otherMgr) otherMgr =
mgr;
299 for (std::map<SWModule *, int>::iterator it = mods.begin(); it != mods.end(); it++) {
301 SWBuf version = module->getConfigEntry(
"Version");
307 if (!onlyNewAndUpdates || status ==
"*" || status ==
"+") {
308 cout << status <<
"[" << module->getName() <<
"] \t(" << version <<
") \t- " << module->getDescription() <<
"\n";
314 void remoteListModules(
const char *sourceName,
bool onlyNewAndUpdated =
false,
bool utilModules =
false) {
316 cout <<
"Available Modules:\n(be sure to refresh remote source (-r) first for most current list)\n\n";
319 fprintf(stderr,
"Couldn't find remote source [%s]\n", sourceName);
322 listModules(source->second->getMgr(), onlyNewAndUpdated, utilModules);
330 fprintf(stderr,
"Couldn't find remote source [%s]\n", sourceName);
333 SWMgr *
mgr = source->second->getMgr();
334 SWModule *
m = mgr->getModule(modName);
336 fprintf(stderr,
"Couldn't find module [%s] in source [%s]\n", modName, sourceName);
339 cout <<
"Module Description\n\n";
340 for (ConfigEntMap::const_iterator it = m->getConfig().begin(); it != m->getConfig().end(); ++it) {
341 cout <<
"[" << it->first <<
"]:" << it->second <<
"\n";
343 cout <<
"\nOption Features available for module: " << m->getName() <<
"\n\n";
344 for (OptionFilterList::const_iterator it = m->getOptionFilters().begin(); it != m->getOptionFilters().end(); ++it) {
345 cout << (*it)->getOptionName() <<
" (" << (*it)->getOptionTip() <<
")\n";
346 StringList optionValues = (*it)->getOptionValues();
347 for (StringList::const_iterator it2 = optionValues.begin(); it2 != optionValues.end(); ++it2) {
348 cout <<
"\t" << *it2 <<
"\n";
355 cout <<
"Available Modules:\n\n";
365 fprintf(stderr,
"Couldn't find remote source [%s]\n", sourceName);
369 SWMgr *rmgr = is->
getMgr();
370 SWModule *
module = rmgr->getModule(modName);
372 fprintf(stderr,
"Remote source [%s] does not make available module [%s]\n", sourceName, modName);
378 cout <<
"\nError installing module: [" << module->getName() <<
"] (write permissions?)\n";
379 }
else cout <<
"\nInstalled module: [" << module->getName() <<
"]\n";
386 SWModule *
module = lmgr.getModule(modName);
388 fprintf(stderr,
"Module [%s] not available at path [%s]\n", modName, dir);
393 cout <<
"\nError installing module: [" << module->getName() <<
"] (write permissions?)\n";
394 }
else cout <<
"\nInstalled module: [" << module->getName() <<
"]\n";
398 void usage(
const char *progName,
const char *error) {
400 if (error) fprintf(stderr,
"\n%s: %s\n", (progName ? progName :
"installmgr"), error);
402 fprintf(stderr,
"\nusage: %s [--allow...] <command> [command ...]\n"
404 "\n\t--allow-internet-access-and-risk-tracing-and-jail-or-martyrdom \n"
405 "\n\t This aptly named option will allow the program to connect to the internet without asking for user confirmation\n"
406 "\t In many places this may well be a risky or even foolish undertaking.\n"
407 "\t Please take special care before you use this option in scripts, particularly in scripts you want to offer for public download.\n"
408 "\t What may appear to be safe for you, may well not be safe for someone else, who uses your scripts. \n"
409 "\n\t--allow-unverified-tls-peer \n"
410 "\n\t This option will allow the program to connect to unverified peers\n"
411 "\t (e.g., hosts using self-signed certificates) without asking for user confirmation.\n"
412 "\n\t Commands (run in order they are passed):\n\n"
413 "\t -init\t\t\t\tcreate a basic user config file.\n"
414 "\t\t\t\t\t\tWARNING: overwrites existing.\n"
415 "\t -sc\t\t\t\tsync config with known remote repo list\n"
416 "\t\t\t\t\t\tNOTE: also creates if none exists\n"
417 "\t -s\t\t\t\tlist remote sources\n"
418 "\t -r <remoteSrcName>\t\trefresh remote source\n"
419 "\t -rl <remoteSrcName>\t\tlist available user modules from remote source\n"
420 "\t -rlu <remoteSrcName>\t\tlist available utility modules from remote source\n"
421 "\t -rd <remoteSrcName>\t\tlist new/updated user modules from remote source\n"
422 "\t -rdu <remoteSrcName>\t\tlist new/updated utility modules from remote source\n"
423 "\t -rdesc <remoteSrcName> <modName>\tdescribe module from remote source\n"
424 "\t -ri <remoteSrcName> <modName>\tinstall module from remote source\n"
425 "\t -l\t\t\t\tlist installed user modules\n"
426 "\t -lu\t\t\t\tlist installed utility modules\n"
427 "\t -u <modName>\t\t\tuninstall module\n"
428 "\t -ll <path>\t\t\tlist available modules at local path\n"
429 "\t -li <path> <modName>\t\tinstall module from local path\n"
430 "\t -d\t\t\t\tturn debug output on\n"
436 int main(
int argc,
char **argv) {
441 if (argc < 2)
usage(*argv);
443 for (
int i = 1; i < argc; i++) {
444 if (!strcmp(argv[i],
"-d")) {
447 else if (!strcmp(argv[i],
"--allow-internet-access-and-risk-tracing-and-jail-or-martyrdom")) {
450 else if (!strcmp(argv[i],
"--allow-unverified-tls-peer")) {
453 else if (!strcmp(argv[i],
"-init")) {
456 else if (!strcmp(argv[i],
"-l")) {
457 cout <<
"Installed User Modules:\n\n";
460 else if (!strcmp(argv[i],
"-lu")) {
461 cout <<
"Installed Utility Modules:\n\n";
464 else if (!strcmp(argv[i],
"-ll")) {
466 else usage(*argv,
"-ll requires <path>");
468 else if (!strcmp(argv[i],
"-li")) {
470 const char *path = argv[++i];
471 const char *modName = argv[++i];
474 else usage(*argv,
"-li requires <path> <modName>");
476 else if (!strcmp(argv[i],
"-u")) {
478 else usage(*argv,
"-u requires <modName>");
480 else if (!strcmp(argv[i],
"-s")) {
483 else if (!strcmp(argv[i],
"-sc")) {
486 else if (!strcmp(argv[i],
"-r")) {
488 else usage(*argv,
"-r requires <remoteSrcName>");
490 else if (!strcmp(argv[i],
"-rl")) {
492 else usage(*argv,
"-rl requires <remoteSrcName>");
494 else if (!strcmp(argv[i],
"-rlu")) {
496 else usage(*argv,
"-rlu requires <remoteSrcName>");
498 else if (!strcmp(argv[i],
"-rd")) {
500 else usage(*argv,
"-rd requires <remoteSrcName>");
502 else if (!strcmp(argv[i],
"-rdu")) {
504 else usage(*argv,
"-rdu requires <remoteSrcName>");
506 else if (!strcmp(argv[i],
"-rdesc")) {
508 const char *source = argv[++i];
509 const char *modName = argv[++i];
512 else usage(*argv,
"-rdesc requires <remoteSrcName> <modName>");
514 else if (!strcmp(argv[i],
"-ri")) {
516 const char *source = argv[++i];
517 const char *modName = argv[++i];
520 else usage(*argv,
"-ri requires <remoteSrcName> <modName>");
522 else usage(*argv, (((SWBuf)
"Unknown argument: ")+ argv[i]).c_str());
static signed char existsFile(const char *ipath, const char *ifileName=0)
virtual int refreshRemoteSourceConfiguration()
static const unsigned int MODSTAT_OLDER
void remoteListModules(const char *sourceName, bool onlyNewAndUpdated=false, bool utilModules=false)
static SWLog * getSystemLog()
MyInstallMgr(const char *privatePath="./", StatusReporter *sr=0)
StatusReporter * statusReporter
bool isUnverifiedPeerAllowed()
static const unsigned int MODSTAT_NEW
void localDirListModules(const char *dir)
virtual void preStatus(long totalBytes, long completedBytes, const char *message)
static std::map< SWModule *, int > getModuleStatus(const SWMgr &base, const SWMgr &other, bool utilModules=false)
std::list< SWBuf > StringList
void refreshRemoteSource(const char *sourceName)
void uninstallModule(const char *modName)
void localDirInstallModule(const char *dir, const char *modName)
virtual bool isUserDisclaimerConfirmed() const
void listModules(SWMgr *otherMgr=0, bool onlyNewAndUpdates=false, bool utilModules=false)
static int createParent(const char *pName)
virtual void update(unsigned long totalBytes, unsigned long completedBytes)
void setUserDisclaimerConfirmed(bool val)
virtual int installModule(SWMgr *destMgr, const char *fromLocation, const char *modName, InstallSource *is=0)
void usage(const char *app)
static SWVersion currentVersion
void setLogLevel(char level)
virtual int refreshRemoteSource(InstallSource *is)
void createBasicConfig(bool enableRemote, bool addCrossWire, bool unverifiedPeerAllowed)
static const unsigned int MODSTAT_UPDATED
void remoteInstallModule(const char *sourceName, const char *modName)
virtual int removeModule(SWMgr *manager, const char *modName)
virtual bool isUserDisclaimerConfirmed() const
void remoteDescribeModule(const char *sourceName, const char *modName)
virtual void save() const
static const char LOG_DEBUG
static FileMgr * getSystemFileMgr()