Esempio n. 1
0
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;
}
Esempio n. 2
0
static void loadCumulativeStats(tr_session const* session, tr_session_stats* setme)
{
    tr_variant top;
    char* filename;
    bool loaded = false;

    filename = getFilename(session);
    loaded = tr_variantFromFile(&top, TR_VARIANT_FMT_JSON, filename, NULL);
    tr_free(filename);

    if (!loaded)
    {
        filename = getOldFilename(session);
        loaded = tr_variantFromFile(&top, TR_VARIANT_FMT_BENC, filename, NULL);
        tr_free(filename);
    }

    if (loaded)
    {
        int64_t i;

        if (tr_variantDictFindInt(&top, TR_KEY_downloaded_bytes, &i))
        {
            setme->downloadedBytes = (uint64_t)i;
        }

        if (tr_variantDictFindInt(&top, TR_KEY_files_added, &i))
        {
            setme->filesAdded = (uint64_t)i;
        }

        if (tr_variantDictFindInt(&top, TR_KEY_seconds_active, &i))
        {
            setme->secondsActive = (uint64_t)i;
        }

        if (tr_variantDictFindInt(&top, TR_KEY_session_count, &i))
        {
            setme->sessionCount = (uint64_t)i;
        }

        if (tr_variantDictFindInt(&top, TR_KEY_uploaded_bytes, &i))
        {
            setme->uploadedBytes = (uint64_t)i;
        }

        tr_variantFree(&top);
    }
}
Esempio n. 3
0
static void on_announce_done(tr_session * session, bool did_connect, bool did_timeout,
    long response_code, const void * msg, size_t msglen, void * vdata) {
    tr_announce_response * response;
    struct announce_data * data = vdata;
    response = &data->response;
    (...)

    // lê os dados da resposta do tracker
    if (variant_loaded && tr_variantIsDict(&benc)) {
        int64_t i; size_t len; tr_variant * tmp; // variáveis ...
        const char * str; const uint8_t * raw;   // ... temporárias

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

        if (tr_variantDictFindStr(&benc, TR_KEY_tracker_id, &str, &len))
            response->tracker_id_str = tr_strndup(str, len);

        if (tr_variantDictFindInt(&benc, TR_KEY_complete, &i))
            response->seeders = i;

        (...)

        if (tr_variantDictFindRaw(&benc, TR_KEY_peers, &raw, &len)) {
            response->pex = tr_peerMgrCompactToPex(raw, len,
            NULL, 0, &response->pex_count);
        }
        else if (tr_variantDictFindList(&benc, TR_KEY_peers, &tmp)) {
            response->pex = listToPex(tmp, &response->pex_count);
        }
    }
Esempio n. 4
0
static const char*
parseFiles (tr_info * inf, tr_variant * files, const tr_variant * length)
{
  int64_t len;

  inf->totalSize = 0;

  if (tr_variantIsList (files)) /* multi-file mode */
    {
      tr_file_index_t i;
      struct evbuffer * buf = evbuffer_new ();

      inf->isMultifile = 1;
      inf->fileCount = tr_variantListSize (files);
      inf->files = tr_new0 (tr_file, inf->fileCount);

      for (i=0; i<inf->fileCount; i++)
        {
          tr_variant * file;
          tr_variant * path;

          file = tr_variantListChild (files, i);
          if (!tr_variantIsDict (file))
            return "files";

          if (!tr_variantDictFindList (file, TR_KEY_path_utf_8, &path))
            if (!tr_variantDictFindList (file, TR_KEY_path, &path))
              return "path";

          if (!getfile (&inf->files[i].name, inf->name, path, buf))
            return "path";

          if (!tr_variantDictFindInt (file, TR_KEY_length, &len))
            return "length";

          inf->files[i].length = len;
          inf->totalSize      += len;
        }

      evbuffer_free (buf);
    }
  else if (tr_variantGetInt (length, &len)) /* single-file mode */
    {
      if (path_is_suspicious (inf->name))
        return "path";

      inf->isMultifile      = 0;
      inf->fileCount        = 1;
      inf->files            = tr_new0 (tr_file, 1);
      inf->files[0].name    = tr_strdup (inf->name);
      inf->files[0].length  = len;
      inf->totalSize       += len;
    }
  else
    {
      return "length";
    }

  return NULL;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
static void
loadSingleSpeedLimit (tr_variant * d, tr_direction dir, tr_torrent * tor)
{
  int64_t i;
  bool boolVal;

  if (tr_variantDictFindInt (d, TR_KEY_speed_Bps, &i))
    tr_torrentSetSpeedLimit_Bps (tor, dir, i);
  else if (tr_variantDictFindInt (d, TR_KEY_speed, &i))
    tr_torrentSetSpeedLimit_Bps (tor, dir, i*1024);

  if (tr_variantDictFindBool (d, TR_KEY_use_speed_limit, &boolVal))
    tr_torrentUseSpeedLimit (tor, dir, boolVal);

  if (tr_variantDictFindBool (d, TR_KEY_use_global_speed_limit, &boolVal))
    tr_torrentUseSessionLimits (tor, boolVal);
}
Esempio n. 7
0
int64_t
gtr_pref_int_get (const tr_quark key)
{
  int64_t i = 0;

  tr_variantDictFindInt (getPrefs (), key, &i);

  return i;
}
Esempio n. 8
0
static int test_elements(void)
{
    char const* in;
    tr_variant top;
    char const* str;
    bool f;
    double d;
    int64_t i;
    int err = 0;
    tr_quark key;

    in =
        "{ \"string\": \"hello world\","
        "  \"escaped\": \"bell \\b formfeed \\f linefeed \\n carriage return \\r tab \\t\","
        "  \"int\": 5, "
        "  \"float\": 6.5, "
        "  \"true\": true, "
        "  \"false\": false, "
        "  \"null\": null }";

    err = tr_variantFromJson(&top, in, strlen(in));
    check_int(err, ==, 0);
    check(tr_variantIsDict(&top));
    str = NULL;
    key = tr_quark_new("string", 6);
    check(tr_variantDictFindStr(&top, key, &str, NULL));
    check_str(str, ==, "hello world");
    check(tr_variantDictFindStr(&top, tr_quark_new("escaped", 7), &str, NULL));
    check_str(str, ==, "bell \b formfeed \f linefeed \n carriage return \r tab \t");
    i = 0;
    check(tr_variantDictFindInt(&top, tr_quark_new("int", 3), &i));
    check_int(i, ==, 5);
    d = 0;
    check(tr_variantDictFindReal(&top, tr_quark_new("float", 5), &d));
    check_int(((int)(d * 10)), ==, 65);
    f = false;
    check(tr_variantDictFindBool(&top, tr_quark_new("true", 4), &f));
    check_int(f, ==, true);
    check(tr_variantDictFindBool(&top, tr_quark_new("false", 5), &f));
    check_int(f, ==, false);
    check(tr_variantDictFindStr(&top, tr_quark_new("null", 4), &str, NULL));
    check_str(str, ==, "");

    if (err == 0)
    {
        tr_variantFree(&top);
    }

    return 0;
}
Esempio n. 9
0
static int
test_elements (void)
{
    const char * in;
    tr_variant top;
    const char * str;
    bool f;
    double d;
    int64_t i;
    int err = 0;
    tr_quark key;

    in = "{ \"string\": \"hello world\","
         "  \"escaped\": \"bell \\b formfeed \\f linefeed \\n carriage return \\r tab \\t\","
         "  \"int\": 5, "
         "  \"float\": 6.5, "
         "  \"true\": true, "
         "  \"false\": false, "
         "  \"null\": null }";

    err = tr_variantFromJson (&top, in, strlen(in));
    check_int_eq (0, err);
    check (tr_variantIsDict (&top));
    str = NULL;
    key = tr_quark_new ("string", 6);
    check (tr_variantDictFindStr (&top, key, &str, NULL));
    check_streq ("hello world", str);
    check (tr_variantDictFindStr (&top, tr_quark_new("escaped",7), &str, NULL));
    check_streq ("bell \b formfeed \f linefeed \n carriage return \r tab \t", str);
    i = 0;
    check (tr_variantDictFindInt (&top, tr_quark_new("int",3), &i));
    check_int_eq (5, i);
    d = 0;
    check (tr_variantDictFindReal (&top, tr_quark_new("float",5), &d));
    check_int_eq (65, ((int)(d*10)));
    f = false;
    check (tr_variantDictFindBool (&top, tr_quark_new("true",4), &f));
    check_int_eq (true, f);
    check (tr_variantDictFindBool (&top, tr_quark_new("false",5), &f));
    check_int_eq (false, f);
    check (tr_variantDictFindStr (&top, tr_quark_new("null",4), &str, NULL));
    check_streq ("", str);

    if (!err)
        tr_variantFree (&top);

    return 0;
}
Esempio n. 10
0
static int test1(void)
{
    char const* in =
        "{\n"
        "    \"headers\": {\n"
        "        \"type\": \"request\",\n"
        "        \"tag\": 666\n"
        "    },\n"
        "    \"body\": {\n"
        "        \"name\": \"torrent-info\",\n"
        "        \"arguments\": {\n"
        "            \"ids\": [ 7, 10 ]\n"
        "        }\n"
        "    }\n"
        "}\n";
    tr_variant top;
    tr_variant* headers;
    tr_variant* body;
    tr_variant* args;
    tr_variant* ids;
    char const* str;
    int64_t i;
    int const err = tr_variantFromJson(&top, in, strlen(in));

    check_int(err, ==, 0);
    check(tr_variantIsDict(&top));
    check_ptr((headers = tr_variantDictFind(&top, tr_quark_new("headers", 7))), !=, NULL);
    check(tr_variantIsDict(headers));
    check(tr_variantDictFindStr(headers, tr_quark_new("type", 4), &str, NULL));
    check_str(str, ==, "request");
    check(tr_variantDictFindInt(headers, TR_KEY_tag, &i));
    check_int(i, ==, 666);
    check_ptr((body = tr_variantDictFind(&top, tr_quark_new("body", 4))), !=, NULL);
    check(tr_variantDictFindStr(body, TR_KEY_name, &str, NULL));
    check_str(str, ==, "torrent-info");
    check_ptr((args = tr_variantDictFind(body, tr_quark_new("arguments", 9))), !=, NULL);
    check(tr_variantIsDict(args));
    check_ptr((ids = tr_variantDictFind(args, TR_KEY_ids)), !=, NULL);
    check(tr_variantIsList(ids));
    check_uint(tr_variantListSize(ids), ==, 2);
    check(tr_variantGetInt(tr_variantListChild(ids, 0), &i));
    check_int(i, ==, 7);
    check(tr_variantGetInt(tr_variantListChild(ids, 1), &i));
    check_int(i, ==, 10);

    tr_variantFree(&top);
    return 0;
}
Esempio n. 11
0
static int
test1 (void)
{
    const char * in =
        "{\n"
        "    \"headers\": {\n"
        "        \"type\": \"request\",\n"
        "        \"tag\": 666\n"
        "    },\n"
        "    \"body\": {\n"
        "        \"name\": \"torrent-info\",\n"
        "        \"arguments\": {\n"
        "            \"ids\": [ 7, 10 ]\n"
        "        }\n"
        "    }\n"
        "}\n";
    tr_variant      top, *headers, *body, *args, *ids;
    const char * str;
    int64_t      i;
    const int    err = tr_variantFromJson (&top, in, strlen(in));

    check (!err);
    check (tr_variantIsDict (&top));
    check ((headers = tr_variantDictFind (&top, tr_quark_new("headers",7))));
    check (tr_variantIsDict (headers));
    check (tr_variantDictFindStr (headers, tr_quark_new("type",4), &str, NULL));
    check_streq ("request", str);
    check (tr_variantDictFindInt (headers, TR_KEY_tag, &i));
    check_int_eq (666, i);
    check ((body = tr_variantDictFind (&top, tr_quark_new("body",4))));
    check (tr_variantDictFindStr (body, TR_KEY_name, &str, NULL));
    check_streq ("torrent-info", str);
    check ((args = tr_variantDictFind (body, tr_quark_new("arguments",9))));
    check (tr_variantIsDict (args));
    check ((ids = tr_variantDictFind (args, TR_KEY_ids)));
    check (tr_variantIsList (ids));
    check_int_eq (2, tr_variantListSize (ids));
    check (tr_variantGetInt (tr_variantListChild (ids, 0), &i));
    check_int_eq (7, i);
    check (tr_variantGetInt (tr_variantListChild (ids, 1), &i));
    check_int_eq (10, i);

    tr_variantFree (&top);
    return 0;
}
Esempio n. 12
0
static tr_pex*
listToPex (tr_variant * peerList, size_t * setme_len)
{
    size_t i;
    size_t n;
    const size_t len = tr_variantListSize (peerList);
    tr_pex * pex = tr_new0 (tr_pex, len);

    for (i=n=0; i<len; ++i)
    {
        int64_t port;
        const char * ip;
        tr_address addr;
        tr_variant * peer = tr_variantListChild (peerList, i);

        if (peer == NULL)
            continue;
        if (!tr_variantDictFindStr (peer, TR_KEY_ip, &ip, NULL))
            continue;
        if (!tr_address_from_string (&addr, ip))
            continue;
        if (!tr_variantDictFindInt (peer, TR_KEY_port, &port))
            continue;
        if ((port < 0) || (port > USHRT_MAX))
            continue;
        if (!tr_address_is_valid_for_peers (&addr, port))
            continue;

        pex[n].addr = addr;
        pex[n].port = htons ((uint16_t)port);
        ++n;
    }

    *setme_len = n;
    return pex;
}
Esempio n. 13
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);
}
Esempio n. 14
0
static void
on_announce_done (tr_session   * session,
                  bool           did_connect,
                  bool           did_timeout,
                  long           response_code,
                  const void   * msg,
                  size_t         msglen,
                  void         * vdata)
{
    tr_announce_response * response;
    struct announce_data * data = vdata;

    response = &data->response;
    response->did_connect = did_connect;
    response->did_timeout = did_timeout;
    dbgmsg (data->log_name, "Got announce response");

    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 benc;
        const bool variant_loaded = !tr_variantFromBenc (&benc, msg, msglen);

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

        if (variant_loaded && tr_variantIsDict (&benc))
        {
            int64_t i;
            size_t len;
            tr_variant * tmp;
            const char * str;
            const uint8_t * raw;

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

            if (tr_variantDictFindStr (&benc, TR_KEY_warning_message, &str, &len))
                response->warning = tr_strndup (str, len);

            if (tr_variantDictFindInt (&benc, TR_KEY_interval, &i))
                response->interval = i;

            if (tr_variantDictFindInt (&benc, TR_KEY_min_interval, &i))
                response->min_interval = i;

            if (tr_variantDictFindStr (&benc, TR_KEY_tracker_id, &str, &len))
                response->tracker_id_str = tr_strndup (str, len);

            if (tr_variantDictFindInt (&benc, TR_KEY_complete, &i))
                response->seeders = i;

            if (tr_variantDictFindInt (&benc, TR_KEY_incomplete, &i))
                response->leechers = i;

            if (tr_variantDictFindInt (&benc, TR_KEY_downloaded, &i))
                response->downloads = i;

            if (tr_variantDictFindRaw (&benc, TR_KEY_peers6, &raw, &len)) {
                dbgmsg (data->log_name, "got a peers6 length of %zu", len);
                response->pex6 = tr_peerMgrCompact6ToPex (raw, len,
                                              NULL, 0, &response->pex6_count);
            }

            if (tr_variantDictFindRaw (&benc, TR_KEY_peers, &raw, &len)) {
                dbgmsg (data->log_name, "got a compact peers length of %zu", len);
                response->pex = tr_peerMgrCompactToPex (raw, len,
                                               NULL, 0, &response->pex_count);
            } else if (tr_variantDictFindList (&benc, TR_KEY_peers, &tmp)) {
                response->pex = listToPex (tmp, &response->pex_count);
                dbgmsg (data->log_name, "got a peers list with %zu entries",
                        response->pex_count);
            }
        }

        if (variant_loaded)
            tr_variantFree (&benc);
    }

    tr_runInEventThread (session, on_announce_done_eventthread, data);
}
Esempio n. 15
0
static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const* length)
{
    int64_t len;

    inf->totalSize = 0;

    if (tr_variantIsList(files)) /* multi-file mode */
    {
        struct evbuffer* buf;
        char const* result;

        if (path_component_is_suspicious(inf->name))
        {
            return "path";
        }

        buf = evbuffer_new();
        result = NULL;

        inf->isFolder = true;
        inf->fileCount = tr_variantListSize(files);
        inf->files = tr_new0(tr_file, inf->fileCount);

        for (tr_file_index_t i = 0; i < inf->fileCount; i++)
        {
            tr_variant* file;
            tr_variant* path;

            file = tr_variantListChild(files, i);

            if (!tr_variantIsDict(file))
            {
                result = "files";
                break;
            }

            if (!tr_variantDictFindList(file, TR_KEY_path_utf_8, &path))
            {
                if (!tr_variantDictFindList(file, TR_KEY_path, &path))
                {
                    result = "path";
                    break;
                }
            }

            if (!getfile(&inf->files[i].name, inf->name, path, buf))
            {
                result = "path";
                break;
            }

            if (!tr_variantDictFindInt(file, TR_KEY_length, &len))
            {
                result = "length";
                break;
            }

            inf->files[i].length = len;
            inf->totalSize += len;
        }

        evbuffer_free(buf);
        return result;
    }
    else if (tr_variantGetInt(length, &len)) /* single-file mode */
    {
        if (path_component_is_suspicious(inf->name))
        {
            return "path";
        }

        inf->isFolder = false;
        inf->fileCount = 1;
        inf->files = tr_new0(tr_file, 1);
        inf->files[0].name = tr_strdup(inf->name);
        inf->files[0].length = len;
        inf->totalSize += len;
    }
    else
    {
        return "length";
    }

    return NULL;
}
Esempio n. 16
0
static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad)
{
    TR_ASSERT(tr_isTorrent(tor));

    size_t len;
    int64_t i;
    char const* str;
    char* filename;
    tr_variant top;
    bool boolVal;
    uint64_t fieldsLoaded = 0;
    bool const wasDirty = tor->isDirty;
    tr_error* error = NULL;

    filename = getResumeFilename(tor);

    if (!tr_variantFromFile(&top, TR_VARIANT_FMT_BENC, filename, &error))
    {
        tr_logAddTorDbg(tor, "Couldn't read \"%s\": %s", filename, error->message);
        tr_error_free(error);

        tr_free(filename);
        return fieldsLoaded;
    }

    tr_logAddTorDbg(tor, "Read resume file \"%s\"", filename);

    if ((fieldsToLoad & TR_FR_CORRUPT) != 0 && tr_variantDictFindInt(&top, TR_KEY_corrupt, &i))
    {
        tor->corruptPrev = i;
        fieldsLoaded |= TR_FR_CORRUPT;
    }

    if ((fieldsToLoad & (TR_FR_PROGRESS | TR_FR_DOWNLOAD_DIR)) != 0 &&
        tr_variantDictFindStr(&top, TR_KEY_destination, &str, &len) && str != NULL && *str != '\0')
    {
        bool const is_current_dir = tor->currentDir == tor->downloadDir;
        tr_free(tor->downloadDir);
        tor->downloadDir = tr_strndup(str, len);

        if (is_current_dir)
        {
            tor->currentDir = tor->downloadDir;
        }

        fieldsLoaded |= TR_FR_DOWNLOAD_DIR;
    }

    if ((fieldsToLoad & (TR_FR_PROGRESS | TR_FR_INCOMPLETE_DIR)) != 0 &&
        tr_variantDictFindStr(&top, TR_KEY_incomplete_dir, &str, &len) && str != NULL && *str != '\0')
    {
        bool const is_current_dir = tor->currentDir == tor->incompleteDir;
        tr_free(tor->incompleteDir);
        tor->incompleteDir = tr_strndup(str, len);

        if (is_current_dir)
        {
            tor->currentDir = tor->incompleteDir;
        }

        fieldsLoaded |= TR_FR_INCOMPLETE_DIR;
    }

    if ((fieldsToLoad & TR_FR_DOWNLOADED) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloaded, &i))
    {
        tor->downloadedPrev = i;
        fieldsLoaded |= TR_FR_DOWNLOADED;
    }

    if ((fieldsToLoad & TR_FR_UPLOADED) != 0 && tr_variantDictFindInt(&top, TR_KEY_uploaded, &i))
    {
        tor->uploadedPrev = i;
        fieldsLoaded |= TR_FR_UPLOADED;
    }

    if ((fieldsToLoad & TR_FR_MAX_PEERS) != 0 && tr_variantDictFindInt(&top, TR_KEY_max_peers, &i))
    {
        tor->maxConnectedPeers = i;
        fieldsLoaded |= TR_FR_MAX_PEERS;
    }

    if ((fieldsToLoad & TR_FR_RUN) != 0 && tr_variantDictFindBool(&top, TR_KEY_paused, &boolVal))
    {
        tor->isRunning = !boolVal;
        fieldsLoaded |= TR_FR_RUN;
    }

    if ((fieldsToLoad & TR_FR_ADDED_DATE) != 0 && tr_variantDictFindInt(&top, TR_KEY_added_date, &i))
    {
        tor->addedDate = i;
        fieldsLoaded |= TR_FR_ADDED_DATE;
    }

    if ((fieldsToLoad & TR_FR_DONE_DATE) != 0 && tr_variantDictFindInt(&top, TR_KEY_done_date, &i))
    {
        tor->doneDate = i;
        fieldsLoaded |= TR_FR_DONE_DATE;
    }

    if ((fieldsToLoad & TR_FR_ACTIVITY_DATE) != 0 && tr_variantDictFindInt(&top, TR_KEY_activity_date, &i))
    {
        tr_torrentSetActivityDate(tor, i);
        fieldsLoaded |= TR_FR_ACTIVITY_DATE;
    }

    if ((fieldsToLoad & TR_FR_TIME_SEEDING) != 0 && tr_variantDictFindInt(&top, TR_KEY_seeding_time_seconds, &i))
    {
        tor->secondsSeeding = i;
        fieldsLoaded |= TR_FR_TIME_SEEDING;
    }

    if ((fieldsToLoad & TR_FR_TIME_DOWNLOADING) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloading_time_seconds, &i))
    {
        tor->secondsDownloading = i;
        fieldsLoaded |= TR_FR_TIME_DOWNLOADING;
    }

    if ((fieldsToLoad & TR_FR_BANDWIDTH_PRIORITY) != 0 &&
        tr_variantDictFindInt(&top, TR_KEY_bandwidth_priority, &i) && tr_isPriority(i))
    {
        tr_torrentSetPriority(tor, i);
        fieldsLoaded |= TR_FR_BANDWIDTH_PRIORITY;
    }

    if ((fieldsToLoad & TR_FR_PEERS) != 0)
    {
        fieldsLoaded |= loadPeers(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_FILE_PRIORITIES) != 0)
    {
        fieldsLoaded |= loadFilePriorities(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_PROGRESS) != 0)
    {
        fieldsLoaded |= loadProgress(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_DND) != 0)
    {
        fieldsLoaded |= loadDND(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_SPEEDLIMIT) != 0)
    {
        fieldsLoaded |= loadSpeedLimits(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_RATIOLIMIT) != 0)
    {
        fieldsLoaded |= loadRatioLimits(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_IDLELIMIT) != 0)
    {
        fieldsLoaded |= loadIdleLimits(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_FILENAMES) != 0)
    {
        fieldsLoaded |= loadFilenames(&top, tor);
    }

    if ((fieldsToLoad & TR_FR_NAME) != 0)
    {
        fieldsLoaded |= loadName(&top, tor);
    }

    /* loading the resume file triggers of a lot of changes,
     * but none of them needs to trigger a re-saving of the
     * same resume information... */
    tor->isDirty = wasDirty;

    tr_variantFree(&top);
    tr_free(filename);
    return fieldsLoaded;
}
Esempio n. 17
0
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);
    }
}