void ScriptSystem::getClassList(const char* prefix, bool sort, StringSeq& result) const { ClassInfoDict::const_iterator it = m_classInfoReg.begin(); size_t prefixlen = 0; if (prefix) { prefixlen = strlen(prefix); } for (; it != m_classInfoReg.end(); ++it) { ClassInfo* ci = it->second; if (prefixlen) { if (strncmp(prefix, ci->m_className.c_str(), prefixlen) != 0) { continue; } result.push_back(ci->m_className.c_str() + prefixlen); } else { result.push_back(ci->m_className); } } if (sort) { std::sort(result.begin(), result.end(), std::less<String>()); } }
int main(int argc, char* argv[]) { CoInitializeEx(NULL, 0); Ice::InitializationData id = InitializationData(); id.properties = Ice::createProperties(); id.properties->load("config.server"); id.logger = new MyLoggerI(); Ice::initialize(argc, argv, id); SyncService svc; int status = EXIT_FAILURE; #ifdef _WIN32 status = svc.main(argc, argv, id); #else // // For UNIX, force --nochdir option, so the service isn't started // with / as the working directory. That way, if the data // directory is specified as a relative path, we don't // misinterpret that path. // StringSeq args; args.push_back(argv[0]); args.push_back("--nochdir"); for(int i = 1; i < argc; ++i) { args.push_back(argv[i]); } status = svc.main(args); #endif return status; }
bool Ice::ObjectAdapterI::filterProperties(StringSeq& unknownProps) { static const string suffixes[] = { "AdapterId", "Endpoints", "Locator", "PublishedEndpoints", "RegisterProcess", "ReplicaGroupId", "Router", "ThreadPerConnection", "ThreadPerConnection.StackSize", "ThreadPool.Size", "ThreadPool.SizeMax", "ThreadPool.SizeWarn", "ThreadPool.StackSize" }; // // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc // bool addUnknown = true; string prefix = _name + "."; for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i) { string icePrefix = string(*i) + "."; if(prefix.find(icePrefix) == 0) { addUnknown = false; break; } } bool noProps = true; PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix); PropertyDict::const_iterator p; for(p = props.begin(); p != props.end(); ++p) { bool valid = false; for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i) { string prop = prefix + suffixes[i]; if(p->first == prop) { noProps = false; valid = true; break; } } if(!valid && addUnknown) { unknownProps.push_back(p->first); } } return noProps; }
StringSeq golem::data::HandlerTrajectory::getProfiles() const { StringSeq profiles; for (auto& k : profileDescMap) profiles.push_back(k.first); return profiles; }
void IceInternal::ReferenceFactory::checkForUnknownProperties(const string& prefix) { static const string suffixes[] = { "EndpointSelection", "ConnectionCached", "PreferSecure", "LocatorCacheTimeout", "InvocationTimeout", "Locator", "Router", "CollocationOptimized", "Context.*" }; // // Do not warn about unknown properties list if Ice prefix, ie Ice, Glacier2, etc // for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i) { if(prefix.find(*i) == 0) { return; } } StringSeq unknownProps; PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix + "."); for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) { bool valid = false; for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i) { string prop = prefix + "." + suffixes[i]; if(IceUtilInternal::match(p->first, prop)) { valid = true; break; } } if(!valid) { unknownProps.push_back(p->first); } } if(unknownProps.size()) { Warning out(_instance->initializationData().logger); out << "found unknown properties for proxy '" << prefix << "':"; for(unsigned int i = 0; i < unknownProps.size(); ++i) { out << "\n " << unknownProps[i]; } } }
StringSeq StringUtil::tokenizeSeq(const char* text, char split /*= ' ' */) { StringSeq result; if (!text || !text[0]) return result; String str; const char* token = text; for (; ;) { /* skip whitespace */ while (*token && uint_t(*token) <= ' ' || *token == split) { token++; } if (!*token) break; str.clear(); // handle quoted strings if (*token == '\"') { token++; while (*token && *token != '\"') { str += *token++; } result.push_back(str); str.clear(); if (!*token) { break; } else { token++; continue; } } do { str+=*token; token++; } while (*token != 0 && *token != split); result.push_back(str); } return result; }
StringSeq Ice::argsToStringSeq(int argc, char* argv[]) { StringSeq result; for(int i = 0; i < argc; i++) { result.push_back(argv[i]); } return result; }
StringSeq PathUtil::listFileByExts(const String& base, const String& path, const String& exts, uint_t flags) { StringSeq strvec; FileInfoSeq fileinfos; fileinfos = getFileInfos(base, path, exts, flags); for (size_t i=0; i<fileinfos.size(); i++) { strvec.push_back(fileinfos[i].fullpath); } return strvec; }
StringSeq Ice::PluginManagerI::getPlugins() { IceUtil::Mutex::Lock sync(*this); StringSeq names; for(PluginInfoList::iterator p = _plugins.begin(); p != _plugins.end(); ++p) { names.push_back(p->name); } return names; }
StringSeq Ice::argsToStringSeq(int /*argc*/, wchar_t* argv[]) { // // Don't need to use a wide string converter argv is expected to // come from Windows API. // const IceUtil::StringConverterPtr converter = IceUtil::getProcessStringConverter(); StringSeq args; for(int i=0; argv[i] != 0; i++) { args.push_back(IceUtil::wstringToString(argv[i], converter)); } return args; }
bool Ice::ObjectAdapterI::filterProperties(StringSeq& unknownProps) { static const string suffixes[] = { "ACM", "ACM.Close", "ACM.Heartbeat", "ACM.Timeout", "AdapterId", "Endpoints", "Locator", "Locator.EncodingVersion", "Locator.EndpointSelection", "Locator.ConnectionCached", "Locator.PreferSecure", "Locator.CollocationOptimized", "Locator.Router", "MessageSizeMax", "PublishedEndpoints", "ReplicaGroupId", "Router", "Router.EncodingVersion", "Router.EndpointSelection", "Router.ConnectionCached", "Router.PreferSecure", "Router.CollocationOptimized", "Router.Locator", "Router.Locator.EndpointSelection", "Router.Locator.ConnectionCached", "Router.Locator.PreferSecure", "Router.Locator.CollocationOptimized", "Router.Locator.LocatorCacheTimeout", "Router.Locator.InvocationTimeout", "Router.LocatorCacheTimeout", "Router.InvocationTimeout", "ProxyOptions", "ThreadPool.Size", "ThreadPool.SizeMax", "ThreadPool.SizeWarn", "ThreadPool.StackSize", "ThreadPool.Serialize", "ThreadPool.ThreadPriority" }; // // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc // bool addUnknown = true; string prefix = _name + "."; for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i) { string icePrefix = string(*i) + "."; if(prefix.find(icePrefix) == 0) { addUnknown = false; break; } } bool noProps = true; PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix); for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) { bool valid = false; for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i) { string prop = prefix + suffixes[i]; if(p->first == prop) { noProps = false; valid = true; break; } } if(!valid && addUnknown) { unknownProps.push_back(p->first); } } return noProps; }
int Activator::activate(const string& name, const string& exePath, const string& pwdPath, #ifndef _WIN32 uid_t uid, gid_t gid, #endif const Ice::StringSeq& options, const Ice::StringSeq& envs, const ServerIPtr& server) { IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); if(_deactivating) { throw string("The node is being shutdown."); } string path = exePath; if(path.empty()) { throw string("The server executable path is empty."); } string pwd = IcePatch2Internal::simplify(pwdPath); #ifdef _WIN32 if(!IceUtilInternal::isAbsolutePath(path)) { if(path.find('/') == string::npos) { // // Get the absolute pathname of the executable. // wchar_t absbuf[_MAX_PATH]; wchar_t* fPart; wstring ext = path.size() <= 4 || path[path.size() - 4] != '.' ? L".exe" : L""; // // IceGrid doesn't support to use string converters, so don't need to use // any string converter in wstringToString conversions. // if(SearchPathW(NULL, IceUtil::stringToWstring(path).c_str(), ext.c_str(), _MAX_PATH, absbuf, &fPart) == 0) { if(_traceLevels->activator > 0) { Trace out(_traceLevels->logger, _traceLevels->activatorCat); out << "couldn't find `" << path << "' executable."; } throw string("Couldn't find `" + path + "' executable."); } path = IceUtil::wstringToString(absbuf); } else if(!pwd.empty()) { path = pwd + "/" + path; } } // // Get the absolute pathname of the working directory. // // IceGrid doesn't support to use string converters, so // don't need to use any string converter in stringToWstring // conversions. // if(!pwd.empty()) { wchar_t absbuf[_MAX_PATH]; if(_wfullpath(absbuf, IceUtil::stringToWstring(pwd).c_str(), _MAX_PATH) == NULL) { if(_traceLevels->activator > 0) { Trace out(_traceLevels->logger, _traceLevels->activatorCat); out << "cannot convert `" << pwd << "' into an absolute path"; } throw string("The server working directory path `" + pwd + "' can't be converted into an absolute path."); } pwd = IceUtil::wstringToString(absbuf); } #endif // // Setup arguments. // StringSeq args; args.push_back(path); args.insert(args.end(), options.begin(), options.end()); if(_traceLevels->activator > 0) { Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); out << "activating server `" << name << "'"; if(_traceLevels->activator > 1) { out << "\n"; out << "path = " << path << "\n"; if(pwd.empty()) { string cwd; if(IceUtilInternal::getcwd(cwd) == 0) { out << "pwd = " << cwd << "\n"; } } else { out << "pwd = " << pwd << "\n"; } #ifndef _WIN32 out << "uid/gid = " << uid << "/" << gid << "\n"; #endif if(!envs.empty()) { out << "envs = " << toString(envs, ", ") << "\n"; } if(!args.empty()) { out << "args = " << toString(args); } } } // // Activate and create. // #ifdef _WIN32 // // Compose command line. // string cmd; for(StringSeq::const_iterator p = args.begin(); p != args.end(); ++p) { if(p != args.begin()) { cmd.push_back(' '); } // // Enclose arguments containing spaces in double quotes. // if((*p).find(' ') != string::npos) { cmd.push_back('"'); cmd.append(*p); cmd.push_back('"'); } else { cmd.append(*p); } } // // IceGrid doesn't support to use string converters, so don't need to use // any string converter in stringToWstring conversions. // wstring wpwd = IceUtil::stringToWstring(pwd); const wchar_t* dir = !wpwd.empty() ? wpwd.c_str() : NULL; // // Make a copy of the command line. // wchar_t* cmdbuf = _wcsdup(IceUtil::stringToWstring(cmd).c_str()); // // Create the environment block for the child process. We start with the environment // of this process, and then merge environment variables from the server description. // Since Windows is case insensitive wrt environment variables we convert the keys to // uppercase to ensure matches are found. // const wchar_t* env = NULL; wstring envbuf; if(!envs.empty()) { map<wstring, wstring, UnicodeStringLess> envMap; LPVOID parentEnv = GetEnvironmentStringsW(); const wchar_t* var = reinterpret_cast<const wchar_t*>(parentEnv); if(*var == L'=') { // // The environment block may start with some information about the // current drive and working directory. This is indicated by a leading // '=' character, so we skip to the first '\0' byte. // while(*var != L'\0') var++; var++; } while(*var != L'\0') { wstring s(var); wstring::size_type pos = s.find(L'='); if(pos != wstring::npos) { envMap[s.substr(0, pos)] = s.substr(pos + 1); } var += s.size(); var++; // Skip the '\0' byte } FreeEnvironmentStringsW(static_cast<wchar_t*>(parentEnv)); for(StringSeq::const_iterator p = envs.begin(); p != envs.end(); ++p) { // // IceGrid doesn't support to use string converters, so don't need to use // any string converter in stringToWstring conversions. // wstring s = IceUtil::stringToWstring(*p); wstring::size_type pos = s.find(L'='); if(pos != wstring::npos) { envMap[s.substr(0, pos)] = s.substr(pos + 1); } } for(map<wstring, wstring, UnicodeStringLess>::const_iterator q = envMap.begin(); q != envMap.end(); ++q) { envbuf.append(q->first); envbuf.push_back(L'='); envbuf.append(q->second); envbuf.push_back(L'\0'); } envbuf.push_back(L'\0'); env = envbuf.c_str(); } Process process; STARTUPINFOW si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); BOOL b = CreateProcessW( NULL, // Executable cmdbuf, // Command line NULL, // Process attributes NULL, // Thread attributes FALSE, // Do NOT inherit handles CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT, // Process creation flags (LPVOID)env, // Process environment dir, // Current directory &si, // Startup info &pi // Process info ); free(cmdbuf); if(!b) { throw IceUtilInternal::lastErrorToString(); } // // Caller is responsible for closing handles in PROCESS_INFORMATION. We don't need to // keep the thread handle, so we close it now. The process handle will be closed later. // CloseHandle(pi.hThread); process.activator = this; process.pid = pi.dwProcessId; process.hnd = pi.hProcess; process.server = server; map<string, Process>::iterator it = _processes.insert(make_pair(name, process)).first; Process* pp = &it->second; if(!RegisterWaitForSingleObject(&pp->waithnd, pp->hnd, activatorWaitCallback, pp, INFINITE, WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) { throw IceUtilInternal::lastErrorToString(); } // // Don't print the following trace, this might interfer with the // output of the started process if it fails with an error message. // // if(_traceLevels->activator > 0) // { // Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); // out << "activated server `" << name << "' (pid = " << pi.dwProcessId << ")"; // } return static_cast<Ice::Int>(process.pid); #else int fds[2]; if(pipe(fds) != 0) { SyscallException ex(__FILE__, __LINE__); ex.error = getSystemErrno(); throw ex; } int errorFds[2]; if(pipe(errorFds) != 0) { SyscallException ex(__FILE__, __LINE__); ex.error = getSystemErrno(); throw ex; } // // Convert to standard argc/argv. // IceUtilInternal::ArgVector av(args); IceUtilInternal::ArgVector env(envs); // // Current directory // const char* pwdCStr = pwd.c_str(); pid_t pid = fork(); if(pid == -1) { SyscallException ex(__FILE__, __LINE__); ex.error = getSystemErrno(); throw ex; } if(pid == 0) // Child process. { // // Until exec, we can only use async-signal safe functions // // // Unblock signals blocked by IceUtil::CtrlCHandler. // sigset_t sigs; sigemptyset(&sigs); sigaddset(&sigs, SIGHUP); sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGTERM); sigprocmask(SIG_UNBLOCK, &sigs, 0); // // Change the uid/gid under which the process will run. // if(setgid(gid) == -1) { ostringstream os; os << gid; reportChildError(getSystemErrno(), errorFds[1], "cannot set process group id", os.str().c_str(), _traceLevels); } errno = 0; struct passwd* pw = getpwuid(uid); if(!pw) { if(errno) { reportChildError(getSystemErrno(), errorFds[1], "cannot read the password database", "", _traceLevels); } else { ostringstream os; os << uid; reportChildError(getSystemErrno(), errorFds[1], "unknown user uid" , os.str().c_str(), _traceLevels); } } // // Don't initialize supplementary groups if we are not running as root. // if(getuid() == 0 && initgroups(pw->pw_name, gid) == -1) { ostringstream os; os << pw->pw_name; reportChildError(getSystemErrno(), errorFds[1], "cannot initialize process supplementary group access list for user", os.str().c_str(), _traceLevels); } if(setuid(uid) == -1) { ostringstream os; os << uid; reportChildError(getSystemErrno(), errorFds[1], "cannot set process user id", os.str().c_str(), _traceLevels); } // // Assign a new process group for this process. // setpgid(0, 0); // // Close all file descriptors, except for standard input, // standard output, standard error, and the write side // of the newly created pipe. // int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX)); for(int fd = 3; fd < maxFd; ++fd) { if(fd != fds[1] && fd != errorFds[1]) { close(fd); } } for(int i = 0; i < env.argc; i++) { // // Each env is leaked on purpose ... see man putenv(). // if(putenv(strdup(env.argv[i])) != 0) { reportChildError(errno, errorFds[1], "cannot set environment variable", env.argv[i], _traceLevels); } } // // Change working directory. // if(strlen(pwdCStr) != 0) { if(chdir(pwdCStr) == -1) { reportChildError(errno, errorFds[1], "cannot change working directory to", pwdCStr, _traceLevels); } } // // Close on exec the error message file descriptor. // int flags = fcntl(errorFds[1], F_GETFD); flags |= 1; // FD_CLOEXEC if(fcntl(errorFds[1], F_SETFD, flags) == -1) { close(errorFds[1]); errorFds[1] = -1; } if(execvp(av.argv[0], av.argv) == -1) { if(errorFds[1] != -1) { reportChildError(errno, errorFds[1], "cannot execute", av.argv[0], _traceLevels); } else { reportChildError(errno, fds[1], "cannot execute", av.argv[0], _traceLevels); } } } else // Parent process. { close(fds[1]); close(errorFds[1]); // // Read a potential error message over the error message pipe. // char s[16]; ssize_t rs; string message; while((rs = read(errorFds[0], &s, 16)) > 0) { message.append(s, rs); } // // If an error occured before the exec() we do some cleanup and throw. // if(!message.empty()) { close(fds[0]); close(errorFds[0]); waitPid(pid); throw message; } // // Otherwise, the exec() was successfull and we don't need the error message // pipe anymore. // close(errorFds[0]); Process process; process.pid = pid; process.pipeFd = fds[0]; process.server = server; _processes.insert(make_pair(name, process)); int flags = fcntl(process.pipeFd, F_GETFL); flags |= O_NONBLOCK; fcntl(process.pipeFd, F_SETFL, flags); setInterrupt(); // // Don't print the following trace, this might interfere with the // output of the started process if it fails with an error message. // // if(_traceLevels->activator > 0) // { // Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); // out << "activated server `" << name << "' (pid = " << pid << ")"; // } } return pid; #endif }
Freeze::MapDb::MapDb(const ConnectionIPtr& connection, const string& dbName, const string& key, const string& value, const KeyCompareBasePtr& keyCompare, const vector<MapIndexBasePtr>& indices, bool createDb) : Db(connection->dbEnv()->getEnv(), 0), _communicator(connection->communicator()), _dbName(dbName), _trace(connection->trace()), _keyCompare(keyCompare) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "opening Db \"" << _dbName << "\""; } Catalog catalog(connection, _catalogName); TransactionPtr tx = connection->currentTransaction(); bool ownTx = (tx == 0); for(;;) { try { if(ownTx) { tx = 0; tx = connection->beginTransaction(); } Catalog::iterator ci = catalog.find(_dbName); if(ci != catalog.end()) { if(ci->second.evictor) { throw DatabaseException(__FILE__, __LINE__, _dbName + " is an evictor database"); } _key = ci->second.key; _value = ci->second.value; checkTypes(key, value); } else { _key = key; _value = value; } set_app_private(this); if(_keyCompare->compareEnabled()) { set_bt_compare(&customCompare); } PropertiesPtr properties = _communicator->getProperties(); string propPrefix = "Freeze.Map." + _dbName + "."; int btreeMinKey = properties->getPropertyAsInt(propPrefix + "BtreeMinKey"); if(btreeMinKey > 2) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Setting \"" << _dbName << "\"'s btree minkey to " << btreeMinKey; } set_bt_minkey(btreeMinKey); } bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0; if(checksum) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Turning checksum on for \"" << _dbName << "\""; } set_flags(DB_CHKSUM); } int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize"); if(pageSize > 0) { if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Setting \"" << _dbName << "\"'s pagesize to " << pageSize; } set_pagesize(pageSize); } DbTxn* txn = getTxn(tx); u_int32_t flags = DB_THREAD; if(createDb) { flags |= DB_CREATE; } open(txn, Ice::nativeToUTF8(_communicator, _dbName).c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE); StringSeq oldIndices; StringSeq newIndices; size_t oldSize = 0; CatalogIndexList catalogIndexList(connection, _catalogIndexListName); if(createDb) { CatalogIndexList::iterator cil = catalogIndexList.find(_dbName); if(cil != catalogIndexList.end()) { oldIndices = cil->second; oldSize = oldIndices.size(); } } for(vector<MapIndexBasePtr>::const_iterator p = indices.begin(); p != indices.end(); ++p) { const MapIndexBasePtr& indexBase = *p; assert(indexBase->_impl == 0); assert(indexBase->_communicator == 0); indexBase->_communicator = connection->communicator(); auto_ptr<MapIndexI> indexI; try { indexI.reset(new MapIndexI(connection, *this, txn, createDb, indexBase)); } catch(const DbDeadlockException&) { throw; } catch(const DbException& dx) { string message = "Error while opening index \"" + _dbName + "." + indexBase->name() + "\": " + dx.what(); throw DatabaseException(__FILE__, __LINE__, message); } #ifndef NDEBUG bool inserted = #endif _indices.insert(IndexMap::value_type(indexBase->name(), indexI.get())).second; assert(inserted); indexBase->_impl = indexI.release(); if(createDb) { newIndices.push_back(indexBase->name()); oldIndices.erase(std::remove(oldIndices.begin(), oldIndices.end(), indexBase->name()), oldIndices.end()); } } if(ci == catalog.end()) { CatalogData catalogData; catalogData.evictor = false; catalogData.key = key; catalogData.value = value; catalog.put(Catalog::value_type(_dbName, catalogData)); } if(createDb) { // // Remove old indices and write the new ones // bool indexRemoved = false; for(StringSeq::const_iterator q = oldIndices.begin(); q != oldIndices.end(); ++q) { const string& index = *q; if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "removing old index \"" << index << "\" on Db \"" << _dbName << "\""; } try { connection->removeMapIndex(_dbName, *q); indexRemoved = true; } catch(const IndexNotFoundException&) { // Ignored if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "index \"" << index << "\" on Db \"" << _dbName << "\" does not exist"; } } } if(indexRemoved || oldSize != newIndices.size()) { if(newIndices.size() == 0) { catalogIndexList.erase(_dbName); if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Removed catalogIndexList entry for Db \"" << _dbName << "\""; } } else { catalogIndexList.put(CatalogIndexList::value_type(_dbName, newIndices)); if(_trace >= 1) { Trace out(_communicator->getLogger(), "Freeze.Map"); out << "Updated catalogIndexList entry for Db \"" << _dbName << "\""; } } } } if(ownTx) { tx->commit(); } break; // for(;;) } catch(const DbDeadlockException& dx) { if(ownTx) { if(connection->deadlockWarning()) { Warning out(connection->communicator()->getLogger()); out << "Deadlock in Freeze::MapDb::MapDb on Map \"" << _dbName << "\"; retrying ..."; } // // Ignored, try again // } else { throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) { if(ownTx) { try { tx->rollback(); } catch(...) { } } string message = "Error while opening Db \"" + _dbName + "\": " + dx.what(); throw DatabaseException(__FILE__, __LINE__, message); } catch(...) { if(ownTx && tx != 0) { try { tx->rollback(); } catch(...) { } } throw; } } }
int main(int argc, char* argv[]) #endif { Ice::StringSeq originalArgs = Ice::argsToStringSeq(argc, argv); assert(originalArgs.size() > 0); const string appName = originalArgs[0]; string dataDir; StringSeq fileSeq; int compress = 1; bool verbose; bool caseInsensitive; IceUtilInternal::Options opts; opts.addOpt("h", "help"); opts.addOpt("v", "version"); opts.addOpt("z", "compress"); opts.addOpt("Z", "no-compress"); opts.addOpt("V", "verbose"); opts.addOpt("i", "case-insensitive"); vector<string> args; try { args = opts.parse(originalArgs); } catch(const IceUtilInternal::BadOptException& e) { cerr << e.reason << endl; usage(appName); return EXIT_FAILURE; } if(opts.isSet("help")) { usage(appName); return EXIT_SUCCESS; } if(opts.isSet("version")) { cout << ICE_STRING_VERSION << endl; return EXIT_SUCCESS; } bool doCompress = opts.isSet("compress"); bool dontCompress = opts.isSet("no-compress"); if(doCompress && dontCompress) { cerr << appName << ": only one of -z and -Z are mutually exclusive" << endl; usage(appName); return EXIT_FAILURE; } if(doCompress) { compress = 2; } else if(dontCompress) { compress = 0; } verbose = opts.isSet("verbose"); caseInsensitive = opts.isSet("case-insensitive"); if(args.empty()) { cerr << appName << ": no data directory specified" << endl; usage(appName); return EXIT_FAILURE; } dataDir = simplify(args[0]); for(vector<string>::size_type i = 1; i < args.size(); ++i) { fileSeq.push_back(simplify(args[i])); } try { string absDataDir = dataDir; string cwd; if(IceUtilInternal::getcwd(cwd) != 0) { throw "cannot get the current directory:\n" + IceUtilInternal::lastErrorToString(); } if(!IceUtilInternal::isAbsolutePath(absDataDir)) { absDataDir = simplify(cwd + '/' + absDataDir); } for(StringSeq::iterator p = fileSeq.begin(); p != fileSeq.end(); ++p) { if(!IceUtilInternal::isAbsolutePath(*p)) { *p = cwd + '/' + *p; } } // // We must call simplify() here: under Cygwin, any path starting with // a double slash simply doesn't work. But, if dataDir is "/", we end // up with paths that start with "//" unless we call simplify(). // string absDataDirWithSlash = simplify(absDataDir + '/'); for(StringSeq::iterator p = fileSeq.begin(); p != fileSeq.end(); ++p) { if(p->compare(0, absDataDirWithSlash.size(), absDataDirWithSlash) != 0) { throw "`" + *p + "' is not a path in `" + dataDir + "'"; } p->erase(0, absDataDirWithSlash.size()); } LargeFileInfoSeq infoSeq; if(fileSeq.empty()) { CalcCB calcCB; if(!getFileInfoSeq(absDataDir, compress, verbose ? &calcCB : 0, infoSeq)) { return EXIT_FAILURE; } } else { loadFileInfoSeq(absDataDir, infoSeq); for(StringSeq::iterator p = fileSeq.begin(); p != fileSeq.end(); ++p) { LargeFileInfoSeq partialInfoSeq; CalcCB calcCB; if(!getFileInfoSeqSubDir(absDataDir, *p, compress, verbose ? &calcCB : 0, partialInfoSeq)) { return EXIT_FAILURE; } LargeFileInfoSeq newInfoSeq; newInfoSeq.reserve(infoSeq.size()); set_difference(infoSeq.begin(), infoSeq.end(), partialInfoSeq.begin(), partialInfoSeq.end(), back_inserter(newInfoSeq), FileInfoPathLess()); infoSeq.swap(newInfoSeq); newInfoSeq.clear(); newInfoSeq.reserve(infoSeq.size() + partialInfoSeq.size()); set_union(infoSeq.begin(), infoSeq.end(), partialInfoSeq.begin(), partialInfoSeq.end(), back_inserter(newInfoSeq), FileInfoPathLess()); infoSeq.swap(newInfoSeq); } } if(caseInsensitive) { LargeFileInfoSeq newInfoSeq = infoSeq; sort(newInfoSeq.begin(), newInfoSeq.end(), IFileInfoPathLess()); string ex; LargeFileInfoSeq::iterator p = newInfoSeq.begin(); while((p = adjacent_find(p, newInfoSeq.end(), IFileInfoPathEqual())) != newInfoSeq.end()) { do { ex += '\n' + dataDir + '/' + p->path; ++p; } while(p < newInfoSeq.end() && IFileInfoPathEqual()(*(p - 1), *p)); } if(!ex.empty()) { ex = "duplicate files:" + ex; throw ex; } } saveFileInfoSeq(absDataDir, infoSeq); } catch(const string& ex) { cerr << appName << ": " << ex << endl; return EXIT_FAILURE; } catch(const char* ex) { cerr << appName << ": " << ex << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }