summaryrefslogtreecommitdiff
path: root/sfeed_web.c
blob: 17541b13e7125f44a314d529ae9090b1b91aa30e (plain)
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
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>

#include "util.h"
#include "xml.h"

static unsigned int isbase = 0, islink = 0, isfeedlink = 0, found = 0;
static char feedlink[4096] = "", basehref[4096] = "";

static void
xmltagstart(XMLParser *p, const char *tag, size_t taglen) {
	isbase = islink = isfeedlink = 0;
	if(taglen == 4) { /* optimization */
		if(!strncasecmp(tag, "base", taglen))
			isbase = 1;
		else if(!strncasecmp(tag, "link", taglen))
			islink = 1;
	}
}

static void
xmltagstartparsed(XMLParser *p, const char *tag, size_t taglen, int isshort) {
	if(isfeedlink) {
		printlink(feedlink, basehref, 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(!strncasecmp(name, "href", namelen))
			strlcpy(basehref, value, sizeof(basehref));
	} else if(islink) {
		if(!strncasecmp(name, "type", namelen)) {
			if(!strncasecmp(value, "application/atom", strlen("application/atom")) ||
			   !strncasecmp(value, "application/rss", strlen("application/rss"))) {
				isfeedlink = 1;
			}
		} else if(!strncasecmp(name, "href", namelen))
			strlcpy(feedlink, value, sizeof(feedlink));
	}
}

int
main(int argc, char **argv) {
	XMLParser x;

	/* base href */
	if(argc > 1)
		strlcpy(basehref, argv[1], sizeof(basehref));

	xmlparser_init(&x, stdin);
	x.xmltagstart = xmltagstart;
	x.xmlattr = xmlattr;
	x.xmltagstartparsed = xmltagstartparsed;

	xmlparser_parse(&x);

	return found > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}