bool TorrentObject::LoadFromPath(const tr_session* Session, const char* TorrentPath) { tr_ctor* ctor = tr_ctorNew(Session); tr_ctorSetPaused(ctor, TR_FORCE, TRUE); if( tr_ctorSetMetainfoFromFile(ctor, TorrentPath) != TR_PARSE_OK ) return false; // // fTorrentHandle = tr_torrentNew(ctor, NULL); tr_ctorFree(ctor); if( fTorrentHandle == NULL ) return false; fInfo = tr_torrentInfo(fTorrentHandle); fStatistics = tr_torrentStat(fTorrentHandle); return true; }
void libttest_zero_torrent_populate (tr_torrent * tor, bool complete) { tr_file_index_t i; for (i=0; i<tor->info.fileCount; ++i) { int err; uint64_t j; FILE * fp; char * path; char * dirname; const tr_file * file = &tor->info.files[i]; struct stat sb; if (!complete && (i==0)) path = tr_strdup_printf ("%s%c%s.part", tor->currentDir, TR_PATH_DELIMITER, file->name); else path = tr_strdup_printf ("%s%c%s", tor->currentDir, TR_PATH_DELIMITER, file->name); dirname = tr_dirname (path); tr_mkdirp (dirname, 0700); fp = fopen (path, "wb+"); for (j=0; j<file->length; ++j) fputc (((!complete) && (i==0) && (j<tor->info.pieceSize)) ? '\1' : '\0', fp); fclose (fp); tr_free (dirname); tr_free (path); path = tr_torrentFindFile (tor, i); assert (path != NULL); err = errno; errno = 0; stat (path, &sb); assert (errno == 0); errno = err; tr_free (path); } sync (); libttest_blockingTorrentVerify (tor); if (complete) assert (tr_torrentStat(tor)->leftUntilDone == 0); else assert (tr_torrentStat(tor)->leftUntilDone == tor->info.pieceSize); }
bool TorrentObject::LoadFromHandle(tr_torrent* TorrentHandle) { fTorrentHandle = TorrentHandle; fInfo = tr_torrentInfo(fTorrentHandle); fStatistics = tr_torrentStat(fTorrentHandle); return true; }
void libttest_zero_torrent_populate (tr_torrent * tor, bool complete) { tr_file_index_t i; for (i=0; i<tor->info.fileCount; ++i) { int err; uint64_t j; tr_sys_file_t fd; char * path; char * dirname; const tr_file * file = &tor->info.files[i]; if (!complete && (i==0)) path = tr_strdup_printf ("%s%c%s.part", tor->currentDir, TR_PATH_DELIMITER, file->name); else path = tr_strdup_printf ("%s%c%s", tor->currentDir, TR_PATH_DELIMITER, file->name); dirname = tr_sys_path_dirname (path, NULL); tr_sys_dir_create (dirname, TR_SYS_DIR_CREATE_PARENTS, 0700, NULL); fd = tr_sys_file_open (path, TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE, 0600, NULL); for (j=0; j<file->length; ++j) tr_sys_file_write (fd, ((!complete) && (i==0) && (j<tor->info.pieceSize)) ? "\1" : "\0", 1, NULL, NULL); tr_sys_file_close (fd, NULL); tr_free (dirname); tr_free (path); path = tr_torrentFindFile (tor, i); assert (path != NULL); err = errno; assert (tr_sys_path_exists (path, NULL)); errno = err; tr_free (path); } libttest_sync (); libttest_blockingTorrentVerify (tor); if (complete) assert (tr_torrentStat(tor)->leftUntilDone == 0); else assert (tr_torrentStat(tor)->leftUntilDone == tor->info.pieceSize); }
int libbt_get_status(int index, struct libbt_status *st) { tr_stat_t *s; tr_torrent_t *tor = tor_list_get(index); if(tor) { MEMSET(st, 0, sizeof(struct libbt_status)); s = tr_torrentStat( tor ); st->status = s->status; st->downloaded = s->downloaded; st->uploaded = s->uploaded; st->progress = s->progress; st->left = s->left; if( s->status & TR_STATUS_DOWNLOAD ) { st->leechers = s->leechers; st->peersTotal = s->peersTotal; st->seeders = s->seeders; st->rateDownload = s->rateDownload; st->rateUpload = s->rateUpload; st->peersUploading = s->peersUploading; st->peersDownloading = s->peersDownloading; } else if( s->status & TR_STATUS_SEED ) { st->rateUpload = s->rateUpload; st->peersDownloading = s->peersDownloading; } return index; } return -1; }
void gtr_confirm_remove (GtkWindow * parent, TrCore * core, GSList * torrent_ids, gboolean delete_files) { GSList * l; GtkWidget * d; GString * primary_text; GString * secondary_text; struct delete_data * dd; int connected = 0; int incomplete = 0; const int count = g_slist_length (torrent_ids); if (!count) return; dd = g_new0 (struct delete_data, 1); dd->core = core; dd->torrent_ids = torrent_ids; dd->delete_files = delete_files; for (l=torrent_ids; l!=NULL; l=l->next) { const int id = GPOINTER_TO_INT (l->data); tr_torrent * tor = gtr_core_find_torrent (core, id); const tr_stat * stat = tr_torrentStat (tor); if (stat->leftUntilDone) ++incomplete; if (stat->peersConnected) ++connected; } primary_text = g_string_new (NULL); if (!delete_files) { g_string_printf (primary_text, ngettext ("Remove torrent?", "Remove %d torrents?", count), count); } else { g_string_printf (primary_text, ngettext ("Delete this torrent's downloaded files?", "Delete these %d torrents' downloaded files?", count), count); } secondary_text = g_string_new (NULL); if (!incomplete && !connected) { g_string_assign (secondary_text, ngettext ( "Once removed, continuing the transfer will require the torrent file or magnet link.", "Once removed, continuing the transfers will require the torrent files or magnet links.", count)); } else if (count == incomplete) { g_string_assign (secondary_text, ngettext ("This torrent has not finished downloading.", "These torrents have not finished downloading.", count)); } else if (count == connected) { g_string_assign (secondary_text, ngettext ("This torrent is connected to peers.", "These torrents are connected to peers.", count)); } else { if (connected) g_string_append (secondary_text, ngettext ("One of these torrents is connected to peers.", "Some of these torrents are connected to peers.", connected)); if (connected && incomplete) g_string_append (secondary_text, "\n"); if (incomplete) g_string_assign (secondary_text, ngettext ("One of these torrents has not finished downloading.", "Some of these torrents have not finished downloading.", incomplete)); } d = gtk_message_dialog_new_with_markup (parent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "<big><b>%s</b></big>", primary_text->str); if (secondary_text->len) gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (d), "%s", secondary_text->str); gtk_dialog_add_buttons (GTK_DIALOG (d), _("_Cancel"), GTK_RESPONSE_CANCEL, (delete_files ? _("_Delete") : _("_Remove")), GTK_RESPONSE_ACCEPT, NULL); gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_CANCEL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (d), GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL, -1); g_signal_connect (d, "response", G_CALLBACK (on_remove_dialog_response), dd); gtk_widget_show_all (d); g_string_free (primary_text, TRUE); g_string_free (secondary_text, TRUE); }
/******************************************************************************* * main ******************************************************************************/ int main(int argc, char ** argv) { /* vars */ int i, error, nat; tr_handle_t * h; tr_torrent_t * tor; tr_stat_t * s; double tf_sharing = 0.0; char tf_string[80]; int tf_seeders, tf_leechers; /* Get options */ if (parseCommandLine(argc, argv)) { printf("Transmission %s [%d] - tfCLI [%d]\nhttp://transmission.m0k.org/ - http://tf-b4rt.berlios.de/\n\n", VERSION_STRING, VERSION_REVISION, VERSION_REVISION_CLI); printf(USAGE, argv[0], TR_DEFAULT_PORT); return 1; } /* show help */ if (showHelp) { printf("Transmission %s [%d] - tfCLI [%d]\nhttp://transmission.m0k.org/ - http://tf-b4rt.berlios.de/\n\n", VERSION_STRING, VERSION_REVISION, VERSION_REVISION_CLI); printf(USAGE, argv[0], TR_DEFAULT_PORT); return 0; } // verbose if (verboseLevel < 0) { verboseLevel = 0; } else if (verboseLevel > 9) { verboseLevel = 9; } if (verboseLevel) { static char env[11]; sprintf(env, "TR_DEBUG=%d", verboseLevel); putenv(env); } // check port if (bindPort < 1 || bindPort > 65535) { printf("Invalid port '%d'\n", bindPort); return 1; } // Initialize libtransmission h = tr_init(); // Open and parse torrent file if (!(tor = tr_torrentInit(h, torrentPath, 0, &error))) { printf("Failed opening torrent file `%s'\n", torrentPath); goto failed; } /* show info */ if (showInfo) { // info tr_info_t * info = tr_torrentInfo(tor); // stat s = tr_torrentStat(tor); // Print torrent info (quite à la btshowmetainfo) printf("hash: "); for (i = 0; i < SHA_DIGEST_LENGTH; i++) { printf("%02x", info->hash[i]); } printf("\n"); printf( "tracker: %s:%d\n", s->trackerAddress, s->trackerPort ); printf( "announce: %s\n", s->trackerAnnounce ); printf("size: %"PRIu64" (%"PRIu64" * %d + %"PRIu64")\n", info->totalSize, info->totalSize / info->pieceSize, info->pieceSize, info->totalSize % info->pieceSize); if (info->comment[0]) { printf("comment: %s\n", info->comment); } if (info->creator[0]) { printf("creator: %s\n", info->creator); } printf("file(s):\n"); for (i = 0; i < info->fileCount; i++) { printf(" %s (%"PRIu64")\n", info->files[i].name, info->files[i].length); } // cleanup goto cleanup; } /* show scrape */ if (showScrape) { int seeders, leechers, downloaded; if (tr_torrentScrape(tor, &seeders, &leechers, &downloaded)) { printf("Scrape failed.\n"); } else { printf("%d seeder(s), %d leecher(s), %d download(s).\n", seeders, leechers, downloaded); } // cleanup goto cleanup; } /* start up transmission */ // Create PID file if wanted by user if (tf_pid != NULL) { FILE * pid_file; pid_file = fopen(tf_pid, "w+"); if (pid_file != NULL) { fprintf(pid_file, "%d", getpid()); fclose(pid_file); } } // signal signal(SIGINT, sigHandler); // If running torrentflux, Download limit = 0 means no limit if (tf_stat_file != NULL) { /* tfCLI */ // up switch (uploadLimit) { case 0: uploadLimit = -1; break; case -2: uploadLimit = 0; break; } // down switch (downloadLimit) { case 0: downloadLimit = -1; break; case -2: downloadLimit = 0; break; } } // init some things tr_setBindPort(h, bindPort); tr_setGlobalUploadLimit(h, uploadLimit); tr_setGlobalDownloadLimit(h, downloadLimit); // nat-traversal if (natTraversal) { tr_natTraversalEnable(h); } else { tr_natTraversalDisable(h); } // set folder tr_torrentSetFolder(tor, "."); // start the torrent tr_torrentStart(tor); /* main-loop */ while (!mustDie) { // status-string char string[80]; int chars = 0; // int result; char stat_state; // sleep sleep(displayInterval); // Check if we must stop if (tf_stat_file != NULL) { /* tfCLI */ tf_stat = fopen(tf_stat_file, "r"); if (tf_stat != NULL) { // Get state stat_state = fgetc(tf_stat); // Close the file fclose(tf_stat); // Torrentflux asked to shutdown the torrent if (stat_state == '0') { mustDie = 1; } } } // torrent-stat s = tr_torrentStat(tor); if (s->status & TR_STATUS_CHECK) { /* --- CHECK --- */ if (tf_stat_file == NULL) { /* standalone */ // status-string chars = snprintf(string, 80, "Checking files... %.2f %%", 100.0 * s->progress ); } else { /* tfCLI */ // write tf-stat-file tr_info_t * info = tr_torrentInfo(tor); tf_stat = fopen(tf_stat_file, "w+"); if (tf_stat != NULL) { fprintf(tf_stat, "%d\n%.1f\n%s\n0 kB/s\n0 kB/s\n%s\n0\n0\n0.0\n%d\n0\n%" PRIu64 "\n%" PRIu64, 1, /* State */ 100.0 * s->progress, /* checking progress */ "Checking existing data", /* State text */ /* download speed */ /* upload speed */ tf_user, /* user */ /* seeds */ /* peers */ /* sharing */ seedLimit, /* seedlimit */ /* uploaded bytes */ s->downloaded, /* downloaded bytes */ info->totalSize); /* global size */ fclose(tf_stat); } } } else if (s->status & TR_STATUS_DOWNLOAD) { /* --- DOWNLOAD --- */ if (tf_stat_file == NULL) { /* standalone */ // status-string chars = snprintf(string, 80, "Progress: %.2f %%, %d peer%s, dl from %d (%.2f KB/s), " "ul to %d (%.2f KB/s)", 100.0 * s->progress, s->peersTotal, ( s->peersTotal == 1 ) ? "" : "s", s->peersUploading, s->rateDownload, s->peersDownloading, s->rateUpload); } else { /* tfCLI */ // sharing if (s->downloaded != 0) { tf_sharing = ((double)(s->uploaded) / (double)(s->downloaded)) * 100; } // seeders + leechers if (s->seeders < 0) { tf_seeders = 0; } else { tf_seeders = s->seeders; } if (s->leechers < 0) { tf_leechers = 0; } else { tf_leechers = s->leechers; } // eta if (s->eta != -1) { // sanity-check. value of eta >= 7 days is not really of use if (s->eta < 604800) { if ((s->eta / (24 * 60 * 60)) != 0) { sprintf(tf_string,"%d:%02d:%02d:%02d", s->eta / (24 * 60 * 60), ((s->eta) % (24 * 60 * 60)) / (60 * 60), ((s->eta) % (60 * 60) / 60), s->eta % 60); } else if ((s->eta / (60 * 60)) != 0) { sprintf(tf_string, "%d:%02d:%02d", (s->eta) / (60 * 60), ((s->eta) % (60 * 60) / 60), s->eta % 60); } else { sprintf(tf_string, "%d:%02d", (s->eta) / 60, s->eta % 60); } } else { sprintf(tf_string,"-"); } } else { sprintf(tf_string,"-"); } if ((s->seeders == -1) && (s->peersTotal == 0)) { sprintf(tf_string,"Connecting to Peers"); } // write tf-stat-file tf_stat = fopen(tf_stat_file, "w+"); if (tf_stat != NULL) { tr_info_t * info = tr_torrentInfo( tor ); fprintf(tf_stat, "%d\n%.1f\n%s\n%.1f kB/s\n%.1f kB/s\n%s\n%d (%d)\n%d (%d)\n%.1f\n%d\n%" PRIu64 "\n%" PRIu64 "\n%" PRIu64, 1, /* State */ 100.0 * s->progress, /* progress */ tf_string, /* Estimated time */ s->rateDownload, /* download speed */ s->rateUpload, /* upload speed */ tf_user, /* user */ s->peersUploading, tf_seeders, /* seeds */ s->peersDownloading, tf_leechers, /* peers */ tf_sharing, /* sharing */ seedLimit, /* seedlimit */ s->uploaded, /* uploaded bytes */ s->downloaded, /* downloaded bytes */ info->totalSize); /* global size */ fclose(tf_stat); } } } else if (s->status & TR_STATUS_SEED) { /* --- SEED --- */ // info tr_info_t * info = tr_torrentInfo(tor); if (tf_stat_file == NULL) { /* standalone */ // status-string chars = snprintf(string, 80, "Seeding, uploading to %d of %d peer(s), %.2f KB/s", s->peersDownloading, s->peersTotal, s->rateUpload); } else { /* tfCLI */ // sharing if (s->downloaded != 0) { tf_sharing = ((double)(s->uploaded) / (double)(s->downloaded)) * 100; } else { tf_sharing = ((double)(s->uploaded) / (double)(info->totalSize)) * 100; } // If we reached the seeding limit, we have to quit transmission if ((seedLimit != 0) && ((tf_sharing > (double)(seedLimit)) || (seedLimit == -1))) { mustDie = 1; } // seeders + leechers if (s->seeders < 0) { tf_seeders = 0; } else { tf_seeders = s->seeders; } if (s->leechers < 0) { tf_leechers = 0; } else { tf_leechers = s->leechers; } // write tf-stat-file tf_stat = fopen(tf_stat_file, "w+"); if (tf_stat != NULL) { fprintf(tf_stat, "%d\n%.1f\n%s\n%.1f kB/s\n%.1f kB/s\n%s\n%d (%d)\n%d (%d)\n%.1f\n%d\n%" PRIu64 "\n%" PRIu64 "\n%" PRIu64, 1, /* State */ 100.0 * s->progress, /* progress */ "Download Succeeded!", /* State text */ s->rateDownload, /* download speed */ s->rateUpload, /* upload speed */ tf_user, /* user */ s->peersUploading, tf_seeders, /* seeds */ s->peersDownloading, tf_leechers, /* peers */ tf_sharing, /* sharing */ seedLimit, /* seedlimit */ s->uploaded, /* uploaded bytes */ s->downloaded, /* downloaded bytes */ info->totalSize); /* global size */ fclose(tf_stat); } } } // status-string if (tf_stat_file == NULL) { /* standalone */ memset( &string[chars], ' ', 79 - chars ); string[79] = '\0'; // print status to stderr fprintf(stderr, "\r%s", string); } // errors if (s->error & TR_ETRACKER) { if (tf_stat_file == NULL) { /* standalone */ // print errors to stderr fprintf(stderr, "\n%s\n", s->trackerError); } else { /* tfCLI */ // append errors to stat-file tf_stat = fopen(tf_stat_file, "a+"); if (tf_stat != NULL) { fprintf(tf_stat, "\n%s\n", s->trackerError); fclose(tf_stat); } } } else if (verboseLevel > 0) { if (tf_stat_file == NULL) { /* standalone */ // stderr fprintf(stderr, "\n"); } } // finishCall if (tr_getFinished(tor)) { result = system(finishCall); } } /* main-loop */ // mark torrent as stopped in tf-stat-file if (tf_stat_file != NULL) { /* tfCLI */ // info tr_info_t * info = tr_torrentInfo(tor); // sharing if (s->downloaded != 0) { tf_sharing = ((double)(s->uploaded) / (double)(s->downloaded)) * 100; } else { tf_sharing = ((double)(s->uploaded) / (double)(info->totalSize)) * 100; } // write tf-stat-file tf_stat = fopen(tf_stat_file, "w+"); if (tf_stat != NULL) { float progress; if (s->status & TR_STATUS_SEED) { sprintf(tf_string,"Download Succeeded!"); progress = 100; } else { sprintf(tf_string,"Torrent Stopped"); progress = -(1 + s->progress) * 100; } fprintf(tf_stat, "%d\n%.1f\n%s\n\n\n%s\n\n\n%.1f\n%d\n%" PRIu64 "\n%" PRIu64 "\n%" PRIu64, 0, /* State */ progress, /* progress */ tf_string, /* State text */ /* download speed */ /* upload speed */ tf_user, /* user */ /* seeds */ /* peers */ tf_sharing, /* sharing */ seedLimit, /* seedlimit */ s->uploaded, /* uploaded bytes */ s->downloaded, /* downloaded bytes */ info->totalSize); /* global size */ fclose(tf_stat); } } // stderr if (tf_stat_file == NULL) { /* standalone */ fprintf(stderr, "\n"); } // Try for 5 seconds to notify the tracker that we are leaving // and to delete any port mappings for nat traversal tr_torrentStop(tor); tr_natTraversalDisable(h); for (i = 0; i < 10; i++) { s = tr_torrentStat(tor); nat = tr_natTraversalStatus(h); if (s->status & TR_STATUS_PAUSE && TR_NAT_TRAVERSAL_DISABLED == nat) { // The 'stopped' tracker message was sent // and port mappings were deleted break; } usleep(500000); } // Remove PID file if created ! if (tf_pid != NULL) { remove(tf_pid); } cleanup: tr_torrentClose(h, tor); failed: tr_close(h); return 0; }
// // @INFO: Use TorrentObject::Statistics directly. // void TorrentObject::Update() { fStatistics = tr_torrentStat(fTorrentHandle); }