1 /*
2 * Copyright (c) 2013 Tim Ruehsen
3 * Copyright (c) 2015-2021 Free Software Foundation, Inc.
4 *
5 * This file is part of libwget.
6 *
7 * Libwget is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Libwget is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with libwget. If not, see <https://www.gnu.org/licenses/>.
19 *
20 *
21 * Extracting URLs from Atom feeds (RFC 4287)
22 *
23 * Changelog
24 * 15.12.2013 Tim Ruehsen created
25 */
26
27 #include <config.h>
28
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <c-ctype.h>
33
34 #include <wget.h>
35 #include "private.h"
36
37 /**
38 * \file
39 * \brief URL extraction from Atom feed XML data
40 * \defgroup libwget-parse_atom Atom URL extraction routines
41 * @{
42 *
43 * Routines for URL extraction from Atom feeds.
44 */
45
46 struct atom_context {
47 wget_vector
48 *urls;
49 };
50
atom_get_url(void * context,int flags,const char * dir,const char * attr,const char * val,size_t len,size_t pos WGET_GCC_UNUSED)51 static void atom_get_url(void *context, int flags, const char *dir, const char *attr, const char *val, size_t len, size_t pos WGET_GCC_UNUSED)
52 {
53 struct atom_context *ctx = context;
54 wget_string *url;
55
56 if (!val || !len)
57 return;
58
59 if ((flags & XML_FLG_ATTRIBUTE)) {
60 if (!wget_strcasecmp_ascii(attr, "href") || !wget_strcasecmp_ascii(attr, "uri")
61 || !wget_strcasecmp_ascii(attr, "src") || !wget_strcasecmp_ascii(attr, "scheme")
62 || !wget_strcasecmp_ascii(attr, "xmlns") || !wget_strncasecmp_ascii(attr, "xmlns:", 6))
63 {
64 for (;len && c_isspace(*val); val++, len--); // skip leading spaces
65 for (;len && c_isspace(val[len - 1]); len--); // skip trailing spaces
66
67 if (!(url = wget_malloc(sizeof(wget_string))))
68 return;
69
70 url->p = val;
71 url->len = len;
72
73 if (!ctx->urls)
74 ctx->urls = wget_vector_create(32, NULL);
75
76 wget_vector_add(ctx->urls, url);
77 }
78 }
79 else if ((flags & XML_FLG_CONTENT)) {
80 const char *elem = strrchr(dir, '/');
81
82 if (elem) {
83 elem++;
84
85 if (!wget_strcasecmp_ascii(elem, "icon") || !wget_strcasecmp_ascii(elem, "id")
86 || !wget_strcasecmp_ascii(elem, "logo"))
87 {
88 for (;len && c_isspace(*val); val++, len--); // skip leading spaces
89 for (;len && c_isspace(val[len - 1]); len--); // skip trailing spaces
90
91 // debug_printf("#2 %02X %s %s '%.*s' %zd\n", flags, dir, attr, (int) len, val, len);
92
93 if (!(url = wget_malloc(sizeof(wget_string))))
94 return;
95
96 url->p = val;
97 url->len = len;
98
99 if (!ctx->urls)
100 ctx->urls = wget_vector_create(32, NULL);
101
102 wget_vector_add(ctx->urls, url);
103 }
104 }
105 }
106 }
107
108 /**
109 * \param[in] atom Atom XML data
110 * \param[in,out] urls Pointer to return vector of URLs
111 *
112 * Finds all URLs within the Atom XML data \p atom and returns them
113 * as vector in \p urls.
114 *
115 */
wget_atom_get_urls_inline(const char * atom,wget_vector ** urls)116 void wget_atom_get_urls_inline(const char *atom, wget_vector **urls)
117 {
118 struct atom_context context = { .urls = NULL };
119
120 wget_xml_parse_buffer(atom, atom_get_url, &context, XML_HINT_REMOVE_EMPTY_CONTENT);
121
122 *urls = context.urls;
123 }
124
125 /**@}*/
126