1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include <ctype.h>
#include <err.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include "util.h"
#include "xml.h"
/* string and size */
#define STRP(s) s,sizeof(s)-1
static XMLParser parser;
static unsigned int isbase, islink, isfeedlink, found;
static char abslink[4096], feedlink[4096], basehref[4096], feedtype[256];
static void
printfeedtype(const char *s, FILE *fp)
{
for (; *s; s++)
if (!isspace((int)*s))
fputc(*s, fp);
}
static void
xmltagstart(XMLParser *p, const char *tag, size_t taglen)
{
isbase = islink = isfeedlink = 0;
if (taglen != 4) /* optimization */
return;
if (!strcasecmp(tag, "base"))
isbase = 1;
else if (!strcasecmp(tag, "link"))
islink = 1;
}
static void
xmltagstartparsed(XMLParser *p, const char *tag, size_t taglen, int isshort)
{
if (!isfeedlink)
return;
if (absuri(abslink, sizeof(abslink), feedlink, basehref) != -1)
fputs(abslink, stdout);
fputc('\t', stdout);
printfeedtype(feedtype, stdout);
putchar('\n');
found++;
}
static void
xmlattr(XMLParser *p, const char *tag, size_t taglen, const char *name,
size_t namelen, const char *value, size_t valuelen)
{
if (namelen != 4) /* optimization */
return;
if (isbase) {
if (!strcasecmp(name, "href"))
strlcpy(basehref, value, sizeof(basehref));
} else if (islink) {
if (!strcasecmp(name, "type")) {
if (!strncasecmp(value, STRP("application/atom")) ||
!strncasecmp(value, STRP("application/xml")) ||
!strncasecmp(value, STRP("application/rss"))) {
isfeedlink = 1;
strlcpy(feedtype, value, sizeof(feedtype));
}
} else if (!strcasecmp(name, "href")) {
strlcpy(feedlink, value, sizeof(feedlink));
}
}
}
int
main(int argc, char *argv[])
{
#ifdef USE_PLEDGE
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
#endif
if (argc > 1)
strlcpy(basehref, argv[1], sizeof(basehref));
parser.xmlattr = xmlattr;
parser.xmltagstart = xmltagstart;
parser.xmltagstartparsed = xmltagstartparsed;
parser.getnext = getchar;
xml_parse(&parser);
return found > 0 ? 0: 1;
}
|