Beispiel #1
0
static FnCallResult CallFunction(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *expargs)
{
    const Rlist *rp = fp->args;
    const FnCallType *fncall_type = FnCallTypeGet(fp->name);

    int argnum = 0;
    for (argnum = 0; rp != NULL && fncall_type->args[argnum].pattern != NULL; argnum++)
    {
        if (rp->val.type != RVAL_TYPE_FNCALL)
        {
            /* Nested functions will not match to lval so don't bother checking */
            SyntaxTypeMatch err = CheckConstraintTypeMatch(fp->name, rp->val,
                                                           fncall_type->args[argnum].dtype,
                                                           fncall_type->args[argnum].pattern, 1);
            if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED)
            {
                FatalError(ctx, "In function '%s', error in variable '%s', '%s'", fp->name, (const char *)rp->val.item, SyntaxTypeMatchToString(err));
            }
        }

        rp = rp->next;
    }

    char output[CF_BUFSIZE];
    if (argnum != RlistLen(expargs) && !(fncall_type->options & FNCALL_OPTION_VARARG))
    {
        snprintf(output, CF_BUFSIZE, "Argument template mismatch handling function %s(", fp->name);
        {
            Writer *w = FileWriter(stderr);
            RlistWrite(w, expargs);
            FileWriterDetach(w);
        }

        fprintf(stderr, ")\n");

        rp = expargs;
        for (int i = 0; i < argnum; i++)
        {
            printf("  arg[%d] range %s\t", i, fncall_type->args[i].pattern);
            if (rp != NULL)
            {
                Writer *w = FileWriter(stdout);
                RvalWrite(w, rp->val);
                FileWriterDetach(w);
                rp = rp->next;
            }
            else
            {
                printf(" ? ");
            }
            printf("\n");
        }

        FatalError(ctx, "Bad arguments");
    }


    return (*fncall_type->impl) (ctx, policy, fp, expargs);
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    EvalContext *ctx = EvalContextNew();
    GenericAgentConfig *config = CheckOpts(ctx, argc, argv);
    GenericAgentConfigApply(ctx, config);

    GenericAgentDiscoverContext(ctx, config);
    Policy *policy = GenericAgentLoadPolicy(ctx, config);
    if (!policy)
    {
        Log(LOG_LEVEL_ERR, "Input files contain errors.");
        exit(EXIT_FAILURE);
    }

    if (SHOWREPORTS)
    {
        ShowPromises(policy->bundles, policy->bodies);
    }

    switch (config->agent_specific.common.policy_output_format)
    {
    case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF:
        {
            Policy *output_policy = ParserParseFile(config->input_file, config->agent_specific.common.parser_warnings,
                                                    config->agent_specific.common.parser_warnings_error);
            Writer *writer = FileWriter(stdout);
            PolicyToString(policy, writer);
            WriterClose(writer);
            PolicyDestroy(output_policy);
        }
        break;

    case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON:
        {
            Policy *output_policy = ParserParseFile(config->input_file, config->agent_specific.common.parser_warnings,
                                                    config->agent_specific.common.parser_warnings_error);
            JsonElement *json_policy = PolicyToJson(output_policy);
            Writer *writer = FileWriter(stdout);
            JsonWrite(writer, json_policy, 2);
            WriterClose(writer);
            JsonDestroy(json_policy);
            PolicyDestroy(output_policy);
        }
        break;

    case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE:
        break;
    }

    GenericAgentConfigDestroy(config);
    EvalContextDestroy(ctx);
}
bool ValidatorGenerator::generate() const
{
    // Writes each files
    QString output = QString(VALIDATOR_HEADER_TEMPLATE).arg(name.toUpper()).arg(name);
    FileWriter(dstDir.filePath(name.toLower() + "validator.h")).write(output, false);

    output = QString(VALIDATOR_IMPL_TEMPLATE).arg(name.toLower()).arg(name);
    FileWriter(dstDir.filePath(name.toLower() + "validator.cpp")).write(output, false);

    // Updates the project file
    ProjectFileGenerator progen(dstDir.filePath("helpers.pro"));
    QStringList files;
    files << name.toLower() + "validator.h" << name.toLower() + "validator.cpp";
    return progen.add(files);
}
Beispiel #4
0
/**
 * @brief Writes a file with a contained release ID based on git SHA,
 *        or file checksum if git SHA is not available.
 * @param filename the release_id file
 * @param dirname the directory to checksum or get the Git hash
 * @return True if successful
 */
static bool WriteReleaseIdFile(const char *filename, const char *dirname)
{
    char release_id[GENERIC_AGENT_CHECKSUM_SIZE];

    bool have_release_id =
        GeneratePolicyReleaseID(release_id, sizeof(release_id), dirname);

    if (!have_release_id)
    {
        return false;
    }

    int fd = creat(filename, 0600);
    if (fd == -1)
    {
        Log(LOG_LEVEL_ERR, "While writing policy release ID file '%s', could not create file (creat: %s)", filename, GetErrorStr());
        return false;
    }

    JsonElement *info = JsonObjectCreate(3);
    JsonObjectAppendString(info, "releaseId", release_id);

    Writer *w = FileWriter(fdopen(fd, "w"));
    JsonWrite(w, info, 0);

    WriterClose(w);
    JsonDestroy(info);

    Log(LOG_LEVEL_VERBOSE, "Saved policy release ID file '%s'", filename);
    return true;
}
Beispiel #5
0
/**
 * @brief Writes a file with a contained timestamp to mark a policy file as validated
 * @param filename the filename
 * @return True if successful.
 */
static bool WritePolicyValidatedFile(ARG_UNUSED const GenericAgentConfig *config, const char *filename)
{
    if (!MakeParentDirectory(filename, true))
    {
        Log(LOG_LEVEL_ERR, "While writing policy validated marker file '%s', could not create directory (MakeParentDirectory: %s)", filename, GetErrorStr());
        return false;
    }

    int fd = creat(filename, 0600);
    if (fd == -1)
    {
        Log(LOG_LEVEL_ERR, "While writing policy validated marker file '%s', could not create file (creat: %s)", filename, GetErrorStr());
        return false;
    }

    JsonElement *info = JsonObjectCreate(3);
    JsonObjectAppendInteger(info, "timestamp", time(NULL));

    Writer *w = FileWriter(fdopen(fd, "w"));
    JsonWrite(w, info, 0);

    WriterClose(w);
    JsonDestroy(info);

    Log(LOG_LEVEL_VERBOSE, "Saved policy validated marker file '%s'", filename);
    return true;
}
static int GenerateAvahiConfig(const char *path)
{
    FILE *fout;
    Writer *writer = NULL;
    fout = safe_fopen(path, "w+");
    if (fout == NULL)
    {
        Log(LOG_LEVEL_ERR, "Unable to open '%s'", path);
        return -1;
    }
    writer = FileWriter(fout);
    fprintf(fout, "<?xml version=\"1.0\" standalone='no'?>\n");
    fprintf(fout, "<!DOCTYPE service-group SYSTEM \"avahi-service.dtd\">\n");
    XmlComment(writer, "This file has been automatically generated by cf-serverd.");
    XmlStartTag(writer, "service-group", 0);
    FprintAvahiCfengineTag(fout);
    XmlStartTag(writer, "service", 0);
    XmlTag(writer, "type", "_cfenginehub._tcp",0);
    DetermineCfenginePort();
    XmlStartTag(writer, "port", 0);
    WriterWriteF(writer, "%d", CFENGINE_PORT);
    XmlEndTag(writer, "port");
    XmlEndTag(writer, "service");
    XmlEndTag(writer, "service-group");
    fclose(fout);

    return 0;
}
Beispiel #7
0
static int GenerateAvahiConfig(const char *path)
{
    FILE *fout;
    Writer *writer = NULL;
    fout = fopen(path, "w+");
    if (fout == NULL)
    {
        CfOut(cf_error, "", "Unable to open %s", path);
        return -1;
    }
    writer = FileWriter(fout);
    fprintf(fout, "<?xml version=\"1.0\" standalone='no'?>\n");
    fprintf(fout, "<!DOCTYPE service-group SYSTEM \"avahi-service.dtd\">\n");
    XmlComment(writer, "This file has been automatically generated by cf-serverd.");
    XmlStartTag(writer, "service-group", 0);
#ifdef HAVE_NOVA
    fprintf(fout,"<name replace-wildcards=\"yes\" >CFEngine Enterprise %s Policy Hub on %s </name>\n", Version(), "%h");
#else
    fprintf(fout,"<name replace-wildcards=\"yes\" >CFEngine Community %s Policy Server on %s </name>\n", Version(), "%h");
#endif
    XmlStartTag(writer, "service", 0);
    XmlTag(writer, "type", "_cfenginehub._tcp",0);
    DetermineCfenginePort();
    XmlTag(writer, "port", STR_CFENGINEPORT, 0);
    XmlEndTag(writer, "service");
    XmlEndTag(writer, "service-group");
    fclose(fout);

    return 0;
}
Beispiel #8
0
void XmlManual(const char *mandir, FILE *fout)
{
    Writer *writer = NULL;
    int i;
    SubTypeSyntax *st = NULL;

    MANUAL_DIRECTORY = (char *) mandir;
    AddSlash(MANUAL_DIRECTORY);

    writer = FileWriter(fout);

/* XML HEADER */
    XmlComment(writer, "AUTOGENERATED SYNTAX DOCUMENTATION BY CF-KNOW");
    WriterWrite(writer, "\n");

/* START XML ELEMENT -- SYNTAX-DOCUMENTATION */
    XmlStartTag(writer, XMLTAG_DOC_ROOT, 0);

/* SPECIAL VARIABLES */
    XmlStartTag(writer, XMLTAG_VARSCOPES_ROOT, 0);
    XmlExportVariables(writer, "const");
    XmlExportVariables(writer, "edit");
    XmlExportVariables(writer, "match");
    XmlExportVariables(writer, "mon");
    XmlExportVariables(writer, "sys");
    XmlExportVariables(writer, "this");
    XmlEndTag(writer, XMLTAG_VARSCOPES_ROOT);

/* SPECIAL FUNCTIONS */
    XmlStartTag(writer, XMLTAG_FUNCTIONS_ROOT, 0);
    for (i = 0; CF_FNCALL_TYPES[i].name != NULL; i++)
    {
        XmlExportFunction(writer, CF_FNCALL_TYPES[i]);
    }
    XmlEndTag(writer, XMLTAG_FUNCTIONS_ROOT);

/* CONTROL */
    XmlStartTag(writer, XMLTAG_CONTROLS_ROOT, 0);
    for (i = 0; CF_ALL_BODIES[i].btype != NULL; i++)
    {
        XmlExportControl(writer, CF_ALL_BODIES[i]);
    }
    XmlEndTag(writer, XMLTAG_CONTROLS_ROOT);

/* PROMISE TYPES */
    XmlStartTag(writer, XMLTAG_PROMISETYPES_ROOT, 0);
    for (i = 0; i < CF3_MODULES; i++)
    {
        st = CF_ALL_SUBTYPES[i];
        XmlExportPromiseType(writer, st);
    }
    XmlEndTag(writer, XMLTAG_PROMISETYPES_ROOT);

/* END XML ELEMENT -- SYNTAX-DOCUMENTATION */
    XmlEndTag(writer, XMLTAG_DOC_ROOT);

    WriterClose(writer);
}
Beispiel #9
0
Policy *GenericAgentLoadPolicy(EvalContext *ctx, GenericAgentConfig *config)
{
    config->policy_last_read_attempt = time(NULL);

    StringSet *parsed_files = StringSetNew();
    StringSet *failed_files = StringSetNew();

    Policy *policy = LoadPolicyFile(ctx, config, config->input_file, parsed_files, failed_files);

    if (StringSetSize(failed_files) > 0)
    {
        Log(LOG_LEVEL_ERR, "There are syntax errors in policy files");
        exit(EXIT_FAILURE);
    }

    StringSetDestroy(parsed_files);
    StringSetDestroy(failed_files);

    {
        Seq *errors = SeqNew(100, PolicyErrorDestroy);

        if (PolicyCheckPartial(policy, errors))
        {
            if (!config->bundlesequence && (PolicyIsRunnable(policy) || config->check_runnable))
            {
                Log(LOG_LEVEL_VERBOSE, "Running full policy integrity checks");
                PolicyCheckRunnable(ctx, policy, errors, config->ignore_missing_bundles);
            }
        }

        if (SeqLength(errors) > 0)
        {
            Writer *writer = FileWriter(stderr);
            for (size_t i = 0; i < errors->length; i++)
            {
                PolicyErrorWrite(writer, errors->data[i]);
            }
            WriterClose(writer);
            exit(EXIT_FAILURE); // TODO: do not exit
        }

        SeqDestroy(errors);
    }

    if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE)
    {
        ShowContext(ctx);
    }

    if (policy)
    {
        VerifyPromises(ctx, policy, config);
    }

    return policy;
}
void ArrayStringCount::writeToDisk(std::string& file_name)
{
    WaitForSingleObject(gHashWriteSemaphone, INFINITE);
    {
        FileWriter FW = FileWriter(file_name);
        FW.write(this->start, this->start_offset - this->start);
        this->total_write += (this->start_offset - this->start);
        this->start_offset = this->start;
    }
    ReleaseSemaphore(gHashWriteSemaphone, 1, NULL);
}
Beispiel #11
0
static void DumpErrors(Seq *errs)
{
    if (SeqLength(errs) > 0)
    {
        Writer *writer = FileWriter(stdout);
        for (size_t i = 0; i < errs->length; i++)
        {
            PolicyErrorWrite(writer, errs->data[i]);
        }
        FileWriterDetach(writer);
    }
}
Beispiel #12
0
void test_empty_file_buffer(void **p)
{
    global_w = StringWriter();
    global_w_closed = false;
    Writer *w = FileWriter(NULL);

    assert_int_equal(StringWriterLength(global_w), 0);
    assert_string_equal(StringWriterData(global_w), "");

    WriterClose(w);
    WriterClose(global_w);
    assert_int_equal(global_w_closed, true);
}
Beispiel #13
0
void test_write_file_buffer(void **p)
{
    global_w = StringWriter();
    Writer *w = FileWriter(NULL);

    WriterWrite(w, "123");

    assert_int_equal(StringWriterLength(global_w), 3);
    assert_string_equal(StringWriterData(global_w), "123");

    WriterClose(w);
    WriterClose(global_w);
    assert_int_equal(global_w_closed, true);
}
void Simulation::writeFile(std::string path, int channels, double duration, bool mayApplyMixingMatrix) {
	int blocks = (duration*getSr()/block_size)+1;
	auto file = FileWriter();
	file.open(path.c_str(), sr, channels);
	//vectors are guaranteed to be contiguous. Using a vector here guarantees proper cleanup.
	std::vector<float> block;
	block.resize(channels*getBlockSize());
	for(int i = 0; i < blocks; i++) {
		getBlock(&block[0], channels, mayApplyMixingMatrix);
		unsigned int written= 0;
		while(written < getBlockSize()) written += file.write(getBlockSize(), &block[0]);
	}
	file.close();
}
bool ProjectFileGenerator::remove(const QStringList &files)
{
    QString output;

    QFile pro(filePath);
    if (pro.exists()) {
        if (pro.open(QIODevice::ReadOnly | QIODevice::Text)) {
            output = pro.readAll();
        } else {
            qCritical("failed to open file: %s", qPrintable(pro.fileName()));
            return false;
        }
    } else {
        qCritical("Project file not found: %s", qPrintable(pro.fileName()));
        return false;
    }
    pro.close();

    if (files.isEmpty())
        return true;

    for (QStringListIterator i(files); i.hasNext(); ) {
        QString f = QFileInfo(i.next()).fileName();
        QString str;
        QRegExp rx("*.h");
        rx.setPatternSyntax(QRegExp::Wildcard);
        if (rx.exactMatch(f)) {
            str  = "HEADERS += ";
            str += f;
            str += '\n';
        } else {
            rx.setPattern("*.cpp");
            if (rx.exactMatch(f)) {
                str  = "SOURCES += ";
                str += f;
                str += '\n';
            }
        }
        
        int idx = 0;
        if (!str.isEmpty() && (idx = output.indexOf(str)) >= 0 ) {
            output.remove(idx, str.length());
        }
    }

    return FileWriter(filePath).write(output, true);
}
bool ProjectFileGenerator::add(const QStringList &files)
{
    QString output;

    QFile pro(filePath);
    if (!pro.exists()) {
        qCritical("Project file not found: %s", qPrintable(pro.fileName()));
        return false;
    } else {
        if (pro.open(QIODevice::ReadOnly | QIODevice::Text)) {
            output = pro.readAll();
        } else {
            qCritical("failed to open file: %s", qPrintable(pro.fileName()));
            return false;
        }
    }
    pro.close();

    for (QStringListIterator i(files); i.hasNext(); ) {
        const QString &f = i.next();
        QString str;
        QRegExp rx("*.h");
        rx.setPatternSyntax(QRegExp::Wildcard);
        if (rx.exactMatch(f)) {
            str  = "HEADERS += ";
            str += f;
            str += '\n';
        } else {
            rx.setPattern("*.cpp");
            if (rx.exactMatch(f)) {
                str  = "SOURCES += ";
                str += f;
                str += '\n';
            }
        }
        
        if (!str.isEmpty() && !output.contains(str)) {
            if (!output.endsWith('\n')) {
                output += '\n';
            }
            output += str;
        }
    }

    return FileWriter(filePath).write(output, true);
}
Beispiel #17
0
static Seq *LoadAndCheckString(const char *policy_code)
{
    const char *tmp = tempnam(NULL, "cfengine_test");

    {
        FILE *out = fopen(tmp, "w");
        Writer *w = FileWriter(out);
        WriterWrite(w, policy_code);

        WriterClose(w);
    }

    Policy *p = ParserParseFile(tmp, PARSER_WARNING_ALL, PARSER_WARNING_ALL);
    assert_true(p);

    Seq *errs = SeqNew(10, PolicyErrorDestroy);
    PolicyCheckPartial(p, errs);

    unlink(tmp);
    return errs;
}
Beispiel #18
0
bool MeshManager::convertMeshToNativeFormat(const String& name)
{
    auto mesh = Mesh();
    if (!MeshFormatRegistry::loadMeshFile(Mesh::MeshDirectory + name, mesh))
    {
        LOG_ERROR << "Failed converting mesh: " << name;
        return false;
    }

    try
    {
        auto file = FileWriter();
        fileSystem().open(Mesh::MeshDirectory + name + Mesh::MeshExtension, file);
        file.write(mesh);
    }
    catch (const Exception& e)
    {
        LOG_ERROR << name << " - " << e;
        return false;
    }

    return true;
}
void FPendingReports::Save() const
{
	auto PendingReportsPath = GetPendingReportsJsonFilepath();

	// Ensure directory structure exists
	FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*FPaths::GetPath(PendingReportsPath));
	
	FJsonReportArray JsonReports;
	for (auto Path : Reports)
	{
		JsonReports.Push(MakeShareable(new FJsonValueString(Path)));
	}
	
	TSharedRef<FJsonObject> JsonRootObject = MakeShareable(new FJsonObject);
	JsonRootObject->SetArrayField(ReportsArrayFieldName, JsonReports);

	TUniquePtr<FArchive> FileWriter(IFileManager::Get().CreateFileWriter(*PendingReportsPath));
	if (!FileWriter)
	{
		UE_LOG(CrashReportClientLog, Warning, TEXT("Failed to save pending reports JSON file"));
		return;
	}
	FJsonSerializer::Serialize(JsonRootObject, FPrettyJsonWriter::Create(FileWriter.Get()));
}
Beispiel #20
0
void CFTestD_Help()
{
    Writer *w = FileWriter(stdout);
    WriterWriteHelp(w, "cf-testd", OPTIONS, HINTS, true, NULL);
    FileWriterDetach(w);
}
Beispiel #21
0
Policy *LoadPolicy(EvalContext *ctx, GenericAgentConfig *config)
{
    StringSet *parsed_files_and_checksums = StringSetNew();
    StringSet *failed_files = StringSetNew();

    Policy *policy = LoadPolicyFile(ctx, config, config->input_file, parsed_files_and_checksums, failed_files);

    if (StringSetSize(failed_files) > 0)
    {
        Log(LOG_LEVEL_ERR, "There are syntax errors in policy files");
        exit(EXIT_FAILURE);
    }

    StringSetDestroy(parsed_files_and_checksums);
    StringSetDestroy(failed_files);

    {
        Seq *errors = SeqNew(100, PolicyErrorDestroy);

        if (PolicyCheckPartial(policy, errors))
        {
            if (!config->bundlesequence && (PolicyIsRunnable(policy) || config->check_runnable))
            {
                Log(LOG_LEVEL_VERBOSE, "Running full policy integrity checks");
                PolicyCheckRunnable(ctx, policy, errors, config->ignore_missing_bundles);
            }
        }

        if (SeqLength(errors) > 0)
        {
            Writer *writer = FileWriter(stderr);
            for (size_t i = 0; i < errors->length; i++)
            {
                PolicyErrorWrite(writer, errors->data[i]);
            }
            WriterClose(writer);
            exit(EXIT_FAILURE); // TODO: do not exit
        }

        SeqDestroy(errors);
    }

    if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE)
    {
        ShowContext(ctx);
    }

    if (policy)
    {
        for (size_t i = 0; i < SeqLength(policy->bundles); i++)
        {
            Bundle *bp = SeqAt(policy->bundles, i);
            EvalContextStackPushBundleFrame(ctx, bp, NULL, false);

            for (size_t j = 0; j < SeqLength(bp->promise_types); j++)
            {
                PromiseType *sp = SeqAt(bp->promise_types, j);
                EvalContextStackPushPromiseTypeFrame(ctx, sp);

                for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++)
                {
                    Promise *pp = SeqAt(sp->promises, ppi);
                    ExpandPromise(ctx, pp, CommonEvalPromise, NULL);
                }

                EvalContextStackPopFrame(ctx);
            }

            EvalContextStackPopFrame(ctx);
        }

        PolicyResolve(ctx, policy, config);

        // TODO: need to move this inside PolicyCheckRunnable eventually.
        if (!config->bundlesequence && config->check_runnable)
        {
            // only verify policy-defined bundlesequence for cf-agent, cf-promises
            if ((config->agent_type == AGENT_TYPE_AGENT) ||
                (config->agent_type == AGENT_TYPE_COMMON))
            {
                if (!VerifyBundleSequence(ctx, policy, config))
                {
                    FatalError(ctx, "Errors in promise bundles: could not verify bundlesequence");
                }
            }
        }
    }

    JsonElement *validated_doc = ReadReleaseIdFileFromInputs();
    if (validated_doc)
    {
        const char *release_id = JsonObjectGetAsString(validated_doc, "releaseId");
        if (release_id)
        {
            policy->release_id = xstrdup(release_id);
        }
        JsonDestroy(validated_doc);
    }

    return policy;
}
Beispiel #22
0
static GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int optindex = 0;
    int c;
    char ld_library_path[CF_BUFSIZE];
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_EXECUTOR);

    while ((c = getopt_long(argc, argv, "dvnKIf:D:N:VxL:hFOV1gMWlC::", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 'l':
            LEGACY_OUTPUT = true;
            break;

        case 'f':
            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 'D':
            config->heap_soft = StringSetFromString(optarg, ',');
            break;

        case 'N':
            config->heap_negated = StringSetFromString(optarg, ',');
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            NO_FORK = true; // TODO: really?
            break;

        case 'n':
            DONTDO = true;
            config->ignore_locks = true;
            break;

        case 'L':
            snprintf(ld_library_path, CF_BUFSIZE - 1, "LD_LIBRARY_PATH=%s", optarg);
            putenv(xstrdup(ld_library_path));
            break;

        case 'W':
            WINSERVICE = false;
            break;

        case 'F':
            NO_FORK = true;
            break;

        case 'O':
            ONCE = true;
            NO_FORK = true;
            break;

        case 'V':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteVersion(w);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'h':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-execd", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'M':
            {
                Writer *out = FileWriter(stdout);
                ManPageWrite(out, "cf-execd", time(NULL),
                             CF_EXECD_SHORT_DESCRIPTION,
                             CF_EXECD_MANPAGE_LONG_DESCRIPTION,
                             OPTIONS, HINTS,
                             true);
                FileWriterDetach(out);
                exit(EXIT_SUCCESS);
            }

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(EXIT_SUCCESS);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        default:
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-execd", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(EXIT_FAILURE);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}
GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_SERVER, GetTTYInteractive());

    while ((c = getopt_long(argc, argv, "dvIKf:D:N:VSxLFMhAC::l",
                            OPTIONS, NULL))
           != -1)
    {
        switch (c)
        {
        case 'f':
            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            NO_FORK = true;
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 'D':
            {
                StringSet *defined_classes = StringSetFromString(optarg, ',');
                if (! config->heap_soft)
                {
                    config->heap_soft = defined_classes;
                }
                else
                {
                    StringSetJoin(config->heap_soft, defined_classes);
                    free(defined_classes);
                }
            }
            break;

        case 'N':
            {
                StringSet *negated_classes = StringSetFromString(optarg, ',');
                if (! config->heap_negated)
                {
                    config->heap_negated = negated_classes;
                }
                else
                {
                    StringSetJoin(config->heap_negated, negated_classes);
                    free(negated_classes);
                }
            }
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            NO_FORK = true;
            break;

        case 'F':
            NO_FORK = true;
            break;

        case 'L':
        {
            static char ld_library_path[CF_BUFSIZE]; /* GLOBAL_A */
            Log(LOG_LEVEL_VERBOSE, "Setting LD_LIBRARY_PATH to '%s'", optarg);
            snprintf(ld_library_path, CF_BUFSIZE - 1, "LD_LIBRARY_PATH=%s", optarg);
            putenv(ld_library_path);
            break;
        }

        case 'V':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteVersion(w);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'h':
            {
                Writer *w = FileWriter(stdout);
                WriterWriteHelp(w, "cf-serverd", OPTIONS, HINTS, true, NULL);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'M':
            {
                Writer *out = FileWriter(stdout);
                ManPageWrite(out, "cf-serverd", time(NULL),
                             CF_SERVERD_SHORT_DESCRIPTION,
                             CF_SERVERD_MANPAGE_LONG_DESCRIPTION,
                             OPTIONS, HINTS,
                             true);
                FileWriterDetach(out);
                exit(EXIT_SUCCESS);
            }

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(EXIT_SUCCESS);

        case 'A':
#ifdef SUPPORT_AVAHI_CONFIG
            Log(LOG_LEVEL_NOTICE, "Generating Avahi configuration file.");
            if (GenerateAvahiConfig("/etc/avahi/services/cfengine-hub.service") != 0)
            {
                exit(EXIT_FAILURE);
            }
            cf_popen("/etc/init.d/avahi-daemon restart", "r", true);
            Log(LOG_LEVEL_NOTICE, "Avahi configuration file generated successfully.");
#else
            Log(LOG_LEVEL_ERR, "Generating avahi configuration can only be done when avahi-daemon and libavahi are installed on the machine.");
#endif
            exit(EXIT_SUCCESS);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        case 'l':
            LoggingEnableTimestamps(true);
            break;

        default:
            {
                Writer *w = FileWriter(stdout);
                WriterWriteHelp(w, "cf-serverd", OPTIONS, HINTS, true, NULL);
                FileWriterDetach(w);
            }
            exit(EXIT_FAILURE);
        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}
Beispiel #24
0
static GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int optindex = 0;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_KEYGEN);

    while ((c = getopt_long(argc, argv, "dvf:VMp:sr:t:hl:C::", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 'f':
            KEY_PATH = optarg;
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'V':
            PrintVersion();
            exit(0);

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'p': /* print digest */
            print_digest_arg = optarg;
            break;

        case 's':
            SHOWHOSTS = true;
            break;

        case 'r':
            REMOVEKEYS = true;
            remove_keys_host = optarg;
            break;

        case 'l':
            LICENSE_INSTALL = true;
            strlcpy(LICENSE_SOURCE, optarg, sizeof(LICENSE_SOURCE));
            break;

        case 't':
            trust_key_arg = optarg;
            break;

        case 'h':
            PrintHelp("cf-key", OPTIONS, HINTS, false);
            exit(0);

        case 'M':
            {
                Writer *out = FileWriter(stdout);
                ManPageWrite(out, "cf-key", time(NULL),
                             CF_KEY_SHORT_DESCRIPTION,
                             CF_KEY_MANPAGE_LONG_DESCRIPTION,
                             OPTIONS, HINTS,
                             false);
                FileWriterDetach(out);
                exit(EXIT_SUCCESS);
            }

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        default:
            PrintHelp("cf-key", OPTIONS, HINTS, false);
            exit(1);

        }
    }

    return config;
}
Beispiel #25
0
CFTestD_Config *CFTestD_CheckOpts(int argc, char **argv, long *n_threads)
{
    extern char *optarg;
    int c;
    CFTestD_Config *config = CFTestD_ConfigInit();
    assert(config != NULL);

    while ((c = getopt_long(argc, argv, "a:df:g:hIj:k:lp:vV", OPTIONS, NULL)) != -1)
    {
        switch (c)
        {
        case 'a':
            config->address = xstrdup(optarg);
            break;
        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;
        case 'h':
            CFTestD_Help();
            exit(EXIT_SUCCESS);
        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;
        case 'g':
            LogSetGlobalLevelArgOrExit(optarg);
            break;
        case 'j':
        {
            int ret = StringToLong(optarg, n_threads);
            if (ret != 0)
            {
                Log(LOG_LEVEL_ERR, "Failed to parse number of threads/jobs from '%s'\n", optarg);
                *n_threads = 1;
            }
            break;
        }
        case 'k':
            config->key_file = xstrdup(optarg);
            break;
        case 'l':
            LoggingEnableTimestamps(true);
            break;
        case 'p':
        {
            bool ret = SetCfenginePort(optarg);
            if (!ret)
            {
                /* the function call above logs an error for us (if any) */
                exit(EXIT_FAILURE);
            }
            break;
        }
        case 'r':
            config->report_file = xstrdup(optarg);
            break;
        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;
        case 'V':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteVersion(w);
            FileWriterDetach(w);
        }
            exit(EXIT_SUCCESS);
        default:
            CFTestD_Help();
            exit(EXIT_FAILURE);
        }
    }

    if (optind < argc) // More unparsed arguments left after getopt_long
    {
        // Enumerate and print all invalid arguments:
        Log(LOG_LEVEL_ERR, "Invalid command line arguments:");

        int start = optind;
        int stop  = argc;
        int total = stop - start;
        for (int i = 0; i < total; ++i)
        {
            Log(LOG_LEVEL_ERR,
                "[%d/%d]: %s\n",
                i + 1,
                total,
                argv[start + i]);
        }
    }

    return config;
}
Beispiel #26
0
void RvalShow(FILE *fp, Rval rval)
{
    Writer *w = FileWriter(fp);
    RvalWrite(w, rval);
    FileWriterDetach(w);
}
Beispiel #27
0
static void ShowContext(EvalContext *ctx)
{
    {
        Writer *w = NULL;
        if (LEGACY_OUTPUT)
        {
            w = FileWriter(stdout);
            WriterWriteF(w, "%s>  -> Hard classes = {", VPREFIX);
        }
        else
        {
            w = StringWriter();
            WriterWrite(w, "Discovered hard classes:");
        }

        Seq *hard_contexts = SeqNew(1000, NULL);
        SetIterator it = EvalContextHeapIteratorHard(ctx);
        char *context = NULL;
        while ((context = SetIteratorNext(&it)))
        {
            if (!EvalContextHeapContainsNegated(ctx, context))
            {
                SeqAppend(hard_contexts, context);
            }
        }

        SeqSort(hard_contexts, (SeqItemComparator)strcmp, NULL);

        for (size_t i = 0; i < SeqLength(hard_contexts); i++)
        {
            const char *context = SeqAt(hard_contexts, i);

            WriterWriteF(w, " %s", context);
        }

        if (LEGACY_OUTPUT)
        {
            WriterWrite(w, "}\n");
            FileWriterDetach(w);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "%s", StringWriterData(w));
            WriterClose(w);
        }


        SeqDestroy(hard_contexts);
    }

    {
        Writer *w = NULL;
        if (LEGACY_OUTPUT)
        {
            w = FileWriter(stdout);
            WriterWriteF(w, "%s>  -> Additional classes = {", VPREFIX);
        }
        else
        {
            w = StringWriter();
            WriterWrite(w, "Additional classes:");
        }

        Seq *soft_contexts = SeqNew(1000, NULL);
        SetIterator it = EvalContextHeapIteratorSoft(ctx);
        char *context = NULL;
        while ((context = SetIteratorNext(&it)))
        {
            if (!EvalContextHeapContainsNegated(ctx, context))
            {
                SeqAppend(soft_contexts, context);
            }
        }

        SeqSort(soft_contexts, (SeqItemComparator)strcmp, NULL);

        for (size_t i = 0; i < SeqLength(soft_contexts); i++)
        {
            const char *context = SeqAt(soft_contexts, i);
            WriterWriteF(w, " %s", context);
        }

        if (LEGACY_OUTPUT)
        {
            WriterWrite(w, "}\n");
            FileWriterDetach(w);
        }
        else
        {
            if (SeqLength(soft_contexts) > 0)
            {
                Log(LOG_LEVEL_VERBOSE, "%s", StringWriterData(w));
            }
            WriterClose(w);
        }
        SeqDestroy(soft_contexts);
    }

    {
        bool have_negated_classes = false;
        Writer *w = NULL;
        if (LEGACY_OUTPUT)
        {
            w = FileWriter(stdout);
            WriterWriteF(w, "%s>  -> Negated classes = {", VPREFIX);
        }
        else
        {
            w = StringWriter();
            WriterWrite(w, "Negated classes:");
        }

        StringSetIterator it = EvalContextHeapIteratorNegated(ctx);
        const char *context = NULL;
        while ((context = StringSetIteratorNext(&it)))
        {
            WriterWriteF(w, " %s", context);
            have_negated_classes = true;
        }

        if (LEGACY_OUTPUT)
        {
            WriterWrite(w, "}\n");
            FileWriterDetach(w);
        }
        else
        {
            if (have_negated_classes)
            {
                Log(LOG_LEVEL_VERBOSE, "%s", StringWriterData(w));
            }
            WriterClose(w);
        }
    }
}
Beispiel #28
0
GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int optindex = 0;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON);

    while ((c = getopt_long(argc, argv, "dvnIf:D:N:VSrxMb:i:p:s:cg:hW:lC::", OPTIONS, &optindex)) != EOF)
    {
        switch ((char) c)
        {
        case 0:
            switch (optindex)
            {
            case PROMISES_OPTION_EVAL_FUNCTIONS:
                if (!optarg)
                {
                    optarg = "yes";
                }
                config->agent_specific.common.eval_functions = strcmp("yes", optarg) == 0;
                break;

            case PROMISES_OPTION_SHOW_CLASSES:
                if (!optarg)
                {
                    optarg = "yes";
                }
                config->agent_specific.common.show_classes = strcmp("yes", optarg) == 0;
                break;

            case PROMISES_OPTION_SHOW_VARIABLES:
                if (!optarg)
                {
                    optarg = "yes";
                }
                config->agent_specific.common.show_variables = strcmp("yes", optarg) == 0;
                break;

            default:
                break;
            }

        case 'l':
            LEGACY_OUTPUT = true;
            break;

        case 'c':
            config->check_runnable = true;
            break;

        case 'f':

            if (optarg && (strlen(optarg) < 5))
            {
                Log(LOG_LEVEL_ERR, " -f used but argument '%s' incorrect", optarg);
                exit(EXIT_FAILURE);
            }

            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'b':
            if (optarg)
            {
                Rlist *bundlesequence = RlistFromSplitString(optarg, ',');
                GenericAgentConfigSetBundleSequence(config, bundlesequence);
                RlistDestroy(bundlesequence);
            }
            break;

        case 'p':
            if (strcmp("none", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE;
            }
            else if (strcmp("cf", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF;
            }
            else if (strcmp("json", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON;
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid policy output format: '%s'. Possible values are 'none', 'cf', 'json'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 's':
            if (strcmp("none", optarg) == 0)
            {
                break;
            }
            else if (strcmp("json", optarg) == 0)
            {
                JsonElement *json_syntax = SyntaxToJson();
                Writer *out = FileWriter(stdout);
                JsonWrite(out, json_syntax, 0);
                FileWriterDetach(out);
                JsonDestroy(json_syntax);
                exit(EXIT_SUCCESS);
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid syntax description output format: '%s'. Possible values are 'none', 'json'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 'D':
            config->heap_soft = StringSetFromString(optarg, ',');
            break;

        case 'N':
            config->heap_negated = StringSetFromString(optarg, ',');
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'n':
            DONTDO = true;
            config->ignore_locks = true;
            break;

        case 'V':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteVersion(w);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'h':
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(EXIT_SUCCESS);

        case 'M':
            {
                Writer *out = FileWriter(stdout);
                ManPageWrite(out, "cf-promises", time(NULL),
                             CF_PROMISES_SHORT_DESCRIPTION,
                             CF_PROMISES_MANPAGE_LONG_DESCRIPTION,
                             OPTIONS, HINTS,
                             true);
                FileWriterDetach(out);
                exit(EXIT_SUCCESS);
            }

        case 'r':
            SHOWREPORTS = true;
            break;

        case 'W':
            if (!GenericAgentConfigParseWarningOptions(config, optarg))
            {
                Log(LOG_LEVEL_ERR, "Error parsing warning option");
                exit(EXIT_FAILURE);
            }
            break;

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(EXIT_SUCCESS);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        default:
            {
                Writer *w = FileWriter(stdout);
                GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
                FileWriterDetach(w);
            }
            exit(EXIT_FAILURE);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}
Beispiel #29
0
PromiseResult ScheduleEditOperation(EvalContext *ctx, char *filename, Attributes a, Promise *pp)
{
    void *vp;
    FnCall *fp;
    Rlist *args = NULL;
    char edit_bundle_name[CF_BUFSIZE], lockname[CF_BUFSIZE], qualified_edit[CF_BUFSIZE], *method_deref;
    CfLock thislock;

    snprintf(lockname, CF_BUFSIZE - 1, "fileedit-%s", filename);
    thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction, pp, false);

    if (thislock.lock == NULL)
    {
        return PROMISE_RESULT_NOOP;
    }

    EditContext *edcontext = NewEditContext(filename, a);

    PromiseResult result = PROMISE_RESULT_NOOP;
    if (edcontext == NULL)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "File '%s' was marked for editing but could not be opened", filename);
        result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
        goto exit;
    }

    Policy *policy = PolicyFromPromise(pp);

    if (a.haveeditline)
    {
        if ((vp = ConstraintGetRvalValue(ctx, "edit_line", pp, RVAL_TYPE_FNCALL)))
        {
            fp = (FnCall *) vp;
            strcpy(edit_bundle_name, fp->name);
            args = fp->args;
        }
        else if ((vp = ConstraintGetRvalValue(ctx, "edit_line", pp, RVAL_TYPE_SCALAR)))
        {
            strcpy(edit_bundle_name, (char *) vp);
            args = NULL;
        }             
        else
        {
            goto exit;
        }

        if (strncmp(edit_bundle_name,"default:",strlen("default:")) == 0) // CF_NS == ':'
        {
            method_deref = strchr(edit_bundle_name, CF_NS) + 1;
        }
        else if ((strchr(edit_bundle_name, CF_NS) == NULL) && (strcmp(PromiseGetNamespace(pp), "default") != 0))
        {
            snprintf(qualified_edit, CF_BUFSIZE, "%s%c%s", PromiseGetNamespace(pp), CF_NS, edit_bundle_name);
            method_deref = qualified_edit;
        }
        else            
        {
            method_deref = edit_bundle_name;
        }        

        Log(LOG_LEVEL_VERBOSE, "Handling file edits in edit_line bundle '%s'", method_deref);

        Bundle *bp = NULL;
        if ((bp = PolicyGetBundle(policy, NULL, "edit_line", method_deref)))
        {
            BannerSubBundle(bp, args);

            EvalContextStackPushBundleFrame(ctx, bp, args, a.edits.inherit);

            BundleResolve(ctx, bp);

            ScheduleEditLineOperations(ctx, bp, a, pp, edcontext);

            EvalContextStackPopFrame(ctx);
        }
        else
        {
            Log(LOG_LEVEL_ERR, "Did not find method '%s' in bundle '%s' for edit operation", method_deref, edit_bundle_name);
        }
    }


    if (a.haveeditxml)
    {
        if ((vp = ConstraintGetRvalValue(ctx, "edit_xml", pp, RVAL_TYPE_FNCALL)))
        {
            fp = (FnCall *) vp;
            strcpy(edit_bundle_name, fp->name);
            args = fp->args;
        }
        else if ((vp = ConstraintGetRvalValue(ctx, "edit_xml", pp, RVAL_TYPE_SCALAR)))
        {
            strcpy(edit_bundle_name, (char *) vp);
            args = NULL;
        }
        else
        {
            goto exit;
        }

        if (strncmp(edit_bundle_name,"default:",strlen("default:")) == 0) // CF_NS == ':'
        {
            method_deref = strchr(edit_bundle_name, CF_NS) + 1;
        }
        else
        {
            method_deref = edit_bundle_name;
        }
        
        Log(LOG_LEVEL_VERBOSE, "Handling file edits in edit_xml bundle '%s'", method_deref);

        Bundle *bp = NULL;
        if ((bp = PolicyGetBundle(policy, NULL, "edit_xml", method_deref)))
        {
            BannerSubBundle(bp, args);

            EvalContextStackPushBundleFrame(ctx, bp, args, a.edits.inherit);
            BundleResolve(ctx, bp);

            ScheduleEditXmlOperations(ctx, bp, a, pp, edcontext);

            EvalContextStackPopFrame(ctx);
        }
    }

    
    if (a.edit_template)
    {
        if (!a.template_method || strcmp("cfengine", a.template_method) == 0)
        {
            Policy *tmp_policy = PolicyNew();
            Bundle *bp = NULL;
            if ((bp = MakeTemporaryBundleFromTemplate(ctx, tmp_policy, a, pp, &result)))
            {
                BannerSubBundle(bp, args);
                a.haveeditline = true;

                EvalContextStackPushBundleFrame(ctx, bp, args, a.edits.inherit);
                BundleResolve(ctx, bp);

                ScheduleEditLineOperations(ctx, bp, a, pp, edcontext);

                EvalContextStackPopFrame(ctx);
            }

            PolicyDestroy(tmp_policy);
        }
        else if (strcmp("mustache", a.template_method) == 0)
        {
            if (!FileCanOpen(a.edit_template, "r"))
            {
                cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Template file '%s' could not be opened for reading", a.edit_template);
                result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
                goto exit;
            }

            Writer *ouput_writer = NULL;
            {
                FILE *output_file = fopen(pp->promiser, "w");
                if (!output_file)
                {
                    cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Output file '%s' could not be opened for writing", pp->promiser);
                    result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
                    goto exit;
                }

                ouput_writer = FileWriter(output_file);
            }

            Writer *template_writer = FileRead(a.edit_template, SIZE_MAX, NULL);
            if (!template_writer)
            {
                cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not read template file '%s'", a.edit_template);
                result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
                WriterClose(ouput_writer);
                goto exit;
            }

            JsonElement *default_template_data = NULL;
            if (!a.template_data)
            {
                a.template_data = default_template_data = DefaultTemplateData(ctx);
            }

            if (!MustacheRender(ouput_writer, StringWriterData(template_writer), a.template_data))
            {
                cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Error rendering mustache template '%s'", a.edit_template);
                result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL);
                WriterClose(template_writer);
                WriterClose(ouput_writer);
                goto exit;
            }

            JsonDestroy(default_template_data);
            WriterClose(template_writer);
            WriterClose(ouput_writer);
        }
    }

exit:
    result = PromiseResultUpdate(result, FinishEditContext(ctx, edcontext, a, pp));
    YieldCurrentLock(thislock);
    return result;
}
Beispiel #30
0
void RlistShow(FILE *fp, const Rlist *list)
{
    Writer *w = FileWriter(fp);
    RlistWrite(w, list);
    FileWriterDetach(w);
}