diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bencoding.c | 3 | ||||
-rw-r--r-- | src/metainfo.c | 90 |
2 files changed, 93 insertions, 0 deletions
diff --git a/src/bencoding.c b/src/bencoding.c index 9ff9f89..6e8a2a2 100644 --- a/src/bencoding.c +++ b/src/bencoding.c @@ -1,3 +1,6 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> #include <stdbool.h> /** diff --git a/src/metainfo.c b/src/metainfo.c new file mode 100644 index 0000000..1a0adcc --- /dev/null +++ b/src/metainfo.c @@ -0,0 +1,90 @@ +#include <bencoding.c> +struct inode { + char * name; + int length; + struct inode * next; + struct inode * child; + struct inode * parent; +}; +struct inode * next (struct inode * inode) { + if (inode->child) + return next(inode->child); + if (inode->next) { + if (inode->next->child) + return next(inode->next->child); + return inode->next; + } + struct inode * predecesor = inode; + while (!predecesor->next) { + predecesor = predecesor->parent; + if (!predecesor) + return NULL; + } + return predecesor->next; +} +enum type { + UNSPEC = 0, + V1 = 1, + V2 = 2 + HYBRID = 1 | 2 +} +struct metainfo { + struct inode * files; + struct sockaddr_in6 ip; + time_t retrieved; + time_t created; + enum type type; + char sha1[20]; + char sha256[32]; + char * name; + char * client; + char * source; + char * publisher; + char * publisher_url; + char * comment; +}; +void metainfo_free (struct metainfo * metainfo) { + inode_free(metainfo->files); + free(metainfo->name); + free(metainfo->client); + free(metainfo->source); + free(metainfo->publisher); + free(metainfo->publisher_url) + free(metainfo->comment); + free(metainfo); +} +struct metainfo * parse (const struct bencoding * metainfo) { + struct metainfo * r = calloc(1, sizeof(metainfo)); +#define EXTRACT(attribute, localvar, from) \ + struct bencoding * localvar = bpath(metainfo, from); \ + if (localvar && localvar->valuelen) { \ + free(r->attribute); \ + r->attribute = localvar->value; \ + localvar->value = NULL; /* this is nonstandard, but it's a monorepo */ \ + } + EXTRACT(name, name, "info/name"); + EXTRACT(name, nameutf8, "info/name.utf-8"); + EXTRACT(client, client, "source/v"); + EXTRACT(source, source, "info/source"); + EXTRACT(publisher, publisher, "info/publisher"); + EXTRACT(publisher, publisherutf8, "info/publisher.utf-8"); + EXTRACT(publisher_url, publisher_url, "info/publisher-url"); + EXTRACT(publisher_url, publisher_urlutf8, "info/publisher-url.utf-8"); + EXTRACT(comment, comment, "comment"); + struct bencoding * retrieved = bpath(metainfo, "info/creation date"); + if (retrieved && retrieved->valuelen) + r->retrieved = atoi(retrieved->value); + struct bencoding * created = bpath(metainfo, "creation date"); + if (created && created->intvalue) + r->created = created->intvalue; + struct bencoding * files = bpath(metainfo, "info/files"); + if (files) { + r->type = V1; + bforeach (files, file) { + struct attr * bpath(file, "attr"); + if (attr && attr->valuelen && strchr(attr, 'p')) + continue; + struct path * bpath(file, "path"); + } + } +} |