/* command */
String CompatUtility::GetCommandLine(const Command::Ptr& command)
{
	Value commandLine = command->GetCommandLine();

	String result;
	if (commandLine.IsObjectType<Array>()) {
		Array::Ptr args = commandLine;

		ObjectLock olock(args);
		for (const String& arg : args) {
			// This is obviously incorrect for non-trivial cases.
			result += " \"" + EscapeString(arg) + "\"";
		}
	} else if (!commandLine.IsEmpty()) {
		result = EscapeString(Convert::ToString(commandLine));
	} else {
		result = "<internal>";
	}

	return result;
}
Exemple #2
0
void PluginUtility::ExecuteCommand(const Command::Ptr& commandObj, const Checkable::Ptr& checkable,
    const CheckResult::Ptr& cr, const MacroProcessor::ResolverList& macroResolvers,
    const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros,
    const boost::function<void(const Value& commandLine, const ProcessResult&)>& callback)
{
	Value raw_command = commandObj->GetCommandLine();
	Dictionary::Ptr raw_arguments = commandObj->GetArguments();

	Value command;
	if (!raw_arguments || raw_command.IsObjectType<Array>())
		command = MacroProcessor::ResolveMacros(raw_command, macroResolvers, cr, NULL,
		    Utility::EscapeShellArg, resolvedMacros, useResolvedMacros);
	else {
		Array::Ptr arr = new Array();
		arr->Add(raw_command);
		command = arr;
	}

	if (raw_arguments) {
		std::vector<CommandArgument> args;

		ObjectLock olock(raw_arguments);
		BOOST_FOREACH(const Dictionary::Pair& kv, raw_arguments) {
			const Value& arginfo = kv.second;

			CommandArgument arg;
			arg.Key = kv.first;

			bool required = false;
			String argval;

			if (arginfo.IsObjectType<Dictionary>()) {
				Dictionary::Ptr argdict = arginfo;
				argval = argdict->Get("value");
				if (argdict->Contains("required"))
					required = argdict->Get("required");
				arg.SkipKey = argdict->Get("skip_key");
				arg.Order = argdict->Get("order");

				String set_if = argdict->Get("set_if");

				if (!set_if.IsEmpty()) {
					String missingMacro;
					String set_if_resolved = MacroProcessor::ResolveMacros(set_if, macroResolvers,
					    cr, &missingMacro, MacroProcessor::EscapeCallback(), resolvedMacros,
					    useResolvedMacros);

					if (!missingMacro.IsEmpty())
						continue;

					try {
						if (!Convert::ToLong(set_if_resolved))
							continue;
					} catch (const std::exception& ex) {
						/* tried to convert a string */
						Log(LogWarning, "PluginUtility")
						    << "Error evaluating set_if value '" << set_if_resolved << "': " << ex.what();
						continue;
					}
				}
			}
			else
				argval = arginfo;

			if (argval.IsEmpty())
				arg.SkipValue = true;

			String missingMacro;
			arg.Value = MacroProcessor::ResolveMacros(argval, macroResolvers,
			    cr, &missingMacro, MacroProcessor::EscapeCallback(), resolvedMacros,
			    useResolvedMacros);

			if (!missingMacro.IsEmpty()) {
				if (required) {
					String message = "Non-optional macro '" + missingMacro + "' used in argument '" +
					    arg.Key + "' is missing while executing command '" + commandObj->GetName() +
					    "' for object '" + checkable->GetName() + "'";
					Log(LogWarning, "PluginUtility", message);

					if (callback) {
						ProcessResult pr;
						pr.PID = -1;
						pr.ExecutionStart = Utility::GetTime();
						pr.ExecutionStart = pr.ExecutionStart;
						pr.ExitStatus = 3; /* Unknown */
						pr.Output = message;
						callback(Empty, pr);
					}

					return;
				}

				continue;
			}

			args.push_back(arg);
		}

		std::sort(args.begin(), args.end());

		Array::Ptr command_arr = command;
		BOOST_FOREACH(const CommandArgument& arg, args) {
			if (!arg.SkipKey)
				command_arr->Add(arg.Key);

			if (!arg.SkipValue)
				command_arr->Add(arg.Value);
		}
	}

	Dictionary::Ptr envMacros = new Dictionary();

	Dictionary::Ptr env = commandObj->GetEnv();

	if (env) {
		ObjectLock olock(env);
		BOOST_FOREACH(const Dictionary::Pair& kv, env) {
			String name = kv.second;

			Value value = MacroProcessor::ResolveMacros(name, macroResolvers, cr,
			    NULL, MacroProcessor::EscapeCallback(), resolvedMacros,
			    useResolvedMacros);

			envMacros->Set(kv.first, value);
		}
	}