Esempio n. 1
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;
}
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;
}
Esempio n. 3
0
//
// 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;
}
Esempio n. 4
0
//
// 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;
}
Esempio n. 5
0
//
// 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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 9
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;
}