// // 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; }
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; }
// // 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; }
// // 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; }
// // 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; }
// // 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; }
// // 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; }
// // 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; }
// // 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; }