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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include "common.h"
char *
afgets(char **p, size_t *size, FILE *fp) {
char buf[BUFSIZ], *alloc = NULL;
size_t n, len = 0, allocsiz;
int end = 0;
while(fgets(buf, sizeof(buf), fp)) {
n = strlen(buf);
if(buf[n - 1] == '\n') { /* dont store newlines. */
buf[n - 1] = '\0';
n--;
end = 1; /* newline found, end */
}
len += n;
allocsiz = len + 1;
if(allocsiz > *size) {
if((alloc = realloc(*p, allocsiz))) {
*p = alloc;
*size = allocsiz;
} else {
free(*p);
*p = NULL;
fputs("error: could not realloc\n", stderr);
exit(EXIT_FAILURE);
return NULL;
}
}
strncpy((*p + (len - n)), buf, n);
if(end || feof(fp))
break;
}
if(*p && len > 0) {
(*p)[len] = '\0';
return *p;
}
return NULL;
}
void /* print link; if link is relative use baseurl to make it absolute */
printlink(const char *link, const char *baseurl, FILE *fp) {
const char *ebaseproto, *ebasedomain, *p;
int isrelative;
/* protocol part */
for(p = link; *p && (isalpha((int)*p) || isdigit((int)*p) || *p == '+' || *p == '-' || *p == '.'); p++);
isrelative = strncmp(p, "://", strlen("://"));
if(isrelative) { /* relative link (baseurl is used). */
if((ebaseproto = strstr(baseurl, "://"))) {
ebaseproto += strlen("://");
fwrite(baseurl, 1, ebaseproto - baseurl, fp);
} else {
ebaseproto = baseurl;
if(*baseurl || (link[0] == '/' && link[1] == '/'))
fputs("http://", fp);
}
if(link[0] == '/') { /* relative to baseurl domain (not path). */
if(link[1] == '/') /* absolute url but with protocol from baseurl. */
link += 2;
else if((ebasedomain = strchr(ebaseproto, '/'))) /* relative to baseurl and baseurl path. */
fwrite(ebaseproto, 1, ebasedomain - ebaseproto, fp);
else
fputs(ebaseproto, stdout);
} else if((ebasedomain = strrchr(ebaseproto, '/'))) /* relative to baseurl and baseurl path. */
fwrite(ebaseproto, 1, ebasedomain - ebaseproto + 1, fp);
else {
fputs(ebaseproto, fp);
if(*baseurl && *link)
fputc('/', fp);
}
}
fputs(link, fp);
}
unsigned int
parseline(char **line, size_t *size, char **fields, unsigned int maxfields, int separator, FILE *fp) {
unsigned int i = 0;
char *prev, *s;
if(afgets(line, size, fp)) {
for(prev = *line; (s = strchr(prev, separator)) && i <= maxfields; i++) {
*s = '\0'; /* null terminate string. */
fields[i] = prev;
prev = s + 1;
}
fields[i] = prev;
for(i++; i < maxfields; i++) /* make non-parsed fields empty. */
fields[i] = "";
}
return i;
}
/* print feed name for id; spaces and tabs in string as "-" (spaces in anchors are not valid). */
void
printfeednameid(const char *s, FILE *fp) {
for(; *s; s++)
fputc(isspace((int)*s) ? '-' : tolower((int)*s), fp);
}
void
printhtmlencoded(const char *s, FILE *fp) {
for(; *s; s++) {
switch(*s) {
case '<': fputs("<", fp); break;
case '>': fputs(">", fp); break;
/* case '&': fputs("&", fp); break;*/
default:
fputc(*s, fp);
}
}
}
void
feedsfree(struct feed *f) {
struct feed *next;
while(f) {
next = f->next;
free(f->name);
free(f);
f = next;
}
}
|