diff --git a/cconf.c b/cconf.c index e7115b0..282c9b8 100644 --- a/cconf.c +++ b/cconf.c @@ -65,9 +65,11 @@ void cconf_free(struct cconf *c) { for(i=0; i < c->nr; i++) { struct target *t = c->target + i; free(t->src); - free(t->dest); - for(j=0; j < t->nr; j++) - free(t->filter[j]); + for(j=0; j < t->nr; j++) { + struct filter *f = t->filter + i; + free(f->pattern); + free(f->dest); + } free(t->filter); } free(c->target); @@ -86,13 +88,13 @@ struct target* cconf_new_target(struct cconf *c) { return t; } -void cconf_add_filter(struct target *t, char *filter) { +void cconf_add_filter(struct target *t, struct filter *filter) { - if (!filter) + if (!filter || !filter->dest) return; - t->filter = realloc(t->filter, sizeof(t->filter) * (t->nr + 1)); - t->filter[t->nr++] = filter; + t->filter = realloc(t->filter, sizeof(*t->filter) * (t->nr + 1)); + memcpy(&t->filter[t->nr++], filter, sizeof(*filter)); } static size_t parse_filter(void *buf, struct target *target) { @@ -102,10 +104,15 @@ static size_t parse_filter(void *buf, struct target *target) { if (target->nr) { int i; - target->filter = malloc(sizeof(char *) * target->nr); + target->filter = malloc(sizeof(*target->filter) * target->nr); for(i=0; i < target->nr; i++) { - target->filter[i] = (char *) buf + offset; + struct filter *filter = &target->filter[i]; + + filter->pattern = (char *) buf + offset; + offset += strsize(buf + offset); + + filter->dest = (char *) buf + offset; offset += strsize(buf + offset); } } @@ -119,9 +126,6 @@ static size_t parse_target(void *buf, struct target *target) { target->src = (char *) buf; offset = strsize(buf); - target->dest = (char *) buf + offset; - offset += strsize(buf + offset); - return offset; } @@ -219,17 +223,19 @@ int cconf_write(int fd, struct cconf *c) { int j; struct target *target = c->target + i; - if (!target->src || !target->dest) + if (!target->src) return -1; + sha1_write(&ctx, fd, target->src, strsize(target->src)); - sha1_write(&ctx, fd, target->dest, strsize(target->dest)); /* write number of filters */ write_int(&ctx, fd, target->nr); for(j=0; j < target->nr; j++) { - sha1_write(&ctx, fd, target->filter[j], - strsize(target->filter[j])); + struct filter *f = &target->filter[j]; + + sha1_write(&ctx, fd, f->pattern, strsize(f->pattern)); + sha1_write(&ctx, fd, f->dest, strsize(f->dest)); } } diff --git a/cconf.h b/cconf.h index ec3d894..c6f7e36 100644 --- a/cconf.h +++ b/cconf.h @@ -32,10 +32,14 @@ struct cconf_header { unsigned char crc[20]; }; +struct filter { + char *pattern; + char *dest; /* destination, path on filesystem */ +}; + struct target { char *src; /* source. (url) */ - char *dest; /* destination, path on filesystem */ - char **filter; + struct filter *filter; unsigned int nr; }; @@ -52,7 +56,7 @@ void cconf_free(struct cconf *c); struct target* cconf_new_target(struct cconf *c); -void cconf_add_filter(struct target *t, char *filter); +void cconf_add_filter(struct target *t, struct filter *filter); int cconf_write(int fd, struct cconf *c); diff --git a/compile.c b/compile.c index faebdff..f1ac3d9 100644 --- a/compile.c +++ b/compile.c @@ -44,6 +44,9 @@ static struct dest_table { char *value; } *dest_table; +/* index to the default destination */ +static unsigned default_dest; + static struct cconf cconf; static int config_lineno = 1; static FILE *config_fd; @@ -69,7 +72,7 @@ static char* fetch_destination(char *key) { int index = find_destination(key); if (index < 0) - index = 0; + index = default_dest; return dest_table[index].value; } @@ -189,10 +192,43 @@ static char* parse_alias() { static int parse_filter(struct target *target) { - char *value = parse_value(); - if (!value || !filter_check_syntax(value)) + struct filter filter; + char pattern[1024]; + char *alias = NULL; + int c, len = 0; + + for(;;) { + c = get_next_ch(); + if (c == EOF || isspace(c)) + break; + if (c == '\\') { + c = get_next_ch(); + if (c != ' ') { + ungetc(c, config_fd); + c = '\\'; + } + } + if (len >= sizeof(pattern)) + return -1; + pattern[len++] = c; + } + pattern[len] = '\0'; + + if (!pattern[0] || !filter_check_syntax(pattern)) return -1; - cconf_add_filter(target, strdup(value)); + + if (c == ' ' || c == '\t') { + alias = parse_alias(); + if (!alias) + return -1; + } + + filter.pattern = strdup(pattern); + if (!alias || !alias[0]) + alias = dest_table[default_dest].key; + filter.dest = strdup(fetch_destination(alias)); + + cconf_add_filter(target, &filter); return 0; } @@ -221,8 +257,7 @@ static int parse_target(struct target *target) { } target->src = strdup(src); - target->dest = strdup(len ? fetch_destination(alias) : - dest_table[0].value); + default_dest = len ? find_destination(alias) : 0; return 0; } diff --git a/config.sample b/config.sample index 269570b..29c65cb 100644 --- a/config.sample +++ b/config.sample @@ -10,4 +10,4 @@ url1 url2 dest2 regex5 - regex6 + regex6 dest1 diff --git a/dlight.c b/dlight.c index b69e80b..790abbd 100644 --- a/dlight.c +++ b/dlight.c @@ -13,22 +13,29 @@ static void process_items(rss_t rss, struct target *t) { + int i; struct rss_item item; while(rss_walk_next(rss, &item)) { - if (!filter_match_list(t->filter, t->nr, item.title) - || dlhist_lookup(item.link)) { + if (dlhist_lookup(item.link)) continue; - } - if (http_download_file(item.link, t->dest) < 0 && - errno != EEXIST) { - error("download failed: %s\n", strerror(errno)); - continue; - } + for(i=0; i < t->nr; i++) { + struct filter *filter = &t->filter[i]; - dlhist_update(item.link); + if (!filter_match(filter->pattern, item.title)) + continue; + + if (http_download_file(item.link, filter->dest) < 0 && + errno != EEXIST) { + printf("download failed: %s\n", + strerror(errno)); + continue; + } + + dlhist_update(item.link); + } } } diff --git a/read-config.c b/read-config.c index d5b7057..16ee788 100644 --- a/read-config.c +++ b/read-config.c @@ -53,10 +53,12 @@ int main(int argc, char **argv) { struct target *t = c->target + i; printf("src: %s\n", t->src); - printf("dest: %s\n", t->dest); for(j=0; j < t->nr; j++) - printf("filter: %s\n", t->filter[j]); + printf("filter:\n" + "\tpattern: %s\n" + "\tdestination: %s\n", + t->filter[j].pattern, t->filter[j].dest); printf("---\n"); }