void Notification::Validate(int types, const ValidationUtils& utils) { ObjectImpl<Notification>::Validate(types, utils); if (!(types & FAConfig)) return; Array::Ptr users = GetUsersRaw(); Array::Ptr groups = GetUserGroupsRaw(); if ((!users || users->GetLength() == 0) && (!groups || groups->GetLength() == 0)) BOOST_THROW_EXCEPTION(ValidationError(this, std::vector<String>(), "Validation failed: No users/user_groups specified.")); }
Value HttpUtility::GetLastParameter(const Dictionary::Ptr& params, const String& key) { Value varr = params->Get(key); if (!varr.IsObjectType<Array>()) return varr; Array::Ptr arr = varr; if (arr->GetLength() == 0) return Empty; else return arr->Get(arr->GetLength() - 1); }
bool HostGroup::ResolveGroupMembership(const Host::Ptr& host, bool add, int rstack) { if (add && rstack > 20) { Log(LogWarning, "HostGroup") << "Too many nested groups for group '" << GetName() << "': Host '" << host->GetName() << "' membership assignment failed."; return false; } Array::Ptr groups = GetGroups(); if (groups && groups->GetLength() > 0) { ObjectLock olock(groups); for (const String& name : groups) { HostGroup::Ptr group = HostGroup::GetByName(name); if (group && !group->ResolveGroupMembership(host, add, rstack + 1)) return false; } } if (add) AddMember(host); else RemoveMember(host); return true; }
static inline ExpressionResult For(ScriptFrame& frame, const String& fkvar, const String& fvvar, const Value& value, Expression *expression, const DebugInfo& debugInfo = DebugInfo()) { if (value.IsObjectType<Array>()) { if (!fvvar.IsEmpty()) BOOST_THROW_EXCEPTION(ScriptError("Cannot use dictionary iterator for array.", debugInfo)); Array::Ptr arr = value; for (Array::SizeType i = 0; i < arr->GetLength(); i++) { frame.Locals->Set(fkvar, arr->Get(i)); ExpressionResult res = expression->Evaluate(frame); CHECK_RESULT_LOOP(res); } } else if (value.IsObjectType<Dictionary>()) { if (fvvar.IsEmpty()) BOOST_THROW_EXCEPTION(ScriptError("Cannot use array iterator for dictionary.", debugInfo)); Dictionary::Ptr dict = value; std::vector<String> keys; { ObjectLock olock(dict); BOOST_FOREACH(const Dictionary::Pair& kv, dict) { keys.push_back(kv.first); } } BOOST_FOREACH(const String& key, keys) { frame.Locals->Set(fkvar, key); frame.Locals->Set(fvvar, dict->Get(key)); ExpressionResult res = expression->Evaluate(frame); CHECK_RESULT_LOOP(res); }
/** * Executes the auto completion script via HTTP and returns HTTP and user errors. * * @param session Local session handler. * @param command The auto completion string. * @param sandboxed Whether to run this sandboxed. * @return Result value, also contains user errors. */ Array::Ptr ConsoleCommand::AutoCompleteScript(const String& session, const String& command, bool sandboxed) { /* Extend the url parameters for the request. */ l_Url->SetPath({ "v1", "console", "auto-complete-script" }); l_Url->SetQuery({ {"session", session}, {"command", command}, {"sandboxed", sandboxed ? "1" : "0"} }); Dictionary::Ptr jsonResponse = SendRequest(); /* Extract the result, and handle user input errors too. */ Array::Ptr results = jsonResponse->Get("results"); Array::Ptr suggestions; if (results && results->GetLength() > 0) { Dictionary::Ptr resultInfo = results->Get(0); if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) { suggestions = resultInfo->Get("suggestions"); } else { String errorMessage = resultInfo->Get("status"); BOOST_THROW_EXCEPTION(ScriptError(errorMessage)); } } return suggestions; }
bool Value::ToBool(void) const { switch (GetType()) { case ValueNumber: return static_cast<bool>(boost::get<double>(m_Value)); case ValueBoolean: return boost::get<bool>(m_Value); case ValueString: return !boost::get<String>(m_Value).IsEmpty(); case ValueObject: if (IsObjectType<Dictionary>()) { Dictionary::Ptr dictionary = *this; return dictionary->GetLength() > 0; } else if (IsObjectType<Array>()) { Array::Ptr array = *this; return array->GetLength() > 0; } else { return true; } case ValueEmpty: return false; default: BOOST_THROW_EXCEPTION(std::runtime_error("Invalid variant type.")); } }
void ConfigWriter::EmitScope(std::ostream& fp, int indentLevel, const Dictionary::Ptr& val, const Array::Ptr& imports) { fp << "{"; if (imports && imports->GetLength() > 0) { ObjectLock xlock(imports); BOOST_FOREACH(const Value& import, imports) { fp << "\n"; EmitIndent(fp, indentLevel); fp << "import \"" << import << "\""; }
void Zone::ValidateEndpointsRaw(const Array::Ptr& value, const ValidationUtils& utils) { ObjectImpl<Zone>::ValidateEndpointsRaw(value, utils); if (value && value->GetLength() > 2) { Log(LogWarning, "Zone") << "The Zone object '" << GetName() << "' has more than two endpoints." << " Due to a known issue this type of configuration is strongly" << " discouraged and may cause Icinga to use excessive amounts of CPU time."; } }
void ApiClient::ExecuteScriptHttpCompletionCallback(HttpRequest& request, HttpResponse& response, const ExecuteScriptCompletionCallback& callback) { Dictionary::Ptr result; String body; char buffer[1024]; size_t count; while ((count = response.ReadBody(buffer, sizeof(buffer))) > 0) body += String(buffer, buffer + count); try { if (response.StatusCode < 200 || response.StatusCode > 299) { std::string message = "HTTP request failed; Code: " + Convert::ToString(response.StatusCode) + "; Body: " + body; BOOST_THROW_EXCEPTION(ScriptError(message)); } result = JsonDecode(body); Array::Ptr results = result->Get("results"); Value result; String errorMessage = "Unexpected result from API."; if (results && results->GetLength() > 0) { Dictionary::Ptr resultInfo = results->Get(0); errorMessage = resultInfo->Get("status"); if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) { result = resultInfo->Get("result"); } else { DebugInfo di; Dictionary::Ptr debugInfo = resultInfo->Get("debug_info"); if (debugInfo) { di.Path = debugInfo->Get("path"); di.FirstLine = debugInfo->Get("first_line"); di.FirstColumn = debugInfo->Get("first_column"); di.LastLine = debugInfo->Get("last_line"); di.LastColumn = debugInfo->Get("last_column"); } bool incompleteExpression = resultInfo->Get("incomplete_expression"); BOOST_THROW_EXCEPTION(ScriptError(errorMessage, di, incompleteExpression)); } } callback(boost::exception_ptr(), result); } catch (const std::exception&) { callback(boost::current_exception(), Empty); } }
static Value ArrayReduce(const Function::Ptr& function) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast<Array::Ptr>(vframe->Self); if (vframe->Sandboxed && !function->IsSideEffectFree()) BOOST_THROW_EXCEPTION(ScriptError("Reduce function must be side-effect free.")); if (self->GetLength() == 0) return Empty; Value result = self->Get(0); ObjectLock olock(self); for (size_t i = 1; i < self->GetLength(); i++) { std::vector<Value> args; args.push_back(result); args.push_back(self->Get(i)); result = function->Invoke(args); } return result; }
double ScriptUtils::Len(const Value& value) { if (value.IsObjectType<Dictionary>()) { Dictionary::Ptr dict = value; return dict->GetLength(); } else if (value.IsObjectType<Array>()) { Array::Ptr array = value; return array->GetLength(); } else if (value.IsString()) { return Convert::ToString(value).GetLength(); } else { return 0; } }
/** * Executes the DSL script via HTTP and returns HTTP and user errors. * * @param session Local session handler. * @param command The DSL string. * @param sandboxed Whether to run this sandboxed. * @return Result value, also contains user errors. */ Value ConsoleCommand::ExecuteScript(const String& session, const String& command, bool sandboxed) { /* Extend the url parameters for the request. */ l_Url->SetPath({"v1", "console", "execute-script"}); l_Url->SetQuery({ {"session", session}, {"command", command}, {"sandboxed", sandboxed ? "1" : "0"} }); Dictionary::Ptr jsonResponse = SendRequest(); /* Extract the result, and handle user input errors too. */ Array::Ptr results = jsonResponse->Get("results"); Value result; if (results && results->GetLength() > 0) { Dictionary::Ptr resultInfo = results->Get(0); if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) { result = resultInfo->Get("result"); } else { String errorMessage = resultInfo->Get("status"); DebugInfo di; Dictionary::Ptr debugInfo = resultInfo->Get("debug_info"); if (debugInfo) { di.Path = debugInfo->Get("path"); di.FirstLine = debugInfo->Get("first_line"); di.FirstColumn = debugInfo->Get("first_column"); di.LastLine = debugInfo->Get("last_line"); di.LastColumn = debugInfo->Get("last_column"); } bool incompleteExpression = resultInfo->Get("incomplete_expression"); BOOST_THROW_EXCEPTION(ScriptError(errorMessage, di, incompleteExpression)); } } return result; }
Array::Ptr LegacyTimePeriod::ScriptFunc(const TimePeriod::Ptr& tp, double begin, double end) { Array::Ptr segments = new Array(); Dictionary::Ptr ranges = tp->GetRanges(); if (ranges) { for (int i = 0; i <= (end - begin) / (24 * 60 * 60); i++) { time_t refts = begin + i * 24 * 60 * 60; tm reference = Utility::LocalTime(refts); #ifdef I2_DEBUG Log(LogDebug, "LegacyTimePeriod") << "Checking reference time " << refts; #endif /* I2_DEBUG */ ObjectLock olock(ranges); for (const Dictionary::Pair& kv : ranges) { if (!IsInDayDefinition(kv.first, &reference)) { #ifdef I2_DEBUG Log(LogDebug, "LegacyTimePeriod") << "Not in day definition '" << kv.first << "'."; #endif /* I2_DEBUG */ continue; } #ifdef I2_DEBUG Log(LogDebug, "LegacyTimePeriod") << "In day definition '" << kv.first << "'."; #endif /* I2_DEBUG */ ProcessTimeRanges(kv.second, &reference, segments); } } } Log(LogDebug, "LegacyTimePeriod") << "Legacy timeperiod update returned " << segments->GetLength() << " segments."; return segments; }
void ApiClient::AutocompleteScriptHttpCompletionCallback(HttpRequest& request, HttpResponse& response, const AutocompleteScriptCompletionCallback& callback) { Dictionary::Ptr result; String body; char buffer[1024]; size_t count; while ((count = response.ReadBody(buffer, sizeof(buffer))) > 0) body += String(buffer, buffer + count); try { if (response.StatusCode < 200 || response.StatusCode > 299) { std::string message = "HTTP request failed; Code: " + Convert::ToString(response.StatusCode) + "; Body: " + body; BOOST_THROW_EXCEPTION(ScriptError(message)); } result = JsonDecode(body); Array::Ptr results = result->Get("results"); Array::Ptr suggestions; String errorMessage = "Unexpected result from API."; if (results && results->GetLength() > 0) { Dictionary::Ptr resultInfo = results->Get(0); errorMessage = resultInfo->Get("status"); if (resultInfo->Get("code") >= 200 && resultInfo->Get("code") <= 299) suggestions = resultInfo->Get("suggestions"); else BOOST_THROW_EXCEPTION(ScriptError(errorMessage)); } callback(boost::exception_ptr(), suggestions); } catch (const std::exception&) { callback(boost::current_exception(), nullptr); } }
bool Zone::IsSingleInstance() const { Array::Ptr endpoints = GetEndpointsRaw(); return !endpoints || endpoints->GetLength() < 2; }
std::pair<Dictionary::Ptr, Dictionary::Ptr> ApiListener::GetStatus() { Dictionary::Ptr perfdata = new Dictionary(); /* cluster stats */ double allEndpoints = 0; Array::Ptr allNotConnectedEndpoints = new Array(); Array::Ptr allConnectedEndpoints = new Array(); Zone::Ptr my_zone = Zone::GetLocalZone(); Dictionary::Ptr connectedZones = new Dictionary(); for (const Zone::Ptr& zone : ConfigType::GetObjectsByType<Zone>()) { /* only check endpoints in a) the same zone b) our parent zone c) immediate child zones */ if (my_zone != zone && my_zone != zone->GetParent() && zone != my_zone->GetParent()) { Log(LogDebug, "ApiListener") << "Not checking connection to Zone '" << zone->GetName() << "' because it's not in the same zone, a parent or a child zone."; continue; } bool zoneConnected = false; int countZoneEndpoints = 0; double zoneLag = 0; ArrayData zoneEndpoints; for (const Endpoint::Ptr& endpoint : zone->GetEndpoints()) { zoneEndpoints.emplace_back(endpoint->GetName()); if (endpoint->GetName() == GetIdentity()) continue; double eplag = CalculateZoneLag(endpoint); if (eplag > 0 && eplag > zoneLag) zoneLag = eplag; allEndpoints++; countZoneEndpoints++; if (!endpoint->GetConnected()) { allNotConnectedEndpoints->Add(endpoint->GetName()); } else { allConnectedEndpoints->Add(endpoint->GetName()); zoneConnected = true; } } /* if there's only one endpoint inside the zone, we're not connected - that's us, fake it */ if (zone->GetEndpoints().size() == 1 && countZoneEndpoints == 0) zoneConnected = true; String parentZoneName; Zone::Ptr parentZone = zone->GetParent(); if (parentZone) parentZoneName = parentZone->GetName(); Dictionary::Ptr zoneStats = new Dictionary({ { "connected", zoneConnected }, { "client_log_lag", zoneLag }, { "endpoints", new Array(std::move(zoneEndpoints)) }, { "parent_zone", parentZoneName } }); connectedZones->Set(zone->GetName(), zoneStats); } /* connection stats */ size_t jsonRpcClients = GetAnonymousClients().size(); size_t httpClients = GetHttpClients().size(); size_t workQueueItems = JsonRpcConnection::GetWorkQueueLength(); size_t workQueueCount = JsonRpcConnection::GetWorkQueueCount(); size_t syncQueueItems = m_SyncQueue.GetLength(); size_t relayQueueItems = m_RelayQueue.GetLength(); double workQueueItemRate = JsonRpcConnection::GetWorkQueueRate(); double syncQueueItemRate = m_SyncQueue.GetTaskCount(60) / 60.0; double relayQueueItemRate = m_RelayQueue.GetTaskCount(60) / 60.0; Dictionary::Ptr status = new Dictionary({ { "identity", GetIdentity() }, { "num_endpoints", allEndpoints }, { "num_conn_endpoints", allConnectedEndpoints->GetLength() }, { "num_not_conn_endpoints", allNotConnectedEndpoints->GetLength() }, { "conn_endpoints", allConnectedEndpoints }, { "not_conn_endpoints", allNotConnectedEndpoints }, { "zones", connectedZones }, { "json_rpc", new Dictionary({ { "clients", jsonRpcClients }, { "work_queue_items", workQueueItems }, { "work_queue_count", workQueueCount }, { "sync_queue_items", syncQueueItems }, { "relay_queue_items", relayQueueItems }, { "work_queue_item_rate", workQueueItemRate }, { "sync_queue_item_rate", syncQueueItemRate }, { "relay_queue_item_rate", relayQueueItemRate } }) }, { "http", new Dictionary({ { "clients", httpClients } }) } }); /* performance data */ perfdata->Set("num_endpoints", allEndpoints); perfdata->Set("num_conn_endpoints", Convert::ToDouble(allConnectedEndpoints->GetLength())); perfdata->Set("num_not_conn_endpoints", Convert::ToDouble(allNotConnectedEndpoints->GetLength())); perfdata->Set("num_json_rpc_clients", jsonRpcClients); perfdata->Set("num_http_clients", httpClients); perfdata->Set("num_json_rpc_work_queue_items", workQueueItems); perfdata->Set("num_json_rpc_work_queue_count", workQueueCount); perfdata->Set("num_json_rpc_sync_queue_items", syncQueueItems); perfdata->Set("num_json_rpc_relay_queue_items", relayQueueItems); perfdata->Set("num_json_rpc_work_queue_item_rate", workQueueItemRate); perfdata->Set("num_json_rpc_sync_queue_item_rate", syncQueueItemRate); perfdata->Set("num_json_rpc_relay_queue_item_rate", relayQueueItemRate); return std::make_pair(status, perfdata); }
std::pair<Dictionary::Ptr, Dictionary::Ptr> ApiListener::GetStatus(void) { Dictionary::Ptr status = new Dictionary(); Dictionary::Ptr perfdata = new Dictionary(); /* cluster stats */ status->Set("identity", GetIdentity()); double allEndpoints = 0; Array::Ptr allNotConnectedEndpoints = new Array(); Array::Ptr allConnectedEndpoints = new Array(); Zone::Ptr my_zone = Zone::GetLocalZone(); Dictionary::Ptr connectedZones = new Dictionary(); for (const Zone::Ptr& zone : ConfigType::GetObjectsByType<Zone>()) { /* only check endpoints in a) the same zone b) our parent zone c) immediate child zones */ if (my_zone != zone && my_zone != zone->GetParent() && zone != my_zone->GetParent()) { Log(LogDebug, "ApiListener") << "Not checking connection to Zone '" << zone->GetName() << "' because it's not in the same zone, a parent or a child zone."; continue; } bool zoneConnected = false; int countZoneEndpoints = 0; double zoneLag = 0; Array::Ptr zoneEndpoints = new Array(); for (const Endpoint::Ptr& endpoint : zone->GetEndpoints()) { zoneEndpoints->Add(endpoint->GetName()); if (endpoint->GetName() == GetIdentity()) continue; double eplag = CalculateZoneLag(endpoint); if (eplag > 0 && eplag > zoneLag) zoneLag = eplag; allEndpoints++; countZoneEndpoints++; if (!endpoint->GetConnected()) { allNotConnectedEndpoints->Add(endpoint->GetName()); } else { allConnectedEndpoints->Add(endpoint->GetName()); zoneConnected = true; } } /* if there's only one endpoint inside the zone, we're not connected - that's us, fake it */ if (zone->GetEndpoints().size() == 1 && countZoneEndpoints == 0) zoneConnected = true; Dictionary::Ptr zoneStats = new Dictionary(); zoneStats->Set("connected", zoneConnected); zoneStats->Set("client_log_lag", zoneLag); zoneStats->Set("endpoints", zoneEndpoints); String parentZoneName; Zone::Ptr parentZone = zone->GetParent(); if (parentZone) parentZoneName = parentZone->GetName(); zoneStats->Set("parent_zone", parentZoneName); connectedZones->Set(zone->GetName(), zoneStats); } status->Set("num_endpoints", allEndpoints); status->Set("num_conn_endpoints", allConnectedEndpoints->GetLength()); status->Set("num_not_conn_endpoints", allNotConnectedEndpoints->GetLength()); status->Set("conn_endpoints", allConnectedEndpoints); status->Set("not_conn_endpoints", allNotConnectedEndpoints); status->Set("zones", connectedZones); perfdata->Set("num_endpoints", allEndpoints); perfdata->Set("num_conn_endpoints", Convert::ToDouble(allConnectedEndpoints->GetLength())); perfdata->Set("num_not_conn_endpoints", Convert::ToDouble(allNotConnectedEndpoints->GetLength())); return std::make_pair(status, perfdata); }
Dictionary::Ptr ObjectQueryHandler::SerializeObjectAttrs(const Object::Ptr& object, const String& attrPrefix, const Array::Ptr& attrs, bool isJoin, bool allAttrs) { Type::Ptr type = object->GetReflectionType(); std::vector<int> fids; if (isJoin && attrs) { ObjectLock olock(attrs); for (const String& attr : attrs) { if (attr == attrPrefix) { allAttrs = true; break; } } } if (!isJoin && (!attrs || attrs->GetLength() == 0)) allAttrs = true; if (allAttrs) { for (int fid = 0; fid < type->GetFieldCount(); fid++) { fids.push_back(fid); } } else if (attrs) { ObjectLock olock(attrs); for (const String& attr : attrs) { String userAttr; if (isJoin) { String::SizeType dpos = attr.FindFirstOf("."); if (dpos == String::NPos) continue; String userJoinAttr = attr.SubStr(0, dpos); if (userJoinAttr != attrPrefix) continue; userAttr = attr.SubStr(dpos + 1); } else userAttr = attr; int fid = type->GetFieldId(userAttr); if (fid < 0) BOOST_THROW_EXCEPTION(ScriptError("Invalid field specified: " + userAttr)); fids.push_back(fid); } } DictionaryData resultAttrs; resultAttrs.reserve(fids.size()); for (int fid : fids) { Field field = type->GetFieldInfo(fid); Value val = object->GetField(fid); /* hide attributes which shouldn't be user-visible */ if (field.Attributes & FANoUserView) continue; /* hide internal navigation fields */ if (field.Attributes & FANavigation && !(field.Attributes & (FAConfig | FAState))) continue; Value sval = Serialize(val, FAConfig | FAState); resultAttrs.emplace_back(field.Name, sval); } return new Dictionary(std::move(resultAttrs)); }
bool AttributeFilter::Apply(const Table::Ptr& table, const Value& row) { Column column = table->GetColumn(m_Column); Value value = column.ExtractValue(row); if (value.IsObjectType<Array>()) { Array::Ptr array = value; if (m_Operator == ">=" || m_Operator == "<") { bool negate = (m_Operator == "<"); ObjectLock olock(array); for (const String& item : array) { if (item == m_Operand) return !negate; /* Item found in list. */ } return negate; /* Item not found in list. */ } else if (m_Operator == "=") { return (array->GetLength() == 0); } else { BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid operator for column '" + m_Column + "': " + m_Operator + " (expected '>=' or '=').")); } } else { if (m_Operator == "=") { if (value.GetType() == ValueNumber || value.GetType() == ValueBoolean) return (static_cast<double>(value) == Convert::ToDouble(m_Operand)); else return (static_cast<String>(value) == m_Operand); } else if (m_Operator == "~") { bool ret; try { boost::regex expr(m_Operand.GetData()); String operand = value; boost::smatch what; ret = boost::regex_search(operand.GetData(), what, expr); } catch (boost::exception&) { Log(LogWarning, "AttributeFilter") << "Regex '" << m_Operand << " " << m_Operator << " " << value << "' error."; ret = false; } //Log(LogDebug, "LivestatusListener/AttributeFilter") // << "Attribute filter '" << m_Operand + " " << m_Operator << " " // << value << "' " << (ret ? "matches" : "doesn't match") << "."; return ret; } else if (m_Operator == "=~") { bool ret; try { String operand = value; ret = boost::iequals(operand, m_Operand.GetData()); } catch (boost::exception&) { Log(LogWarning, "AttributeFilter") << "Case-insensitive equality '" << m_Operand << " " << m_Operator << " " << value << "' error."; ret = false; } return ret; } else if (m_Operator == "~~") { bool ret; try { boost::regex expr(m_Operand.GetData(), boost::regex::icase); String operand = value; boost::smatch what; ret = boost::regex_search(operand.GetData(), what, expr); } catch (boost::exception&) { Log(LogWarning, "AttributeFilter") << "Regex '" << m_Operand << " " << m_Operator << " " << value << "' error."; ret = false; } //Log(LogDebug, "LivestatusListener/AttributeFilter") // << "Attribute filter '" << m_Operand << " " << m_Operator << " " // << value << "' " << (ret ? "matches" : "doesn't match") << "."; return ret; } else if (m_Operator == "<") { if (value.GetType() == ValueNumber) return (static_cast<double>(value) < Convert::ToDouble(m_Operand)); else return (static_cast<String>(value) < m_Operand); } else if (m_Operator == ">") { if (value.GetType() == ValueNumber) return (static_cast<double>(value) > Convert::ToDouble(m_Operand)); else return (static_cast<String>(value) > m_Operand); } else if (m_Operator == "<=") { if (value.GetType() == ValueNumber) return (static_cast<double>(value) <= Convert::ToDouble(m_Operand)); else return (static_cast<String>(value) <= m_Operand); } else if (m_Operator == ">=") { if (value.GetType() == ValueNumber) return (static_cast<double>(value) >= Convert::ToDouble(m_Operand)); else return (static_cast<String>(value) >= m_Operand); } else { BOOST_THROW_EXCEPTION(std::invalid_argument("Unknown operator for column '" + m_Column + "': " + m_Operator)); } } return false; }
static double ArrayLen(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); Array::Ptr self = static_cast<Array::Ptr>(vframe->Self); return self->GetLength(); }
String icinga::DiagnosticInformation(const std::exception& ex, bool verbose, StackTrace *stack, ContextTrace *context) { std::ostringstream result; String message = ex.what(); const ValidationError *vex = dynamic_cast<const ValidationError *>(&ex); if (message.IsEmpty()) result << boost::diagnostic_information(ex); else result << "Error: " << message; const ScriptError *dex = dynamic_cast<const ScriptError *>(&ex); if (dex && !dex->GetDebugInfo().Path.IsEmpty()) { result << "\nLocation:\n"; ShowCodeFragment(result, dex->GetDebugInfo()); } if (vex) { DebugInfo di; ConfigObject::Ptr dobj = vex->GetObject(); if (dobj) di = dobj->GetDebugInfo(); Dictionary::Ptr currentHint = vex->GetDebugHint(); Array::Ptr messages; if (currentHint) { BOOST_FOREACH(const String& attr, vex->GetAttributePath()) { Dictionary::Ptr props = currentHint->Get("properties"); if (!props) break; currentHint = props->Get(attr); if (!currentHint) break; messages = currentHint->Get("messages"); } } if (messages && messages->GetLength() > 0) { Array::Ptr message = messages->Get(messages->GetLength() - 1); di.Path = message->Get(1); di.FirstLine = message->Get(2); di.FirstColumn = message->Get(3); di.LastLine = message->Get(4); di.LastColumn = message->Get(5); } if (!di.Path.IsEmpty()) { result << "\nLocation:\n"; ShowCodeFragment(result, di); } } const user_error *uex = dynamic_cast<const user_error *>(&ex); const posix_error *pex = dynamic_cast<const posix_error *>(&ex); if (!uex && !pex && verbose) { const StackTrace *st = boost::get_error_info<StackTraceErrorInfo>(ex); if (st) { result << *st; } else { result << std::endl; if (!stack) stack = GetLastExceptionStack(); if (stack) result << *stack; } if (boost::get_error_info<ContextTraceErrorInfo>(ex) == NULL) { result << std::endl; if (!context) context = GetLastExceptionContext(); if (context) result << *context; } } return result.str(); }