File in revision tree ksandstr@iki.fi--2005-successor/successor--mainline--0.1--base-0

File: src/dumptorrent.c Size: 3201 Mime type: text/x-csrc

/* successor -- an experimental bittorrent tracker
 * Copyright (C) 2003, 2004 Kalle A. Sandstr   *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * Kalle A. Sandstr   * <ksandstr@iki.fi>
 */


#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;
  }
  /* since a torrent file is supposed to be just one big, huge, enormous
   * dictionary, we'll slurp it completely into memory just like that.
   */

  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;
}

ArchZoom 0.5.0 (devel)