+/*
+ * Find TAG in XML and return a pointer into xml set just behind the
+ * closing angle. Return NULL if not found.
+ */
+static const char *
+find_xml_tag (const char *xml, const char *tag)
+{
+ int taglen = strlen (tag);
+ const char *s = xml;
+
+ while ( (s = strchr (s, '<')) ) {
+ s++;
+ if (!strncmp (s, tag, taglen)) {
+ const char *s2 = s + taglen;
+ if (*s2 == '>' || isspace (*(const unsigned char*)s2) ) {
+ /* found */
+ while (*s2 && *s2 != '>') /* skip attributes */
+ s2++;
+ /* fixme: do need to handle angles inside attribute vallues? */
+ return *s2? (s2+1):NULL;
+ }
+ }
+ while (*s && *s != '>') /* skip to end of tag */
+ s++;
+ }
+ return NULL;
+}
+
+
+/*
+ * Extract the micalg from an GnupgOperationInfo XML container.
+ */
+static char *
+extract_micalg (char *xml)
+{
+ const char *s;
+
+ s = find_xml_tag (xml, "GnupgOperationInfo");
+ if (s) {
+ const char *s_end = find_xml_tag (s, "/GnupgOperationInfo");
+ s = find_xml_tag (s, "signature");
+ if (s && s_end && s < s_end) {
+ const char *s_end2 = find_xml_tag (s, "/signature");
+ if (s_end2 && s_end2 < s_end) {
+ s = find_xml_tag (s, "micalg");
+ if (s && s < s_end2) {
+ s_end = strchr (s, '<');
+ if (s_end) {
+ char *p = g_malloc (s_end - s + 1);
+ memcpy (p, s, s_end - s);
+ p[s_end-s] = 0;
+ return p;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+