Пример #1
0
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;
}
Пример #2
0
//
// Handler
//
INT_32 FnArrayElement::Handler(CDT            * aArguments,
                               const UINT_32    iArgNum,
                               CDT            & oCDTRetVal,
                               Logger         & oLogger)
{
	// Only 2 args allowed
	if (iArgNum != 2)
	{
		oLogger.Emerg("Usage: ARRAY_ELEMENT(index, array)");
		return -1;
	}

	// Second argument *MUST* be an ARRAY
	if (aArguments[0].GetType() != CDT::ARRAY_VAL)
	{
		oLogger.Error("Second argument MUST be ARRAY");
		return -1;
	}

	// Element index
	const UINT_32 iElement = aArguments[1].GetInt();
	if (aArguments[0].Size() <= iElement)
	{
		oCDTRetVal = CDT();
		return 0;
	}

	// Return element
	oCDTRetVal = aArguments[0][iElement];

return 0;
}
Пример #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;
}
Пример #4
0
//
// Handler
//
INT_32 FnLog::Handler(CDT            * aArguments,
                      const UINT_32    iArgNum,
                      CDT            & oCDTRetVal,
                      Logger         & oLogger)
{
	// Natural logarithm
	if (iArgNum == 1)
	{
		// NaN
		oCDTRetVal = log(aArguments[0].GetFloat());
		return 0;
	}
	// Logarithm with specified base
	else if (iArgNum == 2)
	{
		const W_FLOAT dBase  = aArguments[0].GetFloat();
		const W_FLOAT dValue = aArguments[1].GetFloat();

		// NaN
		if (dBase <= 0) { return (INT_32)log((W_FLOAT)-1); }

		oCDTRetVal = log(dValue) / log(dBase);
		return 0;
	}

	oLogger.Emerg("Usage: LOG(x[, base])");
return -1;
}
Пример #5
0
//
// Handler
//
INT_32 FnSprintf::Handler(CDT            * aArguments,
                          const UINT_32    iArgNum,
                          CDT            & oCDTRetVal,
                          Logger         & oLogger)
{
	if (iArgNum == 0)
	{
		oLogger.Emerg("Usage: SPRINTF(format, a[, b, ...])");
		return -1;
	}

	CDT oArgs(CDT::ARRAY_VAL);
	INT_32 iPos = iArgNum - 2;

	while (iPos >= 0)
	{
		oArgs.PushBack(aArguments[iPos]);
		--iPos;
	}

	STLW::string sResult;
	FormatString(aArguments[iArgNum - 1].GetString(), sResult, oArgs);
	oCDTRetVal = sResult;

return 0;
}
Пример #6
0
//
// Handler
//
INT_32 FnListElement::Handler(CDT            * aArguments,
                              const UINT_32    iArgNum,
                              CDT            & oCDTRetVal,
                              Logger         & oLogger)
{
	if (iArgNum <= 1)
	{
		oLogger.Emerg("Usage: LIST_ELEMENT(data1, data2, ..., element_number); at least 2 arguments need");
		return -1;
	}

	// Element index
	const UINT_32 iLastElement = iArgNum - 1;

	// Element
	const UINT_32 iElement = (UINT_32)aArguments[iLastElement].GetInt();

	// Element does not exist?
	if (iElement >= iLastElement) { return -1; }

	// Return element
	oCDTRetVal = aArguments[iLastElement - iElement - 1];

return 0;
}
Пример #7
0
//
// Handler
//
INT_32 FnGetText::Handler(CDT            * aArguments,
		          const UINT_32    iArgNum,
		          CDT            & oCDTRetVal,
		          Logger         & oLogger)
{
	if (iArgNum == 1)
	{
		oCDTRetVal = gettext(aArguments[0].GetString().c_str());
		return 0;
	}
	else if (iArgNum == 2)
	{
		oCDTRetVal = dgettext(aArguments[1].GetString().c_str(), aArguments[0].GetString().c_str());
		return 0;
	}
	else if (iArgNum == 3)
	{
		oCDTRetVal = ngettext(aArguments[2].GetString().c_str(), aArguments[1].GetString().c_str(), INT_32(aArguments[0].GetInt()));
		return 0;
	}
	else if (iArgNum == 4)
	{
		oCDTRetVal = dngettext(aArguments[3].GetString().c_str(), aArguments[2].GetString().c_str(), aArguments[1].GetString().c_str(), INT_32(aArguments[0].GetInt()));
		return 0;
	}

	oLogger.Emerg("Usage: GETTEXT(message), GETTEXT(domain, message) or GETTEXT(message, message-plural, n)");
	return -1;
}
Пример #8
0
//
// Handler
//
INT_32 FnDefined::Handler(CDT            * aArguments,
                          const UINT_32    iArgNum,
                          CDT            & oCDTRetVal,
                          Logger         & oLogger)
{
	// At least one argument need
	if (iArgNum == 0)
	{
		oLogger.Emerg("Usage: DEFINED(a[, b, ...])");
		return -1;
	}

	oCDTRetVal = 1;

	INT_32 iI = iArgNum - 1;
	for (; iI >= 0; --iI)
	{
		if (aArguments[iI].GetType() == CDT::UNDEF)
		{
			oCDTRetVal = 0;
			break;
		}
	}

return 0;
}
Пример #9
0
//
// Handler
//
INT_32 FnInSet::Handler(CDT            * aArguments,
                        const UINT_32    iArgNum,
                        CDT            & oCDTRetVal,
                        Logger         & oLogger)
{
	if (iArgNum <= 1)
	{
		oLogger.Emerg("Usage: IN_SET(x, a[, b, ...])");
		return -1;
	}

	INT_32 iI = iArgNum - 1;

	CDT & oCDT1 = aArguments[iI];

	--iI;
	for (; iI >= 0; --iI)
	{
		if (oCDT1.Equal(aArguments[iI]))
		{
			oCDTRetVal = 1;
			return 0;
		}
	}

	oCDTRetVal = 0;
return 0;
}
Пример #10
0
//
// Setup server: create sockets, load modules, etc
//
INT_32 MainProcess::Setup(Logger  & oLogger,
                          bool    & bLoggerStarted)
{
	// Initialize loggers, before of all other modules
	oLogger.Info("Starting logger subsystem");
	STLW::vector<ModuleConfig>::const_iterator itvLoggers = oGlobalContext.config.loggers.begin();
	while (itvLoggers != oGlobalContext.config.loggers.end())
	{
		const INT_32 iRC = LoadModule(itvLoggers -> type,
		                              itvLoggers -> name,
		                              itvLoggers -> library,
		                              itvLoggers -> driver,
		                              itvLoggers -> params,
		                              oGlobalContext.config.libexec_dirs,
		                              oLogger);
		if (iRC != 0) { return iRC; }
		oLogger.Info("Logger `%s` started", itvLoggers -> name.c_str());
		++itvLoggers;
	}

	// Get logger from factory for main process
	Object * pObject = oGlobalContext.factory.GetObject("Logger/" + oGlobalContext.config.logger_type);
	if (pObject == NULL)
	{
		oLogger.Emerg("Can't get main process logger `%s`", oGlobalContext.config.logger_type.c_str());
		return -1;
	}

	oLogger.Info("Logger subsystem started");

	// Start logger subsystem
	oGlobalContext.error_log  = static_cast<LoggerObject *>(pObject) -> GetErrorLog(NULL);
	oGlobalContext.error_log -> Notice("Log started");

	oGlobalContext.transfer_log = static_cast<LoggerObject *>(pObject) -> GetCustomLog(NULL);
	oGlobalContext.transfer_log -> Notice("Log started");

	bLoggerStarted = true;

	// Load modules
	oGlobalContext.error_log -> Info("Starting modules");
	STLW::vector<ModuleConfig>::const_iterator itvModules = oGlobalContext.config.modules.begin();
	while(itvModules != oGlobalContext.config.modules.end())
	{
		const INT_32 iRC = LoadModule(itvModules -> type,
		                              itvModules -> name,
		                              itvModules -> library,
		                              itvModules -> driver,
		                              itvModules -> params,
		                              oGlobalContext.config.libexec_dirs,
		                             *oGlobalContext.error_log);
		if (iRC != 0) { return iRC; }

		++itvModules;
	}
	oGlobalContext.error_log -> Info("All modules started");

return 0;
}
Пример #11
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;
}
Пример #12
0
//
// Handler
//
INT_32 FnContext::Handler(CDT            * aArguments,
                          const UINT_32    iArgNum,
                          CDT            & oCDTRetVal,
                          Logger         & oLogger)
{
    if (iArgNum != 0)
    {
		oLogger.Emerg("Usage: CONTEXT()");
        return -1;
    }
    oCDTRetVal = *pCDT;

return 0;
}
Пример #13
0
//
// Handler
//
INT_32 FnBase64Decode::Handler(CDT            * aArguments,
                               const UINT_32    iArgNum,
                               CDT            & oCDTRetVal,
                               Logger         & oLogger)
{
	// Only 1 argument
	if (iArgNum != 1)
	{
		oLogger.Emerg("Usage: BASE64_DECODE(x)");
		return -1;
	}

	oCDTRetVal = Base64Decode(aArguments[0].GetString());

return 0;
}
Пример #14
0
//
// Handler
//
INT_32 FnHashElement::Handler(CDT            * aArguments,
                              const UINT_32    iArgNum,
                              CDT            & oCDTRetVal,
                              Logger         & oLogger)
{
	if (iArgNum <= 1)
	{
		oLogger.Emerg("Usage: HASH_ELEMENT(index, hash); 2 arguments need");
		return -1;
	}

	// Return element
	oCDTRetVal = aArguments[0].GetCDT(aArguments[1].GetString());

return 0;
}
Пример #15
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;
}
Пример #16
0
//
// Handler
//
INT_32 FnJSON::Handler(CDT            * aArguments,
                       const UINT_32    iArgNum,
                       CDT            & oCDTRetVal,
                       Logger         & oLogger)
{
	if (iArgNum != 1)
	{
		oLogger.Emerg("Usage: JSON(data)");
		return -1;
	}

	STLW::string sData;

	CDT2JSON(aArguments[0], sData);

	oCDTRetVal = sData;

return 0;
}
Пример #17
0
//
// Handler
//
INT_32 FnMin::Handler(CDT            * aArguments,
                      const UINT_32    iArgNum,
                      CDT            & oCDTRetVal,
                      Logger         & oLogger)
{
	if (iArgNum == 0)
	{
		oLogger.Emerg("Usage: MIN(a[, b, ...])");
		return -1;
	}

	INT_32  iMinPos = 0;
	W_FLOAT dMinVal = aArguments[0].GetFloat();
	for (UINT_32 iPos = 0; iPos < iArgNum; ++iPos)
	{
		const W_FLOAT dCurVal = aArguments[iPos].GetFloat();
		if (dCurVal < dMinVal) { iMinPos = iPos; dMinVal = dCurVal; }
	}

	oCDTRetVal = aArguments[iMinPos];

return 0;
}
Пример #18
0
//
// Handler
//
INT_32 FnMax::Handler(CDT            * aArguments,
                      const UINT_32    iArgNum,
                      CDT            & oCDTRetVal,
                      Logger         & oLogger)
{
	if (iArgNum == 0)
	{
		oLogger.Emerg("Usage: MAX(data1, data2, ..., dataN); at least 1 argument need");
		return -1;
	}

	INT_32  iMaxPos = 0;
	W_FLOAT dMaxVal = aArguments[0].GetFloat();
	for (UINT_32 iPos = 0; iPos < iArgNum; ++iPos)
	{
		const W_FLOAT dCurVal = aArguments[iPos].GetFloat();
		if (dCurVal > dMaxVal) { iMaxPos = iPos; dMaxVal = dCurVal; }
	}

	oCDTRetVal = aArguments[iMaxPos];

return 0;
}
Пример #19
0
//
// Handler
//
INT_32 FnGetText_::Handler(CDT            * aArguments,
                          const UINT_32    iArgNum,
                          CDT            & oCDTRetVal,
                          Logger         & oLogger)
{
	if (iArgNum == 1)
	{
		oCDTRetVal = gettext(aArguments[0].GetString().c_str());
		return 0;
	}
	else if (iArgNum == 2)
	{
		oCDTRetVal = dgettext(aArguments[1].GetString().c_str(), aArguments[0].GetString().c_str());
		return 0;
	}
	else if (iArgNum == 3)
	{
		oCDTRetVal = dcgettext(aArguments[2].GetString().c_str(), aArguments[1].GetString().c_str(), INT_32(aArguments[3].GetInt()));
		return 0;
	}

	oLogger.Emerg("Usage: _(message) or _(message, domain) or _(message, domain, category)");
return -1;
}
Пример #20
0
//
// Handler
//
INT_32 FnAvg::Handler(CDT            * aArguments,
                      const UINT_32    iArgNum,
                      CDT            & oCDTRetVal,
                      Logger         & oLogger)
{
	// Need at least 2 args
	if (iArgNum < 2)
	{
		oLogger.Emerg("Usage: AVG(data1, data2, ..., dataN, '[aAgGhHqQ]')");
		return -1;
	}

	// First Arg 1: destination type
	const STLW::string & sWhat = aArguments[iArgNum - 1].GetString();
	if (sWhat.length() == 0)
	{
		oLogger.Error("Last argument should be 'a', 'A', 'g', 'G', 'h', 'H', 'q' or 'Q', but is `%s`", sWhat.c_str());
		return -1;
	}

	// http://en.wikipedia.org/wiki/Average
	switch (sWhat[0])
	{
		// Arithmetic
		case 'A':
		case 'a':
			{
				W_FLOAT  dSum = 0.0;
				for(INT_32 iPos = iArgNum - 2; iPos >= 0 ; --iPos)
				{
					dSum += aArguments[iPos].GetFloat();
				}
				oCDTRetVal = dSum / (iArgNum - 1);
			}
			break;

		// Geometric
		case 'G':
		case 'g':
			{
				W_FLOAT  dSum = 1.0;
				for(INT_32 iPos = iArgNum - 2; iPos >= 0 ; --iPos)
				{
					dSum *= aArguments[iPos].GetFloat();
				}
				oCDTRetVal = pow(dSum, 1.0 / (iArgNum - 1));
			}
			break;

		// Harmonic
		case 'H':
		case 'h':
			{
				W_FLOAT  dSum = 0.0;
				for(INT_32 iPos = iArgNum - 2; iPos >= 0 ; --iPos)
				{
					const W_FLOAT dTMP = aArguments[iPos].GetFloat();
					if (dTMP == 0.0) { dSum = 0; break; }
					dSum += 1.0 / dTMP;
				}
				oCDTRetVal = 1.0 * (iArgNum - 1) / dSum;
			}
			break;

		// Quadratic
		case 'Q':
		case 'q':
			{
				W_FLOAT  dSum = 0.0;
				for(INT_32 iPos = iArgNum - 1; iPos >= 0 ; --iPos)
				{
					const W_FLOAT dTMP = aArguments[iPos].GetFloat();
					dSum += dTMP * dTMP;
				}
				oCDTRetVal = sqrt(dSum / (iArgNum - 1));
			}
			break;

		default:
			oLogger.Error("Last argument should be 'a', 'A', 'g', 'G', 'h', 'H', 'q' or 'Q', but is `%s`", sWhat.c_str());
			return -1;
	}

return 0;
}
Пример #21
0
//
// Get configuration from variant data type
//
ServiceConfig::State ServiceConfig::GetConfig(const VariantNC  & oData,
                                              ServiceConfig    & oServiceConfig,
                                              Logger           & oLogger)
{
	// Allow connection from specified IP's or subnets
	if (ParseNetworks(oData, "AllowConnect", oServiceConfig, oServiceConfig.ipv4_allowed_networks, oLogger) != OK)
	{
		return CONFIG_ERROR;
	}

	// Deny connection from specified IP's or subnets
	if (ParseNetworks(oData, "DenyConnect", oServiceConfig, oServiceConfig.ipv4_denied_networks, oLogger) != OK)
	{
		return CONFIG_ERROR;
	}

	// Order of networks check
	oServiceConfig.allow_deny_order = ALLOW_DENY;

	const STLW::vector<STLW::string> vDenyAllow = oData["AllowDenyOrder"];
	if (!vDenyAllow.empty() && vDenyAllow[0] != "")
	{
		if (vDenyAllow.size() != 2)
		{
		 	oLogger.Emerg("Invalid format of parameter `Service/%s/AllowDenyOrder`: need `allow deny` or `deny allow`", oServiceConfig.name.c_str());
		 	return CONFIG_ERROR;
		}

		if (Unicode::CompareIgnoreCase(vDenyAllow[0].data(), vDenyAllow[0].size(), "deny", sizeof("deny") - 1) == 0)
		{
			oServiceConfig.allow_deny_order = DENY_ALLOW;
		}
	}

	// Listen to inteface
	STLW::vector<STLW::string> vListen;
	ConfigHelper::GetList(oData["Listen"], vListen);
	STLW::vector<STLW::string>::const_iterator itvListen = vListen.begin();
	while(itvListen != vListen.end())
	{
		ListenInterface  oInterface;
		ConfigHelper::State oRC = ConfigHelper::ParseAddress(*itvListen, oInterface.af, oInterface.address, oInterface.port);
		if (oRC != ConfigHelper::OK)
		{
			oLogger.Emerg("Invalid address: `%s`", itvListen -> c_str());
			return CONFIG_ERROR;
		}
		oServiceConfig.listen.push_back(oInterface);
		++itvListen;
	}
	// Socket listen queue
	oServiceConfig.listen_queue = oData["MaxQueueLength"];
	if (oServiceConfig.listen_queue == 0)
	{
		oLogger.Emerg("Invalid format of parameter `Service/%s/MaxQueueLength` not set", oServiceConfig.name.c_str());
		return CONFIG_ERROR;
	}

	// Read buffer size
	oServiceConfig.recv_buffer_size = ConfigHelper::ParseSize(oData["RecvBufferSize"]);
	if (oServiceConfig.recv_buffer_size == 0 || oServiceConfig.recv_buffer_size == UINT_32(-1))
	{
		oLogger.Emerg("Invalid format of parameter `Service/%s/RecvBufferSize` not set", oServiceConfig.name.c_str());
		return CONFIG_ERROR;
	}

	//  Maximum number of connections for this service
	oServiceConfig.max_clients    = oData["MaxClients"];
	if (oServiceConfig.max_clients == 0) { oLogger.Warn("Parameter `Service/%s/MaxClients`: not set", oServiceConfig.name.c_str()); }

	// Number of active clients
	oServiceConfig.active_clients = 0;

	// Read/Write timeout
	oServiceConfig.io_timeout = ConfigHelper::ParseTimeout(oData["IOTimeout"]) / 1000.0;
	if (oServiceConfig.io_timeout == 0)
	{
		oLogger.Emerg("Parameter `Service/%s/IOTimeout`: need to set positive value", oServiceConfig.name.c_str());
		return CONFIG_ERROR;
	}

#ifdef IRIS_TLS_SUPPORT
	// TLS parameters
	oServiceConfig.enable_ssl_tls = ConfigHelper::ParseBool(oData["EnableTLSSSL"]);
	if (oServiceConfig.enable_ssl_tls)
	{
		// File with the RSA certificate in PEM format.
		oServiceConfig.tls_cert_file = oData["TLSCertFile"];
		// File with the RSA private key in PEM format
		oServiceConfig.tls_key_file  = oData["TLSKeyFile"];
		// File with the DH data
		oServiceConfig.dh_file.assign(oData["DHFile"]);
		// SSL Ciphers
		oServiceConfig.ciphers.assign(oData["SSLCiphers"]);

		if (oServiceConfig.tls_cert_file.size() != oServiceConfig.tls_key_file.size())
		{
			oLogger.Emerg("Number of files `Service/%s/TLSCertFile` and Service/%s/TLSKeyFile` must be equal", oServiceConfig.name.c_str());
			return CONFIG_ERROR;
		}

		// Use Transport Level Security at connection time
		oServiceConfig.use_tls               = ConfigHelper::ParseBool(oData["UseTLS"]);
		// Allow upgrade an existing insecure connection to a secure connection using SSL/TLS
		oServiceConfig.start_tls             = ConfigHelper::ParseBool(oData["StartTLS"]);
		// Prefer to user server ciphers
		oServiceConfig.prefer_server_ciphers = ConfigHelper::ParseBool(oData["PreferServerCiphers"], true);
	}
#endif // IRIS_TLS_SUPPORT

	// Handler name
	oServiceConfig.handler_name.assign(oData["Handler"]);
	// Handler object
	oServiceConfig.handler = NULL;

return OK;
}
Пример #22
0
//
// Handler
//
INT_32 FnRandom::Handler(CDT            * aArguments,
                         const UINT_32    iArgNum,
                         CDT            & oCDTRetVal,
                         Logger         & oLogger)
{
	// 0 .. MAX(unsigned long)
	if (iArgNum == 0)
	{
		oCDTRetVal = UINT_64(random());
		return 0;
	}
	// RAND(x) -> 0 .. RAND(x)
	else if (iArgNum == 1)
	{
		const CDT & oFirstArg = aArguments[0];
		// Integer value
		if (oFirstArg.GetType() == CDT::INT_VAL)
		{
			oCDTRetVal = INT_64(random() % oFirstArg.GetInt());
			return 0;
		}
		// Floating point value
		else if (oFirstArg.GetType() == CDT::REAL_VAL)
		{
			oCDTRetVal = W_FLOAT(oFirstArg.GetFloat() * (random() % UINT_64(RAND_MAX)) / UINT_64(RAND_MAX));
			return 0;
		}

		// Invalid data type, just return 0
		oCDTRetVal = 0;
		return 0;
	}
	// RAND(x, y) -> x .. y
	else if (iArgNum == 2)
	{
		const CDT & oFirstArg  = aArguments[1];
		const CDT & oSecondArg = aArguments[0];

		// x and y is integer values
		if (oFirstArg.GetType()  == CDT::INT_VAL &&
		    oSecondArg.GetType() == CDT::INT_VAL)
		{
			const UINT_64 iFirst    = oFirstArg.GetInt();
			const UINT_64 iInterval = oSecondArg.GetInt() - iFirst;

			oCDTRetVal = INT_64(random() % iInterval + iFirst);
			return 0;
		}
		// x or y (or both) are floating point value
		else if ((oFirstArg.GetType() == CDT::REAL_VAL && oSecondArg.GetType() == CDT::INT_VAL)  ||
		         (oFirstArg.GetType() == CDT::INT_VAL  && oSecondArg.GetType() == CDT::REAL_VAL) ||
		         (oFirstArg.GetType() == CDT::REAL_VAL && oSecondArg.GetType() == CDT::REAL_VAL))
		{
			const W_FLOAT dFirst    = oFirstArg.GetFloat();
			const W_FLOAT dInterval = oSecondArg.GetFloat() - dFirst;

			oCDTRetVal = W_FLOAT(dInterval * (random() % UINT_64(RAND_MAX)) / UINT_64(RAND_MAX) + dFirst);
			return 0;
		}

		// Invalid data type, just return 0
		oCDTRetVal = 0;
		return 0;
	}

	oLogger.Emerg("Usage: RANDOM([[min,] max])");
return -1;
}
Пример #23
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;
}
Пример #24
0
	INT_32 FN_CoNaN::Usage(Logger &logger) {
		logger.Emerg("Usage: CoNaN(N, LIST(\"язык\", \"языка\", \"языков\"), [concat_num = true]) or CoNaN(N, \"язык\", \"языка\", \"языков\", [concat_num = true])");
		return -1;
	}
Пример #25
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;
}
Пример #26
0
//
// Handler
//
INT_32 FnCast::Handler(CDT            * aArguments,
                       const UINT_32    iArgNum,
                       CDT            & oCDTRetVal,
                       Logger         & oLogger)
{
	// 2 arguments need
	if (iArgNum != 2)
	{
		oLogger.Emerg("Usage: CAST(flag, x)");
		return -1;
	}

	// Arg 1: destination type
	const STLW::string & sWhat = aArguments[1].GetString();
	if (sWhat.length() == 0)
	{
		oLogger.Error("The last argument should be 's', 'S', 'o', 'O', 'd', 'D', 'i', 'I', 'h', 'H', 'f' or 'F', but is `%s`", sWhat.c_str());
		return -1;
	}

	CDT & oTMP = aArguments[0];
	switch(sWhat[0])
	{
		// S[tring]
		case 'S':
		case 's':
			oCDTRetVal = oTMP.GetString();
			return 0;

		// O[ct[al]]
		case 'o':
		case 'O':
			if      (oTMP.GetType() <= CDT::REAL_VAL)   { oCDTRetVal = oTMP.GetInt(); return 0; }
			else if (oTMP.GetType() == CDT::STRING_VAL)
			{
				unsigned long long iLL = 0;
				sscanf(oTMP.GetString().c_str(), "%llo", &iLL);
				oCDTRetVal = INT_64(iLL);
				return 0;
			}
			oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
			return -1;

		// D[ec[imal]]
		case 'd':
		case 'D':
			if      (oTMP.GetType() <= CDT::REAL_VAL)   { oCDTRetVal = oTMP.GetInt(); return 0; }
			else if (oTMP.GetType() == CDT::STRING_VAL)
			{
				long long iLL = 0;
				sscanf(oTMP.GetString().c_str(), "%lld", &iLL);
				oCDTRetVal = INT_64(iLL);
				return 0;
			}
			oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
			return -1;

		// I[nt[eger]]
		case 'i':
		case 'I':
			if      (oTMP.GetType() <= CDT::REAL_VAL)   { oCDTRetVal = oTMP.GetInt(); return 0; }
			else if (oTMP.GetType() == CDT::STRING_VAL)
			{
				long long iLL = 0;
				sscanf(oTMP.GetString().c_str(), "%lli", &iLL);
				oCDTRetVal = INT_64(iLL);
				return 0;
			}
			oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
			return -1;

		// H[ex[adecimal]]
		case 'H':
		case 'h':
			if      (oTMP.GetType() <= CDT::REAL_VAL)   { oCDTRetVal = oTMP.GetInt(); return 0; }
			else if (oTMP.GetType() == CDT::STRING_VAL)
			{
				unsigned long long iLL = 0;
				sscanf(oTMP.GetString().c_str(), "%llx", &iLL);
				oCDTRetVal = INT_64(iLL);
				return 0;
			}
			oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
			return -1;

		// F[loat]
		case 'F':
		case 'f':
			if      (oTMP.GetType() <= CDT::REAL_VAL)   { oCDTRetVal = oTMP.GetFloat(); return 0; }
			else if (oTMP.GetType() == CDT::STRING_VAL)
			{
				double dVal = 0;
				sscanf(oTMP.GetString().c_str(), "%lg", &dVal);
				oCDTRetVal = dVal;
				return 0;
			}
			oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
			return -1;

		// Error
		default:
			oLogger.Error("The last argument should be 's', 'S', 'o', 'O', 'd', 'D', 'i', 'I', 'h', 'H', 'f' or 'F', but is `%s`", sWhat.c_str());
			return -1;
	}
}
Пример #27
0
//
// 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;
}
Пример #28
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;
}