Greenbone Vulnerability Management Libraries 22.8.0
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
899static int
900try_read_string_s (int socket, int timeout, GString **string_return)
901{
902 GString *string;
903 time_t last_time;
904 /* Buffer for reading from the socket. */
905 char *buffer;
906
907 /* Record the start time. */
908
909 if (time (&last_time) == -1)
910 {
911 g_warning (" failed to get current time: %s\n", strerror (errno));
912 return -1;
913 }
914
915 if (timeout > 0)
916 {
917 /* Turn off blocking. */
918
919 if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
920 return -1;
921 }
922
923 buffer = g_malloc0 (BUFFER_SIZE);
924 if (!buffer)
925 return -5;
926
927 /* Setup return arg. */
928
929 if (string_return == NULL)
930 string = NULL;
931 else if (*string_return == NULL)
932 string = g_string_sized_new (8192);
933 else
934 string = *string_return;
935
936 /* Read until encountering end of file or error. */
937
938 while (1)
939 {
940 int count;
941 while (1)
942 {
943 g_debug (" asking for %i\n", BUFFER_SIZE);
944 count = read (socket, buffer, BUFFER_SIZE);
945 if (count < 0)
946 {
947 if (errno == EINTR)
948 /* Interrupted, try read again. */
949 continue;
950 if (timeout > 0)
951 {
952 if (errno == EAGAIN)
953 {
954 /* Server still busy, either timeout or try read again. */
955 if ((timeout - (time (NULL) - last_time)) <= 0)
956 {
957 g_warning (" timeout\n");
958 if (fcntl (socket, F_SETFL, 0L) < 0)
959 g_warning ("%s :failed to set socket flag: %s",
960 __func__, strerror (errno));
961 g_free (buffer);
962 if (string && *string_return == NULL)
963 g_string_free (string, TRUE);
964 return -4;
965 }
966 }
967 continue;
968 }
969 if (string && *string_return == NULL)
970 g_string_free (string, TRUE);
971 if (timeout > 0)
972 fcntl (socket, F_SETFL, 0L);
973 g_free (buffer);
974 return -1;
975 }
976 if (count == 0)
977 {
978 /* End of file. */
979 if (timeout > 0)
980 {
981 if (fcntl (socket, F_SETFL, 0L) < 0)
982 g_warning ("%s :failed to set socket flag: %s", __func__,
983 strerror (errno));
984 }
985 if (string)
986 *string_return = string;
987 g_free (buffer);
988 return 0;
989 }
990 break;
991 }
992
993 g_debug ("<= %.*s\n", (int) count, buffer);
994
995 if (string)
996 g_string_append_len (string, buffer, count);
997
998 if ((timeout > 0) && (time (&last_time) == -1))
999 {
1000 g_warning (" failed to get current time (1): %s\n",
1001 strerror (errno));
1002 if (fcntl (socket, F_SETFL, 0L) < 0)
1003 g_warning ("%s :failed to set server socket flag: %s", __func__,
1004 strerror (errno));
1005 g_free (buffer);
1006 if (string && *string_return == NULL)
1007 g_string_free (string, TRUE);
1008 return -1;
1009 }
1010 }
1011}
1012
1029static int
1030try_read_entity_and_string_s (int socket, int timeout, entity_t *entity,
1031 GString **string_return)
1032{
1033 GMarkupParser xml_parser;
1034 GError *error = NULL;
1035 GMarkupParseContext *xml_context;
1036 GString *string;
1037 time_t last_time;
1038 /* Buffer for reading from the socket. */
1039 char *buffer;
1040
1041 /* Record the start time. */
1042
1043 if (time (&last_time) == -1)
1044 {
1045 g_warning (" failed to get current time: %s\n", strerror (errno));
1046 return -1;
1047 }
1048
1049 if (timeout > 0)
1050 {
1051 /* Turn off blocking. */
1052
1053 if (fcntl (socket, F_SETFL, O_NONBLOCK) == -1)
1054 return -1;
1055 }
1056
1057 buffer = g_malloc0 (BUFFER_SIZE);
1058 if (!buffer)
1059 return -5;
1060
1061 /* Setup return arg. */
1062
1063 if (string_return == NULL)
1064 string = NULL;
1065 else if (*string_return == NULL)
1066 string = g_string_new ("");
1067 else
1068 string = *string_return;
1069
1070 /* Create the XML parser. */
1071
1072 if (entity)
1073 {
1074 xml_parser.start_element = handle_start_element;
1075 xml_parser.end_element = handle_end_element;
1076 xml_parser.text = handle_text;
1077 }
1078 else
1079 {
1080 xml_parser.start_element = ignore_start_element;
1081 xml_parser.end_element = ignore_end_element;
1082 xml_parser.text = ignore_text;
1083 }
1084 xml_parser.passthrough = NULL;
1085 xml_parser.error = handle_error;
1086
1087 context_data_t context_data;
1088 context_data.done = FALSE;
1089 context_data.first = NULL;
1090 context_data.current = NULL;
1091
1092 /* Setup the XML context. */
1093
1094 xml_context =
1095 g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
1096
1097 /* Read and parse, until encountering end of file or error. */
1098
1099 while (1)
1100 {
1101 int count;
1102 while (1)
1103 {
1104 g_debug (" asking for %i\n", BUFFER_SIZE);
1105 count = read (socket, buffer, BUFFER_SIZE);
1106 if (count < 0)
1107 {
1108 if (errno == EINTR)
1109 /* Interrupted, try read again. */
1110 continue;
1111 if (timeout > 0)
1112 {
1113 if (errno == EAGAIN)
1114 {
1115 /* Server still busy, either timeout or try read again. */
1116 if ((timeout - (time (NULL) - last_time)) <= 0)
1117 {
1118 g_warning (" timeout\n");
1119 if (fcntl (socket, F_SETFL, 0L) < 0)
1120 g_warning ("%s :failed to set socket flag: %s",
1121 __func__, strerror (errno));
1122 g_markup_parse_context_free (xml_context);
1123 g_free (buffer);
1124 if (string && *string_return == NULL)
1125 g_string_free (string, TRUE);
1126 return -4;
1127 }
1128 }
1129 continue;
1130 }
1131 if (context_data.first && context_data.first->data)
1132 {
1133 free_entity (context_data.first->data);
1134 g_slist_free_1 (context_data.first);
1135 }
1136 if (string && *string_return == NULL)
1137 g_string_free (string, TRUE);
1138 if (timeout > 0)
1139 fcntl (socket, F_SETFL, 0L);
1140 g_markup_parse_context_free (xml_context);
1141 g_free (buffer);
1142 return -1;
1143 }
1144 if (count == 0)
1145 {
1146 /* End of file. */
1147 g_markup_parse_context_end_parse (xml_context, &error);
1148 if (error)
1149 {
1150 g_warning (" End error: %s\n", error->message);
1151 g_error_free (error);
1152 }
1153 if (context_data.first && context_data.first->data)
1154 {
1155 free_entity (context_data.first->data);
1156 g_slist_free_1 (context_data.first);
1157 }
1158 if (string && *string_return == NULL)
1159 g_string_free (string, TRUE);
1160 if (timeout > 0)
1161 {
1162 if (fcntl (socket, F_SETFL, 0L) < 0)
1163 g_warning ("%s :failed to set socket flag: %s", __func__,
1164 strerror (errno));
1165 }
1166 g_markup_parse_context_free (xml_context);
1167 g_free (buffer);
1168 return -3;
1169 }
1170 break;
1171 }
1172
1173 g_debug ("<= %.*s\n", (int) count, buffer);
1174
1175 if (string)
1176 g_string_append_len (string, buffer, count);
1177
1178 g_markup_parse_context_parse (xml_context, buffer, count, &error);
1179 if (error)
1180 {
1181 g_error_free (error);
1182 // FIX there may be multiple entries in list
1183 if (context_data.first && context_data.first->data)
1184 {
1185 free_entity (context_data.first->data);
1186 g_slist_free_1 (context_data.first);
1187 }
1188 if (string && *string_return == NULL)
1189 g_string_free (string, TRUE);
1190 if (timeout > 0)
1191 {
1192 if (fcntl (socket, F_SETFL, 0L) < 0)
1193 g_warning ("%s :failed to set socket flag: %s", __func__,
1194 strerror (errno));
1195 }
1196 g_markup_parse_context_free (xml_context);
1197 g_free (buffer);
1198 return -2;
1199 }
1200 if (context_data.done)
1201 {
1202 g_markup_parse_context_end_parse (xml_context, &error);
1203 if (error)
1204 {
1205 g_warning (" End error: %s\n", error->message);
1206 g_error_free (error);
1207 if (context_data.first && context_data.first->data)
1208 {
1209 free_entity (context_data.first->data);
1210 g_slist_free_1 (context_data.first);
1211 }
1212 if (timeout > 0)
1213 fcntl (socket, F_SETFL, 0L);
1214 g_markup_parse_context_free (xml_context);
1215 g_free (buffer);
1216 if (string && *string_return == NULL)
1217 g_string_free (string, TRUE);
1218 return -2;
1219 }
1220 if (entity)
1221 *entity = (entity_t) context_data.first->data;
1222 if (string)
1223 *string_return = string;
1224 if (timeout > 0)
1225 fcntl (socket, F_SETFL, 0L);
1226 g_slist_free (context_data.first);
1227 g_markup_parse_context_free (xml_context);
1228 g_free (buffer);
1229 return 0;
1230 }
1231
1232 if ((timeout > 0) && (time (&last_time) == -1))
1233 {
1234 g_warning (" failed to get current time (1): %s\n",
1235 strerror (errno));
1236 if (fcntl (socket, F_SETFL, 0L) < 0)
1237 g_warning ("%s :failed to set server socket flag: %s", __func__,
1238 strerror (errno));
1239 g_markup_parse_context_free (xml_context);
1240 g_free (buffer);
1241 if (string && *string_return == NULL)
1242 g_string_free (string, TRUE);
1243 return -1;
1244 }
1245 }
1246}
1247
1261int
1262read_entity_and_string (gnutls_session_t *session, entity_t *entity,
1263 GString **string_return)
1264{
1265 return try_read_entity_and_string (session, 0, entity, string_return);
1266}
1267
1281int
1283 GString **string_return)
1284{
1285 if (connection->tls)
1286 return try_read_entity_and_string (&connection->session, 0, entity,
1287 string_return);
1288 return try_read_entity_and_string_s (connection->socket, 0, entity,
1289 string_return);
1290}
1291
1304int
1305read_entity_and_text (gnutls_session_t *session, entity_t *entity, char **text)
1306{
1307 if (text)
1308 {
1309 GString *string = NULL;
1310 int ret = read_entity_and_string (session, entity, &string);
1311 if (ret)
1312 {
1313 if (string)
1314 g_string_free (string, TRUE);
1315 return ret;
1316 }
1317 *text = g_string_free (string, FALSE);
1318 return 0;
1319 }
1320 return read_entity_and_string (session, entity, NULL);
1321}
1322
1335int
1337 char **text)
1338{
1339 if (text)
1340 {
1341 GString *string = NULL;
1342 int ret = read_entity_and_string_c (connection, entity, &string);
1343 if (ret)
1344 {
1345 if (string)
1346 g_string_free (string, TRUE);
1347 return ret;
1348 }
1349 *text = g_string_free (string, FALSE);
1350 return 0;
1351 }
1352 return read_entity_and_string_c (connection, entity, NULL);
1353}
1354
1365int
1366read_text_c (gvm_connection_t *connection, char **text)
1367{
1368 GString *string;
1369 int ret;
1370
1371 if (text == NULL)
1372 return -2;
1373
1374 string = NULL;
1375
1376 if (connection->tls)
1377 ret = try_read_string (&connection->session, 0, &string);
1378 else
1379 ret = try_read_string_s (connection->socket, 0, &string);
1380
1381 if (ret)
1382 {
1383 if (string)
1384 g_string_free (string, TRUE);
1385 return ret;
1386 }
1387 *text = g_string_free (string, FALSE);
1388 return 0;
1389}
1390
1399int
1400read_string (gnutls_session_t *session, GString **string)
1401{
1402 int ret = 0;
1403 entity_t entity;
1404
1405 if (!(ret = read_entity_and_string (session, &entity, string)))
1406 free_entity (entity);
1407
1408 return ret;
1409}
1410
1419int
1420read_string_c (gvm_connection_t *connection, GString **string)
1421{
1422 return read_entity_and_string_c (connection, NULL, string);
1423}
1424
1435int
1436try_read_entity (gnutls_session_t *session, int timeout, entity_t *entity)
1437{
1438 return try_read_entity_and_string (session, timeout, entity, NULL);
1439}
1440
1451int
1452try_read_entity_c (gvm_connection_t *connection, int timeout, entity_t *entity)
1453{
1454 if (connection->tls)
1455 return try_read_entity_and_string (&connection->session, 0, entity, NULL);
1456 return try_read_entity_and_string_s (connection->socket, timeout, entity,
1457 NULL);
1458}
1459
1468int
1469read_entity (gnutls_session_t *session, entity_t *entity)
1470{
1471 return try_read_entity (session, 0, entity);
1472}
1473
1482int
1483read_entity_s (int socket, entity_t *entity)
1484{
1485 return try_read_entity_and_string_s (socket, 0, entity, NULL);
1486}
1487
1496int
1498{
1499 return try_read_entity_c (connection, 0, entity);
1500}
1501
1510int
1511parse_entity (const char *string, entity_t *entity)
1512{
1513 GMarkupParser xml_parser;
1514 GError *error = NULL;
1515 GMarkupParseContext *xml_context;
1516 context_data_t context_data;
1517
1518 /* Create the XML parser. */
1519
1520 xml_parser.start_element = handle_start_element;
1521 xml_parser.end_element = handle_end_element;
1522 xml_parser.text = handle_text;
1523 xml_parser.passthrough = NULL;
1524 xml_parser.error = handle_error;
1525
1526 context_data.done = FALSE;
1527 context_data.first = NULL;
1528 context_data.current = NULL;
1529
1530 /* Setup the XML context. */
1531
1532 xml_context =
1533 g_markup_parse_context_new (&xml_parser, 0, &context_data, NULL);
1534
1535 /* Parse the string. */
1536
1537 g_markup_parse_context_parse (xml_context, string, strlen (string), &error);
1538 if (error)
1539 {
1540 g_error_free (error);
1541 if (context_data.first && context_data.first->data)
1542 {
1543 free_entity (context_data.first->data);
1544 g_slist_free_1 (context_data.first);
1545 }
1546 return -2;
1547 }
1548 if (context_data.done)
1549 {
1550 g_markup_parse_context_end_parse (xml_context, &error);
1551 if (error)
1552 {
1553 g_warning (" End error: %s\n", error->message);
1554 g_error_free (error);
1555 if (context_data.first && context_data.first->data)
1556 {
1557 free_entity (context_data.first->data);
1558 g_slist_free_1 (context_data.first);
1559 }
1560 return -2;
1561 }
1562 *entity = (entity_t) context_data.first->data;
1563 g_slist_free_1 (context_data.first);
1564 return 0;
1565 }
1566 if (context_data.first && context_data.first->data)
1567 {
1568 free_entity (context_data.first->data);
1569 g_slist_free_1 (context_data.first);
1570 }
1571 return -3;
1572}
1573
1580static void
1581foreach_print_entity_to_string (gpointer entity, gpointer string)
1582{
1583 print_entity_to_string ((entity_t) entity, (GString *) string);
1584}
1585
1593static void
1594foreach_print_attribute_to_string (gpointer name, gpointer value,
1595 gpointer string)
1596{
1597 gchar *text_escaped;
1598 text_escaped = g_markup_escape_text ((gchar *) value, -1);
1599 g_string_append_printf ((GString *) string, " %s=\"%s\"", (char *) name,
1600 text_escaped);
1601 g_free (text_escaped);
1602}
1603
1611void
1612print_entity_to_string (entity_t entity, GString *string)
1613{
1614 gchar *text_escaped = NULL;
1615 g_string_append_printf (string, "<%s", entity->name);
1616 if (entity->attributes && g_hash_table_size (entity->attributes))
1617 g_hash_table_foreach (entity->attributes, foreach_print_attribute_to_string,
1618 string);
1619 g_string_append_printf (string, ">");
1620 text_escaped = g_markup_escape_text (entity->text, -1);
1621 g_string_append_printf (string, "%s", text_escaped);
1622 g_free (text_escaped);
1623 g_slist_foreach (entity->entities, foreach_print_entity_to_string, string);
1624 g_string_append_printf (string, "</%s>", entity->name);
1625}
1626
1633static void
1634foreach_print_entity (gpointer entity, gpointer stream)
1635{
1636 print_entity ((FILE *) stream, (entity_t) entity);
1637}
1638
1646static void
1647foreach_print_attribute (gpointer name, gpointer value, gpointer stream)
1648{
1649 fprintf ((FILE *) stream, " %s=\"%s\"", (char *) name, (char *) value);
1650}
1651
1658void
1659print_entity (FILE *stream, entity_t entity)
1660{
1661 gchar *text_escaped = NULL;
1662 fprintf (stream, "<%s", entity->name);
1663 if (entity->attributes && g_hash_table_size (entity->attributes))
1664 g_hash_table_foreach (entity->attributes, foreach_print_attribute, stream);
1665 fprintf (stream, ">");
1666 text_escaped = g_markup_escape_text (entity->text, -1);
1667 fprintf (stream, "%s", text_escaped);
1668 g_free (text_escaped);
1669 g_slist_foreach (entity->entities, foreach_print_entity, stream);
1670 fprintf (stream, "</%s>", entity->name);
1671 fflush (stream);
1672}
1673
1674/* "Formatted" (indented) output of entity_t */
1675
1683static void
1684foreach_print_attribute_format (gpointer name, gpointer value, gpointer none)
1685{
1686 (void) none;
1687 printf (" %s=\"%s\"", (char *) name, (char *) value);
1688}
1689
1701void
1702print_entity_format (entity_t entity, gpointer indent)
1703{
1704 int i = 0;
1705 int indentation = GPOINTER_TO_INT (indent);
1706 gchar *text_escaped = NULL;
1707
1708 for (i = 0; i < indentation; i++)
1709 printf (" ");
1710
1711 printf ("<%s", entity->name);
1712 if (entity->attributes && g_hash_table_size (entity->attributes))
1713 g_hash_table_foreach (entity->attributes, foreach_print_attribute_format,
1714 indent);
1715 printf (">");
1716
1717 text_escaped = g_markup_escape_text (entity->text, -1);
1718 printf ("%s", text_escaped);
1719 g_free (text_escaped);
1720
1721 if (entity->entities)
1722 {
1723 printf ("\n");
1724 g_slist_foreach (entity->entities, (GFunc) print_entity_format,
1725 GINT_TO_POINTER (indentation + 1));
1726 for (i = 0; i < indentation; i++)
1727 printf (" ");
1728 }
1729
1730 printf ("</%s>\n", entity->name);
1731}
1732
1742static gboolean
1743compare_find_attribute (gpointer key, gpointer value, gpointer attributes2)
1744{
1745 gchar *value2 = g_hash_table_lookup (attributes2, key);
1746 if (value2 && strcmp (value, value2) == 0)
1747 return FALSE;
1748 g_debug (" compare failed attribute: %s\n", (char *) value);
1749 return TRUE;
1750}
1751
1760int
1762{
1763 if (entity1 == NULL)
1764 return entity2 == NULL ? 0 : 1;
1765 if (entity2 == NULL)
1766 return 1;
1767
1768 if (strcmp (entity1->name, entity2->name))
1769 {
1770 g_debug (" compare failed name: %s vs %s\n", entity1->name,
1771 entity2->name);
1772 return 1;
1773 }
1774 if (strcmp (entity1->text, entity2->text))
1775 {
1776 g_debug (" compare failed text %s vs %s (%s)\n", entity1->text,
1777 entity2->text, entity1->name);
1778 return 1;
1779 }
1780
1781 if (entity1->attributes == NULL)
1782 {
1783 if (entity2->attributes)
1784 return 1;
1785 }
1786 else
1787 {
1788 if (entity2->attributes == NULL)
1789 return 1;
1790 if (g_hash_table_find (entity1->attributes, compare_find_attribute,
1791 (gpointer) entity2->attributes))
1792 {
1793 g_debug (" compare failed attributes\n");
1794 return 1;
1795 }
1796 }
1797
1798 // FIX entities can be in any order
1799 GSList *list1 = entity1->entities;
1800 GSList *list2 = entity2->entities;
1801 while (list1 && list2)
1802 {
1803 if (compare_entities (list1->data, list2->data))
1804 {
1805 g_debug (" compare failed subentity\n");
1806 return 1;
1807 }
1808 list1 = g_slist_next (list1);
1809 list2 = g_slist_next (list2);
1810 }
1811 if (list1 == list2)
1812 return 0;
1813 /* More entities in one of the two. */
1814 g_debug (" compare failed number of entities (%s)\n", entity1->name);
1815 return 1;
1816}
1817
1825int
1827{
1828 int count = 0;
1829 while (first_entity (entities))
1830 {
1831 entities = next_entities (entities);
1832 count++;
1833 }
1834 return count;
1835}
1836
1844void
1845xml_string_append (GString *xml, const char *format, ...)
1846{
1847 gchar *piece;
1848 va_list args;
1849
1850 va_start (args, format);
1851 piece = g_markup_vprintf_escaped (format, args);
1852 va_end (args);
1853 g_string_append (xml, piece);
1854 g_free (piece);
1855}
1856
1857/* XML file utilities */
1858
1869static void
1870xml_search_handle_start_element (GMarkupParseContext *ctx,
1871 const gchar *element_name,
1872 const gchar **attribute_names,
1873 const gchar **attribute_values, gpointer data,
1874 GError **error)
1875{
1876 (void) ctx;
1877 (void) error;
1878
1879 xml_search_data_t *search_data = ((xml_search_data_t *) data);
1880
1881 if (strcmp (element_name, search_data->find_element) == 0
1882 && search_data->found == 0)
1883 {
1884 g_debug ("%s: Found element <%s>", __func__, element_name);
1885
1886 if (search_data->find_attributes
1887 && g_hash_table_size (search_data->find_attributes))
1888 {
1889 int index;
1890 GHashTable *found_attributes;
1891 found_attributes =
1892 g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1893 index = 0;
1894 while (attribute_names[index])
1895 {
1896 gchar *searched_value;
1897 searched_value = g_hash_table_lookup (
1898 search_data->find_attributes, attribute_names[index]);
1899 if (searched_value
1900 && strcmp (searched_value, attribute_values[index]) == 0)
1901 {
1902 g_debug ("%s: Found attribute %s=\"%s\"", __func__,
1903 attribute_names[index], searched_value);
1904 g_hash_table_add (found_attributes, searched_value);
1905 }
1906 index++;
1907 }
1908 g_debug ("%s: Found %d of %d attributes", __func__,
1909 g_hash_table_size (found_attributes),
1910 g_hash_table_size (search_data->find_attributes));
1911
1912 if (g_hash_table_size (found_attributes)
1913 == g_hash_table_size (search_data->find_attributes))
1914 {
1915 search_data->found = 1;
1916 }
1917
1918 g_hash_table_destroy (found_attributes);
1919 }
1920 else
1921 {
1922 search_data->found = 1;
1923 }
1924 }
1925}
1926
1927#define XML_FILE_BUFFER_SIZE 1048576
1928int
1938find_element_in_xml_file (gchar *file_path, gchar *find_element,
1939 GHashTable *find_attributes)
1940{
1941 gchar buffer[XML_FILE_BUFFER_SIZE];
1942 FILE *file;
1943 int read_len;
1944 GMarkupParser xml_parser;
1945 GMarkupParseContext *xml_context;
1946 xml_search_data_t search_data;
1947 GError *error = NULL;
1948
1949 search_data.find_element = find_element;
1950 search_data.find_attributes = find_attributes;
1951 search_data.found = 0;
1952
1953 /* Create the XML parser. */
1954 xml_parser.start_element = xml_search_handle_start_element;
1955 xml_parser.end_element = NULL;
1956 xml_parser.text = NULL;
1957 xml_parser.passthrough = NULL;
1958 xml_parser.error = NULL;
1959 xml_context = g_markup_parse_context_new (&xml_parser, 0, &search_data, NULL);
1960
1961 file = fopen (file_path, "r");
1962 if (file == NULL)
1963 {
1964 g_markup_parse_context_free (xml_context);
1965 g_warning ("%s: Failed to open '%s':", __func__, strerror (errno));
1966 return 0;
1967 }
1968
1969 while ((read_len = fread (&buffer, sizeof (char), XML_FILE_BUFFER_SIZE, file))
1970 && g_markup_parse_context_parse (xml_context, buffer, read_len, &error)
1971 && error == NULL)
1972 {
1973 }
1974 g_markup_parse_context_end_parse (xml_context, &error);
1975
1976 fclose (file);
1977
1978 g_markup_parse_context_free (xml_context);
1979 return search_data.found;
1980}
1981#undef XML_FILE_BUFFER_SIZE
1982
1983/* The new faster parser that uses libxml2. */
1984
1998int
1999parse_element (const gchar *string, element_t *element)
2000{
2001 xmlDocPtr doc;
2002
2003 LIBXML_TEST_VERSION
2004
2005 if (element)
2006 *element = NULL;
2007
2008 if (xmlMemSetup (g_free, g_malloc, g_realloc, g_strdup))
2009 return -4;
2010
2011 doc =
2012 xmlReadMemory (string, strlen (string), "noname.xml", NULL, XML_PARSE_HUGE);
2013 if (doc == NULL)
2014 return -2;
2015
2016 if (element)
2017 *element = xmlDocGetRootElement (doc);
2018
2019 return 0;
2020}
2021
2030void
2032{
2033 if (element)
2034 {
2035 assert (element->doc);
2036 xmlFreeDoc (element->doc);
2037 }
2038}
2039
2047const gchar *
2049{
2050 if (element && (element->type == XML_ELEMENT_NODE))
2051 return (const gchar *) element->name;
2052
2053 return "";
2054}
2055
2064static element_t
2065find_child (element_t element, const gchar *name)
2066{
2067 for (xmlNode *node = element->children; node; node = node->next)
2068 if (xmlStrcmp (node->name, (const xmlChar *) name) == 0)
2069 return node;
2070 return NULL;
2071}
2072
2082element_child (element_t element, const gchar *name)
2083{
2084 const gchar *stripped_name;
2085
2086 if (!element)
2087 return NULL;
2088
2089 stripped_name = strchr (name, ':');
2090 if (stripped_name)
2091 {
2092 element_t child;
2093
2094 /* There was a namespace in the name.
2095 *
2096 * First try without the namespace, because libxml2 doesn't consider the
2097 * namespace in the name when the namespace is defined. */
2098
2099 stripped_name++;
2100
2101 if (*stripped_name == '\0')
2102 /* Don't search for child with empty stripped name, because we'll
2103 * find text nodes. But search with just the namespace for glib
2104 * compatibility. */
2105 return find_child (element, name);
2106
2107 child = find_child (element, stripped_name);
2108 if (child)
2109 return child;
2110
2111 /* Didn't find anything. */
2112 }
2113
2114 /* There was no namespace, or we didn't find anything without the namespace.
2115 *
2116 * Try with the full name. */
2117
2118 return find_child (element, name);
2119}
2120
2132gchar *
2134{
2135 gchar *string;
2136
2137 if (!element)
2138 return NULL;
2139
2140 string =
2141 (gchar *) xmlNodeListGetString (element->doc, element->xmlChildrenNode, 1);
2142 if (string)
2143 return string;
2144 string = xmlMalloc (1);
2145 string[0] = '\0';
2146 return string;
2147}
2148
2157gchar *
2158element_attribute (element_t element, const gchar *name)
2159{
2160 const gchar *stripped_name;
2161
2162 if (!element)
2163 return NULL;
2164
2165 stripped_name = strchr (name, ':');
2166 if (stripped_name)
2167 {
2168 gchar *attribute;
2169
2170 /* There was a namespace in the name.
2171 *
2172 * First try without the namespace, because libxml2 doesn't consider the
2173 * namespace in the name when the namespace is defined. */
2174
2175 stripped_name++;
2176
2177 if (*stripped_name == '\0')
2178 /* Don't search for child with empty stripped name, because we'll
2179 * find text nodes. But search with just the namespace for glib
2180 * compatibility. */
2181 return (gchar *) xmlGetProp (element, (const xmlChar *) name);
2182
2183 attribute =
2184 (gchar *) xmlGetProp (element, (const xmlChar *) stripped_name);
2185 if (attribute)
2186 return attribute;
2187
2188 /* Didn't find anything. */
2189 }
2190
2191 /* There was no namespace, or we didn't find anything without the namespace.
2192 *
2193 * Try with the full name. */
2194
2195 return (gchar *) xmlGetProp (element, (const xmlChar *) name);
2196}
2197
2207{
2208 if (element)
2209 {
2210 element = element->children;
2211 while (element && (element->type != XML_ELEMENT_NODE))
2212 element = element->next;
2213 return element;
2214 }
2215 return NULL;
2216}
2217
2227{
2228 if (element)
2229 {
2230 element = element->next;
2231 while (element && (element->type != XML_ELEMENT_NODE))
2232 element = element->next;
2233 return element;
2234 }
2235 return NULL;
2236}
2237
2248gchar *
2250{
2251 xmlBufferPtr buffer;
2252 char *xml_string;
2253
2254 // Copy element to ensure XML namespaces are included
2255 element_t element_copy;
2256 element_copy = xmlCopyNode (element, 1);
2257
2258 buffer = xmlBufferCreate ();
2259 xmlNodeDump (buffer, element_copy->doc, element_copy, 0, 0);
2260 xmlFreeNode (element_copy);
2261
2262 xml_string = g_strdup ((char *) xmlBufferContent (buffer));
2263
2264 xmlBufferFree (buffer);
2265 return xml_string;
2266}
2267
2275void
2276print_element_to_string (element_t element, GString *string)
2277{
2278 gchar *text_escaped, *text;
2279 element_t ch;
2280 xmlAttr *attribute;
2281
2282 text_escaped = NULL;
2283
2284 g_string_append_printf (string, "<%s", element_name (element));
2285
2286 attribute = element->properties;
2287 while (attribute)
2288 {
2289 xmlChar *value;
2290
2291 value = xmlNodeListGetString (element->doc, attribute->children, 1);
2292
2293 text_escaped = g_markup_escape_text ((gchar *) value, -1);
2294 g_string_append_printf (string, " %s=\"%s\"", attribute->name,
2295 text_escaped);
2296 g_free (text_escaped);
2297
2298 xmlFree (value);
2299
2300 attribute = attribute->next;
2301 }
2302
2303 g_string_append_printf (string, ">");
2304
2305 text = element_text (element);
2306 text_escaped = g_markup_escape_text (text, -1);
2307 g_free (text);
2308 g_string_append_printf (string, "%s", text_escaped);
2309 g_free (text_escaped);
2310
2311 ch = element_first_child (element);
2312 while (ch)
2313 {
2314 print_element_to_string (ch, string);
2315 ch = element_next (ch);
2316 }
2317
2318 g_string_append_printf (string, "</%s>", element_name (element));
2319}
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:900
void element_free(element_t element)
Free an entire element tree.
Definition xmlutils.c:2031
int read_entity_c(gvm_connection_t *connection, entity_t *entity)
Read an XML entity tree from the manager.
Definition xmlutils.c:1497
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:1400
int read_string_c(gvm_connection_t *connection, GString **string)
Read entity and text. Free the entity immediately.
Definition xmlutils.c:1420
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:1938
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:2048
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:1870
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:1030
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:2133
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:1282
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:2276
int read_entity(gnutls_session_t *session, entity_t *entity)
Read an XML entity tree from the manager.
Definition xmlutils.c:1469
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:1262
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:1581
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:1436
static void foreach_print_entity(gpointer entity, gpointer stream)
Print an XML entity for g_slist_foreach.
Definition xmlutils.c:1634
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:2158
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:1684
element_t element_first_child(element_t element)
Get the first child of an element.
Definition xmlutils.c:2206
void print_entity_format(entity_t entity, gpointer indent)
Print an XML entity to stdout, recursively printing its children.
Definition xmlutils.c:1702
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:1743
static element_t find_child(element_t element, const gchar *name)
Find child in an element.
Definition xmlutils.c:2065
int read_text_c(gvm_connection_t *connection, char **text)
Read text from the server.
Definition xmlutils.c:1366
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:1336
int parse_element(const gchar *string, element_t *element)
Read an XML element tree from a string.
Definition xmlutils.c:1999
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:1305
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:1826
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:2226
gchar * element_to_string(element_t element)
Output the XML element as a string.
Definition xmlutils.c:2249
element_t element_child(element_t element, const gchar *name)
Get a child of an element.
Definition xmlutils.c:2082
int parse_entity(const char *string, entity_t *entity)
Read an XML entity tree from a string.
Definition xmlutils.c:1511
#define XML_FILE_BUFFER_SIZE
Definition xmlutils.c:1927
int compare_entities(entity_t entity1, entity_t entity2)
Compare two XML entity.
Definition xmlutils.c:1761
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:1452
static void foreach_print_attribute(gpointer name, gpointer value, gpointer stream)
Print an XML attribute for g_hash_table_foreach.
Definition xmlutils.c:1647
int read_entity_s(int socket, entity_t *entity)
Read an XML entity tree from the socket.
Definition xmlutils.c:1483
void print_entity(FILE *stream, entity_t entity)
Print an XML entity.
Definition xmlutils.c:1659
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:1594
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:1845
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:1612
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