#include<torrent.h>
#define FEED_DIRECTORY PREFIX "/feeds"
+#define FEED_FILE_EXTENSION ".xml"
int feeds();
int feed_entries(FILE*,struct torrent*);
-int feed_info(struct torrent*,struct rss_channel_info*);
+int feed_info(FILE*,struct torrent*);
char *feed_path(const char*);
#endif
void rss_channel_info_free(struct rss_channel_info*);
int rss_channel_info_init(struct rss_channel_info**);
-int rss_entry(FILE*,struct rss_entry*);
+int rss_entry(FILE*,const struct rss_entry*);
void rss_entry_free(struct rss_entry*);
int rss_entry_init(struct rss_entry**);
int rss_footer(FILE*);
int rss_header(FILE*);
-int rss_info(FILE*,struct rss_channel_info*);
+int rss_info(FILE*,const struct rss_channel_info*);
#endif
struct rss_entry **entries, *entry;
size_t count, index;
+ if(NULL==fp) { return -1; }
+ if(NULL==torrent) { return -1; }
+
count = 0;
for(size_t i=0;i<torrent->files.roots->size;i++) {
if(torrent->files.roots->map[i]!=NULL) { count++; }
qsort(entries,count,sizeof(struct rss_entry*),&entries_sort);
+ for(size_t i=0;i<count;i++) {
+ entry = entries[i];
+ if(NULL==entry) { goto clean; }
+ if(rss_entry(fp,entry)<0) { goto clean; }
+ rss_entry_free(entry);
+ entries[i] = NULL;
+ }
+
+ free(entries);
+
return 1;
clean:
for(size_t i=0;i<count;i++) {
static int feed_generate(struct torrent *torrent) {
FILE *fp;
- struct rss_channel_info info;
char *path;
if(is_directory(FEED_DIRECTORY)<0) {
if(torrent_file(torrent)<0) { goto clean; }
if(rss_header(fp)<0) { goto clean; }
- if(feed_info(torrent,&info)<0) { goto clean; }
- if(rss_info(fp,&info)<0) { return -1; }
-
+
+ if(feed_info(fp,torrent)<0) { goto clean; }
if(feed_entries(fp,torrent)<0) { goto clean; }
if(rss_footer(fp)<0) { goto clean; }
#include<feed.h>
-int feed_info(struct torrent *torrent_p, struct rss_channel_info *info) {
+int feed_info(FILE *fp, struct torrent *torrent_p) {
+ struct rss_channel_info *info;
+
+ if(NULL==fp) { return -1; }
+ if(NULL==torrent_p) { return -1; }
+
+ info = NULL;
+ if(rss_channel_info_init(&info)<0) { return -1; }
+
+ if(meta_info(torrent_p->root,info)<0) { goto clean; }
+
+ if(rss_info(fp,info)<0) { goto clean; }
+
+ rss_channel_info_free(info);
+
+ return 1;
+clean:
+ if(info!=NULL) { rss_channel_info_free(info); }
return -1;
}
#include<feed.h>
char *feed_path(const char *name) {
- return NULL;
+ char *p, *path;
+
+ p = concat(FEED_DIRECTORY,name);
+ if(NULL==p) { return NULL; }
+
+ path = malloc(strlen(p)+strlen(FEED_FILE_EXTENSION)+1);
+ if(NULL==path) {
+ free(p);
+ return NULL;
+ }
+
+ if(sprintf(path,"%s" FEED_FILE_EXTENSION,p)<0) {
+ free(p);
+ free(path);
+ return NULL;
+ }
+
+ free(p);
+
+ return path;
}
static int rss_entry_start(FILE*);
static int rss_entry_title(FILE*,const char*);
-int rss_entry(FILE *fp, struct rss_entry *entry) {
+int rss_entry(FILE *fp, const struct rss_entry *entry) {
if(NULL==fp) { return -1; }
if(NULL==entry) { return -1; }
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) {
+int rss_info(FILE *fp, const struct rss_channel_info *info) {
if(NULL==fp) { return -1; }
if(NULL==info) { return -1; }
p = concat(TORRENT_FILE_DIRECTORY,hex);
if(NULL==p) { return NULL; }
- path = malloc(strlen(p)+strlen(".torrent")+1);
+ path = malloc(strlen(p)+strlen(TORRENT_FILE_EXTENSION)+1);
if(NULL==path) {
free(p);
return NULL;
-Werror
EXTRA_DIST = \
- test_utils.h
+ test_utils.h \
+ test_macros.h
if ENABLE_DEBUG
else
-DNDEBUG
endif
-check_PROGRAMS = bencode.tests block.tests file.tests fs.concat.tests fs.filter.tests hash.tests hashmap.tests meta.tests rss.tests torrent.tests tree.tests
+check_PROGRAMS = bencode.tests block.tests feed.tests file.tests fs.concat.tests fs.filter.tests hash.tests hashmap.tests meta.tests rss.tests torrent.tests tree.tests
TESTS = $(check_PROGRAMS)
if ENABLE_MEMCHECK
endif
common_SOURCES = \
- test_utils.c \
- $(top_srcdir)/src/hash.c
+ test_utils.c
+
+torrent_SOURCES = \
+ $(top_srcdir)/src/bencode/encode.c \
+ $(top_srcdir)/src/block.c \
+ $(top_srcdir)/src/file.c \
+ $(top_srcdir)/src/hashmap.c \
+ $(top_srcdir)/src/torrent/add.c \
+ $(top_srcdir)/src/torrent/free.c \
+ $(top_srcdir)/src/torrent/init.c \
+ $(top_srcdir)/src/tree.c
bencode_tests_SOURCES = \
$(common_SOURCES) \
block_tests_SOURCES = \
$(common_SOURCES) \
block.tests.c \
- $(top_srcdir)/src/block.c
+ $(top_srcdir)/src/block.c \
+ $(top_srcdir)/src/hash.c
+
+feed_tests_SOURCES = \
+ $(common_SOURCES) \
+ $(torrent_SOURCES) \
+ feed.tests.c \
+ $(top_srcdir)/src/feed/entries.c \
+ $(top_srcdir)/src/feed/info.c \
+ $(top_srcdir)/src/fs/concat.c \
+ $(top_srcdir)/src/fs/dir.c \
+ $(top_srcdir)/src/hash.c \
+ $(top_srcdir)/src/meta.c \
+ $(top_srcdir)/src/rss/entry.c \
+ $(top_srcdir)/src/rss/free.c \
+ $(top_srcdir)/src/rss/info.c \
+ $(top_srcdir)/src/rss/init.c
file_tests_SOURCES = \
$(common_SOURCES) \
file.tests.c \
$(top_srcdir)/src/bencode/encode.c \
$(top_srcdir)/src/block.c \
- $(top_srcdir)/src/file.c
+ $(top_srcdir)/src/file.c \
+ $(top_srcdir)/src/hash.c
fs_concat_tests_SOURCES = \
$(common_SOURCES) \
hash_tests_SOURCES = \
$(common_SOURCES) \
- hash.tests.c
+ hash.tests.c \
+ $(top_srcdir)/src/hash.c
hashmap_tests_SOURCES = \
$(common_SOURCES) \
rss_tests_SOURCES = \
$(common_SOURCES) \
rss.tests.c \
+ $(top_srcdir)/src/hash.c \
$(top_srcdir)/src/rss/entry.c \
$(top_srcdir)/src/rss/footer.c \
$(top_srcdir)/src/rss/free.c \
torrent_tests_SOURCES = \
$(common_SOURCES) \
+ $(torrent_SOURCES) \
torrent.tests.c \
- $(top_srcdir)/src/bencode/encode.c \
- $(top_srcdir)/src/block.c \
- $(top_srcdir)/src/file.c \
$(top_srcdir)/src/fs/concat.c \
$(top_srcdir)/src/fs/dir.c \
- $(top_srcdir)/src/hashmap.c \
- $(top_srcdir)/src/torrent/add.c \
+ $(top_srcdir)/src/hash.c \
$(top_srcdir)/src/torrent/file.c \
- $(top_srcdir)/src/torrent/free.c \
- $(top_srcdir)/src/torrent/init.c \
$(top_srcdir)/src/torrent/magnet.c \
$(top_srcdir)/src/torrent/path.c \
- $(top_srcdir)/src/torrent/piece.c \
- $(top_srcdir)/src/tree.c
+ $(top_srcdir)/src/torrent/piece.c
torrent_tests_CPPFLAGS = $(AM_CPPFLAGS) \
-DTORRENT_INFO_SRC_FILE="$(top_srcdir)/src/torrent/info.c"
$(top_srcdir)/src/bencode/encode.c \
$(top_srcdir)/src/block.c \
$(top_srcdir)/src/file.c \
+ $(top_srcdir)/src/hash.c \
$(top_srcdir)/src/tree.c
--- /dev/null
+#include<test_utils.h>
+
+#include<feed.h>
+
+int main();
+static void feed_info_basic_test();
+static void feed_entries_basic_test();
+static FILE *setup_file_pointer();
+
+int main() {
+ setup_env();
+
+ feed_info_basic_test();
+ feed_entries_basic_test();
+
+ clean_env();
+
+ return EXIT_SUCCESS;
+}
+
+static void feed_entries_basic_test() {
+ FILE *fp;
+ struct torrent *p;
+ unsigned char hash[crypto_hash_sha256_BYTES];
+ unsigned char expected[crypto_hash_sha256_BYTES] = {185,160,108,238,240,237,217,219,97,190,118,39,179,198,241,61,191,24,149,75,124,56,189,148,163,13,185,110,30,115,222,186};
+
+ fp = setup_file_pointer();
+
+ TORRENT_SETUP_EXAMPLE(&p);
+
+ assert(-1==feed_entries(NULL,NULL));
+ assert(-1==feed_entries(fp,NULL));
+
+ assert(1==feed_entries(fp,p));
+
+ torrent_free(p);
+
+ fclose(fp);
+
+ HASH_FILE(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
+ assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
+
+ reset_env();
+}
+
+static void feed_info_basic_test() {
+ FILE *fp;
+ struct torrent *p;
+ unsigned char hash[crypto_hash_sha256_BYTES];
+ unsigned char expected[crypto_hash_sha256_BYTES] = {185,160,108,238,240,237,217,219,97,190,118,39,179,198,241,61,191,24,149,75,124,56,189,148,163,13,185,110,30,115,222,186};
+
+ fp = setup_file_pointer();
+
+ assert(feed_info(NULL,NULL)==-1);
+ assert(feed_info(fp,NULL)==-1);
+
+ assert(1==torrent_init(&p,TEST_DIRECTORY,TEST_DIRECTORY,16384));
+
+ assert(1==feed_info(fp,p));
+
+ torrent_free(p);
+
+ fclose(fp);
+
+ HASH_FILE(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
+ assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
+
+ reset_env();
+}
+
+static FILE *setup_file_pointer() {
+ FILE *fp;
+
+ fp = fopen(TEST_FILE_7,"w");
+ assert(fp!=NULL);
+
+ return fp;
+}
#include<test_utils.h>
+#include<meta.h>
+
char *strptime(const char *s, const char *format, struct tm *tm) {
return (char*)s;
}
fclose(fp);
- hash_file(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
+ HASH_FILE(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
rss_entry_free(p);
fclose(fp);
- hash_file(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
+ HASH_FILE(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
reset_env();
fclose(fp);
- hash_file(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
+ HASH_FILE(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
reset_env();
fclose(fp);
- hash_file(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
+ HASH_FILE(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
rss_channel_info_free(p);
--- /dev/null
+#ifndef __TEST_MACROS_H_
+#define __TEST_MACROS_H_
+
+/* Parameters:
+ * const char *path
+ * unsigned char *hash
+ * size_t hash_len
+ */
+#define HASH_FILE(path,hash,hash_len) { \
+ uint8_t buf[16384]; \
+ crypto_hash_sha256_state st; \
+ FILE *fp; \
+ size_t i; \
+\
+ assert(hash_len==crypto_hash_sha256_BYTES); \
+\
+ fp = fopen(path,"r"); \
+ assert(fp!=NULL); \
+\
+ assert(1==hash_init(&st)); \
+\
+ while(feof(fp)==0) { \
+ i = fread(buf,sizeof(uint8_t),16384,fp); \
+ if(i>0) { \
+ assert(1==hash_update(&st,buf,i)); \
+ } \
+ } \
+\
+ assert(0==fclose(fp)); \
+\
+ assert(hash_final(&st,hash,crypto_hash_sha256_BYTES)==1);\
+}
+
+/* Parameters:
+ * struct file *file_p
+ * const char *filename
+ * int root_val
+ */
+#define TORRENT_SETUP_EXAMPLE_FILE(file_p,filename,root_val) { \
+ struct block *block, *p; \
+\
+ assert(file_init(file_p,filename)==1); \
+ memset((*file_p)->root,root_val,crypto_hash_sha256_BYTES); \
+ for(size_t i=0;i<10;i++) { \
+ assert(block_init(&block)==1); \
+ memset(block->hash,i,crypto_hash_sha256_BYTES); \
+\
+ if((*file_p)->piece_layers==NULL) { \
+ (*file_p)->piece_layers = block; \
+ } else { \
+ p->next = block; \
+ } \
+ p = block; \
+ } \
+}
+
+/* Parameters:
+ * struct torrent **p
+ */
+#define TORRENT_SETUP_EXAMPLE(p) { \
+ struct file *file1, *file2; \
+\
+ TORRENT_SETUP_EXAMPLE_FILE(&file1,TEST_FILE_1,1); \
+ TORRENT_SETUP_EXAMPLE_FILE(&file2,TEST_FILE_2,2); \
+\
+ assert(torrent_init(p,TEST_DIRECTORY,TEST_DIRECTORY,16384)==1); \
+\
+ assert(torrent_add(*p,file1)==1); \
+ assert(torrent_add(*p,file2)==1); \
+}
+
+#endif
assert(strlen(contents)==fwrite(contents,sizeof(char),strlen(contents),fp));
assert(fclose(fp)==0);
}
-
-void hash_file(const char *filepath, unsigned char *hash, size_t hash_len) {
- uint8_t buf[16384];
- crypto_hash_sha256_state st;
- FILE *fp;
- size_t i;
-
- assert(hash_len==crypto_hash_sha256_BYTES);
-
- fp = fopen(filepath,"r");
- assert(fp!=NULL);
-
- assert(1==hash_init(&st));
-
- while(feof(fp)==0) {
- i = fread(buf,sizeof(uint8_t),16384,fp);
- if(i>0) {
- assert(1==hash_update(&st,buf,i));
- }
- }
-
- assert(0==fclose(fp));
-
- assert(hash_final(&st,hash,crypto_hash_sha256_BYTES)==1);
-}
#ifndef __TEST_UTILS_H_
#define __TEST_UTILS_H_
+#include<test_macros.h>
+
#include<assert.h>
#include<stdlib.h>
#include<string.h>
void clean_env();
void reset_env();
void setup_env();
-void hash_file(const char*,unsigned char*,size_t);
#endif
static void torrent_file_piece_layers_basic_test();
static void torrent_init_basic_test();
static void torrent_magnet_basic_test();
-static void torrent_setup_example(struct torrent**);
-static void torrent_setup_example_file(struct file**,const char*,uint8_t);
int main() {
setup_env();
static void torrent_file_basic_test() {
struct torrent *torrent;
- torrent_setup_example(&torrent);
+ TORRENT_SETUP_EXAMPLE(&torrent);
assert(1==torrent_file(torrent));
struct torrent *torrent;
uint8_t *buf;
- torrent_setup_example(&torrent);
+ TORRENT_SETUP_EXAMPLE(&torrent);
assert(-1==torrent_file_info(NULL,NULL));
assert(-1==torrent_file_info(torrent,NULL));
assert(i==32);
sprintf(path,"%s/torrents/%s.torrent",TEST_DIRECTORY,infohash_expected);
- hash_file(path,out,crypto_hash_sha256_BYTES);
+ HASH_FILE(path,out,crypto_hash_sha256_BYTES);
assert(memcmp(out,expected,crypto_hash_sha256_BYTES)==0);
fp = fopen(TEST_FILE_6,"w");
assert(fp!=NULL);
- torrent_setup_example(&torrent);
+ TORRENT_SETUP_EXAMPLE(&torrent);
assert(torrent_file_piece_layers(fp,torrent)==1);
assert(0==fclose(fp));
- hash_file(TEST_FILE_6,hash,crypto_hash_sha256_BYTES);
+ HASH_FILE(TEST_FILE_6,hash,crypto_hash_sha256_BYTES);
assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
char *p;
char expected[] = "magnet:?xt=urn:btmh:59b2020fe4275cac5c3b8ac32bdc79010c95cf0bac2fd91ced8dd071f8ef91ca&dn=" TEST_DIRECTORY;
- torrent_setup_example(&torrent);
+ TORRENT_SETUP_EXAMPLE(&torrent);
p = torrent_magnet(torrent);
assert(p!=NULL);
reset_env();
}
-
-static void torrent_setup_example_file(struct file **file_p, const char *filename, uint8_t root_val) {
- struct block *block, *p;
-
- assert(file_init(file_p,filename)==1);
- memset((*file_p)->root,root_val,crypto_hash_sha256_BYTES);
- for(size_t i=0;i<10;i++) {
- assert(block_init(&block)==1);
- memset(block->hash,i,crypto_hash_sha256_BYTES);
-
- if((*file_p)->piece_layers==NULL) {
- (*file_p)->piece_layers = block;
- } else {
- p->next = block;
- }
-
- p = block;
- }
-}
-
-static void torrent_setup_example(struct torrent **p) {
- struct file *file1, *file2;
-
- torrent_setup_example_file(&file1,TEST_FILE_1,1);
- torrent_setup_example_file(&file2,TEST_FILE_2,2);
-
- assert(torrent_init(p,TEST_DIRECTORY,TEST_DIRECTORY,16384)==1);
-
- assert(torrent_add(*p,file1)==1);
- assert(torrent_add(*p,file2)==1);
-}