/* * Copyright (C) 2012 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See . * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "imv_remediation_string.h" #include typedef struct private_imv_remediation_string_t private_imv_remediation_string_t; /** * Private data of an imv_remediation_string_t object. */ struct private_imv_remediation_string_t { /** * Public members of imv_remediation_string_t */ imv_remediation_string_t public; /** * XML or plaintext encoding */ bool as_xml; /** * Preferred language */ char *lang; /** * Contains the concatenated remediation instructions */ chunk_t instructions; }; METHOD(imv_remediation_string_t, add_instruction, void, private_imv_remediation_string_t *this, imv_lang_string_t title[], imv_lang_string_t description[], imv_lang_string_t itemsheader[], linked_list_t *item_list) { char xml_format[] = " \n" " %s\n" " %s\n" "%s%s" " \n"; char *instruction, *format, *item, *pos, *header, *items; char *s_title, *s_description, *s_itemsheader; size_t len; s_title = imv_lang_string_select_string(title, this->lang); s_description = imv_lang_string_select_string(description, this->lang); s_itemsheader = imv_lang_string_select_string(itemsheader, this->lang); header = NULL; items = NULL; if (s_itemsheader) { int header_len = strlen(s_itemsheader); char *header_format; if (this->as_xml) { header_format = " %s\n"; header_len += strlen(header_format) - 2; } else { header_format = "\n %s"; header_len += 3; } header = malloc(header_len + 1); sprintf(header, header_format, s_itemsheader); } if (item_list && item_list->get_count(item_list)) { enumerator_t *enumerator; int items_len = 0; /* compute total length of all items */ enumerator = item_list->create_enumerator(item_list); while (enumerator->enumerate(enumerator, &item)) { items_len += strlen(item); } enumerator->destroy(enumerator); if (this->as_xml) { items_len += 12 + 20 * item_list->get_count(item_list) + 13; pos = items = malloc(items_len + 1); pos += sprintf(pos, " \n"); enumerator = item_list->create_enumerator(item_list); while (enumerator->enumerate(enumerator, &item)) { pos += sprintf(pos, " %s\n", item); } enumerator->destroy(enumerator); pos += sprintf(pos, " \n"); } else { items_len += 5 * item_list->get_count(item_list); pos = items = malloc(items_len + 1); enumerator = item_list->create_enumerator(item_list); while (enumerator->enumerate(enumerator, &item)) { pos += sprintf(pos, "\n %s", item); } enumerator->destroy(enumerator); } } len = strlen(s_title) + strlen(s_description); if (header) { len += strlen(header); } if (items) { len += strlen(items); } if (this->as_xml) { format = xml_format; len += strlen(xml_format) - 8; } else { format = this->instructions.len ? "\n%s\n %s%s%s" : "%s\n %s%s%s"; len += 4; } instruction = malloc(len + 1); sprintf(instruction, format, s_title, s_description, header ? header : "", items ? items : ""); free(header); free(items); this->instructions = chunk_cat("mm", this->instructions, chunk_create(instruction, strlen(instruction))); } METHOD(imv_remediation_string_t, get_encoding, chunk_t, private_imv_remediation_string_t *this) { char xml_header[] = "\n" "\n"; char xml_trailer[] = ""; if (!this->instructions.len) { return chunk_empty; } if (this->as_xml) { this->instructions = chunk_cat("cmc", chunk_create(xml_header, strlen(xml_header)), this->instructions, chunk_create(xml_trailer, strlen(xml_trailer)) ); } return this->instructions; } METHOD(imv_remediation_string_t, destroy, void, private_imv_remediation_string_t *this) { free(this->instructions.ptr); free(this); } /** * Described in header. */ imv_remediation_string_t *imv_remediation_string_create(bool as_xml, char *lang) { private_imv_remediation_string_t *this; INIT(this, .public = { .add_instruction = _add_instruction, .get_encoding = _get_encoding, .destroy = _destroy, }, .as_xml = as_xml, .lang = lang, ); return &this->public; }