Greenbone Vulnerability Management Libraries  11.0.0
xmlutils.c File Reference

Simple XML reader. More...

#include "xmlutils.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <glib/gtypes.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
Include dependency graph for xmlutils.c:

Go to the source code of this file.

Macros

#define G_LOG_DOMAIN   "lib xml"
 GLib log domain. More...
 
#define BUFFER_SIZE   1048576
 Size of the buffer for reading from the manager. More...
 
#define XML_FILE_BUFFER_SIZE   1048576
 

Functions

entity_t make_entity (const char *name, const char *text)
 Create an entity. More...
 
entities_t next_entities (entities_t entities)
 Return all the entities from an entities_t after the first. More...
 
entity_t first_entity (entities_t entities)
 Return the first entity from an entities_t. More...
 
entity_t add_entity (entities_t *entities, const char *name, const char *text)
 Add an XML entity to a tree of entities. More...
 
void free_entity (entity_t entity)
 Free an entity, recursively. More...
 
char * entity_text (entity_t entity)
 Get the text an entity. More...
 
char * entity_name (entity_t entity)
 Get the name an entity. More...
 
int compare_entity_with_name (gconstpointer entity, gconstpointer name)
 Compare a given name with the name of a given entity. More...
 
entity_t entity_child (entity_t entity, const char *name)
 Get a child of an entity. More...
 
const char * entity_attribute (entity_t entity, const char *name)
 Get an attribute of an entity. More...
 
void add_attributes (entity_t entity, const gchar **names, const gchar **values)
 Add attributes from an XML callback to an entity. More...
 
static void handle_start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
 Handle the start of an OMP XML element. More...
 
void xml_handle_start_element (context_data_t *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values)
 Handle the start of an OMP XML element. More...
 
static void handle_end_element (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
 Handle the end of an XML element. More...
 
void xml_handle_end_element (context_data_t *context, const gchar *element_name)
 Handle the end of an XML element. More...
 
static void handle_text (GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
 Handle additional text of an XML element. More...
 
void xml_handle_text (context_data_t *context, const gchar *text, gsize text_len)
 Handle additional text of an XML element. More...
 
void handle_error (GMarkupParseContext *context, GError *error, gpointer user_data)
 Handle an OMP XML parsing error. More...
 
int try_read_entity_and_string (gnutls_session_t *session, int timeout, entity_t *entity, GString **string_return)
 Try read an XML entity tree from the manager. More...
 
int try_read_entity_and_string_s (int socket, int timeout, entity_t *entity, GString **string_return)
 Try read an XML entity tree from the socket. More...
 
int read_entity_and_string (gnutls_session_t *session, entity_t *entity, GString **string_return)
 Try read an XML entity tree from the manager. More...
 
int read_entity_and_string_c (gvm_connection_t *connection, entity_t *entity, GString **string_return)
 Try read an XML entity tree from the manager. More...
 
int read_entity_and_text (gnutls_session_t *session, entity_t *entity, char **text)
 Read an XML entity tree from the manager. More...
 
int read_entity_and_text_c (gvm_connection_t *connection, entity_t *entity, char **text)
 Read an XML entity tree from the manager. More...
 
int read_string (gnutls_session_t *session, GString **string)
 Read entity and text. Free the entity immediately. More...
 
int read_string_c (gvm_connection_t *connection, GString **string)
 Read entity and text. Free the entity immediately. More...
 
int try_read_entity (gnutls_session_t *session, int timeout, entity_t *entity)
 Try read an XML entity tree from the manager. More...
 
int try_read_entity_c (gvm_connection_t *connection, int timeout, entity_t *entity)
 Try read an XML entity tree from the manager. More...
 
int read_entity (gnutls_session_t *session, entity_t *entity)
 Read an XML entity tree from the manager. More...
 
int read_entity_s (int socket, entity_t *entity)
 Read an XML entity tree from the socket. More...
 
int read_entity_c (gvm_connection_t *connection, entity_t *entity)
 Read an XML entity tree from the manager. More...
 
int parse_entity (const char *string, entity_t *entity)
 Read an XML entity tree from a string. More...
 
static void foreach_print_entity_to_string (gpointer entity, gpointer string)
 Print an XML entity for g_slist_foreach to a GString. More...
 
static void foreach_print_attribute_to_string (gpointer name, gpointer value, gpointer string)
 Print an XML attribute for g_hash_table_foreach to a GString. More...
 
void print_entity_to_string (entity_t entity, GString *string)
 Print an XML entity tree to a GString, appending it if string is not. More...
 
static void foreach_print_entity (gpointer entity, gpointer stream)
 Print an XML entity for g_slist_foreach. More...
 
static void foreach_print_attribute (gpointer name, gpointer value, gpointer stream)
 Print an XML attribute for g_hash_table_foreach. More...
 
void print_entity (FILE *stream, entity_t entity)
 Print an XML entity. More...
 
static void foreach_print_attribute_format (gpointer name, gpointer value, gpointer none)
 Print an XML attribute for g_hash_table_foreach to stdout. More...
 
void print_entity_format (entity_t entity, gpointer indent)
 Print an XML entity to stdout, recursively printing its children. More...
 
gboolean compare_find_attribute (gpointer key, gpointer value, gpointer attributes2)
 Look for a key-value pair in a hash table. More...
 
int compare_entities (entity_t entity1, entity_t entity2)
 Compare two XML entity. More...
 
int xml_count_entities (entities_t entities)
 Count the number of entities. More...
 
void xml_string_append (GString *xml, const char *format,...)
 Append formatted escaped XML to a string. More...
 
static void xml_search_handle_start_element (GMarkupParseContext *ctx, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
 Handle the opening tag of an element in an XML search. More...
 
int find_element_in_xml_file (gchar *file_path, gchar *find_element, GHashTable *find_attributes)
 Tests if an XML file contains an element with given attributes. More...
 

Detailed Description

Simple XML reader.

This is a generic XML interface. The key function is read_entity.

There are examples of using this interface in omp.c.

Definition in file xmlutils.c.

Macro Definition Documentation

◆ BUFFER_SIZE

#define BUFFER_SIZE   1048576

Size of the buffer for reading from the manager.

Definition at line 49 of file xmlutils.c.

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib xml"

GLib log domain.

Definition at line 44 of file xmlutils.c.

◆ XML_FILE_BUFFER_SIZE

#define XML_FILE_BUFFER_SIZE   1048576

Definition at line 1514 of file xmlutils.c.

Function Documentation

◆ add_attributes()

void add_attributes ( entity_t  entity,
const gchar **  names,
const gchar **  values 
)

Add attributes from an XML callback to an entity.

Parameters
[in]entityThe entity.
[in]namesList of attribute names.
[in]valuesList of attribute values.

Definition at line 246 of file xmlutils.c.

247 {
248  if (names && values && *names && *values)
249  {
250  if (entity->attributes == NULL)
251  entity->attributes =
252  g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
253  while (*names && *values)
254  {
255  if (*values)
256  g_hash_table_insert (entity->attributes, g_strdup (*names),
257  g_strdup (*values));
258  names++;
259  values++;
260  }
261  }
262 }

References entity_s::attributes.

Referenced by handle_start_element().

Here is the caller graph for this function:

◆ add_entity()

entity_t add_entity ( entities_t entities,
const char *  name,
const char *  text 
)

Add an XML entity to a tree of entities.

Parameters
[in]entitiesThe tree of entities
[in]nameName of the entity. Copied, copy is freed by free_entity.
[in]textText of the entity. Copied, copy is freed by free_entity.
Returns
The new entity.

Definition at line 113 of file xmlutils.c.

114 {
115  entity_t entity = make_entity (name, text);
116  if (entities)
117  *entities = g_slist_append (*entities, entity);
118  return entity;
119 }

References make_entity().

Referenced by handle_start_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compare_entities()

int compare_entities ( entity_t  entity1,
entity_t  entity2 
)

Compare two XML entity.

Parameters
[in]entity1First entity.
[in]entity2First entity.
Returns
0 if equal, 1 otherwise.

Definition at line 1346 of file xmlutils.c.

1347 {
1348  if (entity1 == NULL)
1349  return entity2 == NULL ? 0 : 1;
1350  if (entity2 == NULL)
1351  return 1;
1352 
1353  if (strcmp (entity1->name, entity2->name))
1354  {
1355  g_debug (" compare failed name: %s vs %s\n", entity1->name,
1356  entity2->name);
1357  return 1;
1358  }
1359  if (strcmp (entity1->text, entity2->text))
1360  {
1361  g_debug (" compare failed text %s vs %s (%s)\n", entity1->text,
1362  entity2->text, entity1->name);
1363  return 1;
1364  }
1365 
1366  if (entity1->attributes == NULL)
1367  {
1368  if (entity2->attributes)
1369  return 1;
1370  }
1371  else
1372  {
1373  if (entity2->attributes == NULL)
1374  return 1;
1375  if (g_hash_table_find (entity1->attributes, compare_find_attribute,
1376  (gpointer) entity2->attributes))
1377  {
1378  g_debug (" compare failed attributes\n");
1379  return 1;
1380  }
1381  }
1382 
1383  // FIX entities can be in any order
1384  GSList *list1 = entity1->entities;
1385  GSList *list2 = entity2->entities;
1386  while (list1 && list2)
1387  {
1388  if (compare_entities (list1->data, list2->data))
1389  {
1390  g_debug (" compare failed subentity\n");
1391  return 1;
1392  }
1393  list1 = g_slist_next (list1);
1394  list2 = g_slist_next (list2);
1395  }
1396  if (list1 == list2)
1397  return 0;
1398  /* More entities in one of the two. */
1399  g_debug (" compare failed number of entities (%s)\n", entity1->name);
1400  return 1;
1401 }

References entity_s::attributes, compare_entities(), compare_find_attribute(), entity_s::entities, entity_s::name, and entity_s::text.

Referenced by compare_entities().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compare_entity_with_name()

int compare_entity_with_name ( gconstpointer  entity,
gconstpointer  name 
)

Compare a given name with the name of a given entity.

Parameters
[in]entityEntity.
[in]nameName.
Returns
Zero if entity name matches name, otherwise a positive or negative number as from strcmp.

Definition at line 191 of file xmlutils.c.

192 {
193  return strcmp (entity_name ((entity_t) entity), (char *) name);
194 }

References entity_name().

Referenced by entity_child().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compare_find_attribute()

gboolean compare_find_attribute ( gpointer  key,
gpointer  value,
gpointer  attributes2 
)

Look for a key-value pair in a hash table.

Parameters
[in]keyKey.
[in]valueValue.
[in]attributes2The hash table.
Returns
FALSE if found, TRUE otherwise.

Definition at line 1328 of file xmlutils.c.

1329 {
1330  gchar *value2 = g_hash_table_lookup (attributes2, key);
1331  if (value2 && strcmp (value, value2) == 0)
1332  return FALSE;
1333  g_debug (" compare failed attribute: %s\n", (char *) value);
1334  return TRUE;
1335 }

Referenced by compare_entities().

Here is the caller graph for this function:

◆ entity_attribute()

const char* entity_attribute ( entity_t  entity,
const char *  name 
)

Get an attribute of an entity.

Parameters
[in]entityEntity.
[in]nameName of the attribute.
Returns
Attribute if found, else NULL.

Definition at line 228 of file xmlutils.c.

229 {
230  if (!entity)
231  return NULL;
232 
233  if (entity->attributes)
234  return (const char *) g_hash_table_lookup (entity->attributes, name);
235  return NULL;
236 }

References entity_s::attributes.

Referenced by gmp_authenticate_info_ext(), gmp_authenticate_info_ext_c(), gmp_check_response(), gmp_check_response_c(), gmp_get_report_ext(), gmp_get_tasks_ext(), gmp_ping(), gmp_ping_c(), gmp_read_create_response(), gmp_resume_task_report_c(), gmp_start_task_report_c(), osp_delete_scan(), osp_get_performance_ext(), osp_get_scan_pop(), osp_get_scan_status_ext(), osp_get_scanner_details(), osp_start_scan(), osp_start_scan_ext(), and osp_stop_scan().

Here is the caller graph for this function:

◆ entity_child()

entity_t entity_child ( entity_t  entity,
const char *  name 
)

Get a child of an entity.

Parameters
[in]entityEntity.
[in]nameName of the child.
Returns
Entity if found, else NULL.

Definition at line 205 of file xmlutils.c.

206 {
207  if (!entity)
208  return NULL;
209 
210  if (entity->entities)
211  {
212  entities_t match =
213  g_slist_find_custom (entity->entities, name, compare_entity_with_name);
214  return match ? (entity_t) match->data : NULL;
215  }
216  return NULL;
217 }

References compare_entity_with_name(), and entity_s::entities.

Referenced by gmp_authenticate_info_ext(), gmp_authenticate_info_ext_c(), gmp_ping_c(), gmp_resume_task_report(), gmp_resume_task_report_c(), gmp_start_task_report(), gmp_start_task_report_c(), gmp_task_status(), osp_get_scan_pop(), osp_get_scan_status_ext(), osp_get_scanner_details(), osp_get_version(), and osp_get_vts_version().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ entity_name()

char* entity_name ( entity_t  entity)

Get the name an entity.

Parameters
[in]entityEntity.
Returns
Entity name, which is freed by free_entity.

Definition at line 173 of file xmlutils.c.

174 {
175  if (!entity)
176  return NULL;
177 
178  return entity->name;
179 }

References entity_s::name.

Referenced by compare_entity_with_name().

Here is the caller graph for this function:

◆ entity_text()

char* entity_text ( entity_t  entity)

Get the text an entity.

Parameters
[in]entityEntity.
Returns
Entity text, which is freed by free_entity.

Definition at line 157 of file xmlutils.c.

158 {
159  if (!entity)
160  return NULL;
161 
162  return entity->text;
163 }

References entity_s::text.

Referenced by gmp_authenticate_info_ext(), gmp_authenticate_info_ext_c(), gmp_ping_c(), gmp_resume_task_report(), gmp_resume_task_report_c(), gmp_start_task_report(), gmp_start_task_report_c(), gmp_task_status(), osp_get_performance_ext(), osp_get_scanner_details(), osp_get_version(), and osp_get_vts_version().

Here is the caller graph for this function:

◆ find_element_in_xml_file()

int find_element_in_xml_file ( gchar *  file_path,
gchar *  find_element,
GHashTable *  find_attributes 
)

Tests if an XML file contains an element with given attributes.

Parameters
[in]file_pathPath of the XML file.
[in]find_elementName of the element to find.
[in]find_attributesGHashTable of attributes to find.
Returns
1 if element was found, 0 if not.

Definition at line 1525 of file xmlutils.c.

1527 {
1528  gchar buffer[XML_FILE_BUFFER_SIZE];
1529  FILE *file;
1530  int read_len;
1531  GMarkupParser xml_parser;
1532  GMarkupParseContext *xml_context;
1533  xml_search_data_t search_data;
1534  GError *error = NULL;
1535 
1536  search_data.find_element = find_element;
1537  search_data.find_attributes = find_attributes;
1538  search_data.found = 0;
1539 
1540  /* Create the XML parser. */
1541  xml_parser.start_element = xml_search_handle_start_element;
1542  xml_parser.end_element = NULL;
1543  xml_parser.text = NULL;
1544  xml_parser.passthrough = NULL;
1545  xml_parser.error = NULL;
1546  xml_context = g_markup_parse_context_new (&xml_parser, 0, &search_data, NULL);
1547 
1548  file = fopen (file_path, "r");
1549  if (file == NULL)
1550  {
1551  g_markup_parse_context_free (xml_context);
1552  g_warning ("%s: Failed to open '%s':", __FUNCTION__, strerror (errno));
1553  return 0;
1554  }
1555 
1556  while ((read_len = fread (&buffer, sizeof (char), XML_FILE_BUFFER_SIZE, file))
1557  && g_markup_parse_context_parse (xml_context, buffer, read_len, &error)
1558  && error == NULL)
1559  {
1560  }
1561  g_markup_parse_context_end_parse (xml_context, &error);
1562 
1563  fclose (file);
1564 
1565  g_markup_parse_context_free (xml_context);
1566  return search_data.found;
1567 }

References xml_search_data_t::find_attributes, xml_search_data_t::find_element, xml_search_data_t::found, XML_FILE_BUFFER_SIZE, and xml_search_handle_start_element().

Here is the call graph for this function:

◆ first_entity()

entity_t first_entity ( entities_t  entities)

Return the first entity from an entities_t.

Parameters
[in]entitiesThe list of entities.
Returns
The first entity.

Definition at line 94 of file xmlutils.c.

95 {
96  if (entities)
97  return (entity_t) entities->data;
98  return NULL;
99 }

Referenced by xml_count_entities().

Here is the caller graph for this function:

◆ foreach_print_attribute()

static void foreach_print_attribute ( gpointer  name,
gpointer  value,
gpointer  stream 
)
static

Print an XML attribute for g_hash_table_foreach.

Parameters
[in]nameThe attribute name.
[in]valueThe attribute value.
[in]streamThe stream to which to print.

Definition at line 1232 of file xmlutils.c.

1233 {
1234  fprintf ((FILE *) stream, " %s=\"%s\"", (char *) name, (char *) value);
1235 }

Referenced by print_entity().

Here is the caller graph for this function:

◆ foreach_print_attribute_format()

static void foreach_print_attribute_format ( gpointer  name,
gpointer  value,
gpointer  none 
)
static

Print an XML attribute for g_hash_table_foreach to stdout.

Parameters
[in]nameThe attribute name.
[in]valueThe attribute value.
[in]none(ignored).

Definition at line 1269 of file xmlutils.c.

1270 {
1271  (void) none;
1272  printf (" %s=\"%s\"", (char *) name, (char *) value);
1273 }

Referenced by print_entity_format().

Here is the caller graph for this function:

◆ foreach_print_attribute_to_string()

static void foreach_print_attribute_to_string ( gpointer  name,
gpointer  value,
gpointer  string 
)
static

Print an XML attribute for g_hash_table_foreach to a GString.

Parameters
[in]nameThe attribute name.
[in]valueThe attribute value.
[in]stringThe string to which to print.

Definition at line 1182 of file xmlutils.c.

1184 {
1185  g_string_append_printf ((GString *) string, " %s=\"%s\"", (char *) name,
1186  (char *) value);
1187 }

Referenced by print_entity_to_string().

Here is the caller graph for this function:

◆ foreach_print_entity()

static void foreach_print_entity ( gpointer  entity,
gpointer  stream 
)
static

Print an XML entity for g_slist_foreach.

Parameters
[in]entityThe entity, as a gpointer.
[in]streamThe stream to which to print, as a gpointer.

Definition at line 1219 of file xmlutils.c.

1220 {
1221  print_entity ((FILE *) stream, (entity_t) entity);
1222 }

References print_entity().

Referenced by print_entity().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ foreach_print_entity_to_string()

static void foreach_print_entity_to_string ( gpointer  entity,
gpointer  string 
)
static

Print an XML entity for g_slist_foreach to a GString.

Parameters
[in]entityThe entity, as a gpointer.
[in]stringThe stream to which to print, as a gpointer.

Definition at line 1169 of file xmlutils.c.

1170 {
1171  print_entity_to_string ((entity_t) entity, (GString *) string);
1172 }

References print_entity_to_string().

Referenced by print_entity_to_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_entity()

void free_entity ( entity_t  entity)

Free an entity, recursively.

Parameters
[in]entityThe entity, can be NULL.

Definition at line 127 of file xmlutils.c.

128 {
129  if (entity)
130  {
131  g_free (entity->name);
132  g_free (entity->text);
133  if (entity->attributes)
134  g_hash_table_destroy (entity->attributes);
135  if (entity->entities)
136  {
137  GSList *list = entity->entities;
138  while (list)
139  {
140  free_entity (list->data);
141  list = list->next;
142  }
143  g_slist_free (entity->entities);
144  }
145  g_free (entity);
146  }
147 }

References entity_s::attributes, entity_s::entities, free_entity(), entity_s::name, and entity_s::text.

Referenced by free_entity(), gmp_authenticate(), gmp_authenticate_info_ext(), gmp_authenticate_info_ext_c(), gmp_check_response(), gmp_check_response_c(), gmp_delete_config_ext(), gmp_delete_lsc_credential_ext(), gmp_delete_port_list_ext(), gmp_delete_report(), gmp_delete_target_ext(), gmp_delete_task(), gmp_delete_task_ext(), gmp_get_report_ext(), gmp_get_tasks_ext(), gmp_modify_task_file(), gmp_ping(), gmp_ping_c(), gmp_read_create_response(), gmp_resume_task_report(), gmp_resume_task_report_c(), gmp_start_task_report(), gmp_start_task_report_c(), gmp_stop_task(), osp_delete_scan(), osp_get_performance_ext(), osp_get_scan_pop(), osp_get_scan_status_ext(), osp_get_scanner_details(), osp_get_version(), osp_get_vts_version(), osp_start_scan(), osp_start_scan_ext(), osp_stop_scan(), parse_entity(), read_string(), read_string_c(), try_read_entity_and_string(), and try_read_entity_and_string_s().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_end_element()

static void handle_end_element ( GMarkupParseContext *  context,
const gchar *  element_name,
gpointer  user_data,
GError **  error 
)
static

Handle the end of an XML element.

Parameters
[in]contextParser context.
[in]element_nameXML element name.
[in]user_dataDummy parameter.
[in]errorError parameter.

Definition at line 328 of file xmlutils.c.

330 {
331  context_data_t *data = (context_data_t *) user_data;
332 
333  (void) context;
334  (void) error;
335  (void) element_name;
336  assert (data->current && data->first);
337  if (data->current == data->first)
338  {
339  assert (strcmp (element_name,
340  /* The name of the very first entity. */
341  ((entity_t) (data->first->data))->name)
342  == 0);
343  data->done = TRUE;
344  /* "Pop" the element. */
345  data->current = g_slist_next (data->current);
346  }
347  else if (data->current)
348  {
349  GSList *front;
350  /* "Pop" and free the element. */
351  front = data->current;
352  data->current = g_slist_next (data->current);
353  g_slist_free_1 (front);
354  }
355 }

References context_data_t::current, context_data_t::done, and context_data_t::first.

Referenced by parse_entity(), try_read_entity_and_string(), try_read_entity_and_string_s(), and xml_handle_end_element().

Here is the caller graph for this function:

◆ handle_error()

void handle_error ( GMarkupParseContext *  context,
GError *  error,
gpointer  user_data 
)

Handle an OMP XML parsing error.

Parameters
[in]contextParser context.
[in]errorThe error.
[in]user_dataDummy parameter.

Definition at line 419 of file xmlutils.c.

420 {
421  (void) context;
422  (void) user_data;
423  g_message (" Error: %s\n", error->message);
424 }

Referenced by parse_entity(), try_read_entity_and_string(), and try_read_entity_and_string_s().

Here is the caller graph for this function:

◆ handle_start_element()

static void handle_start_element ( GMarkupParseContext *  context,
const gchar *  element_name,
const gchar **  attribute_names,
const gchar **  attribute_values,
gpointer  user_data,
GError **  error 
)
static

Handle the start of an OMP XML element.

Parameters
[in]contextParser context.
[in]element_nameXML element name.
[in]attribute_namesXML attribute name.
[in]attribute_valuesXML attribute values.
[in]user_dataDummy parameter.
[in]errorError parameter.

Definition at line 275 of file xmlutils.c.

279 {
280  entity_t entity;
281  context_data_t *data = (context_data_t *) user_data;
282 
283  (void) context;
284  (void) error;
285  if (data->current)
286  {
287  entity_t current = (entity_t) data->current->data;
288  entity = add_entity (&current->entities, element_name, NULL);
289  }
290  else
291  entity = add_entity (NULL, element_name, NULL);
292 
293  add_attributes (entity, attribute_names, attribute_values);
294 
295  /* "Push" the element. */
296  if (data->first == NULL)
297  data->current = data->first = g_slist_prepend (NULL, entity);
298  else
299  data->current = g_slist_prepend (data->current, entity);
300 }

References add_attributes(), add_entity(), context_data_t::current, entity_s::entities, and context_data_t::first.

Referenced by parse_entity(), try_read_entity_and_string(), try_read_entity_and_string_s(), and xml_handle_start_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_text()

static void handle_text ( GMarkupParseContext *  context,
const gchar *  text,
gsize  text_len,
gpointer  user_data,
GError **  error 
)
static

Handle additional text of an XML element.

Parameters
[in]contextParser context.
[in]textThe text.
[in]text_lenLength of the text.
[in]user_dataDummy parameter.
[in]errorError parameter.

Definition at line 379 of file xmlutils.c.

381 {
382  context_data_t *data = (context_data_t *) user_data;
383 
384  (void) context;
385  (void) text_len;
386  (void) error;
387  entity_t current = (entity_t) data->current->data;
388  if (current->text)
389  {
390  gchar *old = current->text;
391  current->text = g_strconcat (current->text, text, NULL);
392  g_free (old);
393  }
394  else
395  current->text = g_strdup (text);
396 }

References context_data_t::current, and entity_s::text.

Referenced by parse_entity(), try_read_entity_and_string(), try_read_entity_and_string_s(), and xml_handle_text().

Here is the caller graph for this function:

◆ make_entity()

entity_t make_entity ( const char *  name,
const char *  text 
)

Create an entity.

Parameters
[in]nameName of the entity. Copied, freed by free_entity.
[in]textText of the entity. Copied, freed by free_entity.
Returns
A newly allocated entity.

Definition at line 60 of file xmlutils.c.

61 {
62  entity_t entity;
63  entity = g_malloc (sizeof (*entity));
64  entity->name = g_strdup (name ? name : "");
65  entity->text = g_strdup (text ? text : "");
66  entity->entities = NULL;
67  entity->attributes = NULL;
68  return entity;
69 }

References entity_s::attributes, entity_s::entities, entity_s::name, and entity_s::text.

Referenced by add_entity().

Here is the caller graph for this function:

◆ next_entities()

entities_t next_entities ( entities_t  entities)

Return all the entities from an entities_t after the first.

Parameters
[in]entitiesThe list of entities.
Returns
All the entities that follow the first.

Definition at line 79 of file xmlutils.c.

80 {
81  if (entities)
82  return (entities_t) entities->next;
83  return NULL;
84 }

Referenced by osp_get_scanner_details(), and xml_count_entities().

Here is the caller graph for this function:

◆ parse_entity()

int parse_entity ( const char *  string,
entity_t entity 
)

Read an XML entity tree from a string.

Parameters
[in]stringInput string.
[out]entityPointer to an entity tree.
Returns
0 success, -1 read error, -2 parse error, -3 XML ended prematurely.

Definition at line 1099 of file xmlutils.c.

1100 {
1101  GMarkupParser xml_parser;
1102  GError *error = NULL;
1103  GMarkupParseContext *xml_context;
1104  context_data_t context_data;
1105 
1106  /* Create the XML parser. */
1107 
1108  xml_parser.start_element = handle_start_element;
1109  xml_parser.end_element = handle_end_element;
1110  xml_parser.text = handle_text;
1111  xml_parser.passthrough = NULL;
1112  xml_parser.error = handle_error;
1113 
1114  context_data.done = FALSE;
1115  context_data.first = NULL;
1116  context_data.current = NULL;
1117 
1118  /* Setup the XML context. */
1119 
1120  xml_context =
1121  g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
1122 
1123  /* Parse the string. */
1124 
1125  g_markup_parse_context_parse (xml_context, string, strlen (string), &error);
1126  if (error)
1127  {
1128  g_error_free (error);
1129  if (context_data.first && context_data.first->data)
1130  {
1131  free_entity (context_data.first->data);
1132  g_slist_free_1 (context_data.first);
1133  }
1134  return -2;
1135  }
1136  if (context_data.done)
1137  {
1138  g_markup_parse_context_end_parse (xml_context, &error);
1139  if (error)
1140  {
1141  g_warning (" End error: %s\n", error->message);
1142  g_error_free (error);
1143  if (context_data.first && context_data.first->data)
1144  {
1145  free_entity (context_data.first->data);
1146  g_slist_free_1 (context_data.first);
1147  }
1148  return -2;
1149  }
1150  *entity = (entity_t) context_data.first->data;
1151  g_slist_free_1 (context_data.first);
1152  return 0;
1153  }
1154  if (context_data.first && context_data.first->data)
1155  {
1156  free_entity (context_data.first->data);
1157  g_slist_free_1 (context_data.first);
1158  }
1159  return -3;
1160 }

References context_data_t::current, context_data_t::done, context_data_t::first, free_entity(), handle_end_element(), handle_error(), handle_start_element(), and handle_text().

Here is the call graph for this function:

◆ print_entity()

void print_entity ( FILE *  stream,
entity_t  entity 
)

Print an XML entity.

Parameters
[in]entityThe entity.
[in]streamThe stream to which to print.

Definition at line 1244 of file xmlutils.c.

1245 {
1246  gchar *text_escaped = NULL;
1247  fprintf (stream, "<%s", entity->name);
1248  if (entity->attributes && g_hash_table_size (entity->attributes))
1249  g_hash_table_foreach (entity->attributes, foreach_print_attribute, stream);
1250  fprintf (stream, ">");
1251  text_escaped = g_markup_escape_text (entity->text, -1);
1252  fprintf (stream, "%s", text_escaped);
1253  g_free (text_escaped);
1254  g_slist_foreach (entity->entities, foreach_print_entity, stream);
1255  fprintf (stream, "</%s>", entity->name);
1256  fflush (stream);
1257 }

References entity_s::attributes, entity_s::entities, foreach_print_attribute(), foreach_print_entity(), entity_s::name, and entity_s::text.

Referenced by foreach_print_entity().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_entity_format()

void print_entity_format ( entity_t  entity,
gpointer  indent 
)

Print an XML entity to stdout, recursively printing its children.

Does very basic indentation for pretty printing.

This function is used as the (callback) GFunc in g_slist_foreach.

Parameters
[in]entityThe entity.
[in]indentIndentation level, indentation width is 2 spaces. Use GINT_TO_POINTER to convert a integer value when passing this parameter.

Definition at line 1287 of file xmlutils.c.

1288 {
1289  int i = 0;
1290  int indentation = GPOINTER_TO_INT (indent);
1291  gchar *text_escaped = NULL;
1292 
1293  for (i = 0; i < indentation; i++)
1294  printf (" ");
1295 
1296  printf ("<%s", entity->name);
1297  if (entity->attributes && g_hash_table_size (entity->attributes))
1298  g_hash_table_foreach (entity->attributes, foreach_print_attribute_format,
1299  indent);
1300  printf (">");
1301 
1302  text_escaped = g_markup_escape_text (entity->text, -1);
1303  printf ("%s", text_escaped);
1304  g_free (text_escaped);
1305 
1306  if (entity->entities)
1307  {
1308  printf ("\n");
1309  g_slist_foreach (entity->entities, (GFunc) print_entity_format,
1310  GINT_TO_POINTER (indentation + 1));
1311  for (i = 0; i < indentation; i++)
1312  printf (" ");
1313  }
1314 
1315  printf ("</%s>\n", entity->name);
1316 }

References entity_s::attributes, entity_s::entities, foreach_print_attribute_format(), entity_s::name, print_entity_format(), and entity_s::text.

Referenced by print_entity_format().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_entity_to_string()

void print_entity_to_string ( entity_t  entity,
GString *  string 
)

Print an XML entity tree to a GString, appending it if string is not.

empty.

Parameters
[in]entityEntity tree to print to string.
[in,out]stringString to write to.

Definition at line 1197 of file xmlutils.c.

1198 {
1199  gchar *text_escaped = NULL;
1200  g_string_append_printf (string, "<%s", entity->name);
1201  if (entity->attributes && g_hash_table_size (entity->attributes))
1202  g_hash_table_foreach (entity->attributes, foreach_print_attribute_to_string,
1203  string);
1204  g_string_append_printf (string, ">");
1205  text_escaped = g_markup_escape_text (entity->text, -1);
1206  g_string_append_printf (string, "%s", text_escaped);
1207  g_free (text_escaped);
1208  g_slist_foreach (entity->entities, foreach_print_entity_to_string, string);
1209  g_string_append_printf (string, "</%s>", entity->name);
1210 }

References entity_s::attributes, entity_s::entities, foreach_print_attribute_to_string(), foreach_print_entity_to_string(), entity_s::name, and entity_s::text.

Referenced by foreach_print_entity_to_string(), and osp_get_scan_pop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_entity()

int read_entity ( gnutls_session_t *  session,
entity_t entity 
)

Read an XML entity tree from the manager.

Parameters
[in]sessionPointer to GNUTLS session.
[out]entityPointer to an entity tree.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 1057 of file xmlutils.c.

1058 {
1059  return try_read_entity (session, 0, entity);
1060 }

References try_read_entity().

Referenced by gmp_check_response(), and gmp_read_create_response().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_entity_and_string()

int read_entity_and_string ( gnutls_session_t *  session,
entity_t entity,
GString **  string_return 
)

Try read an XML entity tree from the manager.

Parameters
[in]sessionPointer to GNUTLS session.
[out]entityPointer to an entity tree.
[out]string_returnAn optional return location for the text read from the session. If NULL then it simply remains NULL. If a pointer to NULL then it points to a freshly allocated GString on successful return. Otherwise it points to an existing GString onto which the text is appended.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 880 of file xmlutils.c.

882 {
883  return try_read_entity_and_string (session, 0, entity, string_return);
884 }

References try_read_entity_and_string().

Referenced by read_entity_and_text(), and read_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_entity_and_string_c()

int read_entity_and_string_c ( gvm_connection_t connection,
entity_t entity,
GString **  string_return 
)

Try read an XML entity tree from the manager.

Parameters
[in]connectionConnection.
[out]entityPointer to an entity tree.
[out]string_returnAn optional return location for the text read from the session. If NULL then it simply remains NULL. If a pointer to NULL then it points to a freshly allocated GString on successful return. Otherwise it points to an existing GString onto which the text is appended.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 900 of file xmlutils.c.

902 {
903  if (connection->tls)
904  return try_read_entity_and_string (&connection->session, 0, entity,
905  string_return);
906  return try_read_entity_and_string_s (connection->socket, 0, entity,
907  string_return);
908 }

References gvm_connection_t::session, gvm_connection_t::socket, gvm_connection_t::tls, try_read_entity_and_string(), and try_read_entity_and_string_s().

Referenced by read_entity_and_text_c(), and read_string_c().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_entity_and_text()

int read_entity_and_text ( gnutls_session_t *  session,
entity_t entity,
char **  text 
)

Read an XML entity tree from the manager.

Parameters
[in]sessionPointer to GNUTLS session.
[out]entityPointer to an entity tree.
[out]textA pointer to a pointer, at which to store the address of a newly allocated string holding the text read from the session, if the text is required, else NULL.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 923 of file xmlutils.c.

924 {
925  if (text)
926  {
927  GString *string = NULL;
928  int ret = read_entity_and_string (session, entity, &string);
929  if (ret)
930  {
931  if (string)
932  g_string_free (string, TRUE);
933  return ret;
934  }
935  *text = g_string_free (string, FALSE);
936  return 0;
937  }
938  return read_entity_and_string (session, entity, NULL);
939 }

References read_entity_and_string().

Here is the call graph for this function:

◆ read_entity_and_text_c()

int read_entity_and_text_c ( gvm_connection_t connection,
entity_t entity,
char **  text 
)

Read an XML entity tree from the manager.

Parameters
[in]connectionConnection.
[out]entityEntity tree.
[out]textA pointer to a pointer, at which to store the address of a newly allocated string holding the text read from the session, if the text is required, else NULL.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 954 of file xmlutils.c.

956 {
957  if (text)
958  {
959  GString *string = NULL;
960  int ret = read_entity_and_string_c (connection, entity, &string);
961  if (ret)
962  {
963  if (string)
964  g_string_free (string, TRUE);
965  return ret;
966  }
967  *text = g_string_free (string, FALSE);
968  return 0;
969  }
970  return read_entity_and_string_c (connection, entity, NULL);
971 }

References read_entity_and_string_c().

Here is the call graph for this function:

◆ read_entity_c()

int read_entity_c ( gvm_connection_t connection,
entity_t entity 
)

Read an XML entity tree from the manager.

Parameters
[in]connectionConnection.
[out]entityPointer to an entity tree.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 1085 of file xmlutils.c.

1086 {
1087  return try_read_entity_c (connection, 0, entity);
1088 }

References try_read_entity_c().

Referenced by gmp_check_response_c(), gmp_resume_task_report_c(), and gmp_start_task_report_c().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_entity_s()

int read_entity_s ( int  socket,
entity_t entity 
)

Read an XML entity tree from the socket.

Parameters
[in]socketSocket to read from.
[out]entityPointer to an entity tree.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 1071 of file xmlutils.c.

1072 {
1073  return try_read_entity_and_string_s (socket, 0, entity, NULL);
1074 }

References try_read_entity_and_string_s().

Here is the call graph for this function:

◆ read_string()

int read_string ( gnutls_session_t *  session,
GString **  string 
)

Read entity and text. Free the entity immediately.

Parameters
[in]sessionPointer to GNUTLS session to read from.
[out]stringReturn location for the string.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 982 of file xmlutils.c.

983 {
984  int ret = 0;
985  entity_t entity;
986 
987  if (!(ret = read_entity_and_string (session, &entity, string)))
988  free_entity (entity);
989 
990  return ret;
991 }

References free_entity(), and read_entity_and_string().

Here is the call graph for this function:

◆ read_string_c()

int read_string_c ( gvm_connection_t connection,
GString **  string 
)

Read entity and text. Free the entity immediately.

Parameters
[in]connectionConnection.
[out]stringReturn location for the string.
Returns
0 success, -1 read error, -2 parse error, -3 end of file.

Definition at line 1002 of file xmlutils.c.

1003 {
1004  int ret = 0;
1005  entity_t entity;
1006 
1007  if (!(ret = read_entity_and_string_c (connection, &entity, string)))
1008  free_entity (entity);
1009 
1010  return ret;
1011 }

References free_entity(), and read_entity_and_string_c().

Here is the call graph for this function:

◆ try_read_entity()

int try_read_entity ( gnutls_session_t *  session,
int  timeout,
entity_t entity 
)

Try read an XML entity tree from the manager.

Parameters
[in]sessionPointer to GNUTLS session.
[in]timeoutServer idle time before giving up, in seconds. 0 to wait forever.
[out]entityPointer to an entity tree.
Returns
0 success, -1 read error, -2 parse error, -3 end of file, -4 timeout.

Definition at line 1024 of file xmlutils.c.

1025 {
1026  return try_read_entity_and_string (session, timeout, entity, NULL);
1027 }

References try_read_entity_and_string().

Referenced by gmp_authenticate_info_ext(), gmp_get_report_ext(), gmp_get_tasks_ext(), gmp_ping(), and read_entity().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_read_entity_and_string()

int try_read_entity_and_string ( gnutls_session_t *  session,
int  timeout,
entity_t entity,
GString **  string_return 
)

Try read an XML entity tree from the manager.

Parameters
[in]sessionPointer to GNUTLS session.
[in]timeoutServer idle time before giving up, in seconds. 0 to wait forever.
[out]entityPointer to an entity tree.
[out]string_returnAn optional return location for the text read from the session. If NULL then it simply remains NULL. If a pointer to NULL then it points to a freshly allocated GString on successful return. Otherwise it points to an existing GString onto which the text is appended.
Returns
0 success, -1 read error, -2 parse error, -3 end of file, -4 timeout.

Definition at line 442 of file xmlutils.c.

444 {
445  GMarkupParser xml_parser;
446  GError *error = NULL;
447  GMarkupParseContext *xml_context;
448  GString *string;
449  int socket;
450  time_t last_time;
451 
452  // Buffer for reading from the manager.
453  char *buffer;
454 
455  /* Record the start time. */
456 
457  if (time (&last_time) == -1)
458  {
459  g_warning (" failed to get current time: %s\n", strerror (errno));
460  return -1;
461  }
462 
463  if (timeout > 0)
464  {
465  /* Turn off blocking. */
466 
467  socket = GPOINTER_TO_INT (gnutls_transport_get_ptr (*session));
468  if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
469  return -1;
470  }
471  else
472  /* Quiet compiler. */
473  socket = 0;
474 
475  buffer = g_malloc0 (BUFFER_SIZE);
476 
477  /* Setup return arg. */
478 
479  if (string_return == NULL)
480  string = NULL;
481  else if (*string_return == NULL)
482  string = g_string_new ("");
483  else
484  string = *string_return;
485 
486  /* Create the XML parser. */
487 
488  xml_parser.start_element = handle_start_element;
489  xml_parser.end_element = handle_end_element;
490  xml_parser.text = handle_text;
491  xml_parser.passthrough = NULL;
492  xml_parser.error = handle_error;
493 
494  context_data_t context_data;
495  context_data.done = FALSE;
496  context_data.first = NULL;
497  context_data.current = NULL;
498 
499  /* Setup the XML context. */
500 
501  xml_context =
502  g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
503 
504  /* Read and parse, until encountering end of file or error. */
505 
506  while (1)
507  {
508  ssize_t count;
509  while (1)
510  {
511  g_debug (" asking for %i\n", BUFFER_SIZE);
512  count = gnutls_record_recv (*session, buffer, BUFFER_SIZE);
513  if (count < 0)
514  {
515  if (count == GNUTLS_E_INTERRUPTED)
516  /* Interrupted, try read again. */
517  continue;
518  if ((timeout > 0) && (count == GNUTLS_E_AGAIN))
519  {
520  /* Server still busy, either timeout or try read again. */
521  if ((timeout - (time (NULL) - last_time)) <= 0)
522  {
523  g_warning (" timeout\n");
524  if (fcntl (socket, F_SETFL, 0L) < 0)
525  g_warning ("%s :failed to set socket flag: %s",
526  __FUNCTION__, strerror (errno));
527  g_markup_parse_context_free (xml_context);
528  g_free (buffer);
529  return -4;
530  }
531  continue;
532  }
533  if (count == GNUTLS_E_REHANDSHAKE)
534  /* Try again. TODO Rehandshake. */
535  continue;
536  if (context_data.first && context_data.first->data)
537  {
538  free_entity (context_data.first->data);
539  g_slist_free_1 (context_data.first);
540  }
541  if (string && *string_return == NULL)
542  g_string_free (string, TRUE);
543  if (timeout > 0)
544  {
545  if (fcntl (socket, F_SETFL, 0L) < 0)
546  g_warning ("%s :failed to set socket flag: %s",
547  __FUNCTION__, strerror (errno));
548  }
549  g_markup_parse_context_free (xml_context);
550  g_free (buffer);
551  return -1;
552  }
553  if (count == 0)
554  {
555  /* End of file. */
556  g_markup_parse_context_end_parse (xml_context, &error);
557  if (error)
558  {
559  g_warning (" End error: %s\n", error->message);
560  g_error_free (error);
561  }
562  if (context_data.first && context_data.first->data)
563  {
564  free_entity (context_data.first->data);
565  g_slist_free_1 (context_data.first);
566  }
567  if (string && *string_return == NULL)
568  g_string_free (string, TRUE);
569  if (timeout > 0)
570  {
571  if (fcntl (socket, F_SETFL, 0L) < 0)
572  g_warning ("%s :failed to set socket flag: %s",
573  __FUNCTION__, strerror (errno));
574  }
575  g_markup_parse_context_free (xml_context);
576  g_free (buffer);
577  return -3;
578  }
579  break;
580  }
581 
582  g_debug ("<= %.*s\n", (int) count, buffer);
583 
584  if (string)
585  g_string_append_len (string, buffer, count);
586 
587  g_markup_parse_context_parse (xml_context, buffer, count, &error);
588  if (error)
589  {
590  g_error_free (error);
591  if (context_data.first && context_data.first->data)
592  {
593  free_entity (context_data.first->data);
594  g_slist_free_1 (context_data.first);
595  }
596  if (string && *string_return == NULL)
597  g_string_free (string, TRUE);
598  if (timeout > 0)
599  {
600  if (fcntl (socket, F_SETFL, 0L) < 0)
601  g_warning ("%s :failed to set socket flag: %s", __FUNCTION__,
602  strerror (errno));
603  }
604  g_markup_parse_context_free (xml_context);
605  g_free (buffer);
606  return -2;
607  }
608  if (context_data.done)
609  {
610  g_markup_parse_context_end_parse (xml_context, &error);
611  if (error)
612  {
613  g_warning (" End error: %s\n", error->message);
614  g_error_free (error);
615  if (context_data.first && context_data.first->data)
616  {
617  free_entity (context_data.first->data);
618  g_slist_free_1 (context_data.first);
619  }
620  if (timeout > 0)
621  fcntl (socket, F_SETFL, 0L);
622  g_markup_parse_context_free (xml_context);
623  g_free (buffer);
624  return -2;
625  }
626  *entity = (entity_t) context_data.first->data;
627  if (string)
628  *string_return = string;
629  if (timeout > 0)
630  fcntl (socket, F_SETFL, 0L);
631  g_markup_parse_context_free (xml_context);
632  g_free (buffer);
633  return 0;
634  }
635 
636  if ((timeout > 0) && (time (&last_time) == -1))
637  {
638  g_warning (" failed to get current time (1): %s\n",
639  strerror (errno));
640  if (fcntl (socket, F_SETFL, 0L) < 0)
641  g_warning ("%s :failed to set socket flag: %s", __FUNCTION__,
642  strerror (errno));
643  g_markup_parse_context_free (xml_context);
644  g_free (buffer);
645  return -1;
646  }
647  }
648 }

References BUFFER_SIZE, context_data_t::current, context_data_t::done, context_data_t::first, free_entity(), handle_end_element(), handle_error(), handle_start_element(), and handle_text().

Referenced by read_entity_and_string(), read_entity_and_string_c(), try_read_entity(), and try_read_entity_c().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_read_entity_and_string_s()

int try_read_entity_and_string_s ( int  socket,
int  timeout,
entity_t entity,
GString **  string_return 
)

Try read an XML entity tree from the socket.

Parameters
[in]socketSocket to read from.
[in]timeoutServer idle time before giving up, in seconds. 0 to wait forever.
[out]entityPointer to an entity tree.
[out]string_returnAn optional return location for the text read from the session. If NULL then it simply remains NULL. If a pointer to NULL then it points to a freshly allocated GString on successful return. Otherwise it points to an existing GString onto which the text is appended.
Returns
0 success, -1 read error, -2 parse error, -3 end of file, -4 timeout.

Definition at line 666 of file xmlutils.c.

668 {
669  GMarkupParser xml_parser;
670  GError *error = NULL;
671  GMarkupParseContext *xml_context;
672  GString *string;
673  time_t last_time;
674  /* Buffer for reading from the socket. */
675  char *buffer;
676 
677  /* Record the start time. */
678 
679  if (time (&last_time) == -1)
680  {
681  g_warning (" failed to get current time: %s\n", strerror (errno));
682  return -1;
683  }
684 
685  if (timeout > 0)
686  {
687  /* Turn off blocking. */
688 
689  if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
690  return -1;
691  }
692 
693  buffer = g_malloc0 (BUFFER_SIZE);
694 
695  /* Setup return arg. */
696 
697  if (string_return == NULL)
698  string = NULL;
699  else if (*string_return == NULL)
700  string = g_string_new ("");
701  else
702  string = *string_return;
703 
704  /* Create the XML parser. */
705 
706  xml_parser.start_element = handle_start_element;
707  xml_parser.end_element = handle_end_element;
708  xml_parser.text = handle_text;
709  xml_parser.passthrough = NULL;
710  xml_parser.error = handle_error;
711 
712  context_data_t context_data;
713  context_data.done = FALSE;
714  context_data.first = NULL;
715  context_data.current = NULL;
716 
717  /* Setup the XML context. */
718 
719  xml_context =
720  g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
721 
722  /* Read and parse, until encountering end of file or error. */
723 
724  while (1)
725  {
726  int count;
727  while (1)
728  {
729  g_debug (" asking for %i\n", BUFFER_SIZE);
730  count = read (socket, buffer, BUFFER_SIZE);
731  if (count < 0)
732  {
733  if (errno == EINTR)
734  /* Interrupted, try read again. */
735  continue;
736  if (timeout > 0)
737  {
738  if (errno == EAGAIN)
739  {
740  /* Server still busy, either timeout or try read again. */
741  if ((timeout - (time (NULL) - last_time)) <= 0)
742  {
743  g_warning (" timeout\n");
744  if (fcntl (socket, F_SETFL, 0L) < 0)
745  g_warning ("%s :failed to set socket flag: %s",
746  __FUNCTION__, strerror (errno));
747  g_markup_parse_context_free (xml_context);
748  g_free (buffer);
749  return -4;
750  }
751  }
752  continue;
753  }
754  if (context_data.first && context_data.first->data)
755  {
756  free_entity (context_data.first->data);
757  g_slist_free_1 (context_data.first);
758  }
759  if (string && *string_return == NULL)
760  g_string_free (string, TRUE);
761  if (timeout > 0)
762  fcntl (socket, F_SETFL, 0L);
763  g_markup_parse_context_free (xml_context);
764  g_free (buffer);
765  return -1;
766  }
767  if (count == 0)
768  {
769  /* End of file. */
770  g_markup_parse_context_end_parse (xml_context, &error);
771  if (error)
772  {
773  g_warning (" End error: %s\n", error->message);
774  g_error_free (error);
775  }
776  if (context_data.first && context_data.first->data)
777  {
778  free_entity (context_data.first->data);
779  g_slist_free_1 (context_data.first);
780  }
781  if (string && *string_return == NULL)
782  g_string_free (string, TRUE);
783  if (timeout > 0)
784  {
785  if (fcntl (socket, F_SETFL, 0L) < 0)
786  g_warning ("%s :failed to set socket flag: %s",
787  __FUNCTION__, strerror (errno));
788  }
789  g_markup_parse_context_free (xml_context);
790  g_free (buffer);
791  return -3;
792  }
793  break;
794  }
795 
796  g_debug ("<= %.*s\n", (int) count, buffer);
797 
798  if (string)
799  g_string_append_len (string, buffer, count);
800 
801  g_markup_parse_context_parse (xml_context, buffer, count, &error);
802  if (error)
803  {
804  g_error_free (error);
805  // FIX there may be multiple entries in list
806  if (context_data.first && context_data.first->data)
807  {
808  free_entity (context_data.first->data);
809  g_slist_free_1 (context_data.first);
810  }
811  if (string && *string_return == NULL)
812  g_string_free (string, TRUE);
813  if (timeout > 0)
814  {
815  if (fcntl (socket, F_SETFL, 0L) < 0)
816  g_warning ("%s :failed to set socket flag: %s", __FUNCTION__,
817  strerror (errno));
818  }
819  g_markup_parse_context_free (xml_context);
820  g_free (buffer);
821  return -2;
822  }
823  if (context_data.done)
824  {
825  g_markup_parse_context_end_parse (xml_context, &error);
826  if (error)
827  {
828  g_warning (" End error: %s\n", error->message);
829  g_error_free (error);
830  if (context_data.first && context_data.first->data)
831  {
832  free_entity (context_data.first->data);
833  g_slist_free_1 (context_data.first);
834  }
835  if (timeout > 0)
836  fcntl (socket, F_SETFL, 0L);
837  g_markup_parse_context_free (xml_context);
838  g_free (buffer);
839  return -2;
840  }
841  *entity = (entity_t) context_data.first->data;
842  if (string)
843  *string_return = string;
844  if (timeout > 0)
845  fcntl (socket, F_SETFL, 0L);
846  g_slist_free (context_data.first);
847  g_markup_parse_context_free (xml_context);
848  g_free (buffer);
849  return 0;
850  }
851 
852  if ((timeout > 0) && (time (&last_time) == -1))
853  {
854  g_warning (" failed to get current time (1): %s\n",
855  strerror (errno));
856  if (fcntl (socket, F_SETFL, 0L) < 0)
857  g_warning ("%s :failed to set server socket flag: %s", __FUNCTION__,
858  strerror (errno));
859  g_markup_parse_context_free (xml_context);
860  g_free (buffer);
861  return -1;
862  }
863  }
864 }

References BUFFER_SIZE, context_data_t::current, context_data_t::done, context_data_t::first, free_entity(), handle_end_element(), handle_error(), handle_start_element(), and handle_text().

Referenced by read_entity_and_string_c(), read_entity_s(), and try_read_entity_c().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_read_entity_c()

int try_read_entity_c ( gvm_connection_t connection,
int  timeout,
entity_t entity 
)

Try read an XML entity tree from the manager.

Parameters
[in]connectionConnection.
[in]timeoutServer idle time before giving up, in seconds. 0 to wait forever.
[out]entityPointer to an entity tree.
Returns
0 success, -1 read error, -2 parse error, -3 end of file, -4 timeout.

Definition at line 1040 of file xmlutils.c.

1041 {
1042  if (connection->tls)
1043  return try_read_entity_and_string (&connection->session, 0, entity, NULL);
1044  return try_read_entity_and_string_s (connection->socket, timeout, entity,
1045  NULL);
1046 }

References gvm_connection_t::session, gvm_connection_t::socket, gvm_connection_t::tls, try_read_entity_and_string(), and try_read_entity_and_string_s().

Referenced by gmp_authenticate_info_ext_c(), gmp_ping_c(), and read_entity_c().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ xml_count_entities()

int xml_count_entities ( entities_t  entities)

Count the number of entities.

Parameters
[in]entitiesEntities.
Returns
Number of entities.

Definition at line 1411 of file xmlutils.c.

1412 {
1413  int count = 0;
1414  while (first_entity (entities))
1415  {
1416  entities = next_entities (entities);
1417  count++;
1418  }
1419  return count;
1420 }

References first_entity(), and next_entities().

Here is the call graph for this function:

◆ xml_handle_end_element()

void xml_handle_end_element ( context_data_t context,
const gchar *  element_name 
)

Handle the end of an XML element.

Parameters
[in]contextParser context.
[in]element_nameXML element name.

Definition at line 364 of file xmlutils.c.

365 {
366  handle_end_element (NULL, element_name, context, NULL);
367 }

References handle_end_element().

Here is the call graph for this function:

◆ xml_handle_start_element()

void xml_handle_start_element ( context_data_t context,
const gchar *  element_name,
const gchar **  attribute_names,
const gchar **  attribute_values 
)

Handle the start of an OMP XML element.

Parameters
[in]contextParser context.
[in]element_nameXML element name.
[in]attribute_namesXML attribute name.
[in]attribute_valuesXML attribute values.

Definition at line 311 of file xmlutils.c.

314 {
315  return handle_start_element (NULL, element_name, attribute_names,
316  attribute_values, context, NULL);
317 }

References handle_start_element().

Here is the call graph for this function:

◆ xml_handle_text()

void xml_handle_text ( context_data_t context,
const gchar *  text,
gsize  text_len 
)

Handle additional text of an XML element.

Parameters
[in]contextParser context.
[in]textThe text.
[in]text_lenLength of the text.

Definition at line 406 of file xmlutils.c.

407 {
408  handle_text (NULL, text, text_len, context, NULL);
409 }

References handle_text().

Here is the call graph for this function:

◆ xml_search_handle_start_element()

static void xml_search_handle_start_element ( GMarkupParseContext *  ctx,
const gchar *  element_name,
const gchar **  attribute_names,
const gchar **  attribute_values,
gpointer  data,
GError **  error 
)
static

Handle the opening tag of an element in an XML search.

Parameters
[in]ctxThe parse context.
[in]element_nameThe name of the element.
[in]attribute_namesNULL-terminated array of attribute names.
[in]attribute_valuesNULL-terminated array of attribute values.
[in]dataThe search data struct.
[out]errorPointer to error output location.

Definition at line 1457 of file xmlutils.c.

1462 {
1463  (void) ctx;
1464  (void) error;
1465 
1466  xml_search_data_t *search_data = ((xml_search_data_t *) data);
1467 
1468  if (strcmp (element_name, search_data->find_element) == 0
1469  && search_data->found == 0)
1470  {
1471  g_debug ("%s: Found element <%s>", __FUNCTION__, element_name);
1472 
1473  if (search_data->find_attributes
1474  && g_hash_table_size (search_data->find_attributes))
1475  {
1476  int index;
1477  GHashTable *found_attributes;
1478  found_attributes =
1479  g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1480  index = 0;
1481  while (attribute_names[index])
1482  {
1483  gchar *searched_value;
1484  searched_value = g_hash_table_lookup (
1485  search_data->find_attributes, attribute_names[index]);
1486  if (searched_value
1487  && strcmp (searched_value, attribute_values[index]) == 0)
1488  {
1489  g_debug ("%s: Found attribute %s=\"%s\"", __FUNCTION__,
1490  attribute_names[index], searched_value);
1491  g_hash_table_add (found_attributes, searched_value);
1492  }
1493  index++;
1494  }
1495  g_debug ("%s: Found %d of %d attributes", __FUNCTION__,
1496  g_hash_table_size (found_attributes),
1497  g_hash_table_size (search_data->find_attributes));
1498 
1499  if (g_hash_table_size (found_attributes)
1500  == g_hash_table_size (search_data->find_attributes))
1501  {
1502  search_data->found = 1;
1503  }
1504 
1505  g_hash_table_destroy (found_attributes);
1506  }
1507  else
1508  {
1509  search_data->found = 1;
1510  }
1511  }
1512 }

References xml_search_data_t::find_attributes, xml_search_data_t::find_element, and xml_search_data_t::found.

Referenced by find_element_in_xml_file().

Here is the caller graph for this function:

◆ xml_string_append()

void xml_string_append ( GString *  xml,
const char *  format,
  ... 
)

Append formatted escaped XML to a string.

Parameters
[in]xmlXML string.
[in]formatFormat string.
[in]...Arguments for format string.
Returns
Result of XSL transformation.

Definition at line 1432 of file xmlutils.c.

1433 {
1434  gchar *piece;
1435  va_list args;
1436 
1437  va_start (args, format);
1438  piece = g_markup_vprintf_escaped (format, args);
1439  va_end (args);
1440  g_string_append (xml, piece);
1441  g_free (piece);
1442 }

Referenced by credential_append_as_xml(), gmp_get_system_reports_ext(), osp_start_scan_ext(), target_append_as_xml(), vt_group_append_as_xml(), vt_single_append_as_xml(), and vt_value_append_as_xml().

Here is the caller graph for this function:
xml_search_handle_start_element
static void xml_search_handle_start_element(GMarkupParseContext *ctx, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
Handle the opening tag of an element in an XML search.
Definition: xmlutils.c:1457
BUFFER_SIZE
#define BUFFER_SIZE
Size of the buffer for reading from the manager.
Definition: xmlutils.c:49
try_read_entity_and_string
int try_read_entity_and_string(gnutls_session_t *session, int timeout, entity_t *entity, GString **string_return)
Try read an XML entity tree from the manager.
Definition: xmlutils.c:442
compare_find_attribute
gboolean compare_find_attribute(gpointer key, gpointer value, gpointer attributes2)
Look for a key-value pair in a hash table.
Definition: xmlutils.c:1328
context_data_t
XML context.
Definition: xmlutils.h:40
add_attributes
void add_attributes(entity_t entity, const gchar **names, const gchar **values)
Add attributes from an XML callback to an entity.
Definition: xmlutils.c:246
handle_end_element
static void handle_end_element(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
Handle the end of an XML element.
Definition: xmlutils.c:328
first_entity
entity_t first_entity(entities_t entities)
Return the first entity from an entities_t.
Definition: xmlutils.c:94
entity_s::entities
entities_t entities
Children.
Definition: xmlutils.h:70
foreach_print_entity_to_string
static void foreach_print_entity_to_string(gpointer entity, gpointer string)
Print an XML entity for g_slist_foreach to a GString.
Definition: xmlutils.c:1169
entity_s::name
char * name
Name.
Definition: xmlutils.h:67
print_entity_format
void print_entity_format(entity_t entity, gpointer indent)
Print an XML entity to stdout, recursively printing its children.
Definition: xmlutils.c:1287
handle_text
static void handle_text(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
Handle additional text of an XML element.
Definition: xmlutils.c:379
entity_name
char * entity_name(entity_t entity)
Get the name an entity.
Definition: xmlutils.c:173
entity_s::attributes
GHashTable * attributes
Attributes.
Definition: xmlutils.h:69
free_entity
void free_entity(entity_t entity)
Free an entity, recursively.
Definition: xmlutils.c:127
compare_entity_with_name
int compare_entity_with_name(gconstpointer entity, gconstpointer name)
Compare a given name with the name of a given entity.
Definition: xmlutils.c:191
XML_FILE_BUFFER_SIZE
#define XML_FILE_BUFFER_SIZE
Definition: xmlutils.c:1514
next_entities
entities_t next_entities(entities_t entities)
Return all the entities from an entities_t after the first.
Definition: xmlutils.c:79
foreach_print_attribute_to_string
static void foreach_print_attribute_to_string(gpointer name, gpointer value, gpointer string)
Print an XML attribute for g_hash_table_foreach to a GString.
Definition: xmlutils.c:1182
xml_search_data_t::find_attributes
GHashTable * find_attributes
Definition: xmlutils.h:82
read_entity_and_string_c
int read_entity_and_string_c(gvm_connection_t *connection, entity_t *entity, GString **string_return)
Try read an XML entity tree from the manager.
Definition: xmlutils.c:900
foreach_print_attribute_format
static void foreach_print_attribute_format(gpointer name, gpointer value, gpointer none)
Print an XML attribute for g_hash_table_foreach to stdout.
Definition: xmlutils.c:1269
add_entity
entity_t add_entity(entities_t *entities, const char *name, const char *text)
Add an XML entity to a tree of entities.
Definition: xmlutils.c:113
handle_error
void handle_error(GMarkupParseContext *context, GError *error, gpointer user_data)
Handle an OMP XML parsing error.
Definition: xmlutils.c:419
gvm_connection_t::socket
int socket
Socket.
Definition: serverutils.h:46
try_read_entity
int try_read_entity(gnutls_session_t *session, int timeout, entity_t *entity)
Try read an XML entity tree from the manager.
Definition: xmlutils.c:1024
gvm_connection_t::tls
int tls
Whether uses TCP-TLS (vs UNIX socket).
Definition: serverutils.h:45
foreach_print_attribute
static void foreach_print_attribute(gpointer name, gpointer value, gpointer stream)
Print an XML attribute for g_hash_table_foreach.
Definition: xmlutils.c:1232
handle_start_element
static void handle_start_element(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
Handle the start of an OMP XML element.
Definition: xmlutils.c:275
xml_search_data_t::find_element
gchar * find_element
Definition: xmlutils.h:81
context_data_t::current
GSList * current
The element currently being parsed.
Definition: xmlutils.h:43
context_data_t::done
gboolean done
Flag which is true when the first element is closed.
Definition: xmlutils.h:44
foreach_print_entity
static void foreach_print_entity(gpointer entity, gpointer stream)
Print an XML entity for g_slist_foreach.
Definition: xmlutils.c:1219
entity_s
XML element.
Definition: xmlutils.h:65
read_entity_and_string
int read_entity_and_string(gnutls_session_t *session, entity_t *entity, GString **string_return)
Try read an XML entity tree from the manager.
Definition: xmlutils.c:880
entity_s::text
char * text
Text.
Definition: xmlutils.h:68
xml_search_data_t
Data for xml search functions.
Definition: xmlutils.h:77
make_entity
entity_t make_entity(const char *name, const char *text)
Create an entity.
Definition: xmlutils.c:60
xml_search_data_t::found
int found
Definition: xmlutils.h:79
try_read_entity_c
int try_read_entity_c(gvm_connection_t *connection, int timeout, entity_t *entity)
Try read an XML entity tree from the manager.
Definition: xmlutils.c:1040
print_entity_to_string
void print_entity_to_string(entity_t entity, GString *string)
Print an XML entity tree to a GString, appending it if string is not.
Definition: xmlutils.c:1197
compare_entities
int compare_entities(entity_t entity1, entity_t entity2)
Compare two XML entity.
Definition: xmlutils.c:1346
context_data_t::first
GSList * first
The very first entity.
Definition: xmlutils.h:42
entity_t
struct entity_s * entity_t
Definition: xmlutils.h:72
gvm_connection_t::session
gnutls_session_t session
Session.
Definition: serverutils.h:47
print_entity
void print_entity(FILE *stream, entity_t entity)
Print an XML entity.
Definition: xmlutils.c:1244
try_read_entity_and_string_s
int try_read_entity_and_string_s(int socket, int timeout, entity_t *entity, GString **string_return)
Try read an XML entity tree from the socket.
Definition: xmlutils.c:666
entities_t
GSList * entities_t
Entities.
Definition: xmlutils.h:60