Greenbone Vulnerability Management Libraries 22.7.1
xmlutils.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2023 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
15#include "xmlutils.h"
16
17#include <assert.h> /* for assert */
18#include <errno.h> /* for errno, EAGAIN, EINTR */
19#include <fcntl.h> /* for fcntl, F_SETFL, O_NONBLOCK */
20#include <glib.h> /* for g_free, GSList, g_markup_parse_context_free */
21#include <glib/gtypes.h> /* for GPOINTER_TO_INT, GINT_TO_POINTER, gsize */
22#include <libxml/parser.h>
23#include <libxml/tree.h>
24#include <string.h> /* for strcmp, strerror, strlen */
25#include <time.h> /* for time, time_t */
26#include <unistd.h> /* for ssize_t */
27
28#undef G_LOG_DOMAIN
32#define G_LOG_DOMAIN "libgvm util"
33
37#define BUFFER_SIZE 1048576
38
47static entity_t
48make_entity (const char *name, const char *text)
49{
50 entity_t entity;
51 entity = g_malloc (sizeof (*entity));
52 entity->name = g_strdup (name ? name : "");
53 entity->text = g_strdup (text ? text : "");
54 entity->entities = NULL;
55 entity->attributes = NULL;
56 return entity;
57}
58
68{
69 if (entities)
70 return (entities_t) entities->next;
71 return NULL;
72}
73
83{
84 if (entities)
85 return (entity_t) entities->data;
86 return NULL;
87}
88
101add_entity (entities_t *entities, const char *name, const char *text)
102{
103 entity_t entity = make_entity (name, text);
104 if (entities)
105 *entities = g_slist_append (*entities, entity);
106 return entity;
107}
108
114void
116{
117 if (entity)
118 {
119 g_free (entity->name);
120 g_free (entity->text);
121 if (entity->attributes)
122 g_hash_table_destroy (entity->attributes);
123 if (entity->entities)
124 {
125 GSList *list = entity->entities;
126 while (list)
127 {
128 free_entity (list->data);
129 list = list->next;
130 }
131 g_slist_free (entity->entities);
132 }
133 g_free (entity);
134 }
135}
136
144char *
146{
147 if (!entity)
148 return NULL;
149
150 return entity->text;
151}
152
160char *
162{
163 if (!entity)
164 return NULL;
165
166 return entity->name;
167}
168
178static int
179compare_entity_with_name (gconstpointer entity, gconstpointer name)
180{
181 return strcmp (entity_name ((entity_t) entity), (char *) name);
182}
183
193entity_child (entity_t entity, const char *name)
194{
195 if (!entity)
196 return NULL;
197
198 if (entity->entities)
199 {
200 entities_t match =
201 g_slist_find_custom (entity->entities, name, compare_entity_with_name);
202 return match ? (entity_t) match->data : NULL;
203 }
204 return NULL;
205}
206
215const char *
216entity_attribute (entity_t entity, const char *name)
217{
218 if (!entity)
219 return NULL;
220
221 if (entity->attributes)
222 return (const char *) g_hash_table_lookup (entity->attributes, name);
223 return NULL;
224}
225
233static void
234add_attributes (entity_t entity, const gchar **names, const gchar **values)
235{
236 if (names && values && *names && *values)
237 {
238 if (entity->attributes == NULL)
239 entity->attributes =
240 g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
241 while (*names && *values)
242 {
243 if (*values)
244 g_hash_table_insert (entity->attributes, g_strdup (*names),
245 g_strdup (*values));
246 names++;
247 values++;
248 }
249 }
250}
251
262static void
263ignore_start_element (GMarkupParseContext *context, const gchar *element_name,
264 const gchar **attribute_names,
265 const gchar **attribute_values, gpointer user_data,
266 GError **error)
267{
268 context_data_t *data = (context_data_t *) user_data;
269
270 (void) context;
271 (void) element_name;
272 (void) attribute_names;
273 (void) attribute_values;
274 (void) error;
275
276 data->current = GINT_TO_POINTER (GPOINTER_TO_INT (data->current) + 1);
277}
278
289static void
290handle_start_element (GMarkupParseContext *context, const gchar *element_name,
291 const gchar **attribute_names,
292 const gchar **attribute_values, gpointer user_data,
293 GError **error)
294{
295 entity_t entity;
296 context_data_t *data = (context_data_t *) user_data;
297
298 (void) context;
299 (void) error;
300 if (data->current)
301 {
302 entity_t current = (entity_t) data->current->data;
303 entity = add_entity (&current->entities, element_name, NULL);
304 }
305 else
306 entity = add_entity (NULL, element_name, NULL);
307
308 add_attributes (entity, attribute_names, attribute_values);
309
310 /* "Push" the element. */
311 if (data->first == NULL)
312 data->current = data->first = g_slist_prepend (NULL, entity);
313 else
314 data->current = g_slist_prepend (data->current, entity);
315}
316
325void
327 const gchar **attribute_names,
328 const gchar **attribute_values)
329{
330 handle_start_element (NULL, element_name, attribute_names, attribute_values,
331 context, NULL);
332}
333
342static void
343ignore_end_element (GMarkupParseContext *context, const gchar *element_name,
344 gpointer user_data, GError **error)
345{
346 context_data_t *data = (context_data_t *) user_data;
347
348 (void) context;
349 (void) element_name;
350 (void) error;
351
352 data->current = GINT_TO_POINTER (GPOINTER_TO_INT (data->current) - 1);
353 if (data->current == NULL)
354 data->done = TRUE;
355}
356
365static void
366handle_end_element (GMarkupParseContext *context, const gchar *element_name,
367 gpointer user_data, GError **error)
368{
369 context_data_t *data = (context_data_t *) user_data;
370
371 (void) context;
372 (void) error;
373 (void) element_name;
374 assert (data->current && data->first);
375 if (data->current == data->first)
376 {
377 assert (strcmp (element_name,
378 /* The name of the very first entity. */
379 ((entity_t) (data->first->data))->name)
380 == 0);
381 data->done = TRUE;
382 /* "Pop" the element. */
383 data->current = g_slist_next (data->current);
384 }
385 else if (data->current)
386 {
387 GSList *front;
388 /* "Pop" and free the element. */
389 front = data->current;
390 data->current = g_slist_next (data->current);
391 g_slist_free_1 (front);
392 }
393}
394
401void
403{
404 handle_end_element (NULL, element_name, context, NULL);
405}
406
416static void
417ignore_text (GMarkupParseContext *context, const gchar *text, gsize text_len,
418 gpointer user_data, GError **error)
419{
420 (void) context;
421 (void) text;
422 (void) text_len;
423 (void) user_data;
424 (void) error;
425}
426
436static void
437handle_text (GMarkupParseContext *context, const gchar *text, gsize text_len,
438 gpointer user_data, GError **error)
439{
440 context_data_t *data = (context_data_t *) user_data;
441
442 (void) context;
443 (void) text_len;
444 (void) error;
445 entity_t current = (entity_t) data->current->data;
446 if (current->text)
447 {
448 gchar *old = current->text;
449 current->text = g_strconcat (current->text, text, NULL);
450 g_free (old);
451 }
452 else
453 current->text = g_strdup (text);
454}
455
463void
464xml_handle_text (context_data_t *context, const gchar *text, gsize text_len)
465{
466 handle_text (NULL, text, text_len, context, NULL);
467}
468
476static void
477handle_error (GMarkupParseContext *context, GError *error, gpointer user_data)
478{
479 (void) context;
480 (void) user_data;
481 g_message (" Error: %s\n", error->message);
482}
483
500int
501try_read_entity_and_string (gnutls_session_t *session, int timeout,
502 entity_t *entity, GString **string_return)
503{
504 GMarkupParser xml_parser;
505 GError *error = NULL;
506 GMarkupParseContext *xml_context;
507 GString *string;
508 int socket;
509 time_t last_time;
510
511 // Buffer for reading from the manager.
512 char *buffer;
513
514 /* Record the start time. */
515
516 if (time (&last_time) == -1)
517 {
518 g_warning (" failed to get current time: %s\n", strerror (errno));
519 return -1;
520 }
521
522 if (timeout > 0)
523 {
524 /* Turn off blocking. */
525
526 socket = GPOINTER_TO_INT (gnutls_transport_get_ptr (*session));
527 if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
528 return -1;
529 }
530 else
531 /* Quiet compiler. */
532 socket = 0;
533
534 buffer = g_malloc0 (BUFFER_SIZE);
535 if (!buffer)
536 return -5;
537
538 /* Setup return arg. */
539
540 if (string_return == NULL)
541 string = NULL;
542 else if (*string_return == NULL)
543 string = g_string_new ("");
544 else
545 string = *string_return;
546
547 /* Create the XML parser. */
548
549 if (entity)
550 {
551 xml_parser.start_element = handle_start_element;
552 xml_parser.end_element = handle_end_element;
553 xml_parser.text = handle_text;
554 }
555 else
556 {
557 xml_parser.start_element = ignore_start_element;
558 xml_parser.end_element = ignore_end_element;
559 xml_parser.text = ignore_text;
560 }
561 xml_parser.passthrough = NULL;
562 xml_parser.error = handle_error;
563
564 context_data_t context_data;
565 context_data.done = FALSE;
566 context_data.first = NULL;
567 context_data.current = NULL;
568
569 /* Setup the XML context. */
570
571 xml_context =
572 g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
573
574 /* Read and parse, until encountering end of file or error. */
575
576 while (1)
577 {
578 ssize_t count;
579 int retries = 10;
580 while (1)
581 {
582 g_debug (" asking for %i\n", BUFFER_SIZE);
583 count = gnutls_record_recv (*session, buffer, BUFFER_SIZE);
584 if (count < 0)
585 {
586 if (count == GNUTLS_E_INTERRUPTED)
587 /* Interrupted, try read again. */
588 continue;
589 if ((timeout > 0) && (count == GNUTLS_E_AGAIN))
590 {
591 /* Server still busy, either timeout or try read again. */
592 if ((timeout - (time (NULL) - last_time)) <= 0)
593 {
594 g_warning (" timeout\n");
595 if (fcntl (socket, F_SETFL, 0L) < 0)
596 g_warning ("%s :failed to set socket flag: %s",
597 __func__, strerror (errno));
598 g_markup_parse_context_free (xml_context);
599 g_free (buffer);
600 return -4;
601 }
602 continue;
603 }
604 else if ((timeout == 0) && (count == GNUTLS_E_AGAIN))
605 {
606 /* Server still busy, try read again.
607 If there is no timeout set and the server is still not
608 ready, it will try up to 10 times before closing the
609 socket.*/
610 if (retries > 0)
611 {
612 retries = retries - 1;
613 continue;
614 }
615 }
616
617 if (count == GNUTLS_E_REHANDSHAKE)
618 /* Try again. TODO Rehandshake. */
619 continue;
620 if (context_data.first && context_data.first->data)
621 {
622 free_entity (context_data.first->data);
623 g_slist_free_1 (context_data.first);
624 }
625 if (string && *string_return == NULL)
626 g_string_free (string, TRUE);
627 if (timeout > 0)
628 {
629 if (fcntl (socket, F_SETFL, 0L) < 0)
630 g_warning ("%s :failed to set socket flag: %s", __func__,
631 strerror (errno));
632 }
633 g_markup_parse_context_free (xml_context);
634 g_free (buffer);
635 return -1;
636 }
637 if (count == 0)
638 {
639 /* End of file. */
640 g_markup_parse_context_end_parse (xml_context, &error);
641 if (error)
642 {
643 g_warning (" End error: %s\n", error->message);
644 g_error_free (error);
645 }
646 if (context_data.first && context_data.first->data)
647 {
648 free_entity (context_data.first->data);
649 g_slist_free_1 (context_data.first);
650 }
651 if (string && *string_return == NULL)
652 g_string_free (string, TRUE);
653 if (timeout > 0)
654 {
655 if (fcntl (socket, F_SETFL, 0L) < 0)
656 g_warning ("%s :failed to set socket flag: %s", __func__,
657 strerror (errno));
658 }
659 g_markup_parse_context_free (xml_context);
660 g_free (buffer);
661 return -3;
662 }
663 break;
664 }
665
666 g_debug ("<= %.*s\n", (int) count, buffer);
667
668 if (string)
669 g_string_append_len (string, buffer, count);
670
671 g_markup_parse_context_parse (xml_context, buffer, count, &error);
672 if (error)
673 {
674 g_error_free (error);
675 if (context_data.first && context_data.first->data)
676 {
677 free_entity (context_data.first->data);
678 g_slist_free_1 (context_data.first);
679 }
680 if (string && *string_return == NULL)
681 g_string_free (string, TRUE);
682 if (timeout > 0)
683 {
684 if (fcntl (socket, F_SETFL, 0L) < 0)
685 g_warning ("%s :failed to set socket flag: %s", __func__,
686 strerror (errno));
687 }
688 g_markup_parse_context_free (xml_context);
689 g_free (buffer);
690 return -2;
691 }
692 if (context_data.done)
693 {
694 g_markup_parse_context_end_parse (xml_context, &error);
695 if (error)
696 {
697 g_warning (" End error: %s\n", error->message);
698 g_error_free (error);
699 if (context_data.first && context_data.first->data)
700 {
701 free_entity (context_data.first->data);
702 g_slist_free_1 (context_data.first);
703 }
704 if (timeout > 0)
705 fcntl (socket, F_SETFL, 0L);
706 g_markup_parse_context_free (xml_context);
707 g_free (buffer);
708 return -2;
709 }
710 if (entity)
711 *entity = (entity_t) context_data.first->data;
712 if (string)
713 *string_return = string;
714 if (timeout > 0)
715 fcntl (socket, F_SETFL, 0L);
716 g_markup_parse_context_free (xml_context);
717 g_free (buffer);
718 return 0;
719 }
720
721 if ((timeout > 0) && (time (&last_time) == -1))
722 {
723 g_warning (" failed to get current time (1): %s\n",
724 strerror (errno));
725 if (fcntl (socket, F_SETFL, 0L) < 0)
726 g_warning ("%s :failed to set socket flag: %s", __func__,
727 strerror (errno));
728 g_markup_parse_context_free (xml_context);
729 g_free (buffer);
730 return -1;
731 }
732 }
733}
734
751static int
752try_read_string (gnutls_session_t *session, int timeout,
753 GString **string_return)
754{
755 GString *string;
756 int socket;
757 time_t last_time;
758 char *buffer; // Buffer for reading from the server.
759
760 /* Record the start time. */
761
762 if (time (&last_time) == -1)
763 {
764 g_warning (" failed to get current time: %s\n", strerror (errno));
765 return -1;
766 }
767
768 if (timeout > 0)
769 {
770 /* Turn off blocking. */
771
772 socket = GPOINTER_TO_INT (gnutls_transport_get_ptr (*session));
773 if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
774 return -1;
775 }
776 else
777 /* Quiet compiler. */
778 socket = 0;
779
780 buffer = g_malloc0 (BUFFER_SIZE);
781 if (!buffer)
782 return -5;
783
784 /* Setup return arg. */
785
786 if (string_return == NULL)
787 string = NULL;
788 else if (*string_return == NULL)
789 string = g_string_new ("");
790 else
791 string = *string_return;
792
793 /* Read until encountering end of file or error. */
794
795 while (1)
796 {
797 ssize_t count;
798 int retries = 10;
799 while (1)
800 {
801 g_debug (" asking for %i\n", BUFFER_SIZE);
802 count = gnutls_record_recv (*session, buffer, BUFFER_SIZE);
803 if (count < 0)
804 {
805 if (count == GNUTLS_E_INTERRUPTED)
806 /* Interrupted, try read again. */
807 continue;
808 if ((timeout > 0) && (count == GNUTLS_E_AGAIN))
809 {
810 /* Server still busy, either timeout or try read again. */
811 if ((timeout - (time (NULL) - last_time)) <= 0)
812 {
813 g_warning (" timeout\n");
814 if (fcntl (socket, F_SETFL, 0L) < 0)
815 g_warning ("%s: failed to set socket flag: %s",
816 __func__, strerror (errno));
817 g_free (buffer);
818 return -4;
819 }
820 continue;
821 }
822 else if ((timeout == 0) && (count == GNUTLS_E_AGAIN))
823 {
824 /* Server still busy, try read again.
825 * If there is no timeout set and the server is still not
826 * ready, it will try up to 10 times before closing the
827 * socket. */
828 if (retries > 0)
829 {
830 retries = retries - 1;
831 continue;
832 }
833 }
834
835 if (count == GNUTLS_E_REHANDSHAKE)
836 /* Try again. TODO Rehandshake. */
837 continue;
838 if (string && (*string_return == NULL))
839 g_string_free (string, TRUE);
840 if (timeout > 0)
841 {
842 if (fcntl (socket, F_SETFL, 0L) < 0)
843 g_warning ("%s: failed to set socket flag: %s", __func__,
844 strerror (errno));
845 }
846 g_free (buffer);
847 return -1;
848 }
849 if (count == 0)
850 {
851 /* End of file. */
852 if (timeout > 0)
853 {
854 if (fcntl (socket, F_SETFL, 0L) < 0)
855 g_warning ("%s :failed to set socket flag: %s", __func__,
856 strerror (errno));
857 }
858 if (string)
859 *string_return = string;
860 g_free (buffer);
861 return 0;
862 }
863 break;
864 }
865
866 g_debug ("<= %.*s\n", (int) count, buffer);
867
868 if (string)
869 g_string_append_len (string, buffer, count);
870
871 if ((timeout > 0) && (time (&last_time) == -1))
872 {
873 g_warning (" failed to get current time (1): %s\n",
874 strerror (errno));
875 if (fcntl (socket, F_SETFL, 0L) < 0)
876 g_warning ("%s :failed to set socket flag: %s", __func__,
877 strerror (errno));
878 g_free (buffer);
879 return -1;
880 }
881 }
882}
883
900static int
901try_read_string_s (int socket, int timeout, GString **string_return)
902{
903 GString *string;
904 time_t last_time;
905 /* Buffer for reading from the socket. */
906 char *buffer;
907
908 /* Record the start time. */
909
910 if (time (&last_time) == -1)
911 {
912 g_warning (" failed to get current time: %s\n", strerror (errno));
913 return -1;
914 }
915
916 if (timeout > 0)
917 {
918 /* Turn off blocking. */
919
920 if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
921 return -1;
922 }
923
924 buffer = g_malloc0 (BUFFER_SIZE);
925 if (!buffer)
926 return -5;
927
928 /* Setup return arg. */
929
930 if (string_return == NULL)
931 string = NULL;
932 else if (*string_return == NULL)
933 string = g_string_sized_new (8192);
934 else
935 string = *string_return;
936
937 /* Read until encountering end of file or error. */
938
939 while (1)
940 {
941 int count;
942 while (1)
943 {
944 g_debug (" asking for %i\n", BUFFER_SIZE);
945 count = read (socket, buffer, BUFFER_SIZE);
946 if (count < 0)
947 {
948 if (errno == EINTR)
949 /* Interrupted, try read again. */
950 continue;
951 if (timeout > 0)
952 {
953 if (errno == EAGAIN)
954 {
955 /* Server still busy, either timeout or try read again. */
956 if ((timeout - (time (NULL) - last_time)) <= 0)
957 {
958 g_warning (" timeout\n");
959 if (fcntl (socket, F_SETFL, 0L) < 0)
960 g_warning ("%s :failed to set socket flag: %s",
961 __func__, strerror (errno));
962 g_free (buffer);
963 if (string && *string_return == NULL)
964 g_string_free (string, TRUE);
965 return -4;
966 }
967 }
968 continue;
969 }
970 if (string && *string_return == NULL)
971 g_string_free (string, TRUE);
972 if (timeout > 0)
973 fcntl (socket, F_SETFL, 0L);
974 g_free (buffer);
975 return -1;
976 }
977 if (count == 0)
978 {
979 /* End of file. */
980 if (timeout > 0)
981 {
982 if (fcntl (socket, F_SETFL, 0L) < 0)
983 g_warning ("%s :failed to set socket flag: %s", __func__,
984 strerror (errno));
985 }
986 if (string)
987 *string_return = string;
988 g_free (buffer);
989 return 0;
990 }
991 break;
992 }
993
994 g_debug ("<= %.*s\n", (int) count, buffer);
995
996 if (string)
997 g_string_append_len (string, buffer, count);
998
999 if ((timeout > 0) && (time (&last_time) == -1))
1000 {
1001 g_warning (" failed to get current time (1): %s\n",
1002 strerror (errno));
1003 if (fcntl (socket, F_SETFL, 0L) < 0)
1004 g_warning ("%s :failed to set server socket flag: %s", __func__,
1005 strerror (errno));
1006 g_free (buffer);
1007 if (string && *string_return == NULL)
1008 g_string_free (string, TRUE);
1009 return -1;
1010 }
1011 }
1012}
1013
1030static int
1031try_read_entity_and_string_s (int socket, int timeout, entity_t *entity,
1032 GString **string_return)
1033{
1034 GMarkupParser xml_parser;
1035 GError *error = NULL;
1036 GMarkupParseContext *xml_context;
1037 GString *string;
1038 time_t last_time;
1039 /* Buffer for reading from the socket. */
1040 char *buffer;
1041
1042 /* Record the start time. */
1043
1044 if (time (&last_time) == -1)
1045 {
1046 g_warning (" failed to get current time: %s\n", strerror (errno));
1047 return -1;
1048 }
1049
1050 if (timeout > 0)
1051 {
1052 /* Turn off blocking. */
1053
1054 if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
1055 return -1;
1056 }
1057
1058 buffer = g_malloc0 (BUFFER_SIZE);
1059 if (!buffer)
1060 return -5;
1061
1062 /* Setup return arg. */
1063
1064 if (string_return == NULL)
1065 string = NULL;
1066 else if (*string_return == NULL)
1067 string = g_string_new ("");
1068 else
1069 string = *string_return;
1070
1071 /* Create the XML parser. */
1072
1073 if (entity)
1074 {
1075 xml_parser.start_element = handle_start_element;
1076 xml_parser.end_element = handle_end_element;
1077 xml_parser.text = handle_text;
1078 }
1079 else
1080 {
1081 xml_parser.start_element = ignore_start_element;
1082 xml_parser.end_element = ignore_end_element;
1083 xml_parser.text = ignore_text;
1084 }
1085 xml_parser.passthrough = NULL;
1086 xml_parser.error = handle_error;
1087
1088 context_data_t context_data;
1089 context_data.done = FALSE;
1090 context_data.first = NULL;
1091 context_data.current = NULL;
1092
1093 /* Setup the XML context. */
1094
1095 xml_context =
1096 g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
1097
1098 /* Read and parse, until encountering end of file or error. */
1099
1100 while (1)
1101 {
1102 int count;
1103 while (1)
1104 {
1105 g_debug (" asking for %i\n", BUFFER_SIZE);
1106 count = read (socket, buffer, BUFFER_SIZE);
1107 if (count < 0)
1108 {
1109 if (errno == EINTR)
1110 /* Interrupted, try read again. */
1111 continue;
1112 if (timeout > 0)
1113 {
1114 if (errno == EAGAIN)
1115 {
1116 /* Server still busy, either timeout or try read again. */
1117 if ((timeout - (time (NULL) - last_time)) <= 0)
1118 {
1119 g_warning (" timeout\n");
1120 if (fcntl (socket, F_SETFL, 0L) < 0)
1121 g_warning ("%s :failed to set socket flag: %s",
1122 __func__, strerror (errno));
1123 g_markup_parse_context_free (xml_context);
1124 g_free (buffer);
1125 if (string && *string_return == NULL)
1126 g_string_free (string, TRUE);
1127 return -4;
1128 }
1129 }
1130 continue;
1131 }
1132 if (context_data.first && context_data.first->data)
1133 {
1134 free_entity (context_data.first->data);
1135 g_slist_free_1 (context_data.first);
1136 }
1137 if (string && *string_return == NULL)
1138 g_string_free (string, TRUE);
1139 if (timeout > 0)
1140 fcntl (socket, F_SETFL, 0L);
1141 g_markup_parse_context_free (xml_context);
1142 g_free (buffer);
1143 return -1;
1144 }
1145 if (count == 0)
1146 {
1147 /* End of file. */
1148 g_markup_parse_context_end_parse (xml_context, &error);
1149 if (error)
1150 {
1151 g_warning (" End error: %s\n", error->message);
1152 g_error_free (error);
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 if (string && *string_return == NULL)
1160 g_string_free (string, TRUE);
1161 if (timeout > 0)
1162 {
1163 if (fcntl (socket, F_SETFL, 0L) < 0)
1164 g_warning ("%s :failed to set socket flag: %s", __func__,
1165 strerror (errno));
1166 }
1167 g_markup_parse_context_free (xml_context);
1168 g_free (buffer);
1169 return -3;
1170 }
1171 break;
1172 }
1173
1174 g_debug ("<= %.*s\n", (int) count, buffer);
1175
1176 if (string)
1177 g_string_append_len (string, buffer, count);
1178
1179 g_markup_parse_context_parse (xml_context, buffer, count, &error);
1180 if (error)
1181 {
1182 g_error_free (error);
1183 // FIX there may be multiple entries in list
1184 if (context_data.first && context_data.first->data)
1185 {
1186 free_entity (context_data.first->data);
1187 g_slist_free_1 (context_data.first);
1188 }
1189 if (string && *string_return == NULL)
1190 g_string_free (string, TRUE);
1191 if (timeout > 0)
1192 {
1193 if (fcntl (socket, F_SETFL, 0L) < 0)
1194 g_warning ("%s :failed to set socket flag: %s", __func__,
1195 strerror (errno));
1196 }
1197 g_markup_parse_context_free (xml_context);
1198 g_free (buffer);
1199 return -2;
1200 }
1201 if (context_data.done)
1202 {
1203 g_markup_parse_context_end_parse (xml_context, &error);
1204 if (error)
1205 {
1206 g_warning (" End error: %s\n", error->message);
1207 g_error_free (error);
1208 if (context_data.first && context_data.first->data)
1209 {
1210 free_entity (context_data.first->data);
1211 g_slist_free_1 (context_data.first);
1212 }
1213 if (timeout > 0)
1214 fcntl (socket, F_SETFL, 0L);
1215 g_markup_parse_context_free (xml_context);
1216 g_free (buffer);
1217 if (string && *string_return == NULL)
1218 g_string_free (string, TRUE);
1219 return -2;
1220 }
1221 if (entity)
1222 *entity = (entity_t) context_data.first->data;
1223 if (string)
1224 *string_return = string;
1225 if (timeout > 0)
1226 fcntl (socket, F_SETFL, 0L);
1227 g_slist_free (context_data.first);
1228 g_markup_parse_context_free (xml_context);
1229 g_free (buffer);
1230 return 0;
1231 }
1232
1233 if ((timeout > 0) && (time (&last_time) == -1))
1234 {
1235 g_warning (" failed to get current time (1): %s\n",
1236 strerror (errno));
1237 if (fcntl (socket, F_SETFL, 0L) < 0)
1238 g_warning ("%s :failed to set server socket flag: %s", __func__,
1239 strerror (errno));
1240 g_markup_parse_context_free (xml_context);
1241 g_free (buffer);
1242 if (string && *string_return == NULL)
1243 g_string_free (string, TRUE);
1244 return -1;
1245 }
1246 }
1247}
1248
1262int
1263read_entity_and_string (gnutls_session_t *session, entity_t *entity,
1264 GString **string_return)
1265{
1266 return try_read_entity_and_string (session, 0, entity, string_return);
1267}
1268
1282int
1284 GString **string_return)
1285{
1286 if (connection->tls)
1287 return try_read_entity_and_string (&connection->session, 0, entity,
1288 string_return);
1289 return try_read_entity_and_string_s (connection->socket, 0, entity,
1290 string_return);
1291}
1292
1305int
1306read_entity_and_text (gnutls_session_t *session, entity_t *entity, char **text)
1307{
1308 if (text)
1309 {
1310 GString *string = NULL;
1311 int ret = read_entity_and_string (session, entity, &string);
1312 if (ret)
1313 {
1314 if (string)
1315 g_string_free (string, TRUE);
1316 return ret;
1317 }
1318 *text = g_string_free (string, FALSE);
1319 return 0;
1320 }
1321 return read_entity_and_string (session, entity, NULL);
1322}
1323
1336int
1338 char **text)
1339{
1340 if (text)
1341 {
1342 GString *string = NULL;
1343 int ret = read_entity_and_string_c (connection, entity, &string);
1344 if (ret)
1345 {
1346 if (string)
1347 g_string_free (string, TRUE);
1348 return ret;
1349 }
1350 *text = g_string_free (string, FALSE);
1351 return 0;
1352 }
1353 return read_entity_and_string_c (connection, entity, NULL);
1354}
1355
1366int
1367read_text_c (gvm_connection_t *connection, char **text)
1368{
1369 GString *string;
1370 int ret;
1371
1372 if (text == NULL)
1373 return -2;
1374
1375 string = NULL;
1376
1377 if (connection->tls)
1378 ret = try_read_string (&connection->session, 0, &string);
1379 else
1380 ret = try_read_string_s (connection->socket, 0, &string);
1381
1382 if (ret)
1383 {
1384 if (string)
1385 g_string_free (string, TRUE);
1386 return ret;
1387 }
1388 *text = g_string_free (string, FALSE);
1389 return 0;
1390}
1391
1400int
1401read_string (gnutls_session_t *session, GString **string)
1402{
1403 int ret = 0;
1404 entity_t entity;
1405
1406 if (!(ret = read_entity_and_string (session, &entity, string)))
1407 free_entity (entity);
1408
1409 return ret;
1410}
1411
1420int
1421read_string_c (gvm_connection_t *connection, GString **string)
1422{
1423 return read_entity_and_string_c (connection, NULL, string);
1424}
1425
1436int
1437try_read_entity (gnutls_session_t *session, int timeout, entity_t *entity)
1438{
1439 return try_read_entity_and_string (session, timeout, entity, NULL);
1440}
1441
1452int
1453try_read_entity_c (gvm_connection_t *connection, int timeout, entity_t *entity)
1454{
1455 if (connection->tls)
1456 return try_read_entity_and_string (&connection->session, 0, entity, NULL);
1457 return try_read_entity_and_string_s (connection->socket, timeout, entity,
1458 NULL);
1459}
1460
1469int
1470read_entity (gnutls_session_t *session, entity_t *entity)
1471{
1472 return try_read_entity (session, 0, entity);
1473}
1474
1483int
1484read_entity_s (int socket, entity_t *entity)
1485{
1486 return try_read_entity_and_string_s (socket, 0, entity, NULL);
1487}
1488
1497int
1499{
1500 return try_read_entity_c (connection, 0, entity);
1501}
1502
1511int
1512parse_entity (const char *string, entity_t *entity)
1513{
1514 GMarkupParser xml_parser;
1515 GError *error = NULL;
1516 GMarkupParseContext *xml_context;
1517 context_data_t context_data;
1518
1519 /* Create the XML parser. */
1520
1521 xml_parser.start_element = handle_start_element;
1522 xml_parser.end_element = handle_end_element;
1523 xml_parser.text = handle_text;
1524 xml_parser.passthrough = NULL;
1525 xml_parser.error = handle_error;
1526
1527 context_data.done = FALSE;
1528 context_data.first = NULL;
1529 context_data.current = NULL;
1530
1531 /* Setup the XML context. */
1532
1533 xml_context =
1534 g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
1535
1536 /* Parse the string. */
1537
1538 g_markup_parse_context_parse (xml_context, string, strlen (string), &error);
1539 if (error)
1540 {
1541 g_error_free (error);
1542 if (context_data.first && context_data.first->data)
1543 {
1544 free_entity (context_data.first->data);
1545 g_slist_free_1 (context_data.first);
1546 }
1547 return -2;
1548 }
1549 if (context_data.done)
1550 {
1551 g_markup_parse_context_end_parse (xml_context, &error);
1552 if (error)
1553 {
1554 g_warning (" End error: %s\n", error->message);
1555 g_error_free (error);
1556 if (context_data.first && context_data.first->data)
1557 {
1558 free_entity (context_data.first->data);
1559 g_slist_free_1 (context_data.first);
1560 }
1561 return -2;
1562 }
1563 *entity = (entity_t) context_data.first->data;
1564 g_slist_free_1 (context_data.first);
1565 return 0;
1566 }
1567 if (context_data.first && context_data.first->data)
1568 {
1569 free_entity (context_data.first->data);
1570 g_slist_free_1 (context_data.first);
1571 }
1572 return -3;
1573}
1574
1581static void
1582foreach_print_entity_to_string (gpointer entity, gpointer string)
1583{
1584 print_entity_to_string ((entity_t) entity, (GString *) string);
1585}
1586
1594static void
1595foreach_print_attribute_to_string (gpointer name, gpointer value,
1596 gpointer string)
1597{
1598 gchar *text_escaped;
1599 text_escaped = g_markup_escape_text ((gchar *) value, -1);
1600 g_string_append_printf ((GString *) string, " %s=\"%s\"", (char *) name,
1601 text_escaped);
1602 g_free (text_escaped);
1603}
1604
1612void
1613print_entity_to_string (entity_t entity, GString *string)
1614{
1615 gchar *text_escaped = NULL;
1616 g_string_append_printf (string, "<%s", entity->name);
1617 if (entity->attributes && g_hash_table_size (entity->attributes))
1618 g_hash_table_foreach (entity->attributes, foreach_print_attribute_to_string,
1619 string);
1620 g_string_append_printf (string, ">");
1621 text_escaped = g_markup_escape_text (entity->text, -1);
1622 g_string_append_printf (string, "%s", text_escaped);
1623 g_free (text_escaped);
1624 g_slist_foreach (entity->entities, foreach_print_entity_to_string, string);
1625 g_string_append_printf (string, "</%s>", entity->name);
1626}
1627
1634static void
1635foreach_print_entity (gpointer entity, gpointer stream)
1636{
1637 print_entity ((FILE *) stream, (entity_t) entity);
1638}
1639
1647static void
1648foreach_print_attribute (gpointer name, gpointer value, gpointer stream)
1649{
1650 fprintf ((FILE *) stream, " %s=\"%s\"", (char *) name, (char *) value);
1651}
1652
1659void
1660print_entity (FILE *stream, entity_t entity)
1661{
1662 gchar *text_escaped = NULL;
1663 fprintf (stream, "<%s", entity->name);
1664 if (entity->attributes && g_hash_table_size (entity->attributes))
1665 g_hash_table_foreach (entity->attributes, foreach_print_attribute, stream);
1666 fprintf (stream, ">");
1667 text_escaped = g_markup_escape_text (entity->text, -1);
1668 fprintf (stream, "%s", text_escaped);
1669 g_free (text_escaped);
1670 g_slist_foreach (entity->entities, foreach_print_entity, stream);
1671 fprintf (stream, "</%s>", entity->name);
1672 fflush (stream);
1673}
1674
1675/* "Formatted" (indented) output of entity_t */
1676
1684static void
1685foreach_print_attribute_format (gpointer name, gpointer value, gpointer none)
1686{
1687 (void) none;
1688 printf (" %s=\"%s\"", (char *) name, (char *) value);
1689}
1690
1702void
1703print_entity_format (entity_t entity, gpointer indent)
1704{
1705 int i = 0;
1706 int indentation = GPOINTER_TO_INT (indent);
1707 gchar *text_escaped = NULL;
1708
1709 for (i = 0; i < indentation; i++)
1710 printf (" ");
1711
1712 printf ("<%s", entity->name);
1713 if (entity->attributes && g_hash_table_size (entity->attributes))
1714 g_hash_table_foreach (entity->attributes, foreach_print_attribute_format,
1715 indent);
1716 printf (">");
1717
1718 text_escaped = g_markup_escape_text (entity->text, -1);
1719 printf ("%s", text_escaped);
1720 g_free (text_escaped);
1721
1722 if (entity->entities)
1723 {
1724 printf ("\n");
1725 g_slist_foreach (entity->entities, (GFunc) print_entity_format,
1726 GINT_TO_POINTER (indentation + 1));
1727 for (i = 0; i < indentation; i++)
1728 printf (" ");
1729 }
1730
1731 printf ("</%s>\n", entity->name);
1732}
1733
1743static gboolean
1744compare_find_attribute (gpointer key, gpointer value, gpointer attributes2)
1745{
1746 gchar *value2 = g_hash_table_lookup (attributes2, key);
1747 if (value2 && strcmp (value, value2) == 0)
1748 return FALSE;
1749 g_debug (" compare failed attribute: %s\n", (char *) value);
1750 return TRUE;
1751}
1752
1761int
1763{
1764 if (entity1 == NULL)
1765 return entity2 == NULL ? 0 : 1;
1766 if (entity2 == NULL)
1767 return 1;
1768
1769 if (strcmp (entity1->name, entity2->name))
1770 {
1771 g_debug (" compare failed name: %s vs %s\n", entity1->name,
1772 entity2->name);
1773 return 1;
1774 }
1775 if (strcmp (entity1->text, entity2->text))
1776 {
1777 g_debug (" compare failed text %s vs %s (%s)\n", entity1->text,
1778 entity2->text, entity1->name);
1779 return 1;
1780 }
1781
1782 if (entity1->attributes == NULL)
1783 {
1784 if (entity2->attributes)
1785 return 1;
1786 }
1787 else
1788 {
1789 if (entity2->attributes == NULL)
1790 return 1;
1791 if (g_hash_table_find (entity1->attributes, compare_find_attribute,
1792 (gpointer) entity2->attributes))
1793 {
1794 g_debug (" compare failed attributes\n");
1795 return 1;
1796 }
1797 }
1798
1799 // FIX entities can be in any order
1800 GSList *list1 = entity1->entities;
1801 GSList *list2 = entity2->entities;
1802 while (list1 && list2)
1803 {
1804 if (compare_entities (list1->data, list2->data))
1805 {
1806 g_debug (" compare failed subentity\n");
1807 return 1;
1808 }
1809 list1 = g_slist_next (list1);
1810 list2 = g_slist_next (list2);
1811 }
1812 if (list1 == list2)
1813 return 0;
1814 /* More entities in one of the two. */
1815 g_debug (" compare failed number of entities (%s)\n", entity1->name);
1816 return 1;
1817}
1818
1826int
1828{
1829 int count = 0;
1830 while (first_entity (entities))
1831 {
1832 entities = next_entities (entities);
1833 count++;
1834 }
1835 return count;
1836}
1837
1847void
1848xml_string_append (GString *xml, const char *format, ...)
1849{
1850 gchar *piece;
1851 va_list args;
1852
1853 va_start (args, format);
1854 piece = g_markup_vprintf_escaped (format, args);
1855 va_end (args);
1856 g_string_append (xml, piece);
1857 g_free (piece);
1858}
1859
1860/* XML file utilities */
1861
1872static void
1873xml_search_handle_start_element (GMarkupParseContext *ctx,
1874 const gchar *element_name,
1875 const gchar **attribute_names,
1876 const gchar **attribute_values, gpointer data,
1877 GError **error)
1878{
1879 (void) ctx;
1880 (void) error;
1881
1882 xml_search_data_t *search_data = ((xml_search_data_t *) data);
1883
1884 if (strcmp (element_name, search_data->find_element) == 0
1885 && search_data->found == 0)
1886 {
1887 g_debug ("%s: Found element <%s>", __func__, element_name);
1888
1889 if (search_data->find_attributes
1890 && g_hash_table_size (search_data->find_attributes))
1891 {
1892 int index;
1893 GHashTable *found_attributes;
1894 found_attributes =
1895 g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1896 index = 0;
1897 while (attribute_names[index])
1898 {
1899 gchar *searched_value;
1900 searched_value = g_hash_table_lookup (
1901 search_data->find_attributes, attribute_names[index]);
1902 if (searched_value
1903 && strcmp (searched_value, attribute_values[index]) == 0)
1904 {
1905 g_debug ("%s: Found attribute %s=\"%s\"", __func__,
1906 attribute_names[index], searched_value);
1907 g_hash_table_add (found_attributes, searched_value);
1908 }
1909 index++;
1910 }
1911 g_debug ("%s: Found %d of %d attributes", __func__,
1912 g_hash_table_size (found_attributes),
1913 g_hash_table_size (search_data->find_attributes));
1914
1915 if (g_hash_table_size (found_attributes)
1916 == g_hash_table_size (search_data->find_attributes))
1917 {
1918 search_data->found = 1;
1919 }
1920
1921 g_hash_table_destroy (found_attributes);
1922 }
1923 else
1924 {
1925 search_data->found = 1;
1926 }
1927 }
1928}
1929
1930#define XML_FILE_BUFFER_SIZE 1048576
1931int
1941find_element_in_xml_file (gchar *file_path, gchar *find_element,
1942 GHashTable *find_attributes)
1943{
1944 gchar buffer[XML_FILE_BUFFER_SIZE];
1945 FILE *file;
1946 int read_len;
1947 GMarkupParser xml_parser;
1948 GMarkupParseContext *xml_context;
1949 xml_search_data_t search_data;
1950 GError *error = NULL;
1951
1952 search_data.find_element = find_element;
1953 search_data.find_attributes = find_attributes;
1954 search_data.found = 0;
1955
1956 /* Create the XML parser. */
1957 xml_parser.start_element = xml_search_handle_start_element;
1958 xml_parser.end_element = NULL;
1959 xml_parser.text = NULL;
1960 xml_parser.passthrough = NULL;
1961 xml_parser.error = NULL;
1962 xml_context = g_markup_parse_context_new (&xml_parser, 0, &search_data, NULL);
1963
1964 file = fopen (file_path, "r");
1965 if (file == NULL)
1966 {
1967 g_markup_parse_context_free (xml_context);
1968 g_warning ("%s: Failed to open '%s':", __func__, strerror (errno));
1969 return 0;
1970 }
1971
1972 while ((read_len = fread (&buffer, sizeof (char), XML_FILE_BUFFER_SIZE, file))
1973 && g_markup_parse_context_parse (xml_context, buffer, read_len, &error)
1974 && error == NULL)
1975 {
1976 }
1977 g_markup_parse_context_end_parse (xml_context, &error);
1978
1979 fclose (file);
1980
1981 g_markup_parse_context_free (xml_context);
1982 return search_data.found;
1983}
1984#undef XML_FILE_BUFFER_SIZE
1985
1986/* The new faster parser that uses libxml2. */
1987
2001int
2002parse_element (const gchar *string, element_t *element)
2003{
2004 xmlDocPtr doc;
2005
2006 LIBXML_TEST_VERSION
2007
2008 if (element)
2009 *element = NULL;
2010
2011 if (xmlMemSetup (g_free, g_malloc, g_realloc, g_strdup))
2012 return -4;
2013
2014 doc =
2015 xmlReadMemory (string, strlen (string), "noname.xml", NULL, XML_PARSE_HUGE);
2016 if (doc == NULL)
2017 return -2;
2018
2019 if (element)
2020 *element = xmlDocGetRootElement (doc);
2021
2022 return 0;
2023}
2024
2033void
2035{
2036 if (element)
2037 {
2038 assert (element->doc);
2039 xmlFreeDoc (element->doc);
2040 }
2041}
2042
2050const gchar *
2052{
2053 if (element && (element->type == XML_ELEMENT_NODE))
2054 return (const gchar *) element->name;
2055
2056 return "";
2057}
2058
2067static element_t
2068find_child (element_t element, const gchar *name)
2069{
2070 for (xmlNode *node = element->children; node; node = node->next)
2071 if (xmlStrcmp (node->name, (const xmlChar *) name) == 0)
2072 return node;
2073 return NULL;
2074}
2075
2085element_child (element_t element, const gchar *name)
2086{
2087 const gchar *stripped_name;
2088
2089 if (!element)
2090 return NULL;
2091
2092 stripped_name = strchr (name, ':');
2093 if (stripped_name)
2094 {
2095 element_t child;
2096
2097 /* There was a namespace in the name.
2098 *
2099 * First try without the namespace, because libxml2 doesn't consider the
2100 * namespace in the name when the namespace is defined. */
2101
2102 stripped_name++;
2103
2104 if (*stripped_name == '\0')
2105 /* Don't search for child with empty stripped name, because we'll
2106 * find text nodes. But search with just the namespace for glib
2107 * compatibility. */
2108 return find_child (element, name);
2109
2110 child = find_child (element, stripped_name);
2111 if (child)
2112 return child;
2113
2114 /* Didn't find anything. */
2115 }
2116
2117 /* There was no namespace, or we didn't find anything without the namespace.
2118 *
2119 * Try with the full name. */
2120
2121 return find_child (element, name);
2122}
2123
2135gchar *
2137{
2138 gchar *string;
2139
2140 if (!element)
2141 return NULL;
2142
2143 string =
2144 (gchar *) xmlNodeListGetString (element->doc, element->xmlChildrenNode, 1);
2145 if (string)
2146 return string;
2147 string = xmlMalloc (1);
2148 string[0] = '\0';
2149 return string;
2150}
2151
2160gchar *
2161element_attribute (element_t element, const gchar *name)
2162{
2163 const gchar *stripped_name;
2164
2165 if (!element)
2166 return NULL;
2167
2168 stripped_name = strchr (name, ':');
2169 if (stripped_name)
2170 {
2171 gchar *attribute;
2172
2173 /* There was a namespace in the name.
2174 *
2175 * First try without the namespace, because libxml2 doesn't consider the
2176 * namespace in the name when the namespace is defined. */
2177
2178 stripped_name++;
2179
2180 if (*stripped_name == '\0')
2181 /* Don't search for child with empty stripped name, because we'll
2182 * find text nodes. But search with just the namespace for glib
2183 * compatibility. */
2184 return (gchar *) xmlGetProp (element, (const xmlChar *) name);
2185
2186 attribute =
2187 (gchar *) xmlGetProp (element, (const xmlChar *) stripped_name);
2188 if (attribute)
2189 return attribute;
2190
2191 /* Didn't find anything. */
2192 }
2193
2194 /* There was no namespace, or we didn't find anything without the namespace.
2195 *
2196 * Try with the full name. */
2197
2198 return (gchar *) xmlGetProp (element, (const xmlChar *) name);
2199}
2200
2210{
2211 if (element)
2212 {
2213 element = element->children;
2214 while (element && (element->type != XML_ELEMENT_NODE))
2215 element = element->next;
2216 return element;
2217 }
2218 return NULL;
2219}
2220
2230{
2231 if (element)
2232 {
2233 element = element->next;
2234 while (element && (element->type != XML_ELEMENT_NODE))
2235 element = element->next;
2236 return element;
2237 }
2238 return NULL;
2239}
2240
2251gchar *
2253{
2254 xmlBufferPtr buffer;
2255 char *xml_string;
2256
2257 // Copy element to ensure XML namespaces are included
2258 element_t element_copy;
2259 element_copy = xmlCopyNode (element, 1);
2260
2261 buffer = xmlBufferCreate ();
2262 xmlNodeDump (buffer, element_copy->doc, element_copy, 0, 0);
2263 xmlFreeNode (element_copy);
2264
2265 xml_string = g_strdup ((char *) xmlBufferContent (buffer));
2266
2267 xmlBufferFree (buffer);
2268 return xml_string;
2269}
2270
2278void
2279print_element_to_string (element_t element, GString *string)
2280{
2281 gchar *text_escaped, *text;
2282 element_t ch;
2283 xmlAttr *attribute;
2284
2285 text_escaped = NULL;
2286
2287 g_string_append_printf (string, "<%s", element_name (element));
2288
2289 attribute = element->properties;
2290 while (attribute)
2291 {
2292 xmlChar *value;
2293
2294 value = xmlNodeListGetString (element->doc, attribute->children, 1);
2295
2296 text_escaped = g_markup_escape_text ((gchar *) value, -1);
2297 g_string_append_printf (string, " %s=\"%s\"", attribute->name,
2298 text_escaped);
2299 g_free (text_escaped);
2300
2301 xmlFree (value);
2302
2303 attribute = attribute->next;
2304 }
2305
2306 g_string_append_printf (string, ">");
2307
2308 text = element_text (element);
2309 text_escaped = g_markup_escape_text (text, -1);
2310 g_free (text);
2311 g_string_append_printf (string, "%s", text_escaped);
2312 g_free (text_escaped);
2313
2314 ch = element_first_child (element);
2315 while (ch)
2316 {
2317 print_element_to_string (ch, string);
2318 ch = element_next (ch);
2319 }
2320
2321 g_string_append_printf (string, "</%s>", element_name (element));
2322}
XML context.
Definition xmlutils.h:27
GSList * first
The very first entity.
Definition xmlutils.h:28
GSList * current
The element currently being parsed.
Definition xmlutils.h:29
gboolean done
Flag which is true when the first element is closed.
Definition xmlutils.h:30
XML element.
Definition xmlutils.h:52
entities_t entities
Children.
Definition xmlutils.h:56
char * text
Text.
Definition xmlutils.h:54
GHashTable * attributes
Attributes.
Definition xmlutils.h:55
char * name
Name.
Definition xmlutils.h:53
Connection.
Definition serverutils.h:30
int tls
Whether uses TCP-TLS (vs UNIX socket).
Definition serverutils.h:31
int socket
Socket.
Definition serverutils.h:32
gnutls_session_t session
Session.
Definition serverutils.h:33
Data for xml search functions.
Definition xmlutils.h:64
gchar * find_element
Definition xmlutils.h:67
GHashTable * find_attributes
Definition xmlutils.h:68
int found
Definition xmlutils.h:65
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:437
static int try_read_string_s(int socket, int timeout, GString **string_return)
Try read an XML entity tree from the socket.
Definition xmlutils.c:901
void element_free(element_t element)
Free an entire element tree.
Definition xmlutils.c:2034
int read_entity_c(gvm_connection_t *connection, entity_t *entity)
Read an XML entity tree from the manager.
Definition xmlutils.c:1498
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.
Definition xmlutils.c:326
const char * entity_attribute(entity_t entity, const char *name)
Get an attribute of an entity.
Definition xmlutils.c:216
int read_string(gnutls_session_t *session, GString **string)
Read entity and text. Free the entity immediately.
Definition xmlutils.c:1401
int read_string_c(gvm_connection_t *connection, GString **string)
Read entity and text. Free the entity immediately.
Definition xmlutils.c:1421
static void ignore_text(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
Handle additional text of an XML element.
Definition xmlutils.c:417
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.
Definition xmlutils.c:1941
char * entity_name(entity_t entity)
Get the name an entity.
Definition xmlutils.c:161
char * entity_text(entity_t entity)
Get the text an entity.
Definition xmlutils.c:145
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:366
const gchar * element_name(element_t element)
Get the name of an element.
Definition xmlutils.c:2051
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:1873
static 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:1031
static int try_read_string(gnutls_session_t *session, int timeout, GString **string_return)
Try read a response from a TLS session.
Definition xmlutils.c:752
entity_t first_entity(entities_t entities)
Return the first entity from an entities_t.
Definition xmlutils.c:82
gchar * element_text(element_t element)
Get text of an element.
Definition xmlutils.c:2136
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:1283
static void handle_error(GMarkupParseContext *context, GError *error, gpointer user_data)
Handle an OMP XML parsing error.
Definition xmlutils.c:477
void print_element_to_string(element_t element, GString *string)
Print an XML element tree to a GString, appending it if string is not.
Definition xmlutils.c:2279
int read_entity(gnutls_session_t *session, entity_t *entity)
Read an XML entity tree from the manager.
Definition xmlutils.c:1470
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:1263
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:1582
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:1437
static void foreach_print_entity(gpointer entity, gpointer stream)
Print an XML entity for g_slist_foreach.
Definition xmlutils.c:1635
entities_t next_entities(entities_t entities)
Return all the entities from an entities_t after the first.
Definition xmlutils.c:67
#define BUFFER_SIZE
Size of the buffer for reading from the manager.
Definition xmlutils.c:37
gchar * element_attribute(element_t element, const gchar *name)
Get an attribute of an element.
Definition xmlutils.c:2161
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:1685
element_t element_first_child(element_t element)
Get the first child of an element.
Definition xmlutils.c:2209
void print_entity_format(entity_t entity, gpointer indent)
Print an XML entity to stdout, recursively printing its children.
Definition xmlutils.c:1703
void free_entity(entity_t entity)
Free an entity, recursively.
Definition xmlutils.c:115
static gboolean compare_find_attribute(gpointer key, gpointer value, gpointer attributes2)
Look for a key-value pair in a hash table.
Definition xmlutils.c:1744
static element_t find_child(element_t element, const gchar *name)
Find child in an element.
Definition xmlutils.c:2068
int read_text_c(gvm_connection_t *connection, char **text)
Read text from the server.
Definition xmlutils.c:1367
int read_entity_and_text_c(gvm_connection_t *connection, entity_t *entity, char **text)
Read an XML entity tree from the manager.
Definition xmlutils.c:1337
int parse_element(const gchar *string, element_t *element)
Read an XML element tree from a string.
Definition xmlutils.c:2002
int read_entity_and_text(gnutls_session_t *session, entity_t *entity, char **text)
Read an XML entity tree from the manager.
Definition xmlutils.c:1306
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:501
static int compare_entity_with_name(gconstpointer entity, gconstpointer name)
Compare a given name with the name of a given entity.
Definition xmlutils.c:179
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:101
int xml_count_entities(entities_t entities)
Count the number of entities.
Definition xmlutils.c:1827
entity_t entity_child(entity_t entity, const char *name)
Get a child of an entity.
Definition xmlutils.c:193
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:290
void xml_handle_end_element(context_data_t *context, const gchar *element_name)
Handle the end of an XML element.
Definition xmlutils.c:402
static void ignore_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:263
static entity_t make_entity(const char *name, const char *text)
Create an entity.
Definition xmlutils.c:48
element_t element_next(element_t element)
Get the next sibling of an element.
Definition xmlutils.c:2229
gchar * element_to_string(element_t element)
Output the XML element as a string.
Definition xmlutils.c:2252
element_t element_child(element_t element, const gchar *name)
Get a child of an element.
Definition xmlutils.c:2085
int parse_entity(const char *string, entity_t *entity)
Read an XML entity tree from a string.
Definition xmlutils.c:1512
#define XML_FILE_BUFFER_SIZE
Definition xmlutils.c:1930
int compare_entities(entity_t entity1, entity_t entity2)
Compare two XML entity.
Definition xmlutils.c:1762
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:1453
static void foreach_print_attribute(gpointer name, gpointer value, gpointer stream)
Print an XML attribute for g_hash_table_foreach.
Definition xmlutils.c:1648
int read_entity_s(int socket, entity_t *entity)
Read an XML entity tree from the socket.
Definition xmlutils.c:1484
void print_entity(FILE *stream, entity_t entity)
Print an XML entity.
Definition xmlutils.c:1660
static void ignore_end_element(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
Handle the end of an XML element.
Definition xmlutils.c:343
static void add_attributes(entity_t entity, const gchar **names, const gchar **values)
Add attributes from an XML callback to an entity.
Definition xmlutils.c:234
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:1595
void xml_handle_text(context_data_t *context, const gchar *text, gsize text_len)
Handle additional text of an XML element.
Definition xmlutils.c:464
void xml_string_append(GString *xml, const char *format,...)
Append formatted escaped XML to a string.
Definition xmlutils.c:1848
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:1613
Headers for simple XML reader.
struct entity_s * entity_t
Definition xmlutils.h:58
struct _xmlNode * element_t
Definition xmlutils.h:157
GSList * entities_t
Entities.
Definition xmlutils.h:46