modified: n.fq
[GalaxyCodeBases.git] / tools / torrent / mktorrent_crc / output.c
blob41ccb54e2f271f2788fb5df595dd537cbfdebd76
1 /*
2 This file is part of mktorrent
3 Copyright (C) 2007, 2009 Emil Renner Berthing
5 mktorrent is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mktorrent is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 #ifndef ALLINONE
20 #include <sys/types.h> /* off_t */
21 #include <stdio.h> /* printf() etc. */
22 #include <string.h> /* strlen() etc. */
23 #include <time.h> /* time() */
24 #ifdef USE_OPENSSL
25 #include <openssl/sha.h> /* SHA_DIGEST_LENGTH */
26 #else
27 #include <inttypes.h>
28 #include "sha1.h"
29 #endif
31 #include "mktorrent.h"
33 #define EXPORT
34 #endif /* ALLINONE */
37 * write announce list
39 static void write_announce_list(FILE *f, llist_t *list)
41 /* the announce list is a list of lists of urls */
42 fprintf(f, "13:announce-listl");
43 /* go through them all.. */
44 for (; list; list = list->next) {
45 slist_t *l;
47 /* .. and print the lists */
48 fprintf(f, "l");
49 for (l = list->l; l; l = l->next)
50 fprintf(f, "%lu:%s",
51 (unsigned long)strlen(l->s), l->s);
52 fprintf(f, "e");
54 fprintf(f, "e");
58 * write file list
60 static void write_file_list(FILE *f, flist_t *list)
62 char *a, *b;
64 fprintf(f, "5:filesl");
66 /* go through all the files */
67 for (; list; list = list->next) {
68 /* the file list contains a dictionary for every file
69 with entries for the length and path
70 write the length first */
71 fprintf(f, "d4:hash8:%s6:lengthi%" PRIoff "e4:pathl",list->hash, list->size);
72 /* the file path is written as a list of subdirectories
73 and the last entry is the filename
74 sorry this code is even uglier than the rest */
75 a = list->path;
76 /* while there are subdirectories before the filename.. */
77 while ((b = strchr(a, DIRSEP_CHAR)) != NULL) {
78 /* set the next DIRSEP_CHAR to '\0' so fprintf
79 will only write the first subdirectory name */
80 *b = '\0';
81 /* print it bencoded */
82 fprintf(f, "%lu:%s", (unsigned long)strlen(a), a);
83 /* undo our alteration to the string */
84 *b = DIRSEP_CHAR;
85 /* and move a to the beginning of the next
86 subdir or filename */
87 a = b + 1;
89 /* now print the filename bencoded and end the
90 path name list and file dictionary */
91 fprintf(f, "%lu:%see", (unsigned long)strlen(a), a);
94 /* whew, now end the file list */
95 fprintf(f, "e");
99 * write web seed list
101 static void write_web_seed_list(FILE *f, slist_t *list)
103 /* print the entry and start the list */
104 fprintf(f, "8:url-listl");
105 /* go through the list and write each URL */
106 for (; list; list = list->next)
107 fprintf(f, "%lu:%s", (unsigned long)strlen(list->s), list->s);
108 /* end the list */
109 fprintf(f, "e");
113 * write metainfo to the file stream using all the information
114 * we've gathered so far and the hash string calculated
116 EXPORT void write_metainfo(FILE *f, metafile_t *m, unsigned char *hash_string)
118 /* let the user know we've started writing the metainfo file */
119 printf("Writing metainfo file... ");
120 fflush(stdout);
122 /* every metainfo file is one big dictonary
123 and the first entry is the announce URL */
124 fprintf(f, "d8:announce%lu:%s",
125 (unsigned long)strlen(m->announce_list->l->s),
126 m->announce_list->l->s);
127 /* write the announce-list entry if we have
128 more than one announce URL */
129 if (m->announce_list->next || m->announce_list->l->next)
130 write_announce_list(f, m->announce_list);
131 /* add the comment if one is specified */
132 if (m->comment != NULL)
133 fprintf(f, "7:comment%lu:%s",
134 (unsigned long)strlen(m->comment),
135 m->comment);
136 /* I made this! */
137 fprintf(f, "10:created by17:mktorrent_crc 0.2");
138 /* add the creation date */
139 if (!m->no_creation_date)
140 fprintf(f, "13:creation datei%lde",
141 (long)time(NULL));
143 /* now here comes the info section
144 it is yet another dictionary */
145 fprintf(f, "4:infod");
146 /* first entry is either 'length', which specifies the length of a
147 single file torrent, or a list of files and their respective sizes */
148 if (!m->target_is_directory)
149 fprintf(f, "6:lengthi%" PRIoff "e", m->file_list->size);
150 else
151 write_file_list(f, m->file_list);
153 /* the info section also contains the name of the torrent,
154 the piece length and the hash string */
155 fprintf(f, "4:name%lu:%s12:piece lengthi%ue6:pieces%u:",
156 (unsigned long)strlen(m->torrent_name), m->torrent_name,
157 m->piece_length, m->pieces * SHA_DIGEST_LENGTH);
158 fwrite(hash_string, 1, m->pieces * SHA_DIGEST_LENGTH, f);
160 /* set the private flag */
161 if (m->private)
162 fprintf(f, "7:privatei1e");
164 /* end the info section */
165 fprintf(f, "e");
167 /* add url-list if one is specified */
168 if (m->web_seed_list != NULL) {
169 if (m->web_seed_list->next == NULL)
170 fprintf(f, "8:url-list%lu:%s",
171 (unsigned long)strlen(m->web_seed_list->s),
172 m->web_seed_list->s);
173 else
174 write_web_seed_list(f, m->web_seed_list);
177 /* end the root dictionary */
178 fprintf(f, "e");
180 /* let the user know we're done already */
181 printf("done.\n");
182 fflush(stdout);