From bd2cfb685a9124ab2a3aea09e88db6a448d6f9d1 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 27 Dec 2021 00:28:55 -0800 Subject: [PATCH] ... --- Makefile.am | 1 + inc/torrent.h | 4 +-- src/torrent/file.c | 56 ++++++++++++--------------------------- src/torrent/path.c | 39 +++++++++++++++++++++++++++ src/torrent/piece.c | 10 ++++--- test/unit/Makefile.am | 2 ++ test/unit/test_utils.c | 1 + test/unit/torrent.tests.c | 23 +++++++++------- 8 files changed, 83 insertions(+), 53 deletions(-) create mode 100644 src/torrent/path.c diff --git a/Makefile.am b/Makefile.am index 746c99b..0972588 100644 --- a/Makefile.am +++ b/Makefile.am @@ -46,6 +46,7 @@ seederd_SOURCES = \ src/torrent/info.c \ src/torrent/init.c \ src/torrent/magnet.c \ + src/torrent/path.c \ src/torrent/piece.c \ src/tree.c \ src/usage.c \ diff --git a/inc/torrent.h b/inc/torrent.h index 939e038..baefb8b 100644 --- a/inc/torrent.h +++ b/inc/torrent.h @@ -30,9 +30,9 @@ struct torrent { }; int torrent_add(struct torrent*,struct file*); -int torrent_file(struct torrent*); +int torrent_file(const char*,struct torrent*); ssize_t torrent_file_info(struct torrent*,uint8_t**); -char *torrent_file_path(unsigned char*,size_t); +char *torrent_file_path(const char*,unsigned char*,size_t); int torrent_file_piece_layers(FILE*,struct torrent*); void torrent_free(struct torrent*); int torrent_init(struct torrent**,const char*,const char*,unsigned long long); diff --git a/src/torrent/file.c b/src/torrent/file.c index dc1e0a7..8f43684 100644 --- a/src/torrent/file.c +++ b/src/torrent/file.c @@ -6,7 +6,7 @@ static int torrent_file_write_info(FILE*,uint8_t*,size_t); static int torrent_file_write_piece_layers(FILE*,struct torrent*); static int torrent_file_write_start(FILE*); -int torrent_file(struct torrent *torrent_p) { +int torrent_file(const char *datadir, struct torrent *torrent_p) { uint8_t *info; FILE *fp; unsigned char infohash[crypto_hash_sha256_BYTES]; @@ -17,11 +17,14 @@ int torrent_file(struct torrent *torrent_p) { fp = NULL; path = NULL; + if(NULL==datadir) { goto clean; } + if(is_directory(datadir)<0) { goto clean; } + if((i = torrent_file_info(torrent_p,&info))<0) { goto clean; } if(hash(info,i,infohash,crypto_hash_sha256_BYTES)<0) { goto clean; } - path = torrent_file_path(infohash,crypto_hash_sha256_BYTES); + path = torrent_file_path(datadir,infohash,crypto_hash_sha256_BYTES); if(NULL==path) { goto clean; } fp = fopen(path,"w"); @@ -35,9 +38,12 @@ int torrent_file(struct torrent *torrent_p) { info = NULL; if(torrent_file_write_piece_layers(fp,torrent_p)<0) { goto clean; } + if(torrent_file_write_end(fp)<0) { goto clean; } fclose(fp); + + // must be done last because of remove() in cleanup free(path); return 1; @@ -49,53 +55,23 @@ clean: return -1; } +#define ANNOUNCE_SAMPLE_SIZE 50 + static int torrent_file_announce(FILE *fp, struct torrent *p) { - uint8_t buf[28]; + uint8_t buf[ANNOUNCE_SAMPLE_SIZE]; ssize_t i; uint8_t announce_string[] = "announce"; - if((i = bencode_string(announce_string,sizeof(announce_string),buf,28))<0) { return -1; } + if((i = bencode_string(announce_string,sizeof(announce_string)-1,buf,ANNOUNCE_SAMPLE_SIZE))<0) { return -1; } if(i!=fwrite(buf,sizeof(uint8_t),i,fp)) { return -1; } uint8_t announce_sample_string[] = "http://example.com/announce"; - if((i = bencode_string(announce_sample_string,sizeof(announce_sample_string),buf,28))<0) { return -1; } + if((i = bencode_string(announce_sample_string,sizeof(announce_sample_string)-1,buf,ANNOUNCE_SAMPLE_SIZE))<0) { return -1; } if(i!=fwrite(buf,sizeof(uint8_t),i,fp)) { return -1; } return 1; } -#define TORRENT_FILE_DIRECTORY "/torrents" -#define TORRENT_FILE_EXTENSION ".torrent" - -char *torrent_file_path(unsigned char *infohash, size_t len) { - char *path, *p; - char hex[(crypto_hash_sha256_BYTES<<1)+1]; - - if(len!=crypto_hash_sha256_BYTES) { return NULL; } - - // this always returns hex, unnecessary to return - sodium_bin2hex(hex,(crypto_hash_sha256_BYTES<<1)+1,infohash,crypto_hash_sha256_BYTES); - - p = concat(TORRENT_FILE_DIRECTORY,hex); - if(NULL==p) { return NULL; } - - path = malloc(strlen(p)+strlen(".torrent")+1); - if(NULL==path) { - free(p); - return NULL; - } - - if(sprintf(path,"%s" TORRENT_FILE_EXTENSION,p)<0) { - free(p); - free(path); - return NULL; - } - - free(p); - - return path; -} - static int torrent_file_write_end(FILE *fp) { uint8_t c; ssize_t i; @@ -111,7 +87,7 @@ static int torrent_file_write_info(FILE *fp, uint8_t *info, size_t info_len) { uint8_t buf[6]; ssize_t i; - if((i = bencode_string(info_string,sizeof(info_string),buf,6))<0) { return -1; } + if((i = bencode_string(info_string,sizeof(info_string)-1,buf,6))<0) { return -1; } if(i!=fwrite(buf,sizeof(uint8_t),i,fp)) { return -1; } if(info_len!=fwrite(info,sizeof(uint8_t),info_len,fp)) { return -1; } @@ -124,10 +100,12 @@ static int torrent_file_write_piece_layers(FILE *fp, struct torrent *p) { uint8_t buf[15]; ssize_t i; - if((i = bencode_string(piece_layers_string,sizeof(piece_layers_string),buf,15))<0) { return -1; } + if((i = bencode_string(piece_layers_string,sizeof(piece_layers_string)-1,buf,15))<0) { return -1; } if(i!=fwrite(buf,sizeof(uint8_t),i,fp)) { return -1; } + if(torrent_file_write_start(fp)<0) { return -1; } if(torrent_file_piece_layers(fp,p)<0) { return -1; } + if(torrent_file_write_end(fp)<0) { return -1; } return 1; } diff --git a/src/torrent/path.c b/src/torrent/path.c new file mode 100644 index 0000000..eb50ba7 --- /dev/null +++ b/src/torrent/path.c @@ -0,0 +1,39 @@ +#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]; + + if(len!=crypto_hash_sha256_BYTES) { return NULL; } + + // this always returns hex, unnecessary to return + sodium_bin2hex(hex,(crypto_hash_sha256_BYTES<<1)+1,infohash,crypto_hash_sha256_BYTES); + + path = concat(prefix,TORRENT_FILE_DIRECTORY); + if(NULL==path) { return NULL; } + + p = concat(path,hex); + free(path); + if(NULL==p) { return NULL; } + + path = malloc(strlen(p)+strlen(".torrent")+1); + if(NULL==path) { + free(p); + return NULL; + } + + if(sprintf(path,"%s" TORRENT_FILE_EXTENSION,p)<0) { + free(p); + free(path); + return NULL; + } + + free(p); + + return path; +} + + diff --git a/src/torrent/piece.c b/src/torrent/piece.c index c8795f1..d788e1a 100644 --- a/src/torrent/piece.c +++ b/src/torrent/piece.c @@ -37,7 +37,9 @@ int torrent_file_piece_layers(FILE *fp, struct torrent *p) { pieces = 0; for(size_t i=0;ifiles.roots->size;i++) { file_p = (struct file*)p->files.roots->map[i]; - if(file_p!=NULL) { pieces++; } + if(file_p!=NULL) { + if(file_p->size>p->piece_length) { pieces++; } + } } hashes = malloc(sizeof(const unsigned char*)*pieces); @@ -47,8 +49,10 @@ int torrent_file_piece_layers(FILE *fp, struct torrent *p) { for(size_t i=0;ifiles.roots->size;i++) { file_p = (struct file*)p->files.roots->map[i]; if(file_p!=NULL) { - hashes[index] = file_p->root; - index++; + if(file_p->size>p->piece_length) { + hashes[index] = file_p->root; + index++; + } } } diff --git a/test/unit/Makefile.am b/test/unit/Makefile.am index 82ec0ae..be1b150 100644 --- a/test/unit/Makefile.am +++ b/test/unit/Makefile.am @@ -69,6 +69,7 @@ torrent_tests_SOURCES = \ $(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/hash.c \ $(top_srcdir)/src/hashmap.c \ $(top_srcdir)/src/torrent/add.c \ @@ -77,6 +78,7 @@ torrent_tests_SOURCES = \ $(top_srcdir)/src/torrent/info.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 diff --git a/test/unit/test_utils.c b/test/unit/test_utils.c index a79c9d1..4ae2891 100644 --- a/test/unit/test_utils.c +++ b/test/unit/test_utils.c @@ -18,6 +18,7 @@ void setup_env() { srand(time(NULL)); create_test_directory(TEST_DIRECTORY); + 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); create_test_file(TEST_FILE_3,TEST_FILE_3_CONTENTS); diff --git a/test/unit/torrent.tests.c b/test/unit/torrent.tests.c index 7b688f2..9e0739e 100644 --- a/test/unit/torrent.tests.c +++ b/test/unit/torrent.tests.c @@ -83,7 +83,13 @@ static void torrent_add_basic_test() { } static void torrent_file_basic_test() { - assert(1); + struct torrent *torrent; + + torrent_setup_example(&torrent); + + assert(1==torrent_file(TEST_DIRECTORY,torrent)); + + torrent_free(torrent); } static void torrent_file_info_basic_test() { @@ -145,7 +151,7 @@ static void torrent_file_info_conformance_test() { assert(memcmp(out,expected,crypto_hash_sha256_BYTES)==0); - assert(torrent_file(torrent_p)==1); + assert(torrent_file(TEST_DIRECTORY,torrent_p)==1); assert(sodium_hex2bin(expected,crypto_hash_sha256_BYTES,torrent_file_hash_expected,strlen(torrent_file_hash_expected),NULL,&i,NULL)==0); assert(i==32); @@ -163,19 +169,18 @@ static void torrent_file_path_basic_test() { char *p; memset(infohash,0,crypto_hash_sha256_BYTES); - - p = torrent_file_path(NULL,0); + p = torrent_file_path(NULL,NULL,0); assert(NULL==p); - p = torrent_file_path(infohash,0); + p = torrent_file_path(TEST_DIRECTORY,infohash,0); assert(NULL==p); - p = torrent_file_path(infohash,23); + p = torrent_file_path(TEST_DIRECTORY,infohash,23); assert(NULL==p); - p = torrent_file_path(infohash,crypto_hash_sha256_BYTES); - assert(strcmp(p,"/torrents/0000000000000000000000000000000000000000000000000000000000000000.torrent")==0); + p = torrent_file_path(TEST_DIRECTORY,infohash,crypto_hash_sha256_BYTES); + assert(strcmp(p,TEST_DIRECTORY "/torrents/0000000000000000000000000000000000000000000000000000000000000000.torrent")==0); free(p); } @@ -209,7 +214,7 @@ static void torrent_file_piece_layers_basic_test() { struct torrent *torrent; FILE *fp; unsigned char hash[crypto_hash_sha256_BYTES]; - unsigned char expected[crypto_hash_sha256_BYTES] = {32,188,23,84,39,38,213,235,27,41,120,194,91,119,181,244,243,49,193,113,138,136,121,232,42,97,20,207,246,225,132,236}; + unsigned char expected[crypto_hash_sha256_BYTES] = {227,176,196,66,152,252,28,20,154,251,244,200,153,111,185,36,39,174,65,228,100,155,147,76,164,149,153,27,120,82,184,85}; fp = fopen(TEST_FILE_6,"w"); assert(fp!=NULL); -- 2.39.5