]> infiniteadaptability.org Git - seeder/commitdiff
...
authoralex <[email protected]>
Mon, 27 Dec 2021 08:28:55 +0000 (00:28 -0800)
committeralex <[email protected]>
Mon, 27 Dec 2021 08:28:55 +0000 (00:28 -0800)
Makefile.am
inc/torrent.h
src/torrent/file.c
src/torrent/path.c [new file with mode: 0644]
src/torrent/piece.c
test/unit/Makefile.am
test/unit/test_utils.c
test/unit/torrent.tests.c

index 746c99b74d17860a4529c77ccd2c42438cb7f7b9..0972588bd1fbd812bfa315fce7067f1e4ff0ffc9 100644 (file)
@@ -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 \
index 939e0383d23c02bd930e3876b7309ee8ce30fad7..baefb8b4e59d1dc62192933e52519c22d505a570 100644 (file)
@@ -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);
index dc1e0a7573d990922b0368da96e2401b76c1eaa2..8f436843ff00fed074cd82f8d8b48f9effc66d40 100644 (file)
@@ -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 (file)
index 0000000..eb50ba7
--- /dev/null
@@ -0,0 +1,39 @@
+#include<torrent.h>
+
+#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;
+}
+
+
index c8795f18794c818d644ac00cf6834339af0cb5df..d788e1a7f5e054fd106cebaad244598802d6ead8 100644 (file)
@@ -37,7 +37,9 @@ int torrent_file_piece_layers(FILE *fp, struct torrent *p) {
        pieces = 0;
        for(size_t i=0;i<p->files.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;i<p->files.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++;
+                       }
                }
        }
 
index 82ec0ae53cb5d6a0eebcb95548b75a9bca0857ea..be1b150d6c971e22f686d8794a545840d40963c1 100644 (file)
@@ -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
 
index a79c9d1d61c5bc6ecfc3f057f093838f31ccf994..4ae2891b18127bde504023a4bcc7538fd1547e32 100644 (file)
@@ -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);
index 7b688f2ec67a474ff616490824c505a4c5620d36..9e0739e1f7421b2c9b7e3d47366e7ea4ae1bd7ea 100644 (file)
@@ -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);