From: alex Date: Fri, 3 Dec 2021 00:01:45 +0000 (-0800) Subject: ... X-Git-Url: http://git.infiniteadaptability.org/?a=commitdiff_plain;h=8aa08b286a71a42f49cba26ca6f8079b38e13b14;p=seeder ... --- diff --git a/inc/torrent.h b/inc/torrent.h index 65e354c..f67ed38 100644 --- a/inc/torrent.h +++ b/inc/torrent.h @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -14,8 +15,12 @@ struct torrent { char *root; char *name; + + unsigned long long piece_length; + struct tree *tree; struct hash_map *files; + int watch_fd; }; @@ -23,7 +28,7 @@ int torrent_add(struct torrent*,struct file*); int torrent_file(struct torrent*); ssize_t torrent_file_info(struct torrent*,uint8_t**); void torrent_free(struct torrent*); -int torrent_init(struct torrent**,const char*,const char*); +int torrent_init(struct torrent**,const char*,const char*,unsigned long long); char *torrent_magnet(struct torrent*); #endif diff --git a/src/opt/watch.c b/src/opt/watch.c index b057f65..e4842b1 100644 --- a/src/opt/watch.c +++ b/src/opt/watch.c @@ -12,7 +12,7 @@ int opt_add_watch(const char *directory) { name = strdup(directory); name = basename(name); - if(torrent_init(&p,directory,name)<0) { return -1; } + if(torrent_init(&p,directory,name,global_options.piece_length)<0) { return -1; } if(session_torrent_add(p)<0) { return -1; } log_msg(OPT_MESSAGE_WATCH_ADD_SUCCESS,p->root,p->name); diff --git a/src/torrent.c b/src/torrent.c index 3c452a9..e23aa1f 100644 --- a/src/torrent.c +++ b/src/torrent.c @@ -128,7 +128,7 @@ ssize_t torrent_file_info(struct torrent *torrent_p, uint8_t **buf) { uint8_t piece_length_string[] = "piece length"; if((i = bencode_string(piece_length_string,sizeof(piece_length_string),&(p[len]),buf_len-len))<0) { goto clean; } len += i; - if((i = bencode_int(global_options.piece_length,&(p[len]),buf_len-len))<0) { goto clean; } + if((i = bencode_int(torrent_p->piece_length,&(p[len]),buf_len-len))<0) { goto clean; } len += i; *buf = malloc(len); @@ -143,6 +143,7 @@ clean: return -1; } +#define TORRENT_FILE_DIRECTORY "/torrents" #define TORRENT_FILE_EXTENSION ".torrent" static char *torrent_file_path(unsigned char *infohash, size_t len) { @@ -154,7 +155,7 @@ static char *torrent_file_path(unsigned char *infohash, size_t len) { // this always returns hex, unnecessary to return sodium_bin2hex(hex,(crypto_hash_sha256_BYTES<<1)+1,infohash,crypto_hash_sha256_BYTES); - p = concat(PREFIX,hex); + p = concat(PREFIX TORRENT_FILE_DIRECTORY,hex); if(NULL==p) { return NULL; } path = malloc(strlen(p)+strlen(".torrent")+1); @@ -244,11 +245,13 @@ void torrent_free(struct torrent *p) { #define TORRENT_FILES_HASHMAP_INITIAL_SIZE 8 -int torrent_init(struct torrent **torrent_p, const char *root, const char *name) { +int torrent_init(struct torrent **torrent_p, const char *root, const char *name, unsigned long long piece_length) { if(NULL==torrent_p) { return -1; } if(NULL==root) { return -1; } if(NULL==name) { return -1; } + if((piece_length<16384)||(!(piece_length&&!(piece_length&(piece_length-1))))) { return -1; } + *(torrent_p) = malloc(sizeof(struct torrent)); if(NULL==(*torrent_p)) { perror("malloc"); @@ -261,6 +264,8 @@ int torrent_init(struct torrent **torrent_p, const char *root, const char *name) (*torrent_p)->name = strdup(name); if(NULL==(*torrent_p)->name) { goto clean; } + (*torrent_p)->piece_length = piece_length; + if(tree_init(&((*torrent_p)->tree))<0) { goto clean; } if(hashmap_init(&((*torrent_p)->files),TORRENT_FILES_HASHMAP_INITIAL_SIZE)<0) { goto clean; } diff --git a/src/tree.c b/src/tree.c index 4f2065a..23bcaac 100644 --- a/src/tree.c +++ b/src/tree.c @@ -146,7 +146,7 @@ int tree_entry_init(struct tree_entry **p, struct file *file) { (*p)->name = strdup(file->name); if(NULL==(*p)->name) { - free(p); + free(*p); return -1; } @@ -158,6 +158,24 @@ int tree_entry_init(struct tree_entry **p, struct file *file) { }; static int tree_entry_init_directory(struct tree_entry **p, const char *dirname) { + if(NULL==p) { return -1; } + if((NULL==dirname)||(0==strlen(dirname))) { return -1; } + + (*p) = malloc(sizeof(struct tree_entry)); + if(NULL==(*p)) { return -1; } + + (*p)->name = NULL; + (*p)->file = NULL; + (*p)->next = NULL; + + (*p)->name = strdup(dirname); + if(NULL==(*p)->name) { goto clean; } + + if(tree_init(&((*p)->children))<0) { goto clean; } + + return 1; +clean: + if((*p)->name!=NULL) { free((*p)->name); } return -1; } diff --git a/test/unit/Makefile.am b/test/unit/Makefile.am index 7fbe09a..17e239c 100644 --- a/test/unit/Makefile.am +++ b/test/unit/Makefile.am @@ -64,8 +64,10 @@ hashmap_tests_SOURCES = \ torrent_tests_SOURCES = \ $(common_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/hash.c \ $(top_srcdir)/src/hashmap.c \ $(top_srcdir)/src/torrent.c \ diff --git a/test/unit/torrent.tests.c b/test/unit/torrent.tests.c index a81cfec..38389c7 100644 --- a/test/unit/torrent.tests.c +++ b/test/unit/torrent.tests.c @@ -26,18 +26,17 @@ static void torrent_add_basic_test() { assert(file_init(&file3,TEST_FILE_3)==1); assert(file_init(&file4,TEST_FILE_4)==1); - assert(torrent_init(&torrent,TEST_DIRECTORY,TEST_DIRECTORY)==1); + assert(torrent_init(&torrent,TEST_DIRECTORY,TEST_DIRECTORY,16384)==1); assert(torrent_add(torrent,file1)==1); assert(torrent_add(torrent,file2)==1); assert(torrent_add(torrent,file3)==1); assert(torrent_add(torrent,file4)==1); - assert(NULL==torrent->tree->directories); - assert(torrent->tree->files->file==file3); - assert(torrent->tree->files->next->file==file4); - assert(torrent->tree->files->next->next->file==file1); - assert(torrent->tree->files->next->next->next->file==file2); + assert(torrent->tree->entries->file==file3); + assert(torrent->tree->entries->next->file==file4); + assert(torrent->tree->entries->next->next->file==file1); + assert(torrent->tree->entries->next->next->next->file==file2); torrent_free(torrent); @@ -47,9 +46,10 @@ static void torrent_add_basic_test() { static void torrent_init_basic_test() { struct torrent *torrent; - assert(torrent_init(&torrent,NULL,NULL)<0); - assert(torrent_init(&torrent,"src",NULL)<0); + assert(torrent_init(&torrent,NULL,NULL,0)<0); + assert(torrent_init(&torrent,"src",NULL,0)<0); + assert(torrent_init(&torrent,"src","src",1000)<0); - assert(torrent_init(&torrent,"src","src")==1); + assert(torrent_init(&torrent,"src","src",16384)==1); torrent_free(torrent); } diff --git a/test/unit/tree.tests.c b/test/unit/tree.tests.c index 9346c42..6034844 100644 --- a/test/unit/tree.tests.c +++ b/test/unit/tree.tests.c @@ -4,7 +4,8 @@ int main(); static char *create_random_path(); -static int tree_deep_equals(struct tree *a, struct tree *b); +static int tree_deep_equals(struct tree*,struct tree*); +static int tree_entry_equals(struct tree_entry*,struct tree_entry*); static void tree_add_basic_test(); static void tree_add_extended_test(); static void tree_bencode_basic_test(); @@ -24,29 +25,17 @@ int main() { } static void tree_add_basic_test() { - struct tree *tree, *root, *test, *test2, *hello, *nope, *helloo; - struct tree_entry *entry1, *entry2, *entry3, *entry4; + struct tree *tree; + struct tree_entry *p; struct file *file1, *file2, *file3, *file4; - assert(1==tree_init(&tree,NULL)); - - assert(1==tree_init(&root,NULL)); - assert(1==tree_init(&test,"test")); - assert(1==tree_init(&test2,"test2")); - assert(1==tree_init(&hello,"hello")); - assert(1==tree_init(&nope,"nope")); - assert(1==tree_init(&helloo,"helloo")); + assert(1==tree_init(&tree)); assert(1==file_init(&file1,"test/file1")); assert(1==file_init(&file2,"test/hello/file2")); assert(1==file_init(&file3,"test2/nope/helloo/file3")); assert(1==file_init(&file4,"test/file4")); - assert(1==tree_entry_init(&entry1,file1)); - assert(1==tree_entry_init(&entry2,file2)); - assert(1==tree_entry_init(&entry3,file3)); - assert(1==tree_entry_init(&entry4,file4)); - /* * Tree: * test(d) @@ -60,16 +49,6 @@ static void tree_add_basic_test() { * file3(f) */ - root->directories = test; - test->next = test2; - test->files = entry1; - entry1->next = entry4; - test->directories = hello; - hello->files = entry2; - test2->directories = nope; - nope->directories = helloo; - helloo->files = entry3; - assert(-1==tree_add(NULL,NULL,NULL)); assert(-1==tree_add(tree,NULL,NULL)); assert(-1==tree_add(tree,"test path",NULL)); @@ -80,51 +59,105 @@ static void tree_add_basic_test() { assert(1==tree_add(tree,file3->path,file3)); assert(1==tree_add(tree,file4->path,file4)); - assert(NULL==tree->name); - assert(NULL==tree->files); - - assert(tree_deep_equals(tree,root)==1); - assert(tree_deep_equals(tree->directories,test)==1); - assert(tree_deep_equals(tree->directories->next,test2)==1); - assert(tree_deep_equals(tree->directories->directories,hello)==1); - assert(tree_deep_equals(tree->directories->next->directories,nope)==1); - assert(tree_deep_equals(tree->directories->next->directories->directories,helloo)==1); + // test/ + p = tree->entries; + assert(strcmp(p->name,"test")==0); + assert(p->children!=NULL); + assert(p->file==NULL); + assert(p->next!=NULL); + + // test/file1 + p = tree->entries->children->entries; + assert(strcmp(p->name,"file1")==0); + assert(p->children==NULL); + assert(p->file==file1); + assert(p->next!=NULL); + + // test/file4 + p = tree->entries->children->entries->next; + assert(strcmp(p->name,"file4")==0); + assert(p->children==NULL); + assert(p->file==file4); + assert(p->next!=NULL); + + // test/hello/ + p = tree->entries->children->entries->next->next; + assert(strcmp(p->name,"hello")==0); + assert(p->children!=NULL); + assert(p->file==NULL); + assert(p->next==NULL); + + // test/hello/file2 + p = tree->entries->children->entries->next->next->children->entries; + assert(strcmp(p->name,"file2")==0); + assert(p->children==NULL); + assert(p->file==file2); + assert(p->next==NULL); + + // test2/ + p = tree->entries->next; + assert(strcmp(p->name,"test2")==0); + assert(p->children!=NULL); + assert(p->file==NULL); + assert(p->next==NULL); + + // test2/nope/ + p = tree->entries->next->children->entries; + assert(strcmp(p->name,"nope")==0); + assert(p->children!=NULL); + assert(p->file==NULL); + assert(p->next==NULL); + + // test2/nope/helloo/ + p = tree->entries->next->children->entries->children->entries; + assert(strcmp(p->name,"helloo")==0); + assert(p->children!=NULL); + assert(p->file==NULL); + assert(p->next==NULL); + + // test2/nope/helloo/file3 + p = tree->entries->next->children->entries->children->entries->children->entries; + assert(strcmp(p->name,"file3")==0); + assert(p->children==NULL); + assert(p->file==file3); + assert(p->next==NULL); tree_free(tree); - - // remove pointers to already free'd entries - entry1->file = NULL; - entry2->file = NULL; - entry3->file = NULL; - entry4->file = NULL; - - tree_free(root); } static int tree_deep_equals(struct tree *a, struct tree *b) { if(a==NULL&&b==NULL) { return 1; } if((a!=NULL&&b==NULL)||(a==NULL&&b!=NULL)) { return -1; } - if((a->name!=NULL&&b->name==NULL)||(a->name==NULL&&b->name!=NULL)) { return -1; } - if(a->name!=NULL) { - if(strcmp(a->name,b->name)!=0) { return -1; } - } { struct tree_entry *p1, *p2; - p1 = a->files; - p2 = b->files; + p1 = a->entries; + p2 = b->entries; while(p1!=NULL) { if(p2==NULL) { return -1; } - if(strcmp(p1->file->name,p2->file->name)!=0) { return -1; } - if(strcmp(p1->file->path,p2->file->path)!=0) { return -1; } + if(tree_entry_equals(p1,p2)<0) { return -1; } p1 = p1->next; p2 = p2->next; } } - if(tree_deep_equals(a->directories,b->directories)<0) { return -1; } - if(tree_deep_equals(a->next,b->next)<0) { return -1; } + return 1; +} + +static int tree_entry_equals(struct tree_entry *a, struct tree_entry *b) { + if((a->name!=NULL&&b->name==NULL)||(a->name==NULL&&b->name!=NULL)) { return -1; } + if(a->name!=NULL) { + if(strcmp(a->name,b->name)!=0) { return -1; } + } + + if(tree_deep_equals(a->children,b->children)<0) { return -1; } + + if((a->file!=NULL&&b->file==NULL)||(a->file==NULL&&b->file!=NULL)) { return -1; } + if(a->file!=NULL) { + if(strcmp(a->file->name,b->file->name)!=0) { return -1; } + if(strcmp(a->file->path,b->file->path)!=0) { return -1; } + } return 1; } @@ -158,7 +191,7 @@ static void tree_add_extended_test() { struct tree *tree; struct file *file; - assert(1==tree_init(&tree,NULL)); + assert(1==tree_init(&tree)); for(int i=0;i<100;i++) { char *path = create_random_path(); @@ -177,7 +210,7 @@ static void tree_bencode_basic_test() { char fileA_path[] = "dir1/dir2/fileA.txt"; uint8_t expected[] = "d4:dir1d4:dir2d9:fileA.txtd0:d5:lengthi102411:pieces root32:00000000000000000000000000000000eeeee"; - assert(1==tree_init(&root,NULL)); + assert(1==tree_init(&root)); assert(1==file_init(&file,fileA_path)); memset(file->root,48,crypto_hash_sha256_BYTES); @@ -190,24 +223,11 @@ static void tree_bencode_basic_test() { static void tree_init_basic_test() { struct tree *p; - char str[] = "this is a test string"; - - assert(-1==tree_init(NULL,NULL)); - assert(1==tree_init(&p,NULL)); - - assert(NULL==p->name); - assert(NULL==p->files); - assert(NULL==p->directories); - assert(NULL==p->next); + assert(-1==tree_init(NULL)); + assert(1==tree_init(&p)); - tree_free(p); - - assert(1==tree_init(&p,str)); + assert(NULL==p->entries); + assert(-1==p->watch_fd); - assert(strcmp(p->name,str)==0); - assert(NULL==p->files); - assert(NULL==p->directories); - assert(NULL==p->next); - tree_free(p); }