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; }
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); } }
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); } }
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; }
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; }
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); }
int64_t gtr_pref_int_get (const tr_quark key) { int64_t i = 0; tr_variantDictFindInt (getPrefs (), key, &i); return i; }
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; }
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; }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
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); } }