+
+/**************************************************************************/
+/* */
+/* Functions in this section handle OpenID protocol */
+/* */
+/**************************************************************************/
+
+
+/*
+ * Locate a <link> tag and, given its 'rel=' parameter, return its 'href' parameter
+ */
+void extract_link(StrBuf *target_buf, const char *rel, long repllen, StrBuf *source_buf)
+{
+ int i;
+ const char *ptr;
+ const char *href_start = NULL;
+ const char *href_end = NULL;
+ const char *link_tag_start = NULL;
+ const char *link_tag_end = NULL;
+ const char *rel_start = NULL;
+ const char *rel_end = NULL;
+
+ if (!target_buf) return;
+ if (!rel) return;
+ if (!source_buf) return;
+
+ ptr = ChrPtr(source_buf);
+
+ FlushStrBuf(target_buf);
+ while (ptr = cbmstrcasestr(ptr, "<link"), ptr != NULL) {
+
+ link_tag_start = ptr;
+ link_tag_end = strchr(ptr, '>');
+ if (link_tag_end == NULL)
+ break;
+ for (i=0; i < 1; i++ ){
+ rel_start = cbmstrcasestr(link_tag_start, "rel=");
+ if ((rel_start == NULL) ||
+ (rel_start > link_tag_end))
+ continue;
+
+ rel_start = strchr(rel_start, '\"');
+ if ((rel_start == NULL) ||
+ (rel_start > link_tag_end))
+ continue;
+ ++rel_start;
+ rel_end = strchr(rel_start, '\"');
+ if ((rel_end == NULL) ||
+ (rel_end == rel_start) ||
+ (rel_end >= link_tag_end) )
+ continue;
+ if (strncasecmp(rel, rel_start, repllen)!= 0)
+ continue; /* didn't match? never mind... */
+
+ href_start = cbmstrcasestr(link_tag_start, "href=");
+ if ((href_start == NULL) ||
+ (href_start >= link_tag_end))
+ continue;
+ href_start = strchr(href_start, '\"');
+ if ((href_start == NULL) |
+ (href_start >= link_tag_end))
+ continue;
+ ++href_start;
+ href_end = strchr(href_start, '\"');
+ if ((href_end == NULL) ||
+ (href_end == href_start) ||
+ (href_start >= link_tag_end))
+ continue;
+ StrBufPlain(target_buf, href_start, href_end - href_start);
+ }
+ ptr = link_tag_end;
+ }
+}
+
+