From: alex <alex@infiniteadaptability.org>
Date: Wed, 8 Dec 2021 03:18:51 +0000 (-0800)
Subject: ...
X-Git-Url: http://git.infiniteadaptability.org/?a=commitdiff_plain;h=f25b4ec925152b36e98e6f9d2e759072f4e8a8f5;p=seeder

...
---

diff --git a/inc/file.h b/inc/file.h
index 2d7d006..2a996a1 100644
--- a/inc/file.h
+++ b/inc/file.h
@@ -21,6 +21,7 @@ struct file {
 };
 
 ssize_t file_bencode(struct file*,uint8_t*,size_t);
+int file_equals(struct file*,struct file*);
 void file_free(struct file*);
 int file_hash(struct file*,int);
 int file_init(struct file**,const char*);
diff --git a/inc/torrent.h b/inc/torrent.h
index e38995c..db1d775 100644
--- a/inc/torrent.h
+++ b/inc/torrent.h
@@ -12,6 +12,11 @@
 #include<opt.h>
 #include<tree.h>
 
+struct torrent_files {
+	struct hash_map *paths;
+	struct hash_map *roots;
+};
+
 struct torrent {
 	char *root;
 	char *name;
@@ -19,7 +24,7 @@ struct torrent {
 	unsigned long long piece_length;
 
 	struct tree *tree;
-	struct hash_map *files;
+	struct torrent_files *files;
 
 	int watch_fd;
 };
diff --git a/src/file.c b/src/file.c
index 1aa0361..1e211d2 100644
--- a/src/file.c
+++ b/src/file.c
@@ -51,6 +51,18 @@ ssize_t file_bencode(struct file *p, uint8_t *buf, size_t len) {
 	return buf_len-len;
 }
 
+int file_equals(struct file *a, struct file *b) {
+	if((NULL==a)&&(b!=NULL)) { return -1; }
+	if((NULL==b)&&(a!=NULL)) { return -1; }
+
+	if(strcmp(a->name,b->name)!=0) { return -1; }
+	if(strcmp(a->path,b->path)!=0) { return -1; }
+
+	if(memcmp(a->root,b->root,crypto_hash_sha256_BYTES)!=0) { return -1; }
+
+	return 1;
+}
+
 void file_free(struct file *p) {
 	if(NULL==p) { return; }
 
diff --git a/src/torrent/add.c b/src/torrent/add.c
index ce012c8..284eff0 100644
--- a/src/torrent/add.c
+++ b/src/torrent/add.c
@@ -27,12 +27,13 @@ int torrent_add(struct torrent *p, struct file *f) {
 static int torrent_add_file(struct torrent *p, struct file *f) {
 	int i;
 
-	while(
-		((i = torrent_add_file_by_root(p->files,f))<=0) ||
-		((i = torrent_add_file_by_path(p->files,f))<=0)
-		) {
+	while((i = torrent_add_file_by_root(p->files,f))<=0) {
+		if(i<0) { return -1; }
+		if(torrent_files_resize(p,p->files->size<<1)<0) { return -1; }
+	}
+
+	while((i = torrent_add_file_by_path(p->files,f))<=0) {
 		if(i<0) { return -1; }
-		
 		if(torrent_files_resize(p,p->files->size<<1)<0) { return -1; }
 	}
 
@@ -47,7 +48,7 @@ static int torrent_add_file_by_path(struct hash_map *files, struct file *f) {
 		if(i<0) { return -1; }
 
 		p = hashmap_find(files,f->path,strlen(f->path));
-		if(p!=NULL) { return 0; }
+		if((p!=NULL)&&(file_equals(f,p)<1)) { return 0; }
 	}
 	
 	return 1;
@@ -61,7 +62,7 @@ static int torrent_add_file_by_root(struct hash_map *files, struct file *f) {
 		if(i<0) { return -1; }
 
 		p = hashmap_find(files,f->root,crypto_hash_sha256_BYTES);
-		if(p!=NULL) { return 0; }
+		if((p!=NULL)&&(file_equals(f,p)<1)) { return 0; }
 	}
 	
 	return 1;
@@ -70,21 +71,44 @@ static int torrent_add_file_by_root(struct hash_map *files, struct file *f) {
 static int torrent_files_resize(struct torrent *torrent_p, size_t new_size) {
 	struct file *p;
 	struct hash_map *new, *old;
-	int ret;
+	int ret1, ret2;
 
 	if(hashmap_init(&new,new_size)<0) { return -1; }
 
 	for(size_t i=0;i<torrent_p->files->size;i++) {
 		p = torrent_p->files->map[i];
+		/*
+		 * cases:
+		 * 1.) p = NULL
+		 * 2.) p = added by torrent_add_file_by_root, not already added
+		 * 3.) p = added by torrent_add_file_by_path, not already added
+		 * 4.) p = added by torrent_add_file_by_root, already added
+		 * 5.) p = added by torrent_add_file_by_path, already added
+		 */
 		if(p!=NULL) {
-			if((ret = torrent_add_file_by_root(new,p))<=0) {
-				if(ret<0) { return -1; }
-				goto resize;
+			found = hashmap_find(torrent_p->files,p->path,strlen(p->path));
+			if(
+			if((ret1 = torrent_add_file_by_root(new,p))<=0) {
+				if(ret1<0) { goto clean; }
+				printf("%s already found [root]\n",p->name);
 			}
-
-			if(ret==0) {
-				if((ret = torrent_add_file_by_path(new,p))<=0) { goto resize; }
+			if((ret2 = torrent_add_file_by_path(new,p))<=0) {
+				if(ret2<0) { goto clean; }
+				printf("%s already found [path]\n",p->name);
 			}
+
+			if((!ret1)&&(!ret2)) { goto resize; }
+		}
+	}
+
+	printf("after\n");
+	for(size_t i=0;i<new->size;i++) {
+		p = new->map[i];
+		printf("%lu: ",i);
+		if(p==NULL) {
+			printf("NULL\n");
+		} else {
+			printf("%s\n",p->name);
 		}
 	}
 
@@ -97,8 +121,12 @@ static int torrent_files_resize(struct torrent *torrent_p, size_t new_size) {
 
 	return 1;
 resize:
-	if(ret<0) { return -1; }
 	hashmap_clear(new);
 	hashmap_free(new);
+	printf("resizing to %lu\n",new_size<<1);
 	return torrent_files_resize(torrent_p,new_size<<1);
+clean:
+	hashmap_clear(new);
+	hashmap_free(new);
+	return -1;
 }
diff --git a/test/unit/torrent.tests.c b/test/unit/torrent.tests.c
index 38de89c..e353d44 100644
--- a/test/unit/torrent.tests.c
+++ b/test/unit/torrent.tests.c
@@ -4,8 +4,11 @@
 
 int main();
 static void torrent_add_basic_test();
+static void torrent_file_info_basic_test();
+static void torrent_file_path_basic_test();
 static void torrent_init_basic_test();
 static void torrent_magnet_basic_test();
+static void torrent_setup_example(struct torrent**);
 
 int main() {
 	setup_env();
@@ -13,6 +16,8 @@ int main() {
 	torrent_init_basic_test();
 	torrent_add_basic_test();
 	torrent_magnet_basic_test();
+	torrent_file_info_basic_test();
+	torrent_file_path_basic_test();
 
 	clean_env();
 
@@ -23,7 +28,7 @@ static void torrent_add_basic_test() {
 	struct torrent *torrent;
 	struct file *file1, *file2, *file3, *file4, *p;
 
-//	for(size_t i=0;i<100;i++) {
+	for(size_t i=0;i<100;i++) {
 		assert(file_init(&file1,TEST_FILE_1)==1);
 		memset(file1->root,1,crypto_hash_sha256_BYTES);
 		assert(file_init(&file2,TEST_FILE_2)==1);
@@ -66,9 +71,23 @@ static void torrent_add_basic_test() {
 		assert(p==file4);
 
 		torrent_free(torrent);
+	}
+}
+
+static void torrent_file_info_basic_test() {
+	struct torrent *torrent;
+
+	torrent_setup_example(&torrent);
+
+	torrent_free(torrent);
+}
 
-		reset_env();
-//	}
+static void torrent_file_path_basic_test() {
+	struct torrent *torrent;
+
+	torrent_setup_example(&torrent);
+
+	torrent_free(torrent);
 }
 
 static void torrent_init_basic_test() {
@@ -82,20 +101,12 @@ static void torrent_init_basic_test() {
 	torrent_free(torrent);
 }
 
+
 static void torrent_magnet_basic_test() {
 	struct torrent *torrent;
-	struct file *file1, *file2;
 	char *p;
 
-	assert(file_init(&file1,TEST_FILE_1)==1);
-	memset(file1->root,1,crypto_hash_sha256_BYTES);
-	assert(file_init(&file2,TEST_FILE_2)==1);
-	memset(file2->root,2,crypto_hash_sha256_BYTES);
-	
-	assert(torrent_init(&torrent,TEST_DIRECTORY,TEST_DIRECTORY,16384)==1);
-		
-	assert(torrent_add(torrent,file1)==1);
-	assert(torrent_add(torrent,file2)==1);
+	torrent_setup_example(&torrent);
 	
 	p = torrent_magnet(torrent);
 	assert(p!=NULL);
@@ -107,3 +118,17 @@ static void torrent_magnet_basic_test() {
 
 	reset_env();
 }
+
+static void torrent_setup_example(struct torrent **p) {
+	struct file *file1, *file2;
+
+	assert(file_init(&file1,TEST_FILE_1)==1);
+	memset(file1->root,1,crypto_hash_sha256_BYTES);
+	assert(file_init(&file2,TEST_FILE_2)==1);
+	memset(file2->root,2,crypto_hash_sha256_BYTES);
+
+	assert(torrent_init(p,TEST_DIRECTORY,TEST_DIRECTORY,16384)==1);
+	
+	assert(torrent_add(*p,file1)==1);
+	assert(torrent_add(*p,file2)==1);
+}