static gboolean system_generate_system(CfgLexer *lexer, gint type, const gchar *name, CfgArgs *args, gpointer user_data) { gchar buf[256]; GString *sysblock; gboolean result = FALSE; GlobalConfig *cfg = (GlobalConfig *) user_data; g_snprintf(buf, sizeof(buf), "source confgen system"); sysblock = g_string_sized_new(1024); g_string_append(sysblock, "channel {\n" " source {\n"); if (!system_generate_system_transports(sysblock)) { goto exit; } g_string_append(sysblock, " }; # source\n"); system_generate_cim_parser(cfg, sysblock); g_string_append(sysblock, "}; # channel\n"); result = cfg_lexer_include_buffer(lexer, buf, sysblock->str, sysblock->len); exit: g_string_free(sysblock, TRUE); return result; }
gboolean confgen_generate(CfgLexer *lexer, gint type, const gchar *name, CfgArgs *args, gpointer user_data) { gchar *value; gsize value_len = 0; FILE *out; gchar *exec = (gchar *) user_data; gsize res; gchar buf[256]; g_snprintf(buf, sizeof(buf), "%s confgen %s", cfg_lexer_lookup_context_name_by_type(type), name); if (!cfg_args_validate(args, NULL, buf)) { msg_error("confgen: confgen invocations do not process arguments, but your argument list is not empty", evt_tag_str("context", cfg_lexer_lookup_context_name_by_type(type)), evt_tag_str("block", name), NULL); return FALSE; } out = popen((gchar *) user_data, "r"); if (!out) { msg_error("confgen: Error executing generator program", evt_tag_str("context", cfg_lexer_lookup_context_name_by_type(type)), evt_tag_str("block", name), evt_tag_str("exec", exec), evt_tag_errno("error", errno), NULL); return FALSE; } value = g_malloc(1024); while ((res = fread(value + value_len, 1, 1024, out)) > 0) { value_len += res; value = g_realloc(value, value_len + 1024); } res = pclose(out); if (res != 0) { msg_error("confgen: Generator program returned with non-zero exit code", evt_tag_str("block", name), evt_tag_str("exec", exec), evt_tag_int("rc", res), NULL); g_free(value); return FALSE; } if (!cfg_lexer_include_buffer(lexer, buf, value, value_len)) { g_free(value); return FALSE; } return TRUE; }
int cfg_lexer_lex(CfgLexer *self, YYSTYPE *yylval, YYLTYPE *yylloc) { CfgBlockGenerator *gen; gint tok; gboolean injected; relex: injected = cfg_lexer_consume_next_injected_token(self, &tok, yylval, yylloc); if (!injected) { if (cfg_lexer_get_context_type(self) == LL_CONTEXT_BLOCK_CONTENT) cfg_lexer_start_block_state(self, "{}"); else if (cfg_lexer_get_context_type(self) == LL_CONTEXT_BLOCK_ARG) cfg_lexer_start_block_state(self, "()"); yylval->type = 0; g_string_truncate(self->token_text, 0); g_string_truncate(self->token_pretext, 0); tok = _invoke__cfg_lexer_lex(self, yylval, yylloc); if (yylval->type == 0) yylval->type = tok; if (self->preprocess_output) g_string_append_printf(self->preprocess_output, "%s", self->token_pretext->str); } /* NOTE: most of the code below is a monster, which should be factored out * to tiny little functions. This is not very simple and I am in the * middle of something that I would rather close than doing the * refactoring desperately needed here. I am silencing my conscience with * this note and also take the time to document some of the quirks below. * * 1) This code is deeply coupled with GlobalConfig and most of it does * not make sense to execute if self->cfg is NULL. Thus, some of the * conditionals contain an explicit self->cfg check, in other cases it is * implicitly checked by the first conditional of a series of if-then-else * statements. * * 2) the role of the relex label is to restart the lexing process once * new tokens were injected into the input stream. (e.g. after a * generator was called). This should really be a loop, and quite * possible any refactors should start here by eliminating that * loop-using-goto * * 3) make note that string tokens are allocated by malloc/free and not * g_malloc/g_free, this is significant. The grammar contains the free() * call, so getting rid of that would require a lot of changes to the * grammar. (on Windows glib, malloc/g_malloc are NOT equivalent) * */ if (tok == LL_IDENTIFIER && self->cfg && (gen = cfg_lexer_find_generator(self, self->cfg, cfg_lexer_get_context_type(self), yylval->cptr))) { CfgArgs *args; CfgIncludeLevel *level = &self->include_stack[self->include_depth]; self->preprocess_suppress_tokens++; gint saved_line = level->lloc.first_line; gint saved_column = level->lloc.first_column; if (cfg_parser_parse(&block_ref_parser, self, (gpointer *) &args, NULL)) { gboolean success; gchar buf[256]; GString *result = g_string_sized_new(256); level->lloc.first_line = saved_line; level->lloc.first_column = saved_column; self->preprocess_suppress_tokens--; success = cfg_block_generator_generate(gen, self->cfg, args, result, cfg_lexer_format_location(self, &level->lloc, buf, sizeof(buf))); free(yylval->cptr); cfg_args_unref(args); if (!success) { g_string_free(result, TRUE); return LL_ERROR; } cfg_block_generator_format_name(gen, buf, sizeof(buf)); if (gen->suppress_backticks) success = cfg_lexer_include_buffer_without_backtick_substitution(self, buf, result->str, result->len); else success = cfg_lexer_include_buffer(self, buf, result->str, result->len); g_string_free(result, TRUE); if (!success) return LL_ERROR; goto relex; } else { level->lloc.first_line = saved_line; level->lloc.first_column = saved_column; free(yylval->cptr); self->preprocess_suppress_tokens--; return LL_ERROR; } } if (self->ignore_pragma || self->cfg == NULL) { /* only process @pragma/@include tokens in case pragma allowed is set * and the associated configuration is not NULL */ ; } else if (tok == LL_PRAGMA) { gpointer dummy; if (self->preprocess_output) g_string_append_printf(self->preprocess_output, "@"); if (!cfg_parser_parse(&pragma_parser, self, &dummy, NULL)) { return LL_ERROR; } goto relex; } else if (tok == KW_INCLUDE && cfg_lexer_get_context_type(self) != LL_CONTEXT_PRAGMA) { gchar *include_file; self->preprocess_suppress_tokens++; tok = cfg_lexer_lex(self, yylval, yylloc); if (tok != LL_STRING && tok != LL_IDENTIFIER) { self->preprocess_suppress_tokens--; return LL_ERROR; } include_file = g_strdup(yylval->cptr); free(yylval->cptr); tok = cfg_lexer_lex(self, yylval, yylloc); if (tok != ';') { self->preprocess_suppress_tokens--; g_free(include_file); return LL_ERROR; } if (!cfg_lexer_include_file(self, include_file)) { g_free(include_file); self->preprocess_suppress_tokens--; return LL_ERROR; } self->preprocess_suppress_tokens--; g_free(include_file); goto relex; } else if (self->cfg->user_version == 0 && self->cfg->parsed_version != 0) { if (!cfg_set_version(self->cfg, configuration->parsed_version)) return LL_ERROR; } else if (cfg_lexer_get_context_type(self) != LL_CONTEXT_PRAGMA && !self->non_pragma_seen) { /* first non-pragma token */ if (self->cfg->user_version == 0 && self->cfg->parsed_version == 0) { msg_error("ERROR: configuration files without a version number has become unsupported in " VERSION_3_13 ", please specify a version number using @version and update your configuration accordingly"); return LL_ERROR; } cfg_load_candidate_modules(self->cfg); cfg_load_forced_modules(self->cfg); self->non_pragma_seen = TRUE; } if (!injected) { if (self->preprocess_suppress_tokens == 0 && self->preprocess_output) { g_string_append_printf(self->preprocess_output, "%s", self->token_text->str); } } return tok; }
gboolean system_generate_system(CfgLexer *lexer, gint type, const gchar *name, CfgArgs *args, gpointer user_data) { gchar buf[256]; GString *sysblock; struct utsname u; g_snprintf(buf, sizeof(buf), "source confgen system"); sysblock = g_string_sized_new(1024); if (uname(&u) < 0) { msg_error("system(): Cannot get information about the running kernel", evt_tag_errno("error", errno), NULL); return FALSE; } if (strcmp(u.sysname, "Linux") == 0) { char *log = system_linux_find_dev_log (); if (!log) { return FALSE; } system_sysblock_add_unix_dgram(sysblock, log, NULL, "8192"); system_sysblock_add_linux_kmsg(sysblock); } else if (strcmp(u.sysname, "SunOS") == 0) { system_sysblock_add_module(sysblock, "afstreams"); if (strcmp(u.release, "5.8") == 0) system_sysblock_add_sun_streams(sysblock, "/dev/log", NULL); else if (strcmp(u.release, "5.9") == 0) system_sysblock_add_sun_streams(sysblock, "/dev/log", "/etc/.syslog_door"); else system_sysblock_add_sun_streams(sysblock, "/dev/log", "/var/run/syslog_door"); } else if (strcmp(u.sysname, "FreeBSD") == 0) { system_sysblock_add_unix_dgram(sysblock, "/var/run/log", NULL, NULL); system_sysblock_add_unix_dgram(sysblock, "/var/run/logpriv", "0600", NULL); system_sysblock_add_freebsd_klog(sysblock, u.release); } else if (strcmp(u.sysname, "GNU/kFreeBSD") == 0) { system_sysblock_add_unix_dgram(sysblock, "/var/run/log", NULL, NULL); system_sysblock_add_freebsd_klog(sysblock, u.release); } else if (strcmp(u.sysname, "HP-UX") == 0) { system_sysblock_add_pipe(sysblock, "/dev/log", 2048); } else if (strcmp(u.sysname, "AIX") == 0 || strcmp(u.sysname, "OSF1") == 0 || strncmp(u.sysname, "CYGWIN", 6) == 0) { system_sysblock_add_unix_dgram(sysblock, "/dev/log", NULL, NULL); } else { msg_error("system(): Error detecting platform, unable to define the system() source. " "Please send your system information to the developers!", evt_tag_str("sysname", u.sysname), evt_tag_str("release", u.release), NULL); return FALSE; } if (!cfg_lexer_include_buffer(lexer, buf, sysblock->str, sysblock->len)) { g_string_free(sysblock, TRUE); return FALSE; } return TRUE; }
gboolean system_generate_system(CfgLexer *lexer, gint type, const gchar *name, CfgArgs *args, gpointer user_data) { gchar buf[256]; GString *sysblock; struct utsname u; g_snprintf(buf, sizeof(buf), "source confgen system"); sysblock = g_string_sized_new(1024); if (uname(&u) != 0) { msg_error("system(): Cannot get information about the running kernel", evt_tag_errno("error", errno), NULL); return FALSE; } if (strcmp(u.sysname, "Linux") == 0) { char *log = "/dev/log"; if (getenv("LISTEN_FDS") != NULL) { struct stat sbuf; if (stat("/run/systemd/journal/syslog", &sbuf) == 0) { if (S_ISSOCK(sbuf.st_mode)) log = "/run/systemd/journal/syslog"; } } system_sysblock_add_unix_dgram(sysblock, log, NULL, "8192"); if (access("/proc/kmsg", R_OK) == -1) { msg_warning("system(): /proc/kmsg is not readable, please " "check permissions if this is unintentional.", evt_tag_errno("error", errno), NULL); } else system_sysblock_add_file(sysblock, "/proc/kmsg", -1, "kernel", "kernel"); } else if (strcmp(u.sysname, "SunOS") == 0) { system_sysblock_add_module(sysblock, "afstreams"); if (strcmp(u.release, "5.8") == 0) system_sysblock_add_sun_streams(sysblock, "/dev/log", NULL); else if (strcmp(u.release, "5.9") == 0) system_sysblock_add_sun_streams(sysblock, "/dev/log", "/etc/.syslog_door"); else system_sysblock_add_sun_streams(sysblock, "/dev/log", "/var/run/syslog_door"); } else if (strcmp(u.sysname, "FreeBSD") == 0) { system_sysblock_add_unix_dgram(sysblock, "/var/run/log", NULL, NULL); system_sysblock_add_unix_dgram(sysblock, "/var/run/logpriv", "0600", NULL); system_sysblock_add_freebsd_klog(sysblock, u.release); } else if (strcmp(u.sysname, "GNU/kFreeBSD") == 0) { system_sysblock_add_unix_dgram(sysblock, "/var/run/log", NULL, NULL); system_sysblock_add_freebsd_klog(sysblock, u.release); } else if (strcmp(u.sysname, "HP-UX") == 0) { system_sysblock_add_pipe(sysblock, "/dev/pipe", 2048); } else if (strcmp(u.sysname, "AIX") == 0 || strcmp(u.sysname, "OSF1") == 0 || strncmp(u.sysname, "CYGWIN", 6) == 0) { system_sysblock_add_unix_dgram(sysblock, "/dev/log", NULL, NULL); } else { msg_error("system(): Error detecting platform, unable to define the system() source. " "Please send your system information to the developers!", evt_tag_str("sysname", u.sysname), evt_tag_str("release", u.release), NULL); return FALSE; } if (!cfg_lexer_include_buffer(lexer, buf, sysblock->str, sysblock->len)) { g_string_free(sysblock, TRUE); return FALSE; } return TRUE; }