#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <ctype.h>
#include <assert.h>
#include <errno.h>
#include "bencode.h"
static char *slurp(FILE *file, long *len_p)
{
assert(len_p != NULL);
int n = fseek(file, 0, SEEK_END);
(*len_p) = ftell(file);
n = fseek(file, 0, SEEK_SET);
char *buffer = g_new(char, (*len_p)+1);
n = fread(buffer, (*len_p), 1, file);
if(n != 1) {
fprintf(stderr, "%s: fread(3) failed: %s\n", __FUNCTION__,
strerror(ferror(file)));
g_free(buffer);
(*len_p) = 0;
return NULL;
}
buffer[(*len_p)] = '\0';
return buffer;
}
void dump_torrent(benc_item_t *t)
{
g_return_if_fail(BENC_IS_DICT(t));
printf("announce URL is '%s'\n", benc_dict_item_s(t, "announce", "NOT KNOWN"));
benc_item_t *info = benc_dict_lookup(t, "info");
if(info != NULL && BENC_IS_DICT(info)) {
const char *name = benc_dict_item_s(info, "name", NULL);
if(name != NULL) printf("info->name is '%s'\n", name);
benc_item_t *piece_length = benc_dict_lookup(info, "piece length");
if(piece_length != NULL && BENC_IS_INT(piece_length)) {
printf("info->piece_length is %d\n", piece_length->i);
}
benc_item_t *length = benc_dict_lookup(info, "length");
if(length != NULL && BENC_IS_INT(length)) {
printf("info->length is %d\n", length->i);
}
benc_item_t *path = benc_dict_lookup(info, "path");
if(path != NULL && BENC_IS_LIST(path)) {
printf("info->path has %d items\n", g_list_length(path->lst));
}
} else {
printf("*** 'info' not available\n");
}
}
int main(int argc, char *argv[])
{
if(argc < 2) {
fprintf(stderr, "%s: argument, please\n", argv[0]);
return EXIT_FAILURE;
}
const char *filename = argv[1];
FILE *torrentfile = fopen(filename, "rb");
if(torrentfile == NULL) {
fprintf(stderr, "can't open '%s'\n", filename);
return EXIT_FAILURE;
}
long len = -1;
char *torrent_data = slurp(torrentfile, &len);
fclose(torrentfile);
if(torrent_data == NULL) {
fprintf(stderr, "file read failed.\n");
return EXIT_FAILURE;
}
benc_item_t *t_dict = NULL;
GError *error = NULL;
int n = benc_decode(&t_dict, torrent_data, len, &error);
g_free(torrent_data);
if(n <= 0) {
fprintf(stderr, "torrent decode failed: %s\n", error->message);
g_error_free(error);
return EXIT_FAILURE;
}
printf("consumed %d bytes of torrent data (out of %ld total).\n",
n, len);
if(!BENC_IS_DICT(t_dict)) {
fprintf(stderr, "decode didn't result in a dictionary!\n");
benc_free(t_dict);
return EXIT_FAILURE;
}
printf("resulted in a dictionary of %d keys.\n",
g_hash_table_size(t_dict->dict));
dump_torrent(t_dict);
benc_free(t_dict);
return EXIT_SUCCESS;
}
|