Added add_segment() method to IETF attributes
[strongswan.git] / src / libimcv / imv / imv_remediation_string.c
1 /*
2 * Copyright (C) 2012 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "imv_remediation_string.h"
17
18 #include <utils/debug.h>
19
20 typedef struct private_imv_remediation_string_t private_imv_remediation_string_t;
21
22 /**
23 * Private data of an imv_remediation_string_t object.
24 */
25 struct private_imv_remediation_string_t {
26
27 /**
28 * Public members of imv_remediation_string_t
29 */
30 imv_remediation_string_t public;
31
32 /**
33 * XML or plaintext encoding
34 */
35 bool as_xml;
36
37 /**
38 * Preferred language
39 */
40 char *lang;
41
42 /**
43 * Contains the concatenated remediation instructions
44 */
45 chunk_t instructions;
46
47 };
48
49 METHOD(imv_remediation_string_t, add_instruction, void,
50 private_imv_remediation_string_t *this, imv_lang_string_t title[],
51 imv_lang_string_t description[], imv_lang_string_t itemsheader[],
52 linked_list_t *item_list)
53 {
54 char xml_format[] = " <instruction>\n"
55 " <title>%s</title>\n"
56 " <description>%s</description>\n"
57 "%s%s"
58 " </instruction>\n";
59 char *instruction, *format, *item, *pos, *header, *items;
60 char *s_title, *s_description, *s_itemsheader;
61 size_t len;
62
63 s_title = imv_lang_string_select_string(title, this->lang);
64 s_description = imv_lang_string_select_string(description, this->lang);
65 s_itemsheader = imv_lang_string_select_string(itemsheader, this->lang);
66 header = NULL;
67 items = NULL;
68
69 if (s_itemsheader)
70 {
71 int header_len = strlen(s_itemsheader);
72 char *header_format;
73
74 if (this->as_xml)
75 {
76 header_format = " <itemsheader>%s</itemsheader>\n";
77 header_len += strlen(header_format) - 2;
78 }
79 else
80 {
81 header_format = "\n %s";
82 header_len += 3;
83 }
84 header = malloc(header_len + 1);
85 sprintf(header, header_format, s_itemsheader);
86 }
87
88 if (item_list && item_list->get_count(item_list))
89 {
90 enumerator_t *enumerator;
91 int items_len = 0;
92
93 /* compute total length of all items */
94 enumerator = item_list->create_enumerator(item_list);
95 while (enumerator->enumerate(enumerator, &item))
96 {
97 items_len += strlen(item);
98 }
99 enumerator->destroy(enumerator);
100
101 if (this->as_xml)
102 {
103 items_len += 12 + 20 * item_list->get_count(item_list) + 13;
104
105 pos = items = malloc(items_len + 1);
106 pos += sprintf(pos, " <items>\n");
107
108 enumerator = item_list->create_enumerator(item_list);
109 while (enumerator->enumerate(enumerator, &item))
110 {
111 pos += sprintf(pos, " <item>%s</item>\n", item);
112 }
113 enumerator->destroy(enumerator);
114
115 pos += sprintf(pos, " </items>\n");
116 }
117 else
118 {
119 items_len += 5 * item_list->get_count(item_list);
120
121 pos = items = malloc(items_len + 1);
122
123 enumerator = item_list->create_enumerator(item_list);
124 while (enumerator->enumerate(enumerator, &item))
125 {
126 pos += sprintf(pos, "\n %s", item);
127 }
128 enumerator->destroy(enumerator);
129 }
130 }
131
132 len = strlen(s_title) + strlen(s_description);
133 if (header)
134 {
135 len += strlen(header);
136 }
137 if (items)
138 {
139 len += strlen(items);
140 }
141
142 if (this->as_xml)
143 {
144 format = xml_format;
145 len += strlen(xml_format) - 8;
146 }
147 else
148 {
149 format = this->instructions.len ? "\n%s\n %s%s%s" : "%s\n %s%s%s";
150 len += 4;
151 }
152 instruction = malloc(len + 1);
153 sprintf(instruction, format, s_title, s_description, header ? header : "",
154 items ? items : "");
155 free(header);
156 free(items);
157 this->instructions = chunk_cat("mm", this->instructions,
158 chunk_create(instruction, strlen(instruction)));
159 }
160
161 METHOD(imv_remediation_string_t, get_encoding, chunk_t,
162 private_imv_remediation_string_t *this)
163 {
164 char xml_header[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
165 "<remediationinstructions>\n";
166 char xml_trailer[] = "</remediationinstructions>";
167
168 if (!this->instructions.len)
169 {
170 return chunk_empty;
171 }
172 if (this->as_xml)
173 {
174 this->instructions = chunk_cat("cmc",
175 chunk_create(xml_header, strlen(xml_header)),
176 this->instructions,
177 chunk_create(xml_trailer, strlen(xml_trailer))
178 );
179 }
180 return this->instructions;
181 }
182
183 METHOD(imv_remediation_string_t, destroy, void,
184 private_imv_remediation_string_t *this)
185 {
186 free(this->instructions.ptr);
187 free(this);
188 }
189
190 /**
191 * Described in header.
192 */
193 imv_remediation_string_t *imv_remediation_string_create(bool as_xml, char *lang)
194 {
195 private_imv_remediation_string_t *this;
196
197 INIT(this,
198 .public = {
199 .add_instruction = _add_instruction,
200 .get_encoding = _get_encoding,
201 .destroy = _destroy,
202 },
203 .as_xml = as_xml,
204 .lang = lang,
205 );
206
207 return &this->public;
208 }
209