Esempio n. 1
0
void
tr_magnetCreateMetainfo (const tr_magnet_info * info, tr_variant * top)
{
  int i;
  tr_variant * d;
  tr_variantInitDict (top, 4);

  /* announce list */
  if (info->trackerCount == 1)
    {
      tr_variantDictAddStr (top, TR_KEY_announce, info->trackers[0]);
    }
  else
    {
      tr_variant * trackers = tr_variantDictAddList (top, TR_KEY_announce_list, info->trackerCount);
      for (i=0; i<info->trackerCount; ++i)
        tr_variantListAddStr (tr_variantListAddList (trackers, 1), info->trackers[i]);
    }

  /* webseeds */
  if (info->webseedCount > 0)
    {
      tr_variant * urls = tr_variantDictAddList (top, TR_KEY_url_list, info->webseedCount);
      for (i=0; i<info->webseedCount; ++i)
        tr_variantListAddStr (urls, info->webseeds[i]);
    }

  /* nonstandard keys */
  d = tr_variantDictAddDict (top, TR_KEY_magnet_info, 2);
  tr_variantDictAddRaw (d, TR_KEY_info_hash, info->hash, 20);
  if (info->displayName != NULL)
    tr_variantDictAddStr (d, TR_KEY_display_name, info->displayName);
}
Esempio n. 2
0
static void
saveFilePriorities (tr_variant * dict, const tr_torrent * tor)
{
  tr_variant * list;
  tr_file_index_t i;
  const tr_info * const inf = tr_torrentInfo (tor);
  const tr_file_index_t n = inf->fileCount;

  list = tr_variantDictAddList (dict, TR_KEY_priority, n);
  for (i=0; i<n; ++i)
    tr_variantListAddInt (list, inf->files[i].priority);
}
Esempio n. 3
0
static void
saveDND (tr_variant * dict, const tr_torrent * tor)
{
  tr_variant * list;
  tr_file_index_t i;
  const tr_info * const inf = tr_torrentInfo (tor);
  const tr_file_index_t n = inf->fileCount;

  list = tr_variantDictAddList (dict, TR_KEY_dnd, n);
  for (i=0; i<n; ++i)
    tr_variantListAddInt (list, inf->files[i].dnd ? 1 : 0);
}
Esempio n. 4
0
static bool
addURL (tr_variant * metainfo, const char * url)
{
  const char * announce = NULL;
  tr_variant * announce_list = NULL;
  bool changed = false;
  const bool had_announce = tr_variantDictFindStr (metainfo, TR_KEY_announce, &announce, NULL);
  const bool had_announce_list = tr_variantDictFindList (metainfo, TR_KEY_announce_list, &announce_list);

  if (!had_announce && !had_announce_list)
    {
      /* this new tracker is the only one, so add it to "announce"... */
      printf ("\tAdded \"%s\" in \"announce\"\n", url);
      tr_variantDictAddStr (metainfo, TR_KEY_announce, url);
      changed = true;
    }
  else
    {
      if (!had_announce_list)
        {
          announce_list = tr_variantDictAddList (metainfo, TR_KEY_announce_list, 2);

          if (had_announce)
            {
              /* we're moving from an 'announce' to an 'announce-list',
               * so copy the old announce URL to the list */
              tr_variant * tier = tr_variantListAddList (announce_list, 1);
              tr_variantListAddStr (tier, announce);
              changed = true;
            }
        }

      /* If the user-specified URL isn't in the announce list yet, add it */
      if (!announce_list_has_url (announce_list, url))
        {
          tr_variant * tier = tr_variantListAddList (announce_list, 1);
          tr_variantListAddStr (tier, url);
          printf ("\tAdded \"%s\" to \"announce-list\" tier %"TR_PRIuSIZE"\n", url, tr_variantListSize (announce_list));
          changed = true;
        }
    }

  return changed;
}
Esempio n. 5
0
static void
saveFilenames (tr_variant * dict, const tr_torrent * tor)
{
  tr_file_index_t i;
  bool any_renamed;
  const tr_file_index_t n = tor->info.fileCount;
  const tr_file * files = tor->info.files;

  any_renamed = false;
  for (i=0; !any_renamed && i<n; ++i)
    any_renamed = files[i].is_renamed;

  if (any_renamed)
    {
      tr_variant * list = tr_variantDictAddList (dict, TR_KEY_files, n);

      for (i=0; i<n; ++i)
        tr_variantListAddStr (list, files[i].is_renamed ? files[i].name : "");
    }
}
Esempio n. 6
0
static void saveProgress(tr_variant* dict, tr_torrent* tor)
{
    tr_variant* l;
    tr_variant* prog;
    tr_info const* inf = tr_torrentInfo(tor);
    time_t const now = tr_time();

    prog = tr_variantDictAddDict(dict, TR_KEY_progress, 3);

    /* add the file/piece check timestamps... */
    l = tr_variantDictAddList(prog, TR_KEY_time_checked, inf->fileCount);

    for (tr_file_index_t fi = 0; fi < inf->fileCount; ++fi)
    {
        time_t oldest_nonzero = now;
        time_t newest = 0;
        bool has_zero = false;
        time_t const mtime = tr_torrentGetFileMTime(tor, fi);
        tr_file const* f = &inf->files[fi];

        /* get the oldest and newest nonzero timestamps for pieces in this file */
        for (tr_piece_index_t i = f->firstPiece; i <= f->lastPiece; ++i)
        {
            tr_piece const* const p = &inf->pieces[i];

            if (p->timeChecked == 0)
            {
                has_zero = true;
            }
            else if (oldest_nonzero > p->timeChecked)
            {
                oldest_nonzero = p->timeChecked;
            }

            if (newest < p->timeChecked)
            {
                newest = p->timeChecked;
            }
        }

        /* If some of a file's pieces have been checked more recently than
           the file's mtime, and some less recently, then that file will
           have a list containing timestamps for each piece.

           However, the most common use case is that the file doesn't change
           after it's downloaded. To reduce overhead in the .resume file,
           only a single timestamp is saved for the file if *all* or *none*
           of the pieces were tested more recently than the file's mtime. */

        if (!has_zero && mtime <= oldest_nonzero) /* all checked */
        {
            tr_variantListAddInt(l, oldest_nonzero);
        }
        else if (newest < mtime) /* none checked */
        {
            tr_variantListAddInt(l, newest);
        }
        else /* some are checked, some aren't... so list piece by piece */
        {
            int const offset = oldest_nonzero - 1;
            tr_variant* ll = tr_variantListAddList(l, 2 + f->lastPiece - f->firstPiece);
            tr_variantListAddInt(ll, offset);

            for (tr_piece_index_t i = f->firstPiece; i <= f->lastPiece; ++i)
            {
                tr_piece const* const p = &inf->pieces[i];

                tr_variantListAddInt(ll, p->timeChecked != 0 ? p->timeChecked - offset : 0);
            }
        }
    }

    /* add the progress */
    if (tor->completeness == TR_SEED)
    {
        tr_variantDictAddStr(prog, TR_KEY_have, "all");
    }

    /* add the blocks bitfield */
    bitfieldToBenc(&tor->completion.blockBitfield, tr_variantDictAdd(prog, TR_KEY_blocks));
}