static int piece_layer_sort(const void*,const void*);
static int torrent_add_file(struct torrent*,struct file*);
+static int torrent_add_file_by_path(struct hash_map*, struct file*);
+static int torrent_add_file_by_root(struct hash_map*,struct file*);
static int torrent_file_announce(FILE*,struct torrent*);
-static char *torrent_file_path(unsigned char*,size_t);
static int torrent_file_piece_layers(FILE*,struct torrent*);
static int torrent_file_write_end(FILE*);
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*);
+static int torrent_files_resize(struct torrent *torrent_p, size_t new_size);
int torrent_add(struct torrent *p, struct file *f) {
const char *path;
}
static int torrent_add_file(struct torrent *p, struct file *f) {
- if(hashmap_insert(p->files,f->root,crypto_hash_sha256_BYTES,f)<0) { return -1; }
+ int i;
+
+ while(
+ ((i = torrent_add_file_by_root(p->files,f))<=0) ||
+ ((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; }
+ }
+
+ return 1;
+}
+
+static int torrent_add_file_by_path(struct hash_map *files, struct file *f) {
+ struct file *p;
+ int i;
+
+ if((i = hashmap_insert(files,f->path,strlen(f->path),f))<0) {
+ if(i<0) { return -1; }
+
+ p = hashmap_find(files,f->path,strlen(f->path));
+ if(p!=NULL) { return 0; }
+ }
+
+ return 1;
+}
+
+static int torrent_add_file_by_root(struct hash_map *files, struct file *f) {
+ struct file *p;
+ int i;
+
+ if((i = hashmap_insert(files,f->root,crypto_hash_sha256_BYTES,f))<0) {
+ if(i<0) { return -1; }
+ p = hashmap_find(files,f->root,crypto_hash_sha256_BYTES);
+ if(p!=NULL) { return 0; }
+ }
+
return 1;
}
#define TORRENT_FILE_DIRECTORY "/torrents"
#define TORRENT_FILE_EXTENSION ".torrent"
-static char *torrent_file_path(unsigned char *infohash, size_t len) {
+char *torrent_file_path(unsigned char *infohash, size_t len) {
char *path, *p;
char hex[(crypto_hash_sha256_BYTES<<1)+1];
// return -1;
}
+
static int piece_layer_sort(const void *p1, const void *p2) {
struct block *a, *b;
a = (struct block*)p1;
return 1;
}
+static int torrent_files_resize(struct torrent *torrent_p, size_t new_size) {
+ struct file *p;
+ struct hash_map *new, *old;
+ int ret;
+
+ 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];
+ if(p!=NULL) {
+ if(
+ ((ret = torrent_add_file_by_root(new,p))<=0) ||
+ ((ret = torrent_add_file_by_path(new,p))<=0)
+ ) {
+ if(ret<0) { return -1; }
+ hashmap_clear(new);
+ hashmap_free(new);
+ return torrent_files_resize(torrent_p,new_size<<1);
+ }
+ }
+ }
+
+ hashmap_clear(torrent_p->files);
+
+ old = torrent_p->files;
+ torrent_p->files = new;
+
+ hashmap_free(old);
+
+ return 1;
+}
void torrent_free(struct torrent *p) {
if(NULL==p) { return; }
return -1;
}
-char *torrent_magnet(struct torrent *p) {
- return NULL;
-}
+//char *torrent_magnet(struct torrent *p) {
+// return NULL;
+//}