コード例 #1
0
ファイル: resume.c プロジェクト: xzcvczx/transmission
static uint64_t loadIdleLimits(tr_variant* dict, tr_torrent* tor)
{
    tr_variant* d;
    uint64_t ret = 0;

    if (tr_variantDictFindDict(dict, TR_KEY_idle_limit, &d))
    {
        int64_t i;
        int64_t imin;

        if (tr_variantDictFindInt(d, TR_KEY_idle_limit, &imin))
        {
            tr_torrentSetIdleLimit(tor, imin);
        }

        if (tr_variantDictFindInt(d, TR_KEY_idle_mode, &i))
        {
            tr_torrentSetIdleMode(tor, i);
        }

        ret = TR_FR_IDLELIMIT;
    }

    return ret;
}
コード例 #2
0
ファイル: resume.c プロジェクト: xzcvczx/transmission
static uint64_t loadRatioLimits(tr_variant* dict, tr_torrent* tor)
{
    tr_variant* d;
    uint64_t ret = 0;

    if (tr_variantDictFindDict(dict, TR_KEY_ratio_limit, &d))
    {
        int64_t i;
        double dratio;

        if (tr_variantDictFindReal(d, TR_KEY_ratio_limit, &dratio))
        {
            tr_torrentSetRatioLimit(tor, dratio);
        }

        if (tr_variantDictFindInt(d, TR_KEY_ratio_mode, &i))
        {
            tr_torrentSetRatioMode(tor, i);
        }

        ret = TR_FR_RATIOLIMIT;
    }

    return ret;
}
コード例 #3
0
ファイル: resume.c プロジェクト: xzcvczx/transmission
static uint64_t loadSpeedLimits(tr_variant* dict, tr_torrent* tor)
{
    tr_variant* d;
    uint64_t ret = 0;

    if (tr_variantDictFindDict(dict, TR_KEY_speed_limit_up, &d))
    {
        loadSingleSpeedLimit(d, TR_UP, tor);
        ret = TR_FR_SPEEDLIMIT;
    }

    if (tr_variantDictFindDict(dict, TR_KEY_speed_limit_down, &d))
    {
        loadSingleSpeedLimit(d, TR_DOWN, tor);
        ret = TR_FR_SPEEDLIMIT;
    }

    return ret;
}
コード例 #4
0
ファイル: torrent-ctor.c プロジェクト: Kengi/Transmission
int
tr_ctorSetMetainfoFromFile (tr_ctor *    ctor,
                            const char * filename)
{
    uint8_t * metainfo;
    size_t    len;
    int       err;

    metainfo = tr_loadFile (filename, &len);
    if (metainfo && len)
        err = tr_ctorSetMetainfo (ctor, metainfo, len);
    else
    {
        clearMetainfo (ctor);
        err = 1;
    }

    setSourceFile (ctor, filename);

    /* if no `name' field was set, then set it from the filename */
    if (ctor->isSet_metainfo)
    {
        tr_variant * info;
        if (tr_variantDictFindDict (&ctor->metainfo, TR_KEY_info, &info))
        {
            const char * name;
            if (!tr_variantDictFindStr (info, TR_KEY_name_utf_8, &name, NULL))
                if (!tr_variantDictFindStr (info, TR_KEY_name, &name, NULL))
                    name = NULL;
            if (!name || !*name)
            {
                char * base = tr_sys_path_basename (filename, NULL);
                tr_variantDictAddStr (info, TR_KEY_name, base);
                tr_free (base);
            }
        }
    }

    tr_free (metainfo);
    return err;
}
コード例 #5
0
static void
on_scrape_done (tr_session   * session,
                bool           did_connect,
                bool           did_timeout,
                long           response_code,
                const void   * msg,
                size_t         msglen,
                void         * vdata)
{
    tr_scrape_response * response;
    struct scrape_data * data = vdata;

    response = &data->response;
    response->did_connect = did_connect;
    response->did_timeout = did_timeout;
    dbgmsg (data->log_name, "Got scrape response for \"%s\"", response->url);

    if (response_code != HTTP_OK)
    {
        const char * fmt = _("Tracker gave HTTP response code %1$ld (%2$s)");
        const char * response_str = tr_webGetResponseStr (response_code);
        response->errmsg = tr_strdup_printf (fmt, response_code, response_str);
    }
    else
    {
        tr_variant top;
        int64_t intVal;
        tr_variant * files;
        tr_variant * flags;
        size_t len;
        const char * str;
        const bool variant_loaded = !tr_variantFromBenc (&top, msg, msglen);

        if (getenv ("TR_CURL_VERBOSE") != NULL)
        {
            if (!variant_loaded)
                fprintf (stderr, "%s", "Scrape response was not in benc format\n");
            else {
                int i, len;
                char * str = tr_variantToStr (&top, TR_VARIANT_FMT_JSON, &len);
                fprintf (stderr, "%s", "Scrape response:\n< ");
                for (i=0; i<len; ++i)
                    fputc (str[i], stderr);
                fputc ('\n', stderr);
                tr_free (str);
            }
        }

        if (variant_loaded)
        {
            if (tr_variantDictFindStr (&top, TR_KEY_failure_reason, &str, &len))
                response->errmsg = tr_strndup (str, len);

            if (tr_variantDictFindDict (&top, TR_KEY_flags, &flags))
                if (tr_variantDictFindInt (flags, TR_KEY_min_request_interval, &intVal))
                    response->min_request_interval = intVal;

            if (tr_variantDictFindDict (&top, TR_KEY_files, &files))
            {
                int i = 0;

                for (;;)
                {
                    int j;
                    tr_quark key;
                    tr_variant * val;

                    /* get the next "file" */
                    if (!tr_variantDictChild (files, i++, &key, &val))
                        break;

                    /* populate the corresponding row in our response array */
                    for (j=0; j<response->row_count; ++j)
                    {
                        struct tr_scrape_response_row * row = &response->rows[j];
                        if (!memcmp (tr_quark_get_string(key,NULL), row->info_hash, SHA_DIGEST_LENGTH))
                        {
                            if (tr_variantDictFindInt (val, TR_KEY_complete, &intVal))
                                row->seeders = intVal;
                            if (tr_variantDictFindInt (val, TR_KEY_incomplete, &intVal))
                                row->leechers = intVal;
                            if (tr_variantDictFindInt (val, TR_KEY_downloaded, &intVal))
                                row->downloads = intVal;
                            if (tr_variantDictFindInt (val, TR_KEY_downloaders, &intVal))
                                row->downloaders = intVal;
                            break;
                        }
                    }
                }
            }

            tr_variantFree (&top);
        }
    }

    tr_runInEventThread (session, on_scrape_done_eventthread, data);
}
コード例 #6
0
ファイル: resume.c プロジェクト: xzcvczx/transmission
static uint64_t loadProgress(tr_variant* dict, tr_torrent* tor)
{
    uint64_t ret = 0;
    tr_variant* prog;
    tr_info const* inf = tr_torrentInfo(tor);

    for (size_t i = 0; i < inf->pieceCount; ++i)
    {
        inf->pieces[i].timeChecked = 0;
    }

    if (tr_variantDictFindDict(dict, TR_KEY_progress, &prog))
    {
        char const* err;
        char const* str;
        uint8_t const* raw;
        size_t rawlen;
        tr_variant* l;
        tr_variant* b;
        struct tr_bitfield blocks = TR_BITFIELD_INIT;

        if (tr_variantDictFindList(prog, TR_KEY_time_checked, &l))
        {
            /* per-piece timestamps were added in 2.20.

               If some of a file's pieces have been checked more recently than
               the file's mtime, and some lest 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. */

            for (tr_file_index_t fi = 0; fi < inf->fileCount; ++fi)
            {
                tr_variant* b = tr_variantListChild(l, fi);
                tr_file const* f = &inf->files[fi];

                if (tr_variantIsInt(b))
                {
                    int64_t t;
                    tr_variantGetInt(b, &t);

                    for (tr_piece_index_t i = f->firstPiece; i <= f->lastPiece; ++i)
                    {
                        inf->pieces[i].timeChecked = (time_t)t;
                    }
                }
                else if (tr_variantIsList(b))
                {
                    int64_t offset = 0;
                    int const pieces = f->lastPiece + 1 - f->firstPiece;

                    tr_variantGetInt(tr_variantListChild(b, 0), &offset);

                    for (int i = 0; i < pieces; ++i)
                    {
                        int64_t t = 0;
                        tr_variantGetInt(tr_variantListChild(b, i + 1), &t);
                        inf->pieces[f->firstPiece + i].timeChecked = (time_t)(t != 0 ? t + offset : 0);
                    }
                }
            }
        }
        else if (tr_variantDictFindList(prog, TR_KEY_mtimes, &l))
        {
            /* Before 2.20, we stored the files' mtimes in the .resume file.
               When loading the .resume file, a torrent's file would be flagged
               as untested if its stored mtime didn't match its real mtime. */

            for (tr_file_index_t fi = 0; fi < inf->fileCount; ++fi)
            {
                int64_t t;

                if (tr_variantGetInt(tr_variantListChild(l, fi), &t))
                {
                    tr_file const* f = &inf->files[fi];
                    time_t const mtime = tr_torrentGetFileMTime(tor, fi);
                    time_t const timeChecked = mtime == t ? mtime : 0;

                    for (tr_piece_index_t i = f->firstPiece; i <= f->lastPiece; ++i)
                    {
                        inf->pieces[i].timeChecked = timeChecked;
                    }
                }
            }
        }

        err = NULL;
        tr_bitfieldConstruct(&blocks, tor->blockCount);

        if ((b = tr_variantDictFind(prog, TR_KEY_blocks)) != NULL)
        {
            size_t buflen;
            uint8_t const* buf;

            if (!tr_variantGetRaw(b, &buf, &buflen))
            {
                err = "Invalid value for \"blocks\"";
            }
            else if (buflen == 3 && memcmp(buf, "all", 3) == 0)
            {
                tr_bitfieldSetHasAll(&blocks);
            }
            else if (buflen == 4 && memcmp(buf, "none", 4) == 0)
            {
                tr_bitfieldSetHasNone(&blocks);
            }
            else
            {
                tr_bitfieldSetRaw(&blocks, buf, buflen, true);
            }
        }
        else if (tr_variantDictFindStr(prog, TR_KEY_have, &str, NULL))
        {
            if (strcmp(str, "all") == 0)
            {
                tr_bitfieldSetHasAll(&blocks);
            }
            else
            {
                err = "Invalid value for HAVE";
            }
        }
        else if (tr_variantDictFindRaw(prog, TR_KEY_bitfield, &raw, &rawlen))
        {
            tr_bitfieldSetRaw(&blocks, raw, rawlen, true);
        }
        else
        {
            err = "Couldn't find 'pieces' or 'have' or 'bitfield'";
        }

        if (err != NULL)
        {
            tr_logAddTorDbg(tor, "Torrent needs to be verified - %s", err);
        }
        else
        {
            tr_cpBlockInit(&tor->completion, &blocks);
        }

        tr_bitfieldDestruct(&blocks);
        ret = TR_FR_PROGRESS;
    }

    return ret;
}
コード例 #7
0
ファイル: show.c プロジェクト: Javierortizc/transmission
static void
doScrape (const tr_info * inf)
{
  unsigned int i;

  for (i=0; i<inf->trackerCount; ++i)
    {
      CURL * curl;
      CURLcode res;
      struct evbuffer * buf;
      const char * scrape = inf->trackers[i].scrape;
      char * url;
      char escaped[SHA_DIGEST_LENGTH*3 + 1];

      if (scrape == NULL)
        continue;

      tr_http_escape_sha1 (escaped, inf->hash);

      url = tr_strdup_printf ("%s%cinfo_hash=%s",
                              scrape,
                              strchr (scrape, '?') ? '&' : '?',
                              escaped);

      printf ("%s ... ", url);
      fflush (stdout);

      buf = evbuffer_new ();
      curl = tr_curl_easy_init (buf);
      curl_easy_setopt (curl, CURLOPT_URL, url);
      curl_easy_setopt (curl, CURLOPT_TIMEOUT, TIMEOUT_SECS);

      if ((res = curl_easy_perform (curl)))
        {
          printf ("error: %s\n", curl_easy_strerror (res));
        }
      else
        {
          long response;
          curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response);
          if (response != 200)
            {
              printf ("error: unexpected response %ld \"%s\"\n",
                      response,
                      tr_webGetResponseStr (response));
            }
          else /* HTTP OK */
            {
              tr_variant top;
              tr_variant * files;
              bool matched = false;
              const char * begin = (const char*) evbuffer_pullup (buf, -1);

              if (!tr_variantFromBenc (&top, begin, evbuffer_get_length(buf)))
                {
                  if (tr_variantDictFindDict (&top, TR_KEY_files, &files))
                    {
                      int i = 0;
                      tr_quark key;
                      tr_variant * val;

                      while (tr_variantDictChild (files, i++, &key, &val))
                        {
                          if (memcmp (inf->hash, tr_quark_get_string (key, NULL), SHA_DIGEST_LENGTH) == 0)
                            {
                              int64_t seeders = -1;
                              int64_t leechers = -1;
                              tr_variantDictFindInt (val, TR_KEY_complete, &seeders);
                              tr_variantDictFindInt (val, TR_KEY_incomplete, &leechers);
                              printf ("%d seeders, %d leechers\n", (int)seeders, (int)leechers);
                              matched = true;
                            }
                        }
                    }

                  tr_variantFree (&top);
                }

              if (!matched)
                printf ("no match\n");
            }
        }

      curl_easy_cleanup (curl);
      evbuffer_free (buf);
      tr_free (url);
    }
}