From: alex Date: Mon, 27 Dec 2021 22:27:39 +0000 (-0800) Subject: ... X-Git-Url: http://git.infiniteadaptability.org/?a=commitdiff_plain;h=c30bb33f408c97d53f2df64acb51781ac8b75e6c;p=seeder ... --- diff --git a/Makefile.am b/Makefile.am index 0972588..4480da7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,7 @@ seederd_SOURCES = \ src/bencode/encode.c \ src/block.c \ src/default.c \ + src/feed.c \ src/file.c \ src/fs/concat.c \ src/fs/dir.c \ @@ -36,6 +37,10 @@ seederd_SOURCES = \ src/opt/set.c \ src/opt/watch.c \ src/opt/worker.c \ + src/rss/entry.c \ + src/rss/footer.c \ + src/rss/header.c \ + src/rss/info.c \ src/server/start.c \ src/session.c \ src/setup.c \ @@ -57,6 +62,7 @@ seederd_SOURCES += \ inc/bencode.h \ inc/block.h \ inc/default.h \ + inc/feed.h \ inc/file.h \ inc/fs.h \ inc/hash.h \ @@ -65,6 +71,7 @@ seederd_SOURCES += \ inc/log.h \ inc/main.h \ inc/opt.h \ + inc/rss.h \ inc/server.h \ inc/session.h \ inc/setup.h \ diff --git a/inc/feed.h b/inc/feed.h new file mode 100644 index 0000000..0908289 --- /dev/null +++ b/inc/feed.h @@ -0,0 +1,11 @@ +#ifndef __FEED_H_ +#define __FEED_H_ + +#include +#include + +#define FEED_DIRECTORY PREFIX "/feeds" + +int feed(); + +#endif diff --git a/inc/main.h b/inc/main.h index 8acd425..7953f8a 100644 --- a/inc/main.h +++ b/inc/main.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/inc/rss.h b/inc/rss.h new file mode 100644 index 0000000..adcbdb0 --- /dev/null +++ b/inc/rss.h @@ -0,0 +1,54 @@ +#ifndef __RSS_H_ +#define __RSS_H_ + +#include +#include +#include + +struct rss_channel_info { + char *title; + char *link; + char *description; + char *language; + struct tm last_build_date; +}; + +struct rss_entry { + char *title; + char *link; + struct tm pub_date; + char *description; + char *guid; +}; + +#define RSS_TAG_CHANNEL_START "" +#define RSS_TAG_CHANNEL_END "" +#define RSS_TAG_DESCRIPTION_START "" +#define RSS_TAG_DESCRIPTION_END "" +#define RSS_TAG_GUID_START "" +#define RSS_TAG_GUID_END "" +#define RSS_TAG_ITEM_START "" +#define RSS_TAG_ITEM_END "" +#define RSS_TAG_LANGUAGE_START "" +#define RSS_TAG_LANGUAGE_END "" +#define RSS_TAG_LASTBUILDDATE_START "" +#define RSS_TAG_LASTBUILDDATE_END "" +#define RSS_TAG_LINK_START "" +#define RSS_TAG_LINK_END "" +#define RSS_TAG_PUBDATE_START "" +#define RSS_TAG_PUBDATE_END "" +#define RSS_TAG_RSS_START "" +#define RSS_TAG_RSS_END "" +#define RSS_TAG_TITLE_START "" +#define RSS_TAG_TITLE_END "" + +#define RSS_DEFAULT_CHANNEL_DESCRIPTION "" +#define RSS_DEFAULT_ENTRY_DESCRIPTION "no description" +#define RSS_DEFAULT_LANGUAGE "en-us" + +int rss_entry(FILE*,struct rss_entry*); +int rss_footer(FILE*); +int rss_header(FILE*); +int rss_info(FILE*,struct rss_channel_info*); + +#endif diff --git a/inc/torrent.h b/inc/torrent.h index baefb8b..a65a443 100644 --- a/inc/torrent.h +++ b/inc/torrent.h @@ -29,6 +29,9 @@ struct torrent { int watch_fd; }; +#define TORRENT_FILE_DIRECTORY "/torrents" +#define TORRENT_FILE_EXTENSION ".torrent" + int torrent_add(struct torrent*,struct file*); int torrent_file(const char*,struct torrent*); ssize_t torrent_file_info(struct torrent*,uint8_t**); diff --git a/src/feed.c b/src/feed.c new file mode 100644 index 0000000..16341ab --- /dev/null +++ b/src/feed.c @@ -0,0 +1,65 @@ +#include + +static int feed_entries(FILE*,struct torrent*); +static int feed_generate(struct torrent*); +static char *feed_path(const char*,const char*); +//static int feed_now(char*,size_t); + +int feed() { + for(size_t i=0;iname); + if(NULL==path) { return -1; } + + fp = fopen(path,"w"); + if(NULL==fp) { + free(path); + return -1; + } + + if(torrent_file(PREFIX TORRENT_FILE_DIRECTORY,torrent)<0) { goto clean; } + + if(rss_header(fp)<0) { goto clean; } + if(rss_info(fp,&info)<0) { goto clean; } + + if(feed_entries(fp,torrent)<0) { goto clean; } + + if(rss_footer(fp)<0) { goto clean; } + + fclose(fp); + free(path); + + return 1; +clean: + fclose(fp); + remove(path); + free(path); + return -1; +} + +static int feed_entries(FILE *fp, struct torrent *torrent) { + return -1; +} + +static char *feed_path(const char *directory, const char *name) { + return NULL; +} + +/*static int feed_now(char *buf,size_t buf_len) { + struct tm now; + + now = *localtime(&(time_t){time(NULL)}); + if(!(strftime((*timebuf),buf_len, "%a, %d %b %Y %H:%M:%S %z", &now))) { return -1; } + + return 1; +} */ diff --git a/src/init.c b/src/init.c index 5d6c93c..ee405a3 100644 --- a/src/init.c +++ b/src/init.c @@ -1,5 +1,8 @@ #include +// NOTE: see src/opt/set.c for list of fields/options +// allowed to be set in config files + struct option long_options[] = { {"config-file", required_argument, 0, 'c'}, {"daemon", no_argument, 0, 'd'}, diff --git a/src/main.c b/src/main.c index e58a4cd..d160967 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ int main(int argc, char **argv) { if(setup_logging()<0) { return EXIT_FAILURE; } if(add()<0) { return EXIT_FAILURE; } - //if(feed()<0) { return EXIT_FAILURE; } + if(feed()<0) { return EXIT_FAILURE; } if(watch()<0) { return EXIT_FAILURE; } while(1) { } diff --git a/src/opt/set.c b/src/opt/set.c index bcc814e..6059b44 100644 --- a/src/opt/set.c +++ b/src/opt/set.c @@ -5,6 +5,8 @@ struct option_lookup_table_entry { int (*function)(const char*); }; +// NOTE: see src/init.c for list of CLI options + struct option_lookup_table_entry option_lookup_table[] = { {"file_filter",&opt_set_file_filter}, {"piece_length",&opt_set_piece_length}, @@ -29,5 +31,5 @@ int opt_set(const char *key, const char *value) { } log_err(OPT_MESSAGE_UNKNOWN_OPTION,key); - return 0; + return -1; } diff --git a/src/rss/entry.c b/src/rss/entry.c new file mode 100644 index 0000000..9874bd2 --- /dev/null +++ b/src/rss/entry.c @@ -0,0 +1,135 @@ +#include + +static int rss_entry_description(FILE*,const char*); +static int rss_entry_end(FILE*); +static int rss_entry_guid(FILE*,const char*); +static int rss_entry_link(FILE*,const char*); +static int rss_entry_pubdate(FILE*,const struct tm*); +static int rss_entry_start(FILE*); +static int rss_entry_title(FILE*,const char*); + +int rss_entry(FILE *fp, struct rss_entry *entry) { + if(NULL==fp) { return -1; } + if(NULL==entry) { return -1; } + + if(rss_entry_start(fp)<0) { return -1; } + + if(rss_entry_title(fp,entry->title)<0) { return -1; } + if(rss_entry_link(fp,entry->link)<0) { return -1; } + if(rss_entry_pubdate(fp,&(entry->pub_date))<0) { return -1; } + if(rss_entry_description(fp,entry->description)<0) { return -1; } + if(rss_entry_guid(fp,entry->guid)<0) { return -1; } + + if(rss_entry_end(fp)<0) { return -1; } + + return -1; +} + +static int rss_entry_description(FILE *fp, const char *description) { + size_t len; + + const char start[] = RSS_TAG_DESCRIPTION_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if((NULL==description)||(0==strlen(description))) { + const char default_description[] = RSS_DEFAULT_ENTRY_DESCRIPTION; + if(fwrite( + default_description, /* void* ptr */ + sizeof(char), /* size_t size */ + sizeof(default_description)-1, /* size_t nmemb */ + fp /* FILE *stream */ + )!=sizeof(default_description)-1) { return -1; } + } else { + len = strlen(description); + if(fwrite(description,sizeof(char),len,fp)!=len) { return -1; } + } + + const char end[] = RSS_TAG_DESCRIPTION_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return -1; +} + +static int rss_entry_end(FILE *fp) { + const char end[] = RSS_TAG_ITEM_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_entry_guid(FILE *fp, const char *guid) { + size_t len; + + if(NULL==guid) { return 1; } + + len = strlen(guid); + if(0==len) { return 1; } + + const char start[] = RSS_TAG_GUID_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if(fwrite(guid,sizeof(char),len,fp)!=len) { return -1; } + + const char end[] = RSS_TAG_GUID_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_entry_link(FILE *fp, const char *link) { + size_t len; + + if(NULL==link) { return -1; } + len = strlen(link); + if(len==0) { return -1; } + + const char start[] = RSS_TAG_LINK_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if(fwrite(link,sizeof(char),len,fp)!=len) { return -1; } + + const char end[] = RSS_TAG_TITLE_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_entry_pubdate(FILE *fp,const struct tm *date) { + char buf[40]; + size_t buf_size = 40; + + const char start[] = RSS_TAG_PUBDATE_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if(!(strftime(buf,buf_size, "%a, %d %b %Y %H:%M:%S %z", date))) { return -1; } + + const char end[] = RSS_TAG_PUBDATE_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_entry_start(FILE *fp) { + const char start[] = RSS_TAG_ITEM_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + return 1; +} + +static int rss_entry_title(FILE *fp, const char *title) { + size_t len; + + if(NULL==title) { return -1; } + len = strlen(title); + if(len==0) { return -1; } + + const char start[] = RSS_TAG_TITLE_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if(fwrite(title,sizeof(char),len,fp)!=len) { return -1; } + + const char end[] = RSS_TAG_TITLE_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} diff --git a/src/rss/footer.c b/src/rss/footer.c new file mode 100644 index 0000000..818520d --- /dev/null +++ b/src/rss/footer.c @@ -0,0 +1,13 @@ +#include + +int rss_footer(FILE *fp) { + const char channel[] = RSS_TAG_CHANNEL_END; + const char rss[] = RSS_TAG_RSS_END; + + if(NULL==fp) { return -1; } + + if(fwrite(channel,sizeof(char),sizeof(channel)-1,fp)!=sizeof(channel)-1) { return -1; } + if(fwrite(rss,sizeof(char),sizeof(rss)-1,fp)!=sizeof(rss)-1) { return -1; } + + return 1; +} diff --git a/src/rss/header.c b/src/rss/header.c new file mode 100644 index 0000000..985955f --- /dev/null +++ b/src/rss/header.c @@ -0,0 +1,13 @@ +#include + +int rss_header(FILE *fp) { + const char rss[] = RSS_TAG_RSS_START; + const char channel[] = RSS_TAG_CHANNEL_START; + + if(NULL==fp) { return -1; } + + if(fwrite(rss,sizeof(char),sizeof(rss)-1,fp)!=sizeof(rss)-1) { return -1; } + if(fwrite(channel,sizeof(char),sizeof(channel)-1,fp)!=sizeof(channel)-1) { return -1; } + + return 1; +} diff --git a/src/rss/info.c b/src/rss/info.c new file mode 100644 index 0000000..2d0317c --- /dev/null +++ b/src/rss/info.c @@ -0,0 +1,121 @@ +#include + +static int rss_info_description(FILE*,const char*); +static int rss_info_language(FILE*,const char*); +static int rss_info_last_build_date(FILE*,const struct tm*); +static int rss_info_link(FILE*,const char*); +static int rss_info_title(FILE*,const char*); + +int rss_info(FILE *fp, struct rss_channel_info *info) { + if(NULL==fp) { return -1; } + if(NULL==info) { return -1; } + + if(rss_info_title(fp,info->title)<0) { return -1; } + if(rss_info_link(fp,info->link)<0) { return -1; } + if(rss_info_description(fp,info->description)<0) { return -1; } + if(rss_info_language(fp,info->language)<0) { return -1; } + if(rss_info_last_build_date(fp,&(info->last_build_date))<0) { return -1; } + + return 1; +} + +static int rss_info_description(FILE *fp, const char *description) { + size_t len; + + const char start[] = RSS_TAG_DESCRIPTION_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if((NULL==description)||(0==strlen(description))) { + const char default_description[] = RSS_DEFAULT_CHANNEL_DESCRIPTION; + if(fwrite( + default_description, /* void* ptr */ + sizeof(char), /* size_t size */ + sizeof(default_description)-1, /* size_t nmemb */ + fp /* FILE *stream */ + )!=sizeof(default_description)-1) { return -1; } + } else { + len = strlen(description); + if(fwrite(description,sizeof(char),len,fp)!=len) { return -1; } + } + + const char end[] = RSS_TAG_DESCRIPTION_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_info_language(FILE *fp, const char *language) { + size_t len; + + const char start[] = RSS_TAG_LANGUAGE_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if((NULL==language)||(0==strlen(language))) { + const char default_language[] = RSS_DEFAULT_LANGUAGE; + if(fwrite( + default_language, /* void* ptr */ + sizeof(char), /* size_t size */ + sizeof(default_language)-1, /* size_t nmemb */ + fp /* FILE *stream */ + )!=sizeof(default_language)-1) { return -1; } + } else { + len = strlen(language); + if(fwrite(language,sizeof(char),len,fp)!=len) { return -1; } + } + + const char end[] = RSS_TAG_LANGUAGE_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_info_last_build_date(FILE *fp, const struct tm *date) { + char buf[40]; + size_t buf_size = 40; + + const char start[] = RSS_TAG_LASTBUILDDATE_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if(!(strftime(buf,buf_size, "%a, %d %b %Y %H:%M:%S %z", date))) { return -1; } + + const char end[] = RSS_TAG_LASTBUILDDATE_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_info_link(FILE *fp, const char *link) { + size_t len; + + if(NULL==link) { return -1; } + len = strlen(link); + if(len==0) { return -1; } + + const char start[] = RSS_TAG_LINK_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if(fwrite(link,sizeof(char),len,fp)!=len) { return -1; } + + const char end[] = RSS_TAG_TITLE_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} + +static int rss_info_title(FILE *fp, const char *title) { + size_t len; + + if(NULL==title) { return -1; } + len = strlen(title); + if(len==0) { return -1; } + + const char start[] = RSS_TAG_TITLE_START; + if(fwrite(start,sizeof(char),sizeof(start)-1,fp)!=sizeof(start)-1) { return -1; } + + if(fwrite(title,sizeof(char),len,fp)!=len) { return -1; } + + const char end[] = RSS_TAG_TITLE_END; + if(fwrite(end,sizeof(char),sizeof(end)-1,fp)!=sizeof(end)-1) { return -1; } + + return 1; +} diff --git a/src/torrent/path.c b/src/torrent/path.c index eb50ba7..44ff9f8 100644 --- a/src/torrent/path.c +++ b/src/torrent/path.c @@ -1,8 +1,5 @@ #include -#define TORRENT_FILE_DIRECTORY "/torrents" -#define TORRENT_FILE_EXTENSION ".torrent" - char *torrent_file_path(const char *prefix, unsigned char *infohash, size_t len) { char *path, *p; char hex[(crypto_hash_sha256_BYTES<<1)+1]; diff --git a/src/usage.c b/src/usage.c index 19d4970..5c929e8 100644 --- a/src/usage.c +++ b/src/usage.c @@ -18,6 +18,8 @@ static void usage_print_options() { size_t i; char *p; + // NOTE: long options defined in src/init.c + i = 0; while( !((0==long_options[i].name) && diff --git a/test/unit/test_utils.c b/test/unit/test_utils.c index 4ae2891..1ce8027 100644 --- a/test/unit/test_utils.c +++ b/test/unit/test_utils.c @@ -18,6 +18,8 @@ void setup_env() { srand(time(NULL)); create_test_directory(TEST_DIRECTORY); + create_test_directory(TEST_DIRECTORY "/data"); + create_test_directory(TEST_DIRECTORY "/feeds"); create_test_directory(TEST_DIRECTORY "/torrents"); create_test_file(TEST_FILE_1,TEST_FILE_1_CONTENTS); create_test_file(TEST_FILE_2,TEST_FILE_2_CONTENTS);