void DataDirLocater::Check() { if (IsIsolationMode()) { LOG("[DataDirLocater::%s] Isolation Mode!", __func__); } else if (IsPortableMode()) { LOG("[DataDirLocater::%s] Portable Mode!", __func__); } // Filter usable DataDirs FilterUsableDataDirs(); if (writeDir == nullptr) { // bail out const std::string errstr = "Not a single writable data directory found!\n\n" "Configure a writable data directory using either:\n" "- the SPRING_DATADIR environment variable,\n" #ifdef WIN32 "- a SpringData=C:/path/to/data declaration in spring's config file ./springsettings.cfg\n" "- by giving your user-account write access to the installation directory"; #else "- a SpringData=/path/to/data declaration in ~/.springrc or\n" "- the configuration file /etc/spring/datadir"; #endif throw content_error(errstr); } if (Platform::FreeDiskSpace(writeDir->path) <= 1024) throw content_error("not enough free space on drive containing writeable data-directory " + writeDir->path); ChangeCwdToWriteDir(); CreateCacheDir(writeDir->path + FileSystem::GetCacheDir()); }
void DataDirLocater::LocateDataDirs() { // Construct the list of dataDirs from various sources. // Note: The first dir added will be the writable data dir! dataDirs.clear(); // Note: first pushed dir is writeDir & dir priority decreases with pos in queue // LEVEL 1: User defined write dirs { if (!forcedWriteDir.empty()) AddDirs(forcedWriteDir); const char* env = getenv("SPRING_WRITEDIR"); if (env != nullptr && *env != 0) AddDirs(env); // ENV{SPRING_WRITEDIR} } // LEVEL 2: automated dirs if (IsIsolationMode()) { // LEVEL 2a: Isolation Mode (either installDir or user set one) if (isolationModeDir.empty()) { AddPortableDir(); // better use curWorkDir? } else { AddDirs(isolationModeDir); } } else { // LEVEL 2b: InstallDir, HomeDirs & Shared dirs if (IsPortableMode()) AddPortableDir(); AddHomeDirs(); //AddCurWorkDir(); AddEtcDirs(); AddShareDirs(); } // LEVEL 3: additional custom data sources { const char* env = getenv("SPRING_DATADIR"); if (env != nullptr && *env != 0) AddDirs(env); // ENV{SPRING_DATADIR} // user defined in spring config (Linux: ~/.springrc, Windows: .\springsettings.cfg) if (configHandler != nullptr) AddDirs(configHandler->GetString("SpringData")); } // Find the folder we save to FindWriteableDataDir(); }
/* ---------------------------------------------------------------------- * Main program. Parse arguments etc. */ int main(int argc, char *argv[]) { int ret; #ifdef PERSOPORT IniFileFlag = 0 ; DirectoryBrowseFlag = 0 ; IsPortableMode() ; #endif ret = psftp_main(argc, argv); return ret; }
/* ---------------------------------------------------------------------- * Main program. Parse arguments etc. */ int main(int argc, char *argv[]) { int ret; #ifdef PERSOPORT IsPortableMode() ; //if( IsPortableMode() ) { printf( "Portable mode on\n" ) ; } #endif ret = psftp_main(argc, argv); return ret; }
void DataDirLocater::AddCwdOrParentDir(const std::string& curWorkDir, bool forceAdd) { // This is useful in case of multiple engine/unitsync versions installed // together in a sub-dir of the data-dir // The data-dir structure then might look similar to this: // maps/ // games/ // engines/engine-0.83.0.0.exe // engines/engine-0.83.1.0.exe // unitsyncs/unitsync-0.83.0.0.exe // unitsyncs/unitsync-0.83.1.0.exe const std::string curWorkDirParent = FileSystem::GetParent(curWorkDir); // we can not add both ./ and ../ as data-dir if ((curWorkDirParent != "") && LooksLikeMultiVersionDataDir(curWorkDirParent)) { AddDirs(curWorkDirParent); // "../" } else if (IsPortableMode() || forceAdd) { // always using this would be unclean, because spring and unitsync // would end up with different sets of data-dirs AddDirs(curWorkDir); // "./" } }
int plink_main(int argc, char **argv) { int sending; int portnumber = -1; SOCKET *sklist; int skcount, sksize; int exitcode; int errors; int got_host = FALSE; int use_subsystem = 0; unsigned long now, next, then; IsPortableMode() ; //if( IsPortableMode() ) { printf( "Portable mode on\n" ) ; } #else int main(int argc, char **argv) { int sending; int portnumber = -1; SOCKET *sklist; int skcount, sksize; int exitcode; int errors; int got_host = FALSE; int use_subsystem = 0; unsigned long now, next, then; #endif sklist = NULL; skcount = sksize = 0; /* * Initialise port and protocol to sensible defaults. (These * will be overridden by more or less anything.) */ default_protocol = PROT_SSH; default_port = 22; flags = FLAG_STDERR; /* * Process the command line. */ conf = conf_new(); do_defaults(NULL, conf); loaded_session = FALSE; default_protocol = conf_get_int(conf, CONF_protocol); default_port = conf_get_int(conf, CONF_port); errors = 0; { /* * Override the default protocol if PLINK_PROTOCOL is set. */ char *p = getenv("PLINK_PROTOCOL"); if (p) { const Backend *b = backend_from_name(p); if (b) { default_protocol = b->protocol; default_port = b->default_port; conf_set_int(conf, CONF_protocol, default_protocol); conf_set_int(conf, CONF_port, default_port); } } } while (--argc) { char *p = *++argv; if (*p == '-') { int ret = cmdline_process_param(p, (argc > 1 ? argv[1] : NULL), 1, conf); if (ret == -2) { fprintf(stderr, "plink: option \"%s\" requires an argument\n", p); errors = 1; } else if (ret == 2) { --argc, ++argv; } else if (ret == 1) { continue; } else if (!strcmp(p, "-batch")) { console_batch_mode = 1; } else if (!strcmp(p, "-s")) { /* Save status to write to conf later. */ use_subsystem = 1; } else if (!strcmp(p, "-V") || !strcmp(p, "--version")) { version(); } else if (!strcmp(p, "--help")) { usage(); } else if (!strcmp(p, "-pgpfp")) { pgp_fingerprints(); exit(1); } else { fprintf(stderr, "plink: unknown option \"%s\"\n", p); errors = 1; } } else if (*p) { if (!conf_launchable(conf) || !(got_host || loaded_session)) { char *q = p; /* * If the hostname starts with "telnet:", set the * protocol to Telnet and process the string as a * Telnet URL. */ if (!strncmp(q, "telnet:", 7)) { char c; q += 7; if (q[0] == '/' && q[1] == '/') q += 2; conf_set_int(conf, CONF_protocol, PROT_TELNET); p = q; while (*p && *p != ':' && *p != '/') p++; c = *p; if (*p) *p++ = '\0'; if (c == ':') conf_set_int(conf, CONF_port, atoi(p)); else conf_set_int(conf, CONF_port, -1); conf_set_str(conf, CONF_host, q); got_host = TRUE; } else { char *r, *user, *host; /* * Before we process the [user@]host string, we * first check for the presence of a protocol * prefix (a protocol name followed by ","). */ r = strchr(p, ','); if (r) { const Backend *b; *r = '\0'; b = backend_from_name(p); if (b) { default_protocol = b->protocol; conf_set_int(conf, CONF_protocol, default_protocol); portnumber = b->default_port; } p = r + 1; } /* * A nonzero length string followed by an @ is treated * as a username. (We discount an _initial_ @.) The * rest of the string (or the whole string if no @) * is treated as a session name and/or hostname. */ r = strrchr(p, '@'); if (r == p) p++, r = NULL; /* discount initial @ */ if (r) { *r++ = '\0'; user = p, host = r; } else { user = NULL, host = p; } /* * Now attempt to load a saved session with the * same name as the hostname. */ { Conf *conf2 = conf_new(); do_defaults(host, conf2); if (loaded_session || !conf_launchable(conf2)) { /* No settings for this host; use defaults */ /* (or session was already loaded with -load) */ conf_set_str(conf, CONF_host, host); conf_set_int(conf, CONF_port, default_port); got_host = TRUE; } else { conf_copy_into(conf, conf2); loaded_session = TRUE; } conf_free(conf2); } if (user) { /* Patch in specified username. */ conf_set_str(conf, CONF_username, user); } } } else { char *command; int cmdlen, cmdsize; cmdlen = cmdsize = 0; command = NULL; while (argc) { while (*p) { if (cmdlen >= cmdsize) { cmdsize = cmdlen + 512; command = sresize(command, cmdsize, char); } command[cmdlen++]=*p++; } if (cmdlen >= cmdsize) { cmdsize = cmdlen + 512; command = sresize(command, cmdsize, char); } command[cmdlen++]=' '; /* always add trailing space */ if (--argc) p = *++argv; } if (cmdlen) command[--cmdlen]='\0'; /* change trailing blank to NUL */ conf_set_str(conf, CONF_remote_cmd, command); conf_set_str(conf, CONF_remote_cmd2, ""); conf_set_int(conf, CONF_nopty, TRUE); /* command => no tty */ break; /* done with cmdline */ } }
void DataDirLocater::LocateDataDirs() { // Prepare the data-dirs defined in different places // environment variable std::string dd_env = ""; { char* env = getenv("SPRING_DATADIR"); if (env && *env) { dd_env = SubstEnvVars(env); } } #if defined(UNITSYNC) const std::string dd_curWorkDir = Platform::GetModulePath(); #else // defined(UNITSYNC) const std::string dd_curWorkDir = Platform::GetProcessExecutablePath(); #endif // defined(UNITSYNC) // This is useful in case of multiple engine/unitsync versions installed // together in a sub-dir of the data-dir // The data-dir structure then might look similar to this: // maps/ // games/ // engines/engine-0.83.0.0.exe // engines/engine-0.83.1.0.exe // unitsyncs/unitsync-0.83.0.0.exe // unitsyncs/unitsync-0.83.1.0.exe const std::string dd_curWorkDirParent = FileSystemHandler::GetParent(dd_curWorkDir); #if defined(WIN32) // fetch my documents path TCHAR pathMyDocs[MAX_PATH]; SHGetFolderPath( NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, pathMyDocs); // fetch app-data path TCHAR pathAppData[MAX_PATH]; SHGetFolderPath( NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, pathAppData); std::string dd_myDocs = pathMyDocs; // e.g. F:\Dokumente und Einstellungen\Karl-Robert\Eigene Dateien\Spring dd_myDocs += "\\Spring"; std::string dd_myDocsMyGames = pathMyDocs; // My Documents\My Games seems to be the MS standard even if no official guidelines exist // most if not all new Games For Windows(TM) games use this dir dd_myDocsMyGames += "\\My Games\\Spring"; std::string dd_appData = pathAppData; // e.g. F:\Dokumente und Einstellungen\All Users\Anwendungsdaten\Spring dd_appData += "\\Spring"; #elif defined(MACOSX_BUNDLE) const std::string dd_curWorkDirData = dd_curWorkDir + "/" + SubstEnvVars(DATADIR); const std::string dd_curWorkDirLib = dd_curWorkDir + "/" + SubstEnvVars(LIBDIR); #else // *nix (-OSX) // settings in /etc std::string dd_etc = ""; { FILE* fileH = ::fopen("/etc/spring/datadir", "r"); if (fileH) { const char whiteSpaces[3] = {'\t', ' ', '\0'}; char lineBuf[1024]; while (fgets(lineBuf, sizeof(lineBuf), fileH)) { char* newLineCharPos = strchr(lineBuf, '\n'); if (newLineCharPos) { // remove the new line char *newLineCharPos = '\0'; } // ignore lines consisting of only whitespaces if ((strlen(lineBuf) > 0) && strspn(lineBuf, whiteSpaces) != strlen(lineBuf)) { // append, separated by sPD (depending on OS): ';' or ':' dd_etc = dd_etc + (dd_etc.empty() ? "" : sPD) + SubstEnvVars(lineBuf); } } fclose(fileH); } } #endif // defined(WIN32), defined(MACOSX_BUNDLE), else // Construct the list of datadirs from various sources. datadirs.clear(); // The first dir added will be the writeable data dir. // same on all platforms AddDirs(dd_env); // ENV{SPRING_DATADIR} // user defined in spring config handler // (Linux: ~/.springrc, Windows: .\springsettings.cfg) AddDirs(SubstEnvVars(configHandler->GetString("SpringData", ""))); #ifdef WIN32 // All MS Windows variants if ((dd_curWorkDirParent != "") && LooksLikeMultiVersionDataDir(dd_curWorkDirParent)) { AddDirs(dd_curWorkDirParent); // "../" } else if (IsPortableMode()) { // we can not add both ./ and ../ as data-dir AddDirs(dd_curWorkDir); // "./" } AddDirs(dd_myDocsMyGames); // "C:/.../My Documents/My Games/Spring/" AddDirs(dd_myDocs); // "C:/.../My Documents/Spring/" AddDirs(dd_appData); // "C:/.../All Users/Applications/Spring/" #elif defined(MACOSX_BUNDLE) // Mac OS X // Maps and mods are supposed to be located in spring's executable location on Mac, but unitsync // cannot find them since it does not know spring binary path. I have no idea but to force users // to locate lobby executables in the same as spring's dir and add its location to search dirs. #ifdef UNITSYNC AddDirs(dd_curWorkDir); // "./" #endif // libs and data are supposed to be located in subdirectories of spring executable, so they // sould be added instead of SPRING_DATADIR definition. AddDirs(dd_curWorkDirData); // "./data/" AddDirs(dd_curWorkDirLib); // "./lib/" #else // Linux, FreeBSD, Solaris, Apple non-bundle if ((dd_curWorkDirParent != "") && LooksLikeMultiVersionDataDir(dd_curWorkDirParent)) { AddDirs(dd_curWorkDirParent); // "../" } else if (IsPortableMode()) { // we can not add both ./ and ../ as data-dir // always using this would be unclean, because spring and unitsync // would end up with different sets of data-dirs AddDirs(dd_curWorkDir); // "./" } AddDirs(SubstEnvVars("$HOME/.spring")); // "~/.spring/" AddDirs(dd_etc); // from /etc/spring/datadir #endif #ifdef SPRING_DATADIR AddDirs(SubstEnvVars(SPRING_DATADIR)); // from -DSPRING_DATADIR #endif // Figure out permissions of all datadirs DeterminePermissions(); if (!writedir) { // bail out const std::string errstr = "Not a single writable data directory found!\n\n" "Configure a writable data directory using either:\n" "- the SPRING_DATADIR environment variable,\n" #ifdef WIN32 "- a SpringData=C:/path/to/data declaration in spring's config file ./springsettings.cfg\n" "- by giving you write access to the installation directory"; #else "- a SpringData=/path/to/data declaration in ~/.springrc or\n" "- the configuration file /etc/spring/datadir"; #endif throw content_error(errstr); } // for now, chdir to the data directory as a safety measure: // Not only safety anymore, it's just easier if other code can safely assume that // writedir == current working directory FileSystemHandler::GetInstance().Chdir(GetWriteDir()->path.c_str()); // Initialize the log. Only after this moment log will be written to file. logOutput.Initialize(); // Logging MAY NOT start before the chdir, otherwise the logfile ends up // in the wrong directory. // Update: now it actually may start before, log has preInitLog. for (std::vector<DataDir>::const_iterator d = datadirs.begin(); d != datadirs.end(); ++d) { if (d->writable) { logOutput.Print("Using read-write data directory: %s", d->path.c_str()); // tag the cache dir const std::string cacheDir = d->path + "cache"; if (filesystem.CreateDirectory(cacheDir)) { CacheDir::SetCacheDir(cacheDir, true); } } else { logOutput.Print("Using read-only data directory: %s", d->path.c_str()); } } }