mirror of https://github.com/BOINC/boinc.git
- Notices: put message bodies inside CDATA
- XML_PARSER: handle CDATA svn path=/trunk/boinc/; revision=20146
This commit is contained in:
parent
ee343cea02
commit
564cd7cece
|
@ -365,3 +365,13 @@ David 12 Jan 2010
|
||||||
sched
|
sched
|
||||||
handle_request.cpp
|
handle_request.cpp
|
||||||
sched_types.cpp,h
|
sched_types.cpp,h
|
||||||
|
|
||||||
|
David 12 Jan 2010
|
||||||
|
- Notices: put message bodies inside CDATA
|
||||||
|
- XML_PARSER: handle CDATA
|
||||||
|
|
||||||
|
client/
|
||||||
|
cs_notice.cpp,h
|
||||||
|
lib/
|
||||||
|
notice.cpp
|
||||||
|
parse.cpp,h
|
||||||
|
|
|
@ -335,15 +335,14 @@ void NOTICES::prune() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write archive file for the RSS feed specified by URL
|
// write archive file for the given RSS feed
|
||||||
// (or, if blank, non-RSS notices)
|
// (or, if NULL, non-RSS notices)
|
||||||
//
|
//
|
||||||
void NOTICES::write_archive(char* url) {
|
void NOTICES::write_archive(RSS_FEED* rfp) {
|
||||||
char buf[256], path[256];
|
char path[256];
|
||||||
|
|
||||||
if (url) {
|
if (rfp) {
|
||||||
escape_project_url(url, buf);
|
rfp->archive_file_name(path);
|
||||||
sprintf(path, NOTICES_DIR"/archive_%s", buf);
|
|
||||||
} else {
|
} else {
|
||||||
strcpy(path, NOTICES_DIR"/archive.xml");
|
strcpy(path, NOTICES_DIR"/archive.xml");
|
||||||
}
|
}
|
||||||
|
@ -355,8 +354,8 @@ void NOTICES::write_archive(char* url) {
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
for (unsigned int i=0; i<notices.size(); i++) {
|
for (unsigned int i=0; i<notices.size(); i++) {
|
||||||
NOTICE& n = notices[i];
|
NOTICE& n = notices[i];
|
||||||
if (url) {
|
if (rfp) {
|
||||||
if (strcmp(url, n.feed_url)) continue;
|
if (strcmp(rfp->url, n.feed_url)) continue;
|
||||||
} else {
|
} else {
|
||||||
if (strlen(n.feed_url)) continue;
|
if (strlen(n.feed_url)) continue;
|
||||||
}
|
}
|
||||||
|
@ -388,13 +387,13 @@ void NOTICES::write(int seqno, MIOFILE& fout, bool public_only) {
|
||||||
|
|
||||||
void RSS_FEED::feed_file_name(char* path) {
|
void RSS_FEED::feed_file_name(char* path) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
escape_project_url(url, buf);
|
escape_project_url(url_base, buf);
|
||||||
sprintf(path, NOTICES_DIR"/%s", buf);
|
sprintf(path, NOTICES_DIR"/%s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSS_FEED::archive_file_name(char* path) {
|
void RSS_FEED::archive_file_name(char* path) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
escape_project_url(url, buf);
|
escape_project_url(url_base, buf);
|
||||||
sprintf(path, NOTICES_DIR"/archive_%s", buf);
|
sprintf(path, NOTICES_DIR"/archive_%s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,6 +427,9 @@ int RSS_FEED::parse_desc(XML_PARSER& xp) {
|
||||||
}
|
}
|
||||||
return ERR_XML_PARSE;
|
return ERR_XML_PARSE;
|
||||||
}
|
}
|
||||||
|
strcpy(url_base, url);
|
||||||
|
char* p = strchr(url_base, '?');
|
||||||
|
if (p) *p = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (xp.parse_str(tag, "url", url, sizeof(url))) continue;
|
if (xp.parse_str(tag, "url", url, sizeof(url))) continue;
|
||||||
|
@ -462,15 +464,25 @@ int RSS_FEED::parse_items(XML_PARSER& xp, int& nitems) {
|
||||||
char tag[256];
|
char tag[256];
|
||||||
bool is_tag;
|
bool is_tag;
|
||||||
nitems = 0;
|
nitems = 0;
|
||||||
|
int ntotal = 0, nerror = 0;
|
||||||
while (!xp.get(tag, sizeof(tag), is_tag)) {
|
while (!xp.get(tag, sizeof(tag), is_tag)) {
|
||||||
if (!is_tag) continue;
|
if (!is_tag) continue;
|
||||||
if (!strcmp(tag, "/rss")) {
|
if (!strcmp(tag, "/rss")) {
|
||||||
|
if (log_flags.notice_debug) {
|
||||||
|
msg_printf(0, MSG_INFO,
|
||||||
|
"[notice_debug] parsed RSS feed: total %d error %d added %d",
|
||||||
|
ntotal, nerror, nitems
|
||||||
|
);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(tag, "item")) {
|
if (!strcmp(tag, "item")) {
|
||||||
NOTICE n;
|
NOTICE n;
|
||||||
|
ntotal++;
|
||||||
int retval = n.parse_rss(xp);
|
int retval = n.parse_rss(xp);
|
||||||
if (!retval) {
|
if (retval) {
|
||||||
|
nerror++;
|
||||||
|
} else {
|
||||||
n.arrival_time = gstate.now;
|
n.arrival_time = gstate.now;
|
||||||
strcpy(n.feed_url, url);
|
strcpy(n.feed_url, url);
|
||||||
if (notices.append_unique(n)) {
|
if (notices.append_unique(n)) {
|
||||||
|
@ -559,7 +571,7 @@ void RSS_FEED_OP::handle_reply(int http_op_retval) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (nitems) {
|
if (nitems) {
|
||||||
notices.write_archive(rfp->url);
|
notices.write_archive(rfp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct NOTICES {
|
||||||
void init();
|
void init();
|
||||||
void init_rss();
|
void init_rss();
|
||||||
int read_archive_file(char* file, char* feed_url);
|
int read_archive_file(char* file, char* feed_url);
|
||||||
void write_archive(char* url);
|
void write_archive(struct RSS_FEED*);
|
||||||
void prune();
|
void prune();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ extern NOTICES notices;
|
||||||
|
|
||||||
struct RSS_FEED {
|
struct RSS_FEED {
|
||||||
char url[256];
|
char url[256];
|
||||||
|
char url_base[256];
|
||||||
double poll_interval;
|
double poll_interval;
|
||||||
double next_poll_time;
|
double next_poll_time;
|
||||||
bool use_seqno;
|
bool use_seqno;
|
||||||
|
|
|
@ -67,7 +67,7 @@ void NOTICE::write(MIOFILE& f, bool for_gui) {
|
||||||
f.printf(
|
f.printf(
|
||||||
"<notice>\n"
|
"<notice>\n"
|
||||||
" <title>%s</title>\n"
|
" <title>%s</title>\n"
|
||||||
" <description>%s</description>\n"
|
" <description><![CDATA[\n%s\n]]></description>\n"
|
||||||
" <create_time>%f</create_time>\n"
|
" <create_time>%f</create_time>\n"
|
||||||
" <arrival_time>%f</arrival_time>\n"
|
" <arrival_time>%f</arrival_time>\n"
|
||||||
" <is_private>%d</is_private>\n"
|
" <is_private>%d</is_private>\n"
|
||||||
|
|
|
@ -464,16 +464,20 @@ bool XML_PARSER::scan_nonws(int& first_char) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define XML_PARSE_COMMENT 1
|
||||||
|
#define XML_PARSE_EOF 2
|
||||||
|
#define XML_PARSE_CDATA 3
|
||||||
|
|
||||||
int XML_PARSER::scan_comment() {
|
int XML_PARSER::scan_comment() {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
char* p = buf;
|
char* p = buf;
|
||||||
while (1) {
|
while (1) {
|
||||||
int c = f->_getc();
|
int c = f->_getc();
|
||||||
if (c == EOF) return 2;
|
if (c == EOF) return XML_PARSE_EOF;
|
||||||
*p++ = c;
|
*p++ = c;
|
||||||
*p = 0;
|
*p = 0;
|
||||||
if (strstr(buf, "-->")) {
|
if (strstr(buf, "-->")) {
|
||||||
return 1;
|
return XML_PARSE_COMMENT;
|
||||||
}
|
}
|
||||||
if (strlen(buf) > 32) {
|
if (strlen(buf) > 32) {
|
||||||
strcpy(buf, buf+16);
|
strcpy(buf, buf+16);
|
||||||
|
@ -482,6 +486,27 @@ int XML_PARSER::scan_comment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int XML_PARSER::scan_cdata(char* buf, int len) {
|
||||||
|
char* p = buf;
|
||||||
|
len--;
|
||||||
|
while (1) {
|
||||||
|
int c = f->_getc();
|
||||||
|
if (c == EOF) return XML_PARSE_EOF;
|
||||||
|
if (len) {
|
||||||
|
*p++ = c;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
if (c == '>') {
|
||||||
|
*p = 0;
|
||||||
|
char* q = strstr(buf, "]]>");
|
||||||
|
if (q) {
|
||||||
|
*q = 0;
|
||||||
|
return XML_PARSE_CDATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we just read a <; read until we find a >.
|
// we just read a <; read until we find a >.
|
||||||
// Given <tag [attr=val attr=val] [/]>:
|
// Given <tag [attr=val attr=val] [/]>:
|
||||||
// - copy tag (or tag/) to tag_buf
|
// - copy tag (or tag/) to tag_buf
|
||||||
|
@ -493,11 +518,13 @@ int XML_PARSER::scan_comment() {
|
||||||
// 2 if reached EOF
|
// 2 if reached EOF
|
||||||
//
|
//
|
||||||
int XML_PARSER::scan_tag(
|
int XML_PARSER::scan_tag(
|
||||||
char* tag_buf, int tag_len, char* attr_buf, int attr_len
|
char* tag_buf, int _tag_len, char* attr_buf, int attr_len
|
||||||
) {
|
) {
|
||||||
int c;
|
int c;
|
||||||
char* buf_start = tag_buf;
|
char* buf_start = tag_buf;
|
||||||
bool found_space = false;
|
bool found_space = false;
|
||||||
|
int tag_len = _tag_len;
|
||||||
|
|
||||||
for (int i=0; ; i++) {
|
for (int i=0; ; i++) {
|
||||||
c = f->_getc();
|
c = f->_getc();
|
||||||
if (c == EOF) return 2;
|
if (c == EOF) return 2;
|
||||||
|
@ -536,6 +563,9 @@ int XML_PARSER::scan_tag(
|
||||||
if (i==2 && !strncmp(buf_start, "!--", 3)) {
|
if (i==2 && !strncmp(buf_start, "!--", 3)) {
|
||||||
return scan_comment();
|
return scan_comment();
|
||||||
}
|
}
|
||||||
|
if (i==7 && !strncmp(buf_start, "![CDATA[", 8)) {
|
||||||
|
return scan_cdata(buf_start, tag_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,9 +602,13 @@ bool XML_PARSER::get(char* buf, int len, bool& is_tag, char* attr_buf, int attr_
|
||||||
if (eof) return true;
|
if (eof) return true;
|
||||||
if (c == '<') {
|
if (c == '<') {
|
||||||
int retval = scan_tag(buf, len, attr_buf, attr_len);
|
int retval = scan_tag(buf, len, attr_buf, attr_len);
|
||||||
if (retval == 2) return true;
|
if (retval == XML_PARSE_EOF) return true;
|
||||||
if (retval == 1) continue;
|
if (retval == XML_PARSE_COMMENT) continue;
|
||||||
is_tag = true;
|
if (retval == XML_PARSE_CDATA) {
|
||||||
|
is_tag = false;
|
||||||
|
} else {
|
||||||
|
is_tag = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buf[0] = c;
|
buf[0] = c;
|
||||||
eof = copy_until_tag(buf+1, len-1);
|
eof = copy_until_tag(buf+1, len-1);
|
||||||
|
|
|
@ -29,6 +29,7 @@ class XML_PARSER {
|
||||||
bool scan_nonws(int&);
|
bool scan_nonws(int&);
|
||||||
int scan_comment();
|
int scan_comment();
|
||||||
int scan_tag(char*, int, char* ab=0, int al=0);
|
int scan_tag(char*, int, char* ab=0, int al=0);
|
||||||
|
int scan_cdata(char*, int);
|
||||||
bool copy_until_tag(char*, int);
|
bool copy_until_tag(char*, int);
|
||||||
public:
|
public:
|
||||||
MIOFILE* f;
|
MIOFILE* f;
|
||||||
|
|
Loading…
Reference in New Issue