// // 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; }
// CTPP2 CTPP2::CTPP2(unsigned int arg_stack_size, unsigned int code_stack_size, unsigned int steps_limit, unsigned int max_functions, STLW::string src_charset, STLW::string dst_charset) { try { params = new CDT(CDT::HASH_VAL); syscalls = new SyscallFactory(max_functions); STDLibInitializer::InitLibrary(*syscalls); vm = new VM(syscalls, arg_stack_size, code_stack_size, steps_limit); int i = 0; while (functions[i]) bind(functions[i++]()); if (src_charset.size() && dst_charset.size()) { charset.src = src_charset; charset.dst = dst_charset; charset.convert = true; } else { // Конвертирование не требуется charset.convert = false; } } catch (...) { cpp_free(params); if (syscalls) { STDLibInitializer::DestroyLibrary(*syscalls); cpp_free(syscalls); } cpp_free(vm); } }
// // Handler // INT_32 FnTruncate::Handler(CDT * aArguments, const UINT_32 iArgNum, CDT & oCDTRetVal, Logger & oLogger) { if (iArgNum == 2) { const UINT_32 iMaxLen = UINT_32(aArguments[0].GetInt()); const STLW::string sData = aArguments[1].GetString(); if (sData.size() > iMaxLen) { oCDTRetVal = STLW::string(sData, 0, iMaxLen); } else { oCDTRetVal = sData; } return 0; } else if (iArgNum == 3) { const UINT_32 iMaxLen = UINT_32(aArguments[1].GetInt()); STLW::string sData = aArguments[2].GetString(); if (sData.size() > iMaxLen) { sData = STLW::string(sData, 0, iMaxLen); sData.append(aArguments[0].GetString()); } oCDTRetVal = sData; return 0; } oLogger.Emerg("Usage: TRUNCATE(x, offest[, addon])"); return -1; }
// // 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; }
// // Handler // INT_32 FnHTMLEscape::Handler(CDT * aArguments, const UINT_32 iArgNum, CDT & oCDTRetVal, Logger & oLogger) { if (iArgNum < 1) { oLogger.Emerg("Usage: HTMLESCAPE(a[, b, ...])"); return -1; } STLW::string sResult; for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { sResult.append(aArguments[iPos].GetString()); } oCDTRetVal = HTMLEscape(sResult); return 0; }
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; }
static STLW::string EscapeString(const STLW::string & sSource) { if (sSource.empty()) { return "\"\""; } STLW::string::const_iterator itsSource = sSource.begin(); while (itsSource != sSource.end()) { const UCHAR_8 ucTMP = *itsSource; if (!((ucTMP >= 'a' && ucTMP <= 'z') || (ucTMP >= 'A' && ucTMP <= 'Z') || (ucTMP >= '0' && ucTMP <= '9') || ucTMP == '.' || ucTMP == '_' || ucTMP == ':' || ucTMP == '*' || ucTMP == '[' || ucTMP == ']' || ucTMP == '\\' || ucTMP == '/' || ucTMP == '-')) { return '"' + sSource + '"'; } ++itsSource; } return sSource; }
// // Character // static void FmtChar(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const INT_32 iWidth, CHAR_8 chPadSymbol) { const CDT::eValType oValType = oCurrentArgument.GetType(); if (oValType == CDT::UNDEF && iWidth > 0) { oBuffer.Append(iWidth, chPadSymbol); return; } UCHAR_8 ucTMP = ' '; if (oValType == CDT::INT_VAL || oValType == CDT::REAL_VAL) { ucTMP = oCurrentArgument.GetInt(); } else if (oValType == CDT::STRING_VAL) { const STLW::string sTMP = oCurrentArgument.GetString(); if (sTMP.empty() && iWidth > 0) { oBuffer.Append(iWidth, chPadSymbol); return; } ucTMP = sTMP[0]; } else if (oValType == CDT::POINTER_VAL) { ucTMP = 'P'; } else if (oValType == CDT::ARRAY_VAL) { ucTMP = 'A'; } else if (oValType == CDT::HASH_VAL) { ucTMP = 'H'; } if (iFmtFlags & F_LEFT_ALIGN) { oBuffer.Append(1, ucTMP); if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); } } else { if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); } oBuffer.Append(1, ucTMP); } }
// // Handler // INT_32 FnJSONEscape::Handler(CDT * aArguments, const UINT_32 iArgNum, CDT & oCDTRetVal, Logger & oLogger) { if (iArgNum < 1) { oLogger.Emerg("Usage: JSONESCAPE(a[, b, ...])"); return -1; } STLW::string sResult; for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { switch (aArguments[iPos].GetType()) { case CDT::UNDEF: sResult.append("null", 4); break; case CDT::INT_VAL: case CDT::REAL_VAL: case CDT::POINTER_VAL: case CDT::STRING_INT_VAL: case CDT::STRING_REAL_VAL: sResult.append(aArguments[iPos].GetString()); break; case CDT::STRING_VAL: sResult.append(EscapeJSONString(aArguments[iPos].GetString(), true, false)); break; default: oLogger.Emerg("Invalid type %s", aArguments[iPos].PrintableType()); return -1; } } oCDTRetVal = sResult; return 0; }
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; }
// // String // static void FmtString(StringBuffer & oBuffer, const CDT & oCurrentArgument, const UINT_32 iFmtFlags, const INT_32 iWidth, const INT_32 iMaxChars, CHAR_8 chPadSymbol) { const STLW::string sTMP = oCurrentArgument.GetString(); INT_32 iFormatSize = sTMP.size(); if (iFormatSize > iMaxChars && iMaxChars > 0) { iFormatSize = iMaxChars; } if (iFmtFlags & F_LEFT_ALIGN) { oBuffer.Append(sTMP.data(), iFormatSize); if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); } } else { if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); } oBuffer.Append(sTMP.data(), iFormatSize); } }
static void IterateString(FILE * F, CCHAR_P szData, UINT_64 iDataLen, STLW::string & sResultString) { STLW::string::iterator itsResultString = sResultString.begin(); for(;;) { UINT_32 iUCS = 0; const INT_64 iCharLen = Unicode::UTF8ToWide(szData, iDataLen, iUCS); if (iCharLen <= 0) { break; } Unicode::WideToUTF8(iUCS, itsResultString); iDataLen -= iCharLen; fprintf(F, "0x%X ", iUCS); } fprintf(F, "\n"); }
// // Load template with specified name // INT_32 CTPP2FileSourceLoader::LoadTemplate(CCHAR_P szTemplateName) { sNormalizedFileName.erase(); INT_32 iStatCode = 0; STLW::vector<STLW::string>::const_iterator itvIncludeDirs = vIncludeDirs.begin(); while(itvIncludeDirs != vIncludeDirs.end()) { STLW::string sTMP = *itvIncludeDirs; #ifdef WIN32 if ( sTMP.length() && sTMP[sTMP.length() - 1] != '/' && sTMP[sTMP.length() - 1] != '\\' ) { sTMP.append("\\", 1); } #else if (sTMP.length() && sTMP[sTMP.length() - 1] != '/') { sTMP.append("/", 1); } #endif sTMP.append(szTemplateName); sCurrentDir = GetBaseDir(sTMP, sNormalizedFileName); if (sNormalizedFileName.length() == 0) { STLW::string sError("invalid file name `"); sError.append(sTMP); sError.append("`"); throw CTPPLogicError(sError.c_str()); } // Get file size struct stat oStat; iStatCode = stat(sNormalizedFileName.c_str(), &oStat); if (iStatCode == 0) { iTemplateSize = oStat.st_size; break; } ++itvIncludeDirs; } if (iStatCode == -1) { STLW::string sError("cannot find file in include directories "); itvIncludeDirs = vIncludeDirs.begin(); for (;;) { sError.append("`"); if (itvIncludeDirs -> size() != 0) { sError.append(*itvIncludeDirs); } else { CHAR_P szPWD = getcwd(NULL, 0); sError.append(szPWD); free(szPWD); } sError.append("`"); ++itvIncludeDirs; if (itvIncludeDirs == vIncludeDirs.end()) { break; } sError.append(", "); } throw CTPPLogicError(sError.c_str()); } if (iTemplateSize == 0) { STLW::string sError("empty file `"); sError.append(sNormalizedFileName); sError.append("` found"); throw CTPPLogicError(sError.c_str()); } // Load file FILE * F = fopen(sNormalizedFileName.c_str(), "rb"); if (F == NULL) { throw CTPPUnixException("fopen", errno); } if (sTemplate != NULL) { free(sTemplate); } // Allocate memory sTemplate = (CHAR_P)malloc(iTemplateSize); // Read from file if (fread(sTemplate, iTemplateSize, 1, F) != 1) { if (ferror(F) != 0) { free(sTemplate); fclose(F); throw CTPPUnixException("fread", errno); } else { free(sTemplate); fclose(F); throw CTPPLogicError("Cannot read from file"); } } fclose(F); return 0; }
// // Initialize module // INT_32 FileLogger::InitModule(IRIS::GlobalContext & oGlobalContext, const IRIS::VariantNC & oConfig, IRIS::SignalHandler & oSigHandler, IRIS::Logger & oLogger) { using namespace IRIS; // Re-open log files oSigHandler.RegisterHandler(SIGHUP, &oLoggerSignalHandler); oSigHandler.RegisterHandler(SIGUSR1, &oLoggerSignalHandler); oSigHandler.RegisterHandler(SIGUSR2, &oLoggerSignalHandler); STLW::string sTMP = oConfig["LogLevel"].Str(); static CCHAR_P aPriorities[] = { "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", NULL }; static LogPriority::LogPriorities oPriorities[] = { LogPriority::LOG_EMERG, LogPriority::LOG_ALERT, LogPriority::LOG_CRIT, LogPriority::LOG_ERROR, LogPriority::LOG_WARNING, LogPriority::LOG_NOTICE, LogPriority::LOG_INFO, LogPriority::LOG_DEBUG }; oActualPriority = oBasePriority = LogPriority::LOG_DEBUG; CCHAR_P * aPriority = aPriorities; IRIS::LogPriority::LogPriorities * oPriority = oPriorities; while (*aPriority != NULL) { if (Unicode::CompareIgnoreCase(sTMP.data(), sTMP.size(), *aPriority, strlen(*aPriority)) == 0) { oActualPriority = oBasePriority = *oPriority; break; } ++aPriority; ++oPriority; } iErrorLogBufferSize = iCustomLogBufferSize = -1; sErrorLogFormat.assign(oConfig["ErrorLogFormat"]); if (sErrorLogFormat.empty()) { oLogger.Emerg("Configuration is broken: parameter %s/%s/ErrorLogFormat not set", GetObjectType(), GetObjectName()); return -1; } sErrorLogFile.assign(oConfig["ErrorLog"]); if (sErrorLogFile.empty()) { oLogger.Emerg("Configuration is broken: parameter %s/%s/ErrorLog not set", GetObjectType(), GetObjectName()); return -1; } sCustomLogFormat.assign(oConfig["CustomLogFormat"]); if (sCustomLogFormat.empty()) { oLogger.Emerg("Configuration is broken: parameter %s/%s/CustomLogFormat not set", GetObjectType(), GetObjectName()); return -1; } sCustomLogFile.assign(oConfig["CustomLog"]); if (sCustomLogFile.empty()) { oLogger.Emerg("Configuration is broken: parameter `%s/%s/CustomLog` not set", GetObjectType(), GetObjectName()); return -1; } // Error log permissions char * pEnd = NULL; iErrorLogPerms = strtol(oConfig["ErrorLogPerms"].Str().c_str(), &pEnd, 8); if (iErrorLogPerms == 0) { oLogger.Info("Parameter `%s/%s/ErrorLogPerms` not set", GetObjectType(), GetObjectName()); } // User and group ConfigHelper::State oConfRC = ConfigHelper::ParseUserGroup(oConfig["ErrorLogOwner"], sErrorLogUser, iErrorLogUID, sErrorLogGroup, iErrorLogGID); switch(oConfRC) { case ConfigHelper::NOT_NEED: oLogger.Info("Parameter `%s/%s/ErrorLogOwner` is useful only if Iris starting from root user", GetObjectType(), GetObjectName()); break; case ConfigHelper::CONFIG_ERROR: oLogger.Info("Parameter `%s/%s/ErrorLogOwner` not set", GetObjectType(), GetObjectName()); break; case ConfigHelper::NO_SUCH_USER: oLogger.Emerg("Parameter `%s/%s/ErrorLogOwner`: no such user: `%s`", GetObjectType(), GetObjectName(), sErrorLogUser.c_str()); return -1; case ConfigHelper::NO_SUCH_GROUP: oLogger.Emerg("Parameter `%s/%s/ErrorLogOwner`: no such group: `%s`", GetObjectType(), GetObjectName(), sErrorLogGroup.c_str()); return -1; default: ;; } // Buffer size for error log iErrorLogBufferSize = ConfigHelper::ParseSize(oConfig["ErrorLogBufferSize"]); if (iErrorLogBufferSize == 0) { oLogger.Info("Parameter `%s/%s/ErrorLogBufferSize` not set", GetObjectType(), GetObjectName()); } // Error log permissions iCustomLogPerms = strtol(oConfig["CustomLogPerms"].Str().c_str(), &pEnd, 8); if (iCustomLogPerms == 0) { oLogger.Info("Parameter `%s/%s/CustomLogPerms` not set", GetObjectType(), GetObjectName()); } // User and group oConfRC = ConfigHelper::ParseUserGroup(oConfig["CustomLogOwner"], sCustomLogUser, iCustomLogUID, sCustomLogGroup, iCustomLogGID); switch(oConfRC) { case ConfigHelper::NOT_NEED: oLogger.Info("Parameter `%s/%s/CustomLogOwner` is useful only if Iris starting from root user", GetObjectType(), GetObjectName()); break; case ConfigHelper::CONFIG_ERROR: oLogger.Info("Parameter `%s/%s/CustomLogOwner` not set", GetObjectType(), GetObjectName()); break; case ConfigHelper::NO_SUCH_USER: oLogger.Emerg("Parameter `%s/%s/CustomLogOwner`: no such user: `%s`", GetObjectType(), GetObjectName(), sErrorLogUser.c_str()); return -1; case ConfigHelper::NO_SUCH_GROUP: oLogger.Emerg("Parameter `%s/%s/CustomLogOwner`: no such group: `%s`", GetObjectType(), GetObjectName(), sErrorLogGroup.c_str()); return -1; default: ;; } // Buffer size for custom log iCustomLogBufferSize = ConfigHelper::ParseSize(oConfig["CustomLogBufferSize"]); if (iCustomLogBufferSize == 0) { oLogger.Info("Parameter `%s/%s/CustomLogBufferSize` not set", GetObjectType(), GetObjectName()); } // Try to open log files oLogger.Info("%s/%s: Try to open log file `%s`", GetObjectType(), GetObjectName(), sErrorLogFile.c_str()); iErrorLogFileHandle = File::Open(sErrorLogFile.c_str(), OpenMode::WRITE | OpenMode::CREATE | OpenMode::APPEND); if (iErrorLogFileHandle == -1) { oLogger.Emerg("%s/%s: Can't open file `%s`: %s", GetObjectType(), GetObjectName(), sErrorLogFile.c_str(), Debug::PrintableError(SystemVars::ErrNo()).c_str()); return -1; } // Change permissions and owner if (iErrorLogPerms != 0) { File::Chmod(iErrorLogFileHandle, iErrorLogPerms); } if (iErrorLogUID != 0) { File::Chown(iErrorLogFileHandle, iErrorLogUID, iErrorLogGID); } // Try to open log files oLogger.Info("%s/%s: Try to open log file `%s`", GetObjectType(), GetObjectName(), sCustomLogFile.c_str()); iCustomLogFileHandle = File::Open(sCustomLogFile.c_str(), OpenMode::WRITE | OpenMode::CREATE | OpenMode::APPEND); if (iCustomLogFileHandle == -1) { oLogger.Emerg("%s/%s: Can't open file `%s`: %s", GetObjectType(), GetObjectName(), sCustomLogFile.c_str(), Debug::PrintableError(SystemVars::ErrNo()).c_str()); File::Close(iErrorLogFileHandle); iErrorLogFileHandle = iCustomLogFileHandle = -1; return -1; } if (iCustomLogPerms != 0) { File::Chmod(iCustomLogFileHandle, iCustomLogPerms); } if (iCustomLogUID != 0) { File::Chown(iCustomLogFileHandle, iCustomLogUID, iCustomLogGID); } // Create writers pErrorLogWriter = new LogWriter(iErrorLogFileHandle, iErrorLogBufferSize); pCustomLogWriter = new LogWriter(iCustomLogFileHandle, iCustomLogBufferSize); return 0; }
void CTPP2::output(zval *out, Bytecode *bytecode, const char *src_enc, const char *dst_enc) { unsigned int IP = 0; if (!bytecode || !bytecode->check()) { error = CTPPError("", "Invalid Bytecode", CTPP_VM_ERROR | STL_UNKNOWN_ERROR, 0, 0, IP); } else { try { if (charset.convert || (src_enc && dst_enc)) { STLW::string src_charset, dst_charset; if (src_enc && dst_enc) { src_charset = STLW::string(src_enc); dst_charset = STLW::string(dst_enc); } else { src_charset = charset.src; dst_charset = charset.dst; } STLW::string result; CTPPPerlLogger logger; StringIconvOutputCollector output_collector(result, src_charset, dst_charset, 3); vm->Init(bytecode->getCode(), &output_collector, &logger); vm->Run(bytecode->getCode(), &output_collector, IP, *params, &logger); vm->Reset(); ZVAL_STRINGL(out, result.data(), result.length()); return; } else { CTPPPerlLogger logger; if (out) { // STLW::string result; // StringOutputCollector output_collector(result); // vm->Init(bytecode->getCode(), &output_collector, &logger); // vm->Run(bytecode->getCode(), &output_collector, IP, *params, &logger); // ZVAL_STRINGL(out, result.data(), result.length()); CTPPPHPVarOutputCollector output_collector(out); vm->Init(bytecode->mem, &output_collector, &logger); vm->Run(bytecode->mem, &output_collector, IP, *params, &logger); } else { CTPPPHPOutputCollector output_collector; vm->Init(bytecode->mem, &output_collector, &logger); vm->Run(bytecode->mem, &output_collector, IP, *params, &logger); } vm->Reset(); return; } } catch (ZeroDivision &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_ZERO_DIVISION_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (ExecutionLimitReached &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_EXECUTION_LIMIT_REACHED_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (CodeSegmentOverrun &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_CODE_SEGMENT_OVERRUN_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (InvalidSyscall &e) { if (e.GetIP() != 0) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_INVALID_SYSCALL_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } else { error = CTPPError(e.GetSourceName(), STLW::string("Unsupported syscall: \"") + e.what() + "\"", CTPP_VM_ERROR | CTPP_INVALID_SYSCALL_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } } catch (IllegalOpcode &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_ILLEGAL_OPCODE_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (StackOverflow &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_STACK_OVERFLOW_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (StackUnderflow &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_STACK_UNDERFLOW_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (VMException &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_VM_GENERIC_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (CTPPUnixException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_UNIX_ERROR, 0, 0, IP); } catch (CDTRangeException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_RANGE_ERROR, 0, 0, IP); } catch (CDTAccessException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_ACCESS_ERROR, 0, 0, IP); } catch (CDTTypeCastException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_TYPE_CAST_ERROR, 0, 0, IP); } catch (CTPPLogicError &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_LOGIC_ERROR, 0, 0, IP); } catch(CTPPCharsetRecodeException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_CHARSET_RECODE_ERROR, 0, 0, 0); } catch (CTPPException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_UNKNOWN_ERROR, 0, 0, IP); } catch (STLW::exception &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | STL_UNKNOWN_ERROR, 0, 0, IP); } catch (...) { error = CTPPError("", "Unknown Error", CTPP_VM_ERROR | STL_UNKNOWN_ERROR, 0, 0, IP); } } vm->Reset(); if (error.line > 0) { php_error(E_WARNING, "CTPP2::output(): %s (error code 0x%08X); IP: 0x%08X, file %s line %d pos %d", error.error_descr.c_str(), error.error_code, error.ip, error.template_name.c_str(), error.line, error.pos); } else { php_error(E_WARNING, "CTPP2::output(): %s (error code 0x%08X); IP: 0x%08X", error.error_descr.c_str(), error.error_code, error.ip); } if (out) ZVAL_BOOL(out, 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(); }
// // Write message to log file // IRIS::Logger::State ParametrizedLogger::ParametrizedLogger::WriteLog(const IRIS::LogPriority::LogPriorities ePriority, CCHAR_P szString, const UINT_32 iStringLen) { using namespace IRIS; MutexLocker oMutexLocker(oMutex); /* # $timegm.unix - current GMT unixtime, seconds # $timegm.ascii - current GMT time, ascii representation [Wkd Mmm DD HH:MM:SS YYYY] # $time.unix - current LOCAL unixtime, seconds # $time.ascii - current LOCAL time, ascii representation */ SystemVars::Time oTimeGM = SystemVars::GetTime(); IRIS::DataBuffer & oDataBuffer = oLogWriter; struct tm oLocalTime; time_t iTime = oTimeGM.sec; localtime_r(&iTime, &oLocalTime); STLW::string::const_iterator itsLogFormat = sLogFormat.begin(); STLW::stringstream sStream; for (;;) { STLW::string::const_iterator itsTMP = itsLogFormat; while(itsLogFormat != sLogFormat.end() && *itsLogFormat != '$') { ++itsLogFormat; } sStream << STLW::string(itsTMP, itsLogFormat); if (itsLogFormat == sLogFormat.end()) { break; } itsTMP = itsLogFormat++; while(itsLogFormat != sLogFormat.end()) { const CHAR_8 chTMP = *itsLogFormat; if (!((chTMP >= 'a' && chTMP <= 'z') || (chTMP >= 'A' && chTMP <= 'Z') || (chTMP >= '0' && chTMP <= '9') || chTMP == '.' || chTMP == '_')) { break; } ++itsLogFormat; } const STLW::string sParam(++itsTMP, itsLogFormat); if (sParam == "message.str") { sStream << STLW::string(szString, iStringLen); } else if (sParam == "timegm.unix") { sStream << oTimeGM.sec << '.' << oTimeGM.nsec; } else if (sParam == "time.unix") { #if defined(sun) || defined(_AIX) sStream << oTimeGM.sec + GetGMTOff(iTime, oLocalTime) << '.' << oTimeGM.nsec; #else sStream << oTimeGM.sec + oLocalTime.tm_gmtoff << '.' << oTimeGM.nsec; #endif } else if (sParam == "timegm.ascii") { sStream << FormatDate(oTimeGM.sec); } else if (sParam == "time.ascii") { #if defined(sun) || defined(_AIX) sStream << FormatDate(oTimeGM.sec + GetGMTOff(iTime, oLocalTime)); #else sStream << FormatDate(oTimeGM.sec + oLocalTime.tm_gmtoff); #endif } else if (sParam == "priority") { sStream << LogPriority::GetPrintableState(ePriority); } else { if (pLoggerContext == NULL) { sStream << "-"; } else { STLW::string sValue; pLoggerContext -> GetParam(sParam, sValue); sStream << sValue; } } } const STLW::string sResult = sStream.str(); STLW::string::const_iterator itsResult = sResult.begin(); for (;;) { STLW::string::const_iterator itsStart = itsResult; while (itsResult != sResult.end() && *itsResult >= ' ') { ++itsResult; } oDataBuffer.Append(itsStart, itsResult); if (itsResult == sResult.end()) { break; } const UCHAR_8 ucTMP = *itsResult; switch (ucTMP) { case '\n': oDataBuffer.Append("\\n"); break; case '\r': oDataBuffer.Append("\\r"); break; case '\t': oDataBuffer.Append("\\t"); break; default: { CHAR_8 szBuf[6]; INT_32 iBufLen = snprintf(szBuf, 6, "\\x%02X", ucTMP); oDataBuffer.Append(szBuf, iBufLen); } } ++itsResult; if (itsResult == sResult.end()) { break; } } oDataBuffer.Append("\n"); oLogWriter.Flush(); return IRIS::Logger::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; }
// // Handler // INT_32 FnMBTruncate::Handler(CDT * aArguments, const UINT_32 iArgNum, CDT & oCDTRetVal, Logger & oLogger) { if (iArgNum == 2) { const UINT_32 iMaxLen = UINT_32(aArguments[0].GetInt()); const STLW::string sData = aArguments[1].GetString(); CCHAR_P szStart = sData.data(); CCHAR_P szEnd = sData.data() + sData.size(); INT_32 iPos = 0; UINT_32 iCharPos = 0; for(;;) { INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd); if (iCharLen == -3) { break; } // Check character length if (iCharLen < 0) { iCharLen = 1; } // Skip errors else { ++iCharPos; } iPos += iCharLen; if (iCharPos >= iMaxLen) { break; } } if (iCharPos == iMaxLen) { oCDTRetVal = STLW::string(sData, 0, iPos); } else { oCDTRetVal = sData; } return 0; } else if (iArgNum == 3) { const UINT_32 iMaxLen = UINT_32(aArguments[1].GetInt()); STLW::string sData = aArguments[2].GetString(); CCHAR_P szStart = sData.data(); CCHAR_P szEnd = sData.data() + sData.size(); INT_32 iPos = 0; UINT_32 iCharPos = 0; for(;;) { INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd); if (iCharLen == -3) { break; } // Check character length if (iCharLen < 0) { iCharLen = 1; } // Skip errors else { ++iCharPos; } iPos += iCharLen; if (iCharPos >= iMaxLen) { break; } } if (iCharPos >= iMaxLen) { sData = STLW::string(sData, 0, iPos); sData.append(aArguments[0].GetString()); } oCDTRetVal = sData; return 0; } oLogger.Emerg("Usage: MB_TRUNCATE(data, offset) or MB_TRUNCATE(data, offset, add_on)"); return -1; }
// // Handler // INT_32 FnIconv::Handler(CDT * aArguments, const UINT_32 iArgNum, CDT & oCDTRetVal, Logger & oLogger) { UINT_32 iMyArgNum = iArgNum; // 3 or 4 arguments need if (iMyArgNum != 3 && iMyArgNum != 4) { oLogger.Emerg("Usage: ICONV(x, src, dst[, flags])"); return -1; } // Arg 3: flags // Arg 2: destination charset // Arg 1: source charset // Arg 0: string to convert UINT_32 iFlags = 0; #ifdef ICONV_DISCARD_ILSEQ iFlags |= C_ICONV_DISCARD_ILSEQ; #endif #ifdef ICONV_TRANSLITERATE iFlags |= C_ICONV_TRANSLITERATE; #endif if (iMyArgNum == 4) { const STLW::string & sFlags = aArguments[0].GetString(); for (UINT_32 iPos = 0; iPos < sFlags.size(); ++iPos) { switch (sFlags[iPos]) { // Discard illegal sequence and continue case 'i': case 'I': iFlags |= C_ICONV_DISCARD_ILSEQ; break; // Enable transliteration case 't': case 'T': iFlags |= C_ICONV_TRANSLITERATE; break; default: oLogger.Error("Last argument should be 'i', 'I', 't' or 'T', but is `%s`", sFlags.c_str()); return -1; } } } const STLW::string & sTo = aArguments[--iMyArgNum].GetString(); const STLW::string & sFrom = aArguments[--iMyArgNum].GetString(); const STLW::string & sWhat = aArguments[--iMyArgNum].GetString(); STLW::string sFromTo(sFrom); sFromTo.append(sTo); iconv_t oIconvConverter = (iconv_t)(-1); STLW::map<STLW::string, iconv_t>::iterator itmIconvMap = mIconvMap.find(sFromTo); if (itmIconvMap != mIconvMap.end()) { oIconvConverter = itmIconvMap -> second; } // Try to open iconv converter else { oIconvConverter = iconv_open(sFrom.c_str(), sTo.c_str()); if (oIconvConverter != (iconv_t)(-1)) { mIconvMap[sFromTo] = oIconvConverter; } else { if (errno == EINVAL) { oLogger.Error("The conversion from `%s` to `%s` is not supported by the implementation", sFrom.c_str(), sTo.c_str()); } else { oLogger.Error("Error(%d) in iconv_open('%s', '%s'): %s", sFrom.c_str(), sTo.c_str(), strerror(errno)); } return -1; } } #if (_LIBICONV_VERSION >= 0x0108) int iFlag = 1; // Discard illegal characters if (iFlags & C_ICONV_DISCARD_ILSEQ) { if (iconvctl(oIconvConverter, ICONV_SET_DISCARD_ILSEQ, &iFlag) == -1) { oLogger.Error("ICONV_SET_DISCARD_ILSEQ is is not supported by the implementation"); return -1; } } // Ånable transliteration in the conver-sion if (iFlags & C_ICONV_TRANSLITERATE) { if (iconvctl(oIconvConverter, ICONV_SET_TRANSLITERATE, &iFlag) == -1) { oLogger.Error("ICONV_SET_TRANSLITERATE is is not supported by the implementation"); return -1; } } #endif // Allocate memory size_t iSrcLength = sWhat.size(); size_t iDstLength = CTPP_ESCAPE_BUFFER_LEN; char aDstData[CTPP_ESCAPE_BUFFER_LEN]; #if defined(linux) || defined(__APPLE__) char * aSrcData = (char *)sWhat.data(); #else const char * aSrcData = (const char *)sWhat.data(); #endif STLW::string sResult; for (;;) { char * aDstTMP = aDstData; size_t iDstLengthTMP = iDstLength; size_t iResult = iconv(oIconvConverter, &aSrcData, &iSrcLength, &aDstTMP, &iDstLengthTMP); if (aDstTMP - aDstData > 0) { sResult.append(aDstData, aDstTMP - aDstData); } // All data converted? if (iResult != (size_t)-1) { break; } else { if (errno != E2BIG) { ++aSrcData; --iSrcLength; } } } oCDTRetVal = sResult; return 0; }
// // 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_32 FormatString(const STLW::string & sFormatString, STLW::string & sResult, const CDT & oArgs) { using namespace CTPP; StringBuffer oBuffer(sResult); CCHAR_P sPos = sFormatString.data(); CCHAR_P sEnd = sFormatString.data() + sFormatString.size(); CCHAR_P sEndSave = sPos; UINT_32 iPos = 0; for(;;) { INT_32 iWidth = -1; INT_32 iPrecision = -1; CHAR_8 chPadSymbol = ' '; UINT_32 iFmtFlags = 0; eFmtLengths oFmtLengths = F_NONE; eParserState oParserState = C_INITIAL_STATE; // Find "%" at start of token while(sPos != sEnd) { if (*sPos == '%') { oParserState = C_START_FOUND; break; } ++sPos; } oBuffer.Append(sEndSave, sPos); if (oParserState == C_START_FOUND) { ++sPos; // Check end of string if (sPos == sEnd) { return -1; } bool bEndCycle = false; while (!bEndCycle) { // Flags switch(*sPos) { // '-' Left-justify within the given field width; Right justification is the default (see width sub-specifier). case '-': iFmtFlags |= F_LEFT_ALIGN; ++sPos; break; // '+' Forces to preceed the result with a plus or minus sign (+ or -) even for positive numbers. // By default, only negative numbers are preceded with a - sign. case '+': iFmtFlags |= F_FORCE_SIGN; iFmtFlags &= ~F_SIGN_SPACE; ++sPos; break; // ' ' (space) If no sign is going to be written, a blank space is inserted before the value. case ' ': iFmtFlags |= F_SIGN_SPACE; iFmtFlags &= ~F_FORCE_SIGN; ++sPos; break; // '#' Used with o, x or X specifiers the value is preceeded with 0, 0x or 0X respectively for values different than zero. // Used with e, E and f, it forces the written output to contain a decimal point even if no digits would follow. // By default, if no digits follow, no decimal point is written. // Used with g or G the result is the same as with e or E but trailing zeros are not removed. case '#': iFmtFlags |= F_HASH_SIGN; ++sPos; break; // '0' Left-pads the number with zeroes (0) instead of spaces, where padding is specified (see width sub-specifier). case '0': chPadSymbol = '0'; ++sPos; break; default: bEndCycle = true; break; } // Check end of string if (sPos == sEnd) { return -1; } } /* Width * number Minimum number of characters to be printed. If the value to be printed is shorter than this number, * the result is padded with blank spaces. The value is not truncated even if the result is larger. */ if (*sPos > '0' && *sPos <= '9') { iWidth = 0; while (sPos != sEnd && (*sPos >= '0' && *sPos <= '9')) { iWidth = iWidth * 10 + *sPos - '0'; ++sPos; } } /* * '*' The width is not specified in the format string, but as an additional integer value argument * preceding the argument that has to be formatted. */ else if (*sPos == '*') { iWidth = oArgs.GetCDT(iPos).GetInt(); ++iPos; ++sPos; } // Check end of string if (sPos == sEnd) { return -1; } // .precision if (*sPos == '.') { ++sPos; if (sPos == sEnd) { return -1; } iPrecision = 0; if (*sPos >= '0' && *sPos <= '9') { while (sPos != sEnd && (*sPos >= '0' && *sPos <= '9')) { iPrecision = iPrecision * 10 + *sPos - '0'; ++sPos; } } else if (*sPos == '*') { iPrecision = oArgs.GetCDT(iPos).GetInt(); ++iPos; ++sPos; } } // length switch(*sPos) { // h The argument is interpreted as a short int or unsigned short int (only applies to integer specifiers: i, d, o, u, x and X). case 'h': oFmtLengths = F_SHORT; ++sPos; break; // l The argument is interpreted as a long int or unsigned long int for integer specifiers (i, d, o, u, x and X), and as a wide character or wide character string for specifiers c and s. case 'l': // L The argument is interpreted as a long double (only applies to floating point specifiers: e, E, f, g and G). case 'L': { oFmtLengths = F_LONG; ++sPos; if (sPos == sEnd) { return -1; } if (*sPos == 'l' || *sPos == 'L') { oFmtLengths = F_LONG_LONG; ++sPos; } } break; } // Check end of string if (sPos == sEnd) { return -1; } // Specifiers // A % followed by another % character will write % to the string. if (*sPos == '%') { oBuffer.Append(sPos, 1); } else { const CDT oCurrentArgument = oArgs.GetCDT(iPos); ++iPos; switch(*sPos) { // Character 'a' case 'c': FmtChar(oBuffer, oCurrentArgument, iFmtFlags, iWidth, chPadSymbol); break; // 'd' or 'i' Signed decimal integer '392' case 'd': case 'i': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_DECIMAL, 10, iWidth, iPrecision, chPadSymbol); break; // Scientific notation (mantise/exponent) using e character '3.9265e+2' case 'e': FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', iWidth, iPrecision, chPadSymbol); break; // Scientific notation (mantise/exponent) using E character '3.9265E+2' case 'E': FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', iWidth, iPrecision, chPadSymbol); break; // Decimal floating point '392.65' case 'f': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', F_FLOAT_F, iWidth, iPrecision, chPadSymbol); break; // Use the shorter of %e or %f '392.65' case 'g': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', F_FLOAT_G, iWidth, iPrecision, chPadSymbol); break; case 'F': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', F_FLOAT_F, iWidth, iPrecision, chPadSymbol); break; case 'G': FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', F_FLOAT_G, iWidth, iPrecision, chPadSymbol); break; // Signed octal '610' case 'o': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_OCTAL, 8, iWidth, iPrecision, chPadSymbol); break; // String of characters 'sample' case 's': FmtString(oBuffer, oCurrentArgument, iFmtFlags, iWidth, iPrecision, chPadSymbol); break; // Unsigned decimal integer '7235' case 'u': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_UNSIGNED, 10, iWidth, iPrecision, chPadSymbol); break; // Unsigned hexadecimal integer '7fa' case 'x': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_HEX, 16, iWidth, iPrecision, chPadSymbol); break; // Unsigned hexadecimal integer (capital letters) 7FA case 'X': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsUc, F_HEX, 16, iWidth, iPrecision, chPadSymbol); break; // Pointer address 1a2b3c4e case 'p': FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_POINTER, 16, iWidth, iPrecision, chPadSymbol); break; // Invalid format; return error code default: return -1; } ++sPos; } sEndSave = sPos; } if (sPos == sEnd) { break; } } oBuffer.Flush(); return 0; }
// // Get parameters // static INT_32 GetParams(const INT_32 iArgc, CHAR_P * aArgv, STLW::string & sGlobalConfigFile, STLW::string & sConfigFile, STLW::string & sModuleName, bool & bDebugInfo, bool & bPrintHelp, bool & bPrintVersion, bool & bPrintCompileInfo, bool & bDaemonize) { bDebugInfo = bPrintHelp = bPrintVersion = bPrintCompileInfo = false; bDaemonize = true; sConfigFile.erase(); UINT_32 iArgNum = 1; CCHAR_P szArgValue; for(;;) { INT_32 iOption = GetOpt(oOptions, iArgNum, iArgc, aArgv, szArgValue); if (iOption == -1) { break; } switch (iOption) { case 'g': sGlobalConfigFile = szArgValue; break; case 'f': sConfigFile = szArgValue; break; case 'm': sModuleName = szArgValue; break; case 'd': bDebugInfo = true; break; case 'h': bPrintHelp = true; break; case 'v': bPrintVersion = true; break; case 'V': bPrintCompileInfo = true; break; case 'F': bDaemonize = false; break; case '?': fprintf(stderr, "Unknown option `%s` or option with missed argument\n", aArgv[iArgNum]); return EX_CONFIG; break; } } if (sConfigFile.empty()) { // Check environment CCHAR_P szConfigFile = getenv(ENV_CONFIG_FILE); if (szConfigFile != NULL && *szConfigFile != '\0') { sConfigFile = szConfigFile; } if (sConfigFile.empty()) { sConfigFile.assign(DEFAULT_CONFIG_FILE); } } if (sGlobalConfigFile.empty()) { CCHAR_P szConfigFile = getenv("CAS_GLOBAL_CONFIG"); if (szConfigFile != NULL) { fprintf(stderr, "Global config not given, using %s from ENVIRONMENT\n", szConfigFile); sGlobalConfigFile = szConfigFile; } } return EX_OK; }
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; }
// // Handler // INT_32 FnMBSubstring::Handler(CDT * aArguments, const UINT_32 iArgNum, CDT & oCDTRetVal, Logger & oLogger) { // Check number of parameters if (iArgNum == 0) { oCDTRetVal = ""; return 0; } // substr('foobar', 2) -> 'obar' if (iArgNum == 2) { const UINT_32 iOffset = UINT_32(aArguments[0].GetInt()); const STLW::string sResult = aArguments[1].GetString(); CCHAR_P szStart = sResult.data(); CCHAR_P szEnd = sResult.data() + sResult.size(); INT_32 iPos = 0; UINT_32 iCharPos = 0; for(;;) { INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd); if (iCharLen == -3) { break; } // Check character length if (iCharLen < 0) { iCharLen = 1; } // Skip errors else { ++iCharPos; } iPos += iCharLen; if (iCharPos >= iOffset) { break; } } if (iCharPos < iOffset) { oCDTRetVal = ""; } else { oCDTRetVal = sResult.substr(iPos); } return 0; } // substr('foobar', 2, 3) -> 'oba' if (iArgNum == 3) { const UINT_32 iBytes = UINT_32(aArguments[0].GetInt()); const UINT_32 iOffset = UINT_32(aArguments[1].GetInt()); const STLW::string sResult = aArguments[2].GetString(); CCHAR_P szStart = sResult.data(); CCHAR_P szEnd = sResult.data() + sResult.size(); INT_32 iPos = 0; UINT_32 iCharOffset = 0; UINT_32 iCharPos = 0; for(;;) { INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd); if (iCharLen == -3) { break; } // Check character length if (iCharLen < 0) { iCharLen = 1; } // Skip errors else { ++iCharPos; } iPos += iCharLen; if (iCharPos == iOffset) { iCharOffset = iPos; } if (iCharPos == iOffset + iBytes) { break; } } if (sResult.size() < iCharOffset) { oCDTRetVal = ""; } else { oCDTRetVal = sResult.substr(iCharOffset, iPos - iCharOffset); } return 0; } // substr('foobar', 2, 3, '1234567') -> 'fo1234567r' if (iArgNum == 4) { STLW::string sReplacement = aArguments[0].GetString(); const UINT_32 iBytes = UINT_32(aArguments[1].GetInt()); const UINT_32 iOffset = UINT_32(aArguments[2].GetInt()); const STLW::string sTMP = aArguments[3].GetString(); CCHAR_P szStart = sTMP.data(); CCHAR_P szEnd = sTMP.data() + sTMP.size(); UINT_32 iPos = 0; UINT_32 iCharOffset = 0; UINT_32 iCharPos = 0; for(;;) { INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd); if (iCharLen == -3) { break; } // Check character length if (iCharLen < 0) { iCharLen = 1; } // Skip errors else { ++iCharPos; } iPos += iCharLen; if (iCharPos == iOffset) { iCharOffset = iPos; } if (iCharPos == iOffset + iBytes) { break; } } if (sTMP.size() < iCharOffset) { oCDTRetVal = ""; return 0; } STLW::string sResult(sTMP, 0, iCharOffset); sResult.append(sReplacement); if (iPos == sTMP.size()) { oCDTRetVal = sResult; return 0; } sResult.append(sTMP, iPos, STLW::string::npos); oCDTRetVal = sResult; return 0; } oLogger.Emerg("Usage: MB_SUBSTR(x, offset[, bytes[, y]]])"); return -1; }
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; }
// // Compare two strings ingnore case // bool NoCaseCmp::operator()(const STLW::string oX, const STLW::string & oY) const { return Unicode::CompareIgnoreCase(oX.data(), oX.size(), oY.data(), oY.size()) < 0; }