...
authoralex <[email protected]>
Wed, 29 Dec 2021 23:43:56 +0000 (15:43 -0800)
committeralex <[email protected]>
Wed, 29 Dec 2021 23:43:56 +0000 (15:43 -0800)
Makefile.am
inc/rss.h
src/feed.c
src/meta.c
src/rss/free.c [new file with mode: 0644]
src/rss/init.c [new file with mode: 0644]
test/unit/Makefile.am
test/unit/meta.tests.c [new file with mode: 0644]
test/unit/rss.tests.c
test/unit/test_utils.c
test/unit/test_utils.h

index 4480da7ee4ef613f07775a675436cfd1a03a8987..1442513dd3554e4db15f2d92f359c1869f6dc947 100644 (file)
@@ -28,6 +28,7 @@ seederd_SOURCES = \
        src/init.c \
        src/log.c \
        src/main.c \
+       src/meta.c \
        src/opt/config.c \
        src/opt/env.c \
        src/opt/filter.c \
@@ -39,8 +40,10 @@ seederd_SOURCES = \
        src/opt/worker.c \
        src/rss/entry.c \
        src/rss/footer.c \
+       src/rss/free.c \
        src/rss/header.c \
        src/rss/info.c \
+       src/rss/init.c \
        src/server/start.c \
        src/session.c \
        src/setup.c \
@@ -70,6 +73,7 @@ seederd_SOURCES += \
        inc/init.h \
        inc/log.h \
        inc/main.h \
+       inc/meta.h \
        inc/opt.h \
        inc/rss.h \
        inc/server.h \
index 848b3207b1dbf63ac308177c4fedda0c7e5b7875..f2e27d14396bba76da304956eb63c67720c72336 100644 (file)
--- a/inc/rss.h
+++ b/inc/rss.h
@@ -2,6 +2,7 @@
 #define __RSS_H_
 
 #include<stdio.h>
+#include<stdlib.h>
 #include<string.h>
 #include<time.h>
 
@@ -56,7 +57,11 @@ struct rss_entry {
 #define RSS_DEFAULT_ENTRY_DESCRIPTION "no description"
 #define RSS_DEFAULT_LANGUAGE "en-us"
 
+void rss_channel_info_free(struct rss_channel_info*);
+int rss_channel_info_init(struct rss_channel_info**);
 int rss_entry(FILE*,struct rss_entry*);
+void rss_entry_free(struct rss_entry*);
+int rss_entry_init(struct rss_entry**);
 int rss_footer(FILE*);
 int rss_header(FILE*);
 int rss_info(FILE*,struct rss_channel_info*);
index afe6fac9821a241fa5d43fbb8ef9cae6434e61f3..502ac5ded557db9e00f74346fb6184b8a92ee690 100644 (file)
@@ -2,8 +2,8 @@
 
 static int feed_entries(FILE*,struct torrent*);
 static int feed_generate(struct torrent*);
+static int feed_info(struct torrent*,struct rss_channel_info*);
 static char *feed_path(const char*,const char*);
-//static int feed_now(char*,size_t);
 
 int feed() {
        for(size_t i=0;i<session.torrent_count;i++) {
index 18b74a4958dce58dc6a549463dfece27becdf683..f920befc59137966c0fe8550f9b720931ee695c3 100644 (file)
@@ -2,17 +2,21 @@
 
 static int meta_escape(char*,size_t);
 static FILE *meta_search(const char*);
-static ssize_t next_line(FILE*,char*,size_t);
+static ssize_t next_line(FILE*,char**,char**,char*,size_t);
 
 int meta_entry(const char *path, struct rss_entry *entry) {
        char buf[META_MAX_LINE_SIZE];
        char *key, *value;
        FILE *fp;
+       ssize_t i;
+
+       if(NULL==path) { return -1; }
+       if(NULL==entry) { return -1; }
 
        fp = meta_search(path);
        if(NULL==fp) { return 0; }
 
-       while((i = next_line(fp,&key,buf,META_MAX_SIZE))>0) {
+       while((i = next_line(fp,&key,&value,buf,META_MAX_LINE_SIZE))>0) {
                if(strcmp(key,RSS_TAG_TITLE)==0) {
                        entry->title = strndup(value,i);
                } else if(strcmp(key,RSS_TAG_LINK)==0) {
@@ -51,7 +55,7 @@ static int meta_escape(char *buf, size_t buf_size) {
                        case '<':
                                if(left<=4) { return -1; }
                                memmove(&(p[4]),p,len);
-                               strcpy(p,"&lt;")
+                               strcpy(p,"&lt;");
                                p += 4;
                                break;
                        case '\\':
@@ -61,16 +65,16 @@ static int meta_escape(char *buf, size_t buf_size) {
                                        p++;
                                }
                                break;
-                       case '>';
+                       case '>':
                                if(left<=4) { return -1; }
                                memmove(&(p[4]),p,len);
-                               strcpy(p,"&gt;")
+                               strcpy(p,"&gt;");
                                p += 4;
                                break;
                        case '&':
                                if(left<=5) { return -1; }
                                memmove(&(p[5]),p,len);
-                               strcpy(p,"&amp;")
+                               strcpy(p,"&amp;");
                                p += 5;
                                break;
                        default:
@@ -87,11 +91,15 @@ int meta_info(const char *path, struct rss_channel_info *info) {
        char buf[META_MAX_LINE_SIZE];
        char *key, *value;
        FILE *fp;
+       ssize_t i;
+
+       if(NULL==path) { return -1; }
+       if(NULL==info) { return -1; }
        
        fp = meta_search(path);
        if(NULL==fp) { return 0; }
 
-       while((i = next_line(fp,&key,&value,buf,META_MAX_SIZE))>0) {
+       while((i = next_line(fp,&key,&value,buf,META_MAX_LINE_SIZE))>0) {
                if(strcmp(key,RSS_TAG_TITLE)==0) {
                        info->title = strndup(value,i);
                } else if(strcmp(key,RSS_TAG_LINK)==0) {
@@ -99,7 +107,7 @@ int meta_info(const char *path, struct rss_channel_info *info) {
                } else if(strcmp(key,RSS_TAG_DESCRIPTION)==0) {
                        info->description = strndup(value,i);
                } else if(strcmp(key,RSS_TAG_LANGUAGE)==0) {
-                       entry->language = strndup(value,i);
+                       info->language = strndup(value,i);
                } else if(strcmp(key,RSS_TAG_LASTBUILDDATE)==0) {
                        return -1;
                } else { goto panic; }
@@ -116,6 +124,7 @@ panic:
 }
 
 static FILE *meta_search(const char *path) {
+       FILE *fp;
        char *p;
        size_t len;
 
@@ -132,17 +141,23 @@ static FILE *meta_search(const char *path) {
                if(NULL==p) { return NULL; }
 
                strcpy(p,path);
-               strncat(p,".meta",5);
+               strcat(p,".meta");
        }
 
        fp = fopen(p,"r");
        return fp;
 }
 
-static ssize_t next_line(FILE *fp, char *buf, size_t buf_size) {
+static ssize_t next_line(FILE *fp, char **key, char **value, char *buf, size_t buf_size) {
        if(fgets(buf,buf_size,fp)==NULL) { return -1; }
 
        if(meta_escape(buf,buf_size)<0) { return -1; }
 
-       return 1;
+       (*key) = buf;
+       (*value) = strchr(buf,'=');
+       if(NULL==(*value)) { return -1; }
+
+       (*value) = '\0';
+       (*value)++;
+       return buf_size - strlen(*key);
 }
diff --git a/src/rss/free.c b/src/rss/free.c
new file mode 100644 (file)
index 0000000..2e46d5f
--- /dev/null
@@ -0,0 +1,19 @@
+#include<rss.h>
+
+void rss_channel_info_free(struct rss_channel_info *p) {
+       if(p->title!=NULL) { free(p->title); }
+       if(p->link!=NULL) { free(p->link); }
+       if(p->description!=NULL) { free(p->description); }
+       if(p->language!=NULL) { free(p->language); }
+
+       free(p);
+}
+
+void rss_entry_free(struct rss_entry *p) {
+       if(p->title!=NULL) { free(p->title); }
+       if(p->link!=NULL) { free(p->link); }
+       if(p->description!=NULL) { free(p->description); }
+       if(p->guid!=NULL) { free(p->guid); }
+
+       free(p);
+}
diff --git a/src/rss/init.c b/src/rss/init.c
new file mode 100644 (file)
index 0000000..6f0729e
--- /dev/null
@@ -0,0 +1,31 @@
+#include<rss.h>
+
+int rss_channel_info_init(struct rss_channel_info **p) {
+       if(NULL==p) { return -1; }
+
+       (*p) = malloc(sizeof(struct rss_channel_info));
+       if(NULL==(*p)) { return -1; }
+
+       (*p)->title = NULL;
+       (*p)->link = NULL;
+       (*p)->description = NULL;
+       (*p)->language = NULL;
+       memset(&((*p)->last_build_date),0,sizeof(struct tm));
+
+       return 1;
+}
+
+int rss_entry_init(struct rss_entry **p) {
+       if(NULL==p) { return -1; }
+
+       (*p) = malloc(sizeof(struct rss_entry));
+       if(NULL==(*p)) { return -1; }
+
+       (*p)->title = NULL;
+       (*p)->link = NULL;
+       memset(&((*p)->pub_date),0,sizeof(struct tm));
+       (*p)->description = NULL;
+       (*p)->guid = NULL;
+
+       return 1;
+}
index 342073701206db6e5a38d269e84f9a735405d437..dc6cc486e98f0edf9e423213389a5c1ac2584c0c 100644 (file)
@@ -12,7 +12,7 @@ AM_CPPFLAGS += \
        -DNDEBUG
 endif
 
-check_PROGRAMS = bencode.tests block.tests file.tests fs.concat.tests fs.filter.tests hash.tests hashmap.tests rss.tests torrent.tests tree.tests
+check_PROGRAMS = bencode.tests block.tests file.tests fs.concat.tests fs.filter.tests hash.tests hashmap.tests meta.tests rss.tests torrent.tests tree.tests
 TESTS = $(check_PROGRAMS)
 
 if ENABLE_MEMCHECK
@@ -61,13 +61,24 @@ hashmap_tests_SOURCES = \
        hashmap.tests.c \
        $(top_srcdir)/src/hashmap.c
 
+meta_tests_SOURCES = \
+       $(common_SOURCES) \
+       meta.tests.c \
+       $(top_srcdir)/src/fs/concat.c \
+       $(top_srcdir)/src/fs/dir.c \
+       $(top_srcdir)/src/meta.c \
+       $(top_srcdir)/src/rss/free.c \
+       $(top_srcdir)/src/rss/init.c
+
 rss_tests_SOURCES = \
        $(common_SOURCES) \
        rss.tests.c \
        $(top_srcdir)/src/rss/entry.c \
        $(top_srcdir)/src/rss/footer.c \
+       $(top_srcdir)/src/rss/free.c \
        $(top_srcdir)/src/rss/header.c \
-       $(top_srcdir)/src/rss/info.c
+       $(top_srcdir)/src/rss/info.c \
+       $(top_srcdir)/src/rss/init.c
 
 torrent_tests_SOURCES = \
        $(common_SOURCES) \
diff --git a/test/unit/meta.tests.c b/test/unit/meta.tests.c
new file mode 100644 (file)
index 0000000..b1f17bd
--- /dev/null
@@ -0,0 +1,70 @@
+#include<test_utils.h>
+
+#include<meta.h>
+
+int main();
+static void meta_entry_basic_test();
+static void meta_info_basic_test();
+
+int main() {
+       setup_env();
+
+       meta_entry_basic_test();
+       meta_info_basic_test();
+
+       clean_env();
+
+       return EXIT_SUCCESS;
+}
+
+static void meta_entry_basic_test() {
+       struct rss_entry *entry;
+
+       assert(1==rss_entry_init(&entry));
+
+       assert(meta_entry(NULL,NULL)==-1);
+       assert(meta_entry(TEST_FILE_1,NULL)==-1);
+
+       // TEST_FILE_3's .meta file contains invalid fields
+       assert(meta_entry(TEST_FILE_3,entry)==-1);
+
+       // PREFIX's .meta file is meant to contain channel info
+       // (and as such will have invalid fields)
+       assert(meta_entry(PREFIX,entry)==-1);
+
+       assert(meta_entry(TEST_FILE_1,entry)==1);
+
+       assert(strcmp(entry->title,"test title")==0);
+       assert(strcmp(entry->link,"https://whatisarealink.com")==0);
+//     assert(strcmp(entry->pub_date,"")==0);
+       assert(strcmp(entry->description,"I wonder if \n this'll properly be formatted/escaped \\&gt;&lt;?")==0);
+       assert(strcmp(entry->guid,"magnet=asldkfjsldkfjslkdjfldsdjlfkjsdf")==0);
+
+       rss_entry_free(entry);
+}
+
+static void meta_info_basic_test() {
+       struct rss_channel_info *info;
+
+       assert(rss_channel_info_init(&info)==1);
+
+       assert(meta_info(NULL,NULL)==-1);
+       assert(meta_info(PREFIX,NULL)==-1);
+       
+       // TEST_FILE_3's .meta file contains invalid fields
+       assert(meta_info(TEST_FILE_3,info)==-1);
+       
+       // TEST_FILE_1's .meta file is meant to contain entry fields
+       // (and as such will have invalid fields)
+       assert(meta_info(TEST_FILE_1,info)==-1);
+       
+       assert(meta_info(PREFIX,info)==1);
+
+       assert(strcmp(info->title,"TITLE")==0);
+       assert(strcmp(info->link,"http://test.com")==0);
+       assert(strcmp(info->description,"what is a description")==0);
+       assert(strcmp(info->language,"en-us")==0);
+//     assert(strcmp(info->last_build_date,"")==0);
+
+       rss_channel_info_free(info);
+}
index ff0cc3d27ac429704c1d9318c5659d5b25a752bb..1c0822aa7185ffdd250d7c638248f814b41bedb7 100644 (file)
@@ -4,8 +4,10 @@
 
 int main();
 static FILE *setup_file_pointer();
+static void rss_channel_info_init_basic_test();
 static void rss_entry_basic_test();
 static void rss_entry_correctness_test();
+static void rss_entry_init_basic_test();
 static void rss_footer_basic_test();
 static void rss_footer_correctness_test();
 static void rss_header_basic_test();
@@ -16,6 +18,8 @@ static void rss_info_correctness_test();
 int main() {
        setup_env();
 
+       rss_entry_init_basic_test();
+       rss_channel_info_init_basic_test();
        rss_entry_basic_test();
        rss_entry_correctness_test();
        rss_footer_basic_test();
@@ -30,18 +34,28 @@ int main() {
        return EXIT_SUCCESS;
 }
 
+static void rss_channel_info_init_basic_test() {
+       struct rss_channel_info *p;
+
+       assert(rss_channel_info_init(NULL)==-1);
+       assert(rss_channel_info_init(&p)==1);
+       
+       rss_channel_info_free(p);
+}
+
 static void rss_entry_basic_test() {
        FILE *fp;
-       struct rss_entry p;
+       struct rss_entry *p;
+       char *tmp;
 
-       memset(&p,0,sizeof(struct rss_entry));
+       assert(rss_entry_init(&p)==1);
 
        fp = setup_file_pointer();
        
        assert(rss_entry(NULL,NULL)==-1);
        assert(rss_entry(fp,NULL)==-1);
 
-       assert(rss_entry(fp,&p)==-1);
+       assert(rss_entry(fp,p)==-1);
 
        char bad_title[] = "";
        char sample_title[] = "sample title";
@@ -51,43 +65,50 @@ static void rss_entry_basic_test() {
        char sample_description[] = "sample description";
        char sample_guid[] = "laskdjflkasdjf";
 
-       p.title = sample_title;
-       p.link = sample_link;
-       p.description = sample_description;
-       p.guid = sample_guid;
-       p.pub_date = *localtime(&(time_t){time(NULL)});
+       p->title = strdup(sample_title);
+       p->link = strdup(sample_link);
+       p->description = strdup(sample_description);
+       p->guid = strdup(sample_guid);
+       p->pub_date = *localtime(&(time_t){time(NULL)});
 
-       assert(rss_entry(fp,&p)==1);
+       assert(rss_entry(fp,p)==1);
        
-       p.title = bad_title;
-       assert(rss_entry(fp,&p)==-1);
-       p.title = sample_title;
-
-       p.link = bad_link;
-       assert(rss_entry(fp,&p)==-1);
-       p.link = sample_link;
-
-       p.description = bad_description;
-       assert(rss_entry(fp,&p)==1);
-       p.description = sample_description;
-       assert(rss_entry(fp,&p)==1);
+       tmp = p->title;
+       p->title = bad_title;
+       assert(rss_entry(fp,p)==-1);
+       p->title = tmp;
+
+       tmp = p->link;
+       p->link = bad_link;
+       assert(rss_entry(fp,p)==-1);
+       p->link = tmp;
+
+       tmp = p->description;
+       p->description = bad_description;
+       assert(rss_entry(fp,p)==1);
+       p->description = tmp;
+       assert(rss_entry(fp,p)==1);
        
-       p.guid = NULL;
-       assert(rss_entry(fp,&p)==1);
-       p.guid = sample_guid;
-       assert(rss_entry(fp,&p)==1);
+       tmp = p->guid;
+       p->guid = NULL;
+       assert(rss_entry(fp,p)==1);
+       p->guid = tmp;
+       assert(rss_entry(fp,p)==1);
 
        fclose(fp);
+
+       rss_entry_free(p);
+
        reset_env();
 }
 
 static void rss_entry_correctness_test() {
        FILE *fp;
-       struct rss_entry p;
+       struct rss_entry *p;
        unsigned char hash[crypto_hash_sha256_BYTES];
        unsigned char expected[crypto_hash_sha256_BYTES] = {252,1,77,6,36,221,191,114,180,137,47,54,77,39,151,196,0,85,115,184,127,210,230,152,114,130,36,140,33,239,194,30};
 
-       memset(&p,0,sizeof(struct rss_entry));
+       assert(1==rss_entry_init(&p));
 
        fp = setup_file_pointer();
 
@@ -96,23 +117,34 @@ static void rss_entry_correctness_test() {
        char sample_description[] = "sample description";
        char sample_guid[] = "laskdjflkasdjf";
 
-       p.title = sample_title;
-       p.link = sample_link;
-       p.description = sample_description;
-       p.guid = sample_guid;
+       p->title = strdup(sample_title);
+       p->link = strdup(sample_link);
+       p->description = strdup(sample_description);
+       p->guid = strdup(sample_guid);
        time_t seconds = 1231006505;
-       memcpy(&(p.pub_date), gmtime(&seconds), sizeof(struct tm));
+       memcpy(&(p->pub_date), gmtime(&seconds), sizeof(struct tm));
 
-       assert(rss_entry(fp,&p)==1);
+       assert(rss_entry(fp,p)==1);
 
        fclose(fp);
 
        hash_file(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
        assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
 
+       rss_entry_free(p);
+
        reset_env();
 }
 
+static void rss_entry_init_basic_test() {
+       struct rss_entry *p;
+
+       assert(rss_entry_init(NULL)==-1);
+       assert(rss_entry_init(&p)==1);
+       
+       rss_entry_free(p);
+}
+
 static void rss_footer_basic_test() {
        FILE *fp;
 
@@ -173,9 +205,10 @@ static void rss_header_correctness_test() {
 
 static void rss_info_basic_test() {
        FILE *fp;
-       struct rss_channel_info p;
+       struct rss_channel_info *p;
+       char *tmp;
        
-       memset(&p,0,sizeof(struct rss_channel_info));
+       assert(1==rss_channel_info_init(&p));
 
        fp = setup_file_pointer();
 
@@ -192,44 +225,51 @@ static void rss_info_basic_test() {
        char bad_language_2[] = "alskdjflkasdjfaslkdf";
        char sample_language[] = "en-us";
 
-       p.title = sample_title;
-       p.link = sample_link;
-       p.description = sample_description;
-       p.language = sample_language;
-       p.last_build_date = *localtime(&(time_t){time(NULL)});
-
-       assert(rss_info(fp,&p)==1);
-
-       p.title = bad_title;
-       assert(rss_info(fp,&p)==-1);
-       p.title = sample_title;
+       p->title = strdup(sample_title);
+       p->link = strdup(sample_link);
+       p->description = strdup(sample_description);
+       p->language = strdup(sample_language);
+       p->last_build_date = *localtime(&(time_t){time(NULL)});
+
+       assert(rss_info(fp,p)==1);
+
+       tmp = p->title;
+       p->title = bad_title;
+       assert(rss_info(fp,p)==-1);
+       p->title = tmp;
+
+       tmp = p->link;
+       p->link = bad_link;
+       assert(rss_info(fp,p)==-1);
+       p->link = tmp;
+
+       tmp = p->description;
+       p->description = bad_description;
+       assert(rss_info(fp,p)==1);
+       p->description = tmp;
+       assert(rss_info(fp,p)==1);
+
+       tmp = p->language;
+       p->language = bad_language_1;
+       assert(rss_info(fp,p)==1); // should succeed (fills with default)
+       p->language = bad_language_2;
+       assert(rss_info(fp,p)==1); // no locale checking done (out of scope of rss_info)
+       p->language = tmp;
 
-       p.link = bad_link;
-       assert(rss_info(fp,&p)==-1);
-       p.link = sample_link;
-
-       p.description = bad_description;
-       assert(rss_info(fp,&p)==1);
-       p.description = sample_description;
-       assert(rss_info(fp,&p)==1);
+       fclose(fp);
 
-       p.language = bad_language_1;
-       assert(rss_info(fp,&p)==1); // should succeed (fills with default)
-       p.language = bad_language_2;
-       assert(rss_info(fp,&p)==1); // no locale checking done (out of scope of rss_info)
-       p.language = sample_language;
+       rss_channel_info_free(p);
 
-       fclose(fp);
        reset_env();
 }
 
 static void rss_info_correctness_test() {
        FILE *fp;
-       struct rss_channel_info p;
+       struct rss_channel_info *p;
        unsigned char hash[crypto_hash_sha256_BYTES];
        unsigned char expected[crypto_hash_sha256_BYTES] = {175,238,191,8,225,134,109,105,86,61,240,232,31,206,163,165,243,43,229,34,169,83,166,18,54,229,225,99,110,47,38,243};
 
-       memset(&p,0,sizeof(struct rss_channel_info));
+       assert(1==rss_channel_info_init(&p));
 
        fp = setup_file_pointer();
 
@@ -238,20 +278,22 @@ static void rss_info_correctness_test() {
        char sample_description[] = "alsdjflaksdjfoikasjdfliasjdfoijawdf";
        char sample_language[] = "en-us";
 
-       p.title = sample_title;
-       p.link = sample_link;
-       p.description = sample_description;
-       p.language = sample_language;
+       p->title = strdup(sample_title);
+       p->link = strdup(sample_link);
+       p->description = strdup(sample_description);
+       p->language = strdup(sample_language);
        time_t seconds = 1231006505;
-       memcpy(&(p.last_build_date), gmtime(&seconds), sizeof(struct tm));
+       memcpy(&(p->last_build_date), gmtime(&seconds), sizeof(struct tm));
 
-       assert(rss_info(fp,&p)==1);
+       assert(rss_info(fp,p)==1);
 
        fclose(fp);
 
        hash_file(TEST_FILE_7,hash,crypto_hash_sha256_BYTES);
        assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0);
        
+       rss_channel_info_free(p);
+
        reset_env();
 }
 
index 924e55c86f0403536f0145b1c468590d2c48b403..901730576b9f3b713ea3254b3c32d7653feeaf24 100644 (file)
@@ -25,6 +25,8 @@ void setup_env() {
        create_test_file(TEST_FILE_2,TEST_FILE_2_CONTENTS);
        create_test_file(TEST_FILE_3,TEST_FILE_3_CONTENTS);
        create_test_file(TEST_FILE_4,TEST_FILE_4_CONTENTS);
+       create_test_file(TEST_FILE_8,TEST_FILE_8_CONTENTS);
+       create_test_file(TEST_FILE_9,TEST_FILE_9_CONTENTS);
 }
 
 static void create_test_directory(const char *directory) {
index 063aacd3965e88c64b7362cdcb5471a40f7b6fbf..cc429040f4f8ea8a6f94c4c999ff0ec72932d0cb 100644 (file)
 #define TEST_FILE_5 PREFIX "/random.test"
 #define TEST_FILE_6 PREFIX "/file.torrent"
 #define TEST_FILE_7 PREFIX "/file.feed"
+#define TEST_FILE_8 PREFIX "/test.meta"
+#define TEST_FILE_8_CONTENTS "title=test title\nlink=https://whatisarealink.com\npubDate=0000\ndescription=I wonder if \\n this'll properly be formatted/escaped \\><?\nguid=magnet=asldkfjsldkfjslkdjfldsdjlfkjsdf"
+#define TEST_FILE_9 PREFIX "/.meta"
+#define TEST_FILE_9_CONTENTS "title=TITLE\nlink=http://test.com\ndescription=what is a description\nlanguage=en-us\nlastBuildDate=0000"
 
 void clean_env();
 void reset_env();