void print_help(const int debuglvl, char *part) { struct vrmr_list HelpList; int max_height = 0, max_width = 0, height = 0, width = 0, startx = 0, starty = 0; #ifdef USE_WIDEC wchar_t wpart[32] = L""; #endif /* USE_WIDEC */ /* get screensize */ getmaxyx(stdscr, max_height, max_width); width = 72; height = max_height - 6; startx = max_width - width - 5; starty = 3; #ifdef USE_WIDEC if(utf8_mode == FALSE) { #endif /* USE_WIDEC */ /* read the helpfile */ if(read_helpfile(debuglvl, &HelpList, part) < 0) return; set_lines(debuglvl, &HelpList, (size_t)(width - 4)); print_list(debuglvl, &HelpList, gettext("Help"), height, width, starty, startx, UTF8_FALSE); vrmr_list_cleanup(debuglvl, &HelpList); #ifdef USE_WIDEC } else { /* convert the part name to a wchar_t string */ mbstowcs(wpart, part, wsizeof(wpart)); if(debuglvl >= LOW) vrmr_debug(__FUNC__, "part: %s, wpart %ls, %u", part, wpart, wsizeof(wpart)); /* read the helpfile */ if(read_wide_helpfile(debuglvl, &HelpList, wpart) < 0) return; set_wide_lines(debuglvl, &HelpList, width - 4); print_list(debuglvl, &HelpList, gettext("Help"), height, width, starty, startx, UTF8_TRUE); vrmr_list_cleanup(debuglvl, &HelpList); } #endif /* USE_WIDEC */ }
int read_wide_helpfile(const int debuglvl, struct vrmr_list *help_list, wchar_t *part) { wchar_t line[128] = L""; FILE *fp = NULL; char inrange = 0; char helpfile[256] = ""; /* safety */ if(!help_list || !part) { vrmr_error(-1, VR_INTERR, "parameter problem " "(in: %s:%d).", __FUNC__, __LINE__); return(-1); } /* setup the list */ if(vrmr_list_setup(debuglvl, help_list, free_helpword) < 0) { vrmr_error(-1, VR_INTERR, "vrmr_list_setup failed " "(in: %s:%d).", __FUNC__, __LINE__); return(-1); } if(utf8_mode == 1) { /* TRANSLATORS: translate this to you language code: so for 'ru' use 'vuurmuur-ru.UTF-8.hlp', for 'pt_BR' use 'vuurmuur-pt_BR.UTF-8.hlp' */ if(snprintf(helpfile, sizeof(helpfile), "%s/%s", vccnf.helpfile_location, gettext("vuurmuur.UTF-8.hlp") ) >= (int)sizeof(helpfile)) { vrmr_error(-1, VR_INTERR, "buffer too small " "for helpfile supplied at compile-time " "(in: %s:%d).", __FUNC__, __LINE__); return(-1); } vrmr_sanitize_path(debuglvl, helpfile, sizeof(helpfile)); /* open the file */ fp = fopen(helpfile, "r"); } if(fp == NULL) { if(utf8_mode == 1) vrmr_debug(__FUNC__, "opening '%s' failed: " "%s, falling back to non UTF-8 language file.", helpfile, strerror(errno)); /* UTF-8 language helpfile does not exist, try to fall back to default */ /* TRANSLATORS: translate this to you language code: so for 'ru' use 'vuurmuur-ru.hlp', for 'pt_BR' use 'vuurmuur-pt_BR.hlp' */ if(snprintf(helpfile, sizeof(helpfile), "%s/%s", vccnf.helpfile_location, gettext("vuurmuur.hlp")) >= (int)sizeof(helpfile)) { vrmr_error(-1, "Error", "buffer too small for " "helpfile supplied at compile-time " "(in: %s:%d).", __FUNC__, __LINE__); return(-1); } vrmr_sanitize_path(debuglvl, helpfile, sizeof(helpfile)); } /* open the file */ fp = fopen(helpfile, "r"); if(fp == NULL) { vrmr_debug(__FUNC__, "opening '%s' failed: %s, " "falling back to default.", helpfile, strerror(errno)); /* language helpfile does not exist, try to fall back to default */ if(snprintf(helpfile, sizeof(helpfile), "%s/vuurmuur.hlp", vccnf.helpfile_location) >= (int)sizeof(helpfile)) { vrmr_error(-1, "Error", "buffer too small for " "helpfile supplied at compile-time " "(in: %s:%d).", __FUNC__, __LINE__); return(-1); } vrmr_sanitize_path(debuglvl, helpfile, sizeof(helpfile)); if(!(fp = fopen(helpfile, "r"))) { vrmr_error(-1, VR_ERR, "%s %s: %s", STR_OPENING_FILE_FAILED, helpfile, strerror(errno)); return(-1); } } while(fgetws(line, wsizeof(line), fp) != NULL) { if(inrange) { if(wcscmp(line, L":[END]:\n") == 0) { /* implied inrange = 0; */ break; } } if(inrange) { if(read_wide_helpline(debuglvl, help_list, line) < 0) return(-1); } else { if(wcsncmp(line, part, wcslen(part)) == 0) inrange = 1; } } fclose(fp); return(0); }
/* startup_screen This is the splash-screen which calls the startup functions, like loading the plugins, zones, services etc. Returncodes: 0: ok -1: error */ int startup_screen(struct vrmr_ctx *vctx, struct vrmr_rules *rules, struct vrmr_zones *zones, struct vrmr_services *services, struct vrmr_interfaces *interfaces, struct vrmr_blocklist *blocklist, struct vrmr_regex *reg) { WINDOW *startup_win = NULL, *startup_print_win = NULL; PANEL *startup_panel[2]; int retval = 0, maxy = 0, maxx = 0, y = 0, x = 0, width = 50, heigth = 15, result = 0, config_done = 0, cnfresult = 0; int print_pan_width = 40; // get screensize and set windowlocation getmaxyx(stdscr, maxy, maxx); y = (maxy - heigth) / 2; x = (maxx - width) / 2; // create the windows and panels startup_win = create_newwin(heigth, width, y, x, "Vuurmuur_conf", vccnf.color_win_init | A_BOLD); startup_print_win = newwin(1, print_pan_width, y + heigth - 3, x + 5); wbkgd(startup_print_win, vccnf.color_win_init | A_BOLD); startup_panel[0] = new_panel(startup_win); startup_panel[1] = new_panel(startup_print_win); update_panels(); doupdate(); // print the logo: it looks a bit weird here because of escape sequences // also print version mvwprintw(startup_win, 3, 4, " \\\\ // |\\\\ //| "); mvwprintw(startup_win, 4, 4, " \\\\ // | | | | |] ||\\//|| | | | | |] "); mvwprintw(startup_win, 5, 4, " \\// \\/| \\/| |\\ || || \\/| \\/| |\\ "); mvwprintw(startup_win, 6, 4, " Config "); mvwprintw(startup_win, 7, 4, " ------------------------------------ "); mvwprintw(startup_win, 9, 3, "%s ", VUURMUUR_COPYRIGHT); mvwprintw(startup_win, 10, 3, gettext("Version: %s"), VUURMUURCONF_VERSION); mvwprintw(startup_win, 12, 4, "["); mvwprintw(startup_win, 12, 4 + print_pan_width + 1, "]"); /* initialize the vuurmuur conf config */ /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_LOAD_VUURMUUR_CONF_SETTINGS); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); while (!config_done) { result = init_vcconfig(&vctx->conf, vccnf.configfile_location, &vccnf); if (result == VRMR_CNF_E_UNKNOWN_ERR || result == VRMR_CNF_E_PARAMETER) return (-1); else if (result == VRMR_CNF_E_FILE_PERMISSION) { return (-1); } /* missing file? use defaults */ else if (result == VRMR_CNF_E_FILE_MISSING) { vcconfig_use_defaults(&vccnf); werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_LOAD_VUURMUUR_CONF_SETTINGS, STR_COK); update_panels(); doupdate(); config_done = 1; } else if (result == VRMR_CNF_E_MISSING_VAR || result == VRMR_CNF_E_ILLEGAL_VAR || result == VRMR_CNF_W_MISSING_VAR || result == VRMR_CNF_W_ILLEGAL_VAR) { if (confirm(gettext("Problem with the Vuurmuur_conf settings"), gettext("Do you want to edit the settings now?"), vccnf.color_win_note, vccnf.color_win_note_rev | A_BOLD, 1)) { /* this prompt the user with the config menu */ cnfresult = edit_vcconfig(); if (cnfresult < 0) return (-1); } else { /* if the user doesn't want to solve the problem we exit if we had an error in case of a warning, we continue */ if (result == VRMR_CNF_E_MISSING_VAR || result == VRMR_CNF_E_FILE_MISSING) return (-1); else { // TODO: print warning to warn the user that the config is // not yet ok? config_done = 1; } } } else if (result == VRMR_CNF_OK) { werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_LOAD_VUURMUUR_CONF_SETTINGS, STR_COK); update_panels(); doupdate(); config_done = 1; } else { vrmr_error(-1, VR_ERR, "unknown return code from init_vcconfig. This can't be " "good"); return (-1); } if (config_done == 0) { werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_LOAD_VUURMUUR_CONF_SETTINGS); update_panels(); doupdate(); } } /* initialize the config */ config_done = 0; werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_LOAD_VUURMUUR_CONFIG); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); while (!config_done) { result = vrmr_init_config(&vctx->conf); if (result == VRMR_CNF_E_UNKNOWN_ERR || result == VRMR_CNF_E_PARAMETER) return (-1); else if (result == VRMR_CNF_E_FILE_PERMISSION) { return (-1); } else if (result == VRMR_CNF_E_FILE_MISSING || result == VRMR_CNF_E_MISSING_VAR || result == VRMR_CNF_E_ILLEGAL_VAR || result == VRMR_CNF_W_MISSING_VAR || result == VRMR_CNF_W_ILLEGAL_VAR) { if (confirm(gettext("Problem with the Vuurmuur config"), gettext("Do you want to edit the config now?"), vccnf.color_win_note, vccnf.color_win_note_rev | A_BOLD, 1)) { /* this prompt the user with the config menu */ cnfresult = config_menu(&vctx->conf); if (cnfresult < 0) return (-1); } else { /* if the user doesn't want to solve the problem we exit if we had an error in case of a warning, we continue */ if (result == VRMR_CNF_E_MISSING_VAR || result == VRMR_CNF_E_FILE_MISSING) return (-1); else { // TODO: print warning to warn the user that the config is // not yet ok? config_done = 1; } } } else if (result == VRMR_CNF_OK) { werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_LOAD_VUURMUUR_CONFIG, STR_COK); update_panels(); doupdate(); config_done = 1; } else { vrmr_error(-1, VR_INTERR, "unknown return code from vrmr_init_config. This can't be " "good"); return (-1); } if (config_done == 0) { werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_LOAD_VUURMUUR_CONFIG); update_panels(); doupdate(); } } /* config done, so now we can use logprinting */ if (vrmr_debug_level >= LOW) vrprint.info = vuumuurconf_print_info; else vrprint.info = vrmr_logprint_info; vrprint.debug = vrmr_logprint_debug; vrprint.audit = vrmr_logprint_audit; /* print that we started */ vrmr_audit("started: effective user %s (%ld), real user %s (%ld).", vctx->user_data.username, (long)vctx->user_data.user, vctx->user_data.realusername, (long)vctx->user_data.realuser); /* now load the backends */ werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_LOAD_PLUGINS); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); result = vrmr_backends_load(&vctx->conf, vctx); if (result < 0) { vrmr_error(-1, VR_ERR, gettext("loading the plugins failed.")); return (-1); } werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_LOAD_PLUGINS, STR_COK); update_panels(); doupdate(); /* init services */ /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_INIT_SERVICES); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); result = vrmr_init_services(vctx, services, reg); if (result < 0) { vrmr_error(-1, VR_ERR, gettext("intializing the services failed.")); return (-1); } /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_INIT_SERVICES, STR_COK); update_panels(); doupdate(); /* init interfaces */ /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_INIT_INTERFACES); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); result = vrmr_init_interfaces(vctx, interfaces); if (result < 0) { vrmr_error(-1, VR_ERR, gettext("intializing the interfaces failed.")); return (-1); } /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_INIT_INTERFACES, STR_COK); update_panels(); doupdate(); /* init zones */ /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_INIT_ZONES); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); result = vrmr_init_zonedata(vctx, zones, interfaces, reg); if (result < 0) { vrmr_error(-1, VR_ERR, gettext("intializing the zones failed.")); return (-1); } /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_INIT_ZONES, STR_COK); update_panels(); doupdate(); /* init rules */ /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_INIT_RULES); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); result = vrmr_rules_init_list(vctx, &vctx->conf, rules, reg); if (result < 0) { /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_INIT_RULES, STR_CFAILED); update_panels(); doupdate(); } else { /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_INIT_RULES, STR_COK); update_panels(); doupdate(); } /* load the blockfile */ /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s...", STR_INIT_BLOCKLIST); update_panels(); doupdate(); if (vrmr_debug_level > LOW) sleep(1); result = vrmr_blocklist_init_list(vctx, &vctx->conf, zones, blocklist, /*load_ips*/ FALSE, /*no_refcnt*/ FALSE); if (result < 0) { /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_INIT_BLOCKLIST, STR_CFAILED); update_panels(); doupdate(); } else { /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s... %s", STR_INIT_BLOCKLIST, STR_COK); update_panels(); doupdate(); } /* try to connect to vuurmuur trough shm */ vuurmuur_shmtable = NULL; werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur...", STR_CONNECTING_TO); update_panels(); doupdate(); vuurmuur_pid = get_vuurmuur_pid("/var/run/vuurmuur.pid", &vuurmuur_shmid); if (vuurmuur_shmid > 0) { /* attach to shared memory */ vuurmuur_shmp = shmat(vuurmuur_shmid, 0, 0); if (vuurmuur_shmp == (char *)(-1)) { vrmr_error(-1, VR_ERR, gettext("attaching to shared memory failed: %s"), strerror(errno)); } else { vuurmuur_shmtable = (struct vrmr_shm_table *)vuurmuur_shmp; vuurmuur_semid = vuurmuur_shmtable->sem_id; /* now try to connect to the shared memory */ if (vrmr_lock(vuurmuur_semid)) { vuurmuur_shmtable->configtool.connected = 1; (void)snprintf(vuurmuur_shmtable->configtool.name, sizeof(vuurmuur_shmtable->configtool.name), "Vuurmuur_conf %s (user: %s)", version_string, vctx->user_data.realusername); (void)strlcpy(vuurmuur_shmtable->configtool.username, vctx->user_data.realusername, sizeof(vuurmuur_shmtable->configtool.username)); vrmr_unlock(vuurmuur_semid); werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur... %s", STR_CONNECTING_TO, STR_COK); update_panels(); doupdate(); } else { werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur... %s", STR_CONNECTING_TO, STR_CFAILED); update_panels(); doupdate(); vuurmuur_shmp = NULL; } } } else { /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur... %s", STR_CONNECTING_TO, STR_CFAILED); update_panels(); doupdate(); vuurmuur_shmp = NULL; } /* try to connect to vuurmuur trough shm */ vuurmuurlog_shmtable = NULL; /* TRANSLATORS: max 40 characters */ werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur_log...", STR_CONNECTING_TO); update_panels(); doupdate(); vuurmuurlog_pid = get_vuurmuur_pid("/var/run/vuurmuur_log.pid", &vuurmuurlog_shmid); if (vuurmuurlog_shmid > 0) { /* attach to shared memory */ vuurmuurlog_shmp = shmat(vuurmuurlog_shmid, 0, 0); if (vuurmuurlog_shmp == (char *)(-1)) { vrmr_error(-1, VR_ERR, "attaching to shared memory failed: %s", strerror(errno)); } else { vuurmuurlog_shmtable = (struct vrmr_shm_table *)vuurmuurlog_shmp; vuurmuurlog_semid = vuurmuurlog_shmtable->sem_id; vrmr_debug(LOW, "vuurmuur_log: sem_id: %d.", vuurmuurlog_semid); /* now try to connect to the shared memory */ if (vrmr_lock(vuurmuurlog_semid)) { vuurmuurlog_shmtable->configtool.connected = 1; (void)snprintf(vuurmuurlog_shmtable->configtool.name, sizeof(vuurmuurlog_shmtable->configtool.name), "Vuurmuur_conf %s (user: %s)", version_string, vctx->user_data.realusername); (void)strlcpy(vuurmuurlog_shmtable->configtool.username, vctx->user_data.realusername, sizeof(vuurmuurlog_shmtable->configtool.username)); vrmr_unlock(vuurmuurlog_semid); werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur_log... %s", STR_CONNECTING_TO, STR_COK); update_panels(); doupdate(); } else { werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur_log... %s", STR_CONNECTING_TO, STR_CFAILED); update_panels(); doupdate(); vuurmuurlog_shmp = NULL; } } } else { werase(startup_print_win); wprintw(startup_print_win, "%s Vuurmuur_log... %s", STR_CONNECTING_TO, STR_CFAILED); update_panels(); doupdate(); vuurmuurlog_shmp = NULL; } /* cleanup */ del_panel(startup_panel[0]); del_panel(startup_panel[1]); destroy_win(startup_print_win); destroy_win(startup_win); update_panels(); doupdate(); return (retval); }
static int filter_save(const int debuglvl, struct vrmr_filter *filter) { size_t i = 0; char filter_str[48] = ""; /* safety */ if(filter == NULL) { vrmr_error(-1, VR_INTERR, "parameter problem (in: %s:%d).", __FUNC__, __LINE__); return(-1); } /* check for changed fields */ for(i = 0; i < FiFi.n_fields; i++) { if(FiFi.fields[i] == FiFi.check_fld) { if(strncmp(field_buffer(FiFi.fields[i], 0), "X", 1) == 0) filter->neg = TRUE; else filter->neg = FALSE; if(debuglvl >= MEDIUM) vrmr_debug(__FUNC__, "filter->neg is now %s.", filter->neg ? "TRUE" : "FALSE"); } /* ipaddress field */ else if(FiFi.fields[i] == FiFi.string_fld) { if(!(copy_field2buf(filter->str, field_buffer(FiFi.fields[i], 0), sizeof(filter->str)))) return(-1); if(debuglvl >= MEDIUM) vrmr_debug(__FUNC__, "filter field changed: %s.", filter->str); /* new str */ if(StrLen(filter->str) > 0) { if(filter->reg_active == TRUE) { /* first remove old regex */ regfree(&filter->reg); /* set reg_active to false */ filter->reg_active = FALSE; } snprintf(filter_str, sizeof(filter_str), ".*%s.*", filter->str); /* create the new regex */ if(regcomp(&filter->reg, filter_str, REG_EXTENDED) != 0) { vrmr_error(-1, VR_INTERR, "setting up the regular expression with regcomp failed. Disabling filter."); return(-1); } /* set reg_active to true */ filter->reg_active = TRUE; } /* empty field, remove regex */ if(StrLen(filter->str) == 0 && filter->reg_active == TRUE) { /* first remove old regex */ regfree(&filter->reg); /* set reg_active to false */ filter->reg_active = FALSE; } } else { vrmr_error(-1, VR_INTERR, "unknown field (in: %s:%d).", __FUNC__, __LINE__); return(-1); } } return(0); }
int tell_textdir(void *backend, const char *name, const char *question, const char *answer, int overwrite, enum vrmr_objecttypes type) { int retval = 0; char *file_location = NULL; char line[512] = "", *line_ptr = NULL, *tmp_line_ptr = NULL; int i = 0, found = 0, skip = 0; FILE *fp = NULL; struct vrmr_list storelist; struct vrmr_list_node *d_node = NULL; assert(backend && name && question && answer); vrmr_debug(HIGH, "question: %s, answer: %s, name: %s, overwrite: %d, type: %d", question, answer, name, overwrite, type); struct textdir_backend *tb = (struct textdir_backend *)backend; if (!tb->backend_open) { vrmr_error(-1, "Error", "backend not opened yet"); return (-1); } /* only uppercase allowed */ while (question[i]) { if ((question[i] >= 'a') && (question[i] <= 'z')) return (-1); ++i; } if (!(file_location = get_filelocation(backend, name, type))) return (-1); /* first open the file for reading */ if (!(fp = vuurmuur_fopen(tb->cfg, file_location, "r"))) { vrmr_error(-1, "Error", "unable to open file '%s' for reading: %s.", file_location, strerror(errno)); free(file_location); return (-1); } /* initialize the store list */ vrmr_list_setup(&storelist, free); /* loop trough the current file */ while (fgets(line, MAX_LINE_LENGTH, fp) != NULL) { skip = 0; size_t line_size = sizeof(line); if (!(line_ptr = malloc(line_size))) { vrmr_error(-1, "Error", "malloc failed: %s", strerror(errno)); /* cleanup */ vrmr_list_cleanup(&storelist); free(file_location); fclose(fp); return (-1); } if (strncmp(question, line, strlen(question)) == 0 && line[strlen(question)] == '=') { if (overwrite && !found) { snprintf(line_ptr, line_size, "%s=\"%s\"\n", question, answer); found = 1; } else if (overwrite && found) { skip = 1; } else { (void)strlcpy(line_ptr, line, line_size); found = 1; } } else { (void)strlcpy(line_ptr, line, line_size); } /* now append the line to the storelist, except if we were told to skip this one. Then just free the data. */ if (!skip) { if (vrmr_list_append(&storelist, line_ptr) == NULL) { vrmr_error(-1, "Internal Error", "inserting line into temporary storage list failed"); /* cleanup */ vrmr_list_cleanup(&storelist); free(line_ptr); free(file_location); fclose(fp); return (-1); } } else { /* free and null */ free(line_ptr); line_ptr = NULL; } } /* if we are not overwriting and the type of data is already found somewhere, we try to insert is just below the last one. */ if (!overwrite && found) { if (!(line_ptr = malloc(sizeof(line)))) { vrmr_error(-1, "Error", "malloc failed: %s", strerror(errno)); /* cleanup */ vrmr_list_cleanup(&storelist); free(file_location); fclose(fp); return (-1); } /* assemble the line */ snprintf(line_ptr, sizeof(line), "%s=\"%s\"\n", question, answer); /* loop the list bottom up so we match the last one first */ for (d_node = storelist.bot; d_node; d_node = d_node->prev) { if (!(tmp_line_ptr = d_node->data)) { vrmr_error(-1, "Internal Error", "NULL pointer"); /* cleanup */ vrmr_list_cleanup(&storelist); free(file_location); free(line_ptr); fclose(fp); return (-1); } /* check if the line is the same. If so insert after it. */ if (strncmp(question, tmp_line_ptr, strlen(question)) == 0) { if (vrmr_list_insert_after(&storelist, d_node, line_ptr) == NULL) { vrmr_error(-1, "Internal Error", "inserting line into temporary storage list " "failed"); /* cleanup */ vrmr_list_cleanup(&storelist); free(file_location); free(line_ptr); fclose(fp); return (-1); } /* after inserting we're done */ line_ptr = NULL; break; } /* Don't free line_ptr yet, because it might be used again in the * next iteration */ } /* we no longer need these */ tmp_line_ptr = NULL; free(line_ptr); line_ptr = NULL; } /* if its not found, we insert it at the end of the list */ if (found == 0) { /* first alloc */ if (!(line_ptr = malloc(sizeof(line)))) { vrmr_error(-1, "Error", "malloc failed: %s.", strerror(errno)); /* cleanup */ vrmr_list_cleanup(&storelist); free(file_location); fclose(fp); return (-1); } snprintf(line_ptr, sizeof(line), "%s=\"%s\"\n", question, answer); /* append into the list */ if (vrmr_list_append(&storelist, line_ptr) == NULL) { vrmr_error(-1, "Internal Error", "inserting line into temporary storage list failed"); /* cleanup */ vrmr_list_cleanup(&storelist); free(file_location); free(line_ptr); fclose(fp); return (-1); } /* we no longer need this */ line_ptr = NULL; } /* close the file */ (void)fclose(fp); /* now open the file for writing */ if (!(fp = vuurmuur_fopen(tb->cfg, file_location, "w+"))) { vrmr_error(-1, "Error", "unable to open file '%s' for writing: %s", file_location, strerror(errno)); /* cleanup */ vrmr_list_cleanup(&storelist); free(file_location); return (-1); } /* print the list into the file */ for (d_node = storelist.top; d_node; d_node = d_node->next) { if (d_node->data == NULL) continue; fprintf(fp, "%s", (char *)d_node->data); } (void)fclose(fp); /* destroy the temp storage */ vrmr_list_cleanup(&storelist); free(file_location); return (retval); }