// // Initialize handler // INT_32 IrisEchoHandler::InitHandler(IRIS::GlobalContext & oGlobalContext, const IRIS::HandlerConfig & oHandlerConfig, IRIS::Logger & oLogger) { // Create thread group pThreadGroup = new IrisEchoThreadGroup; // Create set of threads for (UINT_32 iPos = 0; iPos < oHandlerConfig.start_threads; ++iPos) { pThreadGroup -> CreateThread(new IrisEchoThreadWorker(oWorkerContext)); ++oWorkerContext.threads; oLogger.Notice("Echo thread %d started", oWorkerContext.threads); } const STLW::string sLogger = oHandlerConfig.logger.empty() ? oGlobalContext.config.logger_type : oHandlerConfig.logger; // Get logger from factory for main process pLoggerObject = static_cast<IRIS::LoggerObject *>(oGlobalContext.factory.GetObject("Logger/" + sLogger)); if (pLoggerObject == NULL) { oLogger.Emerg("Can't get logger `%s` for %s", sLogger.c_str(), GetObjectName()); return -1; } oLogger.Notice("Echo module initialized"); return 0; }
// // Find file in specified list of directories // INT_32 MainProcess::FindFile(const STLW::vector<STLW::string> & vDirectories, const STLW::string & sFilename, STLW::string & sFullpath) { STLW::vector<STLW::string>::const_iterator itvDirectories = vDirectories.begin(); while (itvDirectories != vDirectories.end()) { sFullpath.erase(); const STLW::string & sDir(*itvDirectories); if (sDir.size()) { sFullpath.assign(sDir); if (sDir[sDir.size() - 1] != '/') { sFullpath.append(1, '/'); } } sFullpath.append(sFilename); const INT_64 iFileHandle = File::Open(sFullpath.c_str(), OpenMode::READ); if (iFileHandle != -1) { File::Close(iFileHandle); return 0; } ++itvDirectories; } return -1; }
// // Switch to unprivileged user // static INT_32 UnixSetup(const WorkerConfig & oWorkerConfig, ASLogger & oLogger) { // Set proper UID/GID if (getuid() == 0) { oLogger.Info("Switching to user/group %d:%d", oWorkerConfig.gid, oWorkerConfig.uid); if (oWorkerConfig.uid == 0) { oLogger.Emerg("CAS FastCGI server won't work from superuser account (root)."); return EX_SOFTWARE; } else { // Set additional groups if (!oWorkerConfig.gids.empty()) { const size_t iGroups = oWorkerConfig.gids.size(); gid_t * aGids = new gid_t[iGroups]; for(UINT_32 iPos = 0; iPos < iGroups; ++iPos) { aGids[iPos] = oWorkerConfig.gids[iPos]; } if (setgroups(oWorkerConfig.gids.size(), aGids) == -1) { STLW::string sGroups; for(UINT_32 iPos = 0; iPos < iGroups; ++iPos) { CHAR_8 szGroup[64]; snprintf(szGroup, 63, "%llu ", (long long unsigned)aGids[iPos]); sGroups.append(szGroup); } delete [] aGids; const INT_32 iErrNo = errno; oLogger.Emerg("Can't set additional groups %s: %s error code %d", sGroups.c_str(), strerror(iErrNo), iErrNo); return EX_SOFTWARE; } delete [] aGids; } if (setgid(oWorkerConfig.gid) == -1) { const INT_32 iErrNo = errno; oLogger.Emerg("Can't set group id to %d: %s error code %d", INT_32(oWorkerConfig.gid), strerror(iErrNo), iErrNo); return EX_SOFTWARE; } if (setuid(oWorkerConfig.uid) == -1) { const INT_32 iErrNo = errno; oLogger.Emerg("Can't set user id to %d: %s, error code %d", INT_32(oWorkerConfig.uid), strerror(iErrNo), iErrNo); return EX_SOFTWARE; } } } oLogger.Info("Switching to unprivileged user completed"); return EX_OK; }
static STLW::string GetBaseDir(const STLW::string & szTemplateName, STLW::string & sNormalizedFileName) { STLW::string sResult; CHAR_8 szPath[MAX_PATH]; CHAR_P szFile = NULL; DWORD dwLen = ::GetFullPathNameA(szTemplateName.c_str(), MAX_PATH, szPath, &szFile); if (szFile == NULL) { return ""; } sNormalizedFileName.assign(szPath, dwLen); sResult.assign(szPath, szFile); return sResult; }
static STLW::string GetBaseDir(const STLW::string & szTemplateName, STLW::string & sNormalizedFileName) { if (szTemplateName.length() == 0) { return ""; } STLW::vector<STLW::string> vCurrentDir; CCHAR_P sBegin = szTemplateName.c_str(); CCHAR_P szEnd = szTemplateName.c_str() + szTemplateName.length(); CCHAR_P sIter = sBegin; while (sIter != szEnd) { if (*sIter == '/') { if (sIter != sBegin) { STLW::string sTMP(sBegin, sIter); if (sTMP == "/." || sTMP == "/") { ;; } else if (sTMP == "/..") { STLW::vector<STLW::string>::iterator itEnd = vCurrentDir.end(); if (vCurrentDir.begin() == itEnd) { return ""; } vCurrentDir.erase(--itEnd); } else { vCurrentDir.push_back(sTMP); } } sBegin = sIter; } ++sIter; } STLW::string sTMP(sBegin, sIter); if (sTMP == "/") { return ""; } STLW::string sResult; for (UINT_32 iI = 0; iI < vCurrentDir.size(); ++iI) { sResult.append(vCurrentDir[iI]); } sNormalizedFileName.assign(sResult); sNormalizedFileName.append(sTMP); sResult.append("/"); return sResult; }
int main(void) { CDT oArgs; oArgs.PushBack(101.5); oArgs.PushBack(101.4); STLW::string sResult; FormatString("_%0.2f_", sResult, oArgs); fwrite(sResult.c_str(), sResult.size(), 1, stdout); // make valgrind happy fclose(stdin); fclose(stdout); fclose(stderr); return EX_OK; }
int main(int argc, char ** argv) { const char * szConfigFile = NULL; if (argc == 1) { fprintf(stderr, "Global config not given, "); szConfigFile = getenv("CAS_GLOBAL_CONFIG"); if (szConfigFile != NULL) { fprintf(stderr, " using %s from ENVIRONMENT", szConfigFile); } else { szConfigFile = CAS_GLOBAL_CONFIG_FILE; fprintf(stderr, " using %s as DEFAULT\n", szConfigFile); } } else if (argc == 2) { szConfigFile = argv[1]; } else { fprintf(stderr, "usage: %s [global-config.xml]\n", argv[0]); return EX_USAGE; } FILE * F = fopen(szConfigFile, "rb"); if (F == NULL) { fprintf(stderr, "ERROR: Cannot open `%s` for reading: %s\n", szConfigFile, strerror(errno)); return EX_SOFTWARE; } // Store path to file as include directory CCHAR_P szTMP = szConfigFile + strlen(szConfigFile); while (szTMP != szConfigFile && *szTMP != '/' && *szTMP != '\\') { --szTMP; } STLW::vector<STLW::string> vIncludeDirs; if (szTMP != szConfigFile) { vIncludeDirs.push_back(STLW::string(szConfigFile, (szTMP - szConfigFile))); } try { ASGlobalConfig oGlobalConfig; ASGlobalConfigHandler oHandler(oGlobalConfig, vIncludeDirs); ASXMLParser oParser(&oHandler); if (oParser.ParseFile(F) == -1) { fprintf(stderr, "ERROR: In file %s: %s\n", szConfigFile, oHandler.GetError().c_str()); return EX_CONFIG; } fclose(F); fprintf(stdout, " Libexec dirs:\n"); UINT_32 iI = 0; for(; iI < oGlobalConfig.libexec_dirs.size(); ++iI) { fprintf(stdout, " %s\n", oGlobalConfig.libexec_dirs[iI].c_str()); } fprintf(stdout, "\n Modules:\n"); for(iI = 0; iI < oGlobalConfig.modules_list.size(); ++iI) { fprintf(stdout, " Name: %s\n" " Type: %s\n", oGlobalConfig.modules_list[iI].name.c_str(), oGlobalConfig.modules_list[iI].moduletype.c_str()); STLW::string sTMP = CheckFile(oGlobalConfig.libexec_dirs, oGlobalConfig.modules_list[iI].library); if (sTMP.size() == 0) { fprintf(stdout, " *** ERROR: Cannot find Library file: %s\n", oGlobalConfig.modules_list[iI].library.c_str()); } else { fprintf(stdout, " Library file: %s\n", CheckFile(oGlobalConfig.libexec_dirs, oGlobalConfig.modules_list[iI].library).c_str()); } STLW::string sData = Dump(oGlobalConfig.modules_list[iI].configuration); if (!sData.empty() && sData != "\"\"\n") { fprintf(stdout, " Configuration: %s\n", sData.c_str()); } // TBD fprintf(stdout, "\n"); } } catch(STLW::exception &e) { fprintf(stderr, "ERROR: %s\n", e.what()); return EX_SOFTWARE; } catch(...) { fprintf(stderr, "ERROR: Ouch!\n"); return EX_SOFTWARE; } fclose(stdin); fclose(stdout); fclose(stderr); return EX_OK; }
// Thread function static void * ThreadFunction(void * pContext) { ThreadContext * pThreadContext = (ThreadContext *)pContext; pthread_mutex_lock(&(pThreadContext -> output_mutex)); fprintf(stderr, "Initilalizing...\n"); pthread_mutex_unlock(&(pThreadContext -> output_mutex)); // Create per-thread VM instance // Syscall factory SyscallFactory * pSyscallFactory = new SyscallFactory(pThreadContext -> max_handlers); // Init standard library STDLibInitializer::InitLibrary(*pSyscallFactory); // Virtual machine VM * pVM = new VM(pSyscallFactory); // Okay, all done with thread-specific // Fill data CDT oData; oData["hello"] = "Hello, World!"; pthread_mutex_lock(&(pThreadContext -> output_mutex)); fprintf(stderr, "Okay, ready to work\n"); pthread_mutex_unlock(&(pThreadContext -> output_mutex)); FileLogger oLogger(stderr); // Perform some work const VMMemoryCore * pVMMemoryCore = NULL; for (UINT_32 iCount = 0; iCount < MAX_ITERATIONS; ++iCount) { STLW::string sResult; StringOutputCollector oDataCollector(sResult); // Get template, thread-safe pthread_mutex_lock(&(pThreadContext -> template_mutex)); STLW::map<STLW::string, VMFileLoader *>::iterator itLoader = pThreadContext -> templates.find("hello.ct2"); if (itLoader == pThreadContext -> templates.end()) { continue; } pVMMemoryCore = itLoader -> second -> GetCore(); pthread_mutex_unlock(&(pThreadContext -> template_mutex)); // Run VM pVM -> Init(pVMMemoryCore, &oDataCollector, &oLogger); UINT_32 iIP = 0; pVM -> Run(pVMMemoryCore, &oDataCollector, iIP, oData, &oLogger); // All done, print results pthread_mutex_lock(&(pThreadContext -> output_mutex)); fwrite(sResult.c_str(), sResult.size(), 1, stdout); pthread_mutex_unlock(&(pThreadContext -> output_mutex)); } delete pVM; delete pSyscallFactory; return NULL; }
ServiceConfig::State ServiceConfig::ParseNetworks(const VariantNC & oData, const STLW::string & sBranch, ServiceConfig & oServiceConfig, IPv4Map & oIPv4Map, Logger & oLogger) { const STLW::vector<STLW::string> vNetworks = oData[sBranch]; STLW::vector<STLW::string>::const_iterator itvNetworks = vNetworks.begin(); while (itvNetworks != vNetworks.end()) { // IPv4 if (itvNetworks -> find(".") != STLW::string::npos) { if (oIPv4Map.AddNet(*itvNetworks) != IPMap::OK) { oLogger.Emerg("Invalid format of parameter `Service/%s/%s`: invalid network `%s`", oServiceConfig.name.c_str(), sBranch.c_str(), itvNetworks -> c_str()); return CONFIG_ERROR; } } // IPv6, TBD else if (itvNetworks -> find(":") != STLW::string::npos) { oLogger.Emerg("Invalid format of parameter `Service/%s/%s`: IPv6 networks `%s` not supported yet", oServiceConfig.name.c_str(), sBranch.c_str(), itvNetworks -> c_str()); } ++itvNetworks; } return OK; }
// // Load modules // INT_32 MainProcess::LoadModule(const STLW::string & sModuleType, const STLW::string & sModuleName, const STLW::string & sLibrary, const STLW::string & sDriver, const VariantNC & oModuleConfig, const STLW::vector<STLW::string> & vLibexecDirs, Logger & oLogger) { oLogger.Info("Opening `%s/%s` from library `%s`", sModuleType.c_str(), sModuleName.c_str(), sLibrary.c_str()); STLW::string sFullpath; INT_32 iRC = FindFile(vLibexecDirs, sLibrary, sFullpath); if (iRC == -1) { STLW::string sDirList; STLW::vector<STLW::string>::const_iterator itvLibexecDirs = vLibexecDirs.begin(); for (;;) { sDirList += "`" + *itvLibexecDirs + "` "; ++itvLibexecDirs; if (itvLibexecDirs == vLibexecDirs.end()) { break; } sDirList += ", "; } oLogger.Emerg("Can't find library `%s` in LibexecDirs(%s) ", sLibrary.c_str(), sDirList.c_str()); return -1; } oLogger.Info("Library `%s` found here: `%s`", sLibrary.c_str(), sFullpath.c_str()); Object * pObject = oGlobalContext.loader.GetObject(sFullpath.c_str(), sDriver.c_str()); if (pObject == NULL) { oLogger.Emerg("Can't load object `%s` from file `%s`", sDriver.c_str(), sFullpath.c_str()); return -1; } // Check type of object const STLW::string sObjectType = pObject -> GetObjectType(); if (Unicode::CompareIgnoreCase(sObjectType.data(), sObjectType.size(), sModuleType.data(), sModuleType.size()) != 0) { oLogger.Emerg("Need type `%s`, but object `%s` loaded from file `%s` has type `%s`", sModuleType.c_str(), pObject -> GetObjectName(), sFullpath.c_str(), pObject -> GetObjectType()); delete pObject; return -1; } oLogger.Info("Object `%s` with type `%s` loaded from file `%s`", pObject -> GetObjectName(), pObject -> GetObjectType(), sFullpath.c_str()); // Initialize module iRC = static_cast<Module *>(pObject) -> InitModule(oGlobalContext, oModuleConfig, oSigHandler, oLogger); if (iRC != 0) { oLogger.Emerg("Can't initialize module `%s` from file `%s`", sModuleName.c_str(), sFullpath.c_str()); delete pObject; return -1; } const STLW::string sFullName = sModuleType + '/' + sModuleName; vModules.push_back(sFullName); // Store object in factory if(oGlobalContext.factory.AddObject(sFullName, pObject) == NULL) { oLogger.Emerg("Can't add module `%s` from file `%s`", sModuleName.c_str(), sFullpath.c_str()); static_cast<Module *>(pObject) -> DestroyModule(oGlobalContext, oSigHandler, oLogger); delete pObject; return -1; } return 0; }
int main(int argc, char ** argv) { STLW::string sGlobalConfigFile; STLW::string sConfigFile; STLW::string sModuleName; bool bPrintHelp = false; bool bPrintVersion = false; bool bPrintCompileInfo = false; bool bDaemonize = true; bool bDebugInfo = false; initproctitle(argc, argv); // Read and parse command-line options INT_32 iRC = GetParams(argc, argv, sGlobalConfigFile, sConfigFile, sModuleName, bDebugInfo, bPrintHelp, bPrintVersion, bPrintCompileInfo, bDaemonize); if (iRC != EX_OK) { Usage(argv[0]); return EX_USAGE; } // Just print help and exit if (bPrintHelp) { Help(argv[0]); return EX_OK; } // Print version if (bPrintVersion) { Version(); return EX_OK; } // Print compiler settings if (bPrintCompileInfo) { CompileInfo(); return EX_OK; } FILE * F = fopen(sConfigFile.c_str(), "rb"); if (F == NULL) { fprintf(stderr, "ERROR: Cannot open `%s` for reading: %s\n", sConfigFile.c_str(), strerror(errno)); return EX_SOFTWARE; } WorkerConfig oWorkerConfig; oWorkerConfig.global_config_file = sGlobalConfigFile; oWorkerConfig.procname = argv[0]; oWorkerConfig.debug = bDebugInfo; oWorkerConfig.foreground = !bDaemonize; try { ConfigHandler oConfigHandler(oWorkerConfig); ASXMLParser oParser(&oConfigHandler); if (oParser.ParseFile(F) == -1) { fprintf(stderr, "ERROR: In file %s: %s\n", sConfigFile.c_str(), oConfigHandler.GetError().c_str()); return EX_CONFIG; } fclose(F); } catch(STLW::exception &e) { fprintf(stderr, "ERROR: %s\n", e.what()); return EX_SOFTWARE; } catch(...) { fprintf(stderr, "ERROR: Ouch!\n"); return EX_SOFTWARE; } if (GetSystemUserData(oWorkerConfig) != EX_OK) { return EX_SOFTWARE; } if (oWorkerConfig.global_config_file.empty()) { oWorkerConfig.global_config_file = CAS_GLOBAL_CONFIG_FILE; fprintf(stderr, "Global config not given, using %s as DEFAULT\n", CAS_GLOBAL_CONFIG_FILE); } MainProcess oMainProcess(oWorkerConfig); ASLoggerFile oLogger(stderr); if (bDaemonize) { if (Daemonize(oWorkerConfig.pid_file.c_str(), oLogger) != EX_OK) { return EX_SOFTWARE; } } if (UnixSetup(oWorkerConfig, oLogger) != EX_OK) { return EX_SOFTWARE; } try { if (oMainProcess.Setup() == -1) { fprintf(stderr, "Can't start FastCGI server: %s; config file %s\n", strerror(errno), sConfigFile.c_str()); return EX_SOFTWARE; } } catch(STLW::exception &e) { fprintf(stderr, "ERROR: %s\n", e.what()); return EX_SOFTWARE; } catch(...) { fprintf(stderr, "ERROR: Ouch!\n"); return EX_SOFTWARE; } return oMainProcess.Run(); }