예제 #1
0
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;
}
예제 #2
0
static tr_watchdir_status onFileAdded(tr_watchdir_t dir, char const* name, void* context)
{
    tr_session* session = context;

    if (!tr_str_has_suffix(name, ".torrent"))
    {
        return TR_WATCHDIR_IGNORE;
    }

    char* filename = tr_buildPath(tr_watchdir_get_path(dir), name, NULL);
    tr_ctor* ctor = tr_ctorNew(session);
    int err = tr_ctorSetMetainfoFromFile(ctor, filename);

    if (err == 0)
    {
        tr_torrentNew(ctor, &err, NULL);

        if (err == TR_PARSE_ERR)
        {
            tr_logAddError("Error parsing .torrent file \"%s\"", name);
        }
        else
        {
            bool trash = false;
            bool const test = tr_ctorGetDeleteSource(ctor, &trash);

            tr_logAddInfo("Parsing .torrent file successful \"%s\"", name);

            if (test && trash)
            {
                tr_error* error = NULL;

                tr_logAddInfo("Deleting input .torrent file \"%s\"", name);

                if (!tr_sys_path_remove(filename, &error))
                {
                    tr_logAddError("Error deleting .torrent file: %s", error->message);
                    tr_error_free(error);
                }
            }
            else
            {
                char* new_filename = tr_strdup_printf("%s.added", filename);
                tr_sys_path_rename(filename, new_filename, NULL);
                tr_free(new_filename);
            }
        }
    }
    else
    {
        err = TR_PARSE_ERR;
    }

    tr_ctorFree(ctor);
    tr_free(filename);

    return err == TR_PARSE_ERR ? TR_WATCHDIR_RETRY : TR_WATCHDIR_ACCEPT;
}
예제 #3
0
static void
metainfoLookupRescan( tr_session * session )
{
    int          i;
    int          n;
    struct stat  sb;
    const char * dirname = tr_getTorrentDir( session );
    DIR *        odir = NULL;
    tr_ctor *    ctor = NULL;
    tr_list *    list = NULL;

    assert( tr_isSession( session ) );

    /* walk through the directory and find the mappings */
    ctor = tr_ctorNew( session );
    tr_ctorSetSave( ctor, FALSE ); /* since we already have them */
    if( !stat( dirname, &sb ) && S_ISDIR( sb.st_mode ) && ( ( odir = opendir( dirname ) ) ) )
    {
        struct dirent *d;
        for( d = readdir( odir ); d != NULL; d = readdir( odir ) )
        {
            if( d->d_name && d->d_name[0] != '.' ) /* skip dotfiles, ., and ..
                                                     */
            {
                tr_info inf;
                char * path = tr_buildPath( dirname, d->d_name, NULL );
                tr_ctorSetMetainfoFromFile( ctor, path );
                if( !tr_torrentParse( session, ctor, &inf ) )
                {
                    tr_list_append( &list, tr_strdup( inf.hashString ) );
                    tr_list_append( &list, tr_strdup( path ) );
                    tr_metainfoFree( &inf );
                }
                tr_free( path );
            }
        }
        closedir( odir );
    }
    tr_ctorFree( ctor );

    n = tr_list_size( list ) / 2;
    session->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
    session->metainfoLookupCount = n;
    for( i = 0; i < n; ++i )
    {
        char * hashString = tr_list_pop_front( &list );
        char * filename = tr_list_pop_front( &list );

        memcpy( session->metainfoLookup[i].hashString, hashString,
                2 * SHA_DIGEST_LENGTH + 1 );
        tr_free( hashString );
        session->metainfoLookup[i].filename = filename;
    }

    metainfoLookupResort( session );
    tr_dbg( "Found %d torrents in \"%s\"", n, dirname );
}
예제 #4
0
int
tr_ctorSetMetainfoFromHash( tr_ctor *    ctor,
                            const char * hashString )
{
    int          err;
    const char * filename;

    filename = tr_sessionFindTorrentFile( ctor->session, hashString );
    if( !filename )
        err = EINVAL;
    else
        err = tr_ctorSetMetainfoFromFile( ctor, filename );

    return err;
}
예제 #5
0
/**
 * When the source .torrent file is deleted
 * (such as, if it was a temp file that a web browser passed to us),
 * gtk invokes this callback and `filename' will be NULL.
 * The `filename' tests here are to prevent us from losing the current
 * metadata when that happens.
 */
static void
sourceChanged (GtkFileChooserButton * b, gpointer gdata)
{
  struct OpenData * o = gdata;
  char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (b));

  /* maybe instantiate a torrent */
  if (filename || !o->tor)
    {
      int err = 0;
      int new_file = 0;
      int duplicate_id = 0;
      tr_torrent * torrent;

      if (filename && (!o->filename || !tr_is_same_file (filename, o->filename)))
        {
          g_free (o->filename);
          o->filename = g_strdup (filename);
          tr_ctorSetMetainfoFromFile (o->ctor, o->filename);
          new_file = 1;
        }

      tr_ctorSetDownloadDir (o->ctor, TR_FORCE, o->downloadDir);
      tr_ctorSetPaused (o->ctor, TR_FORCE, TRUE);
      tr_ctorSetDeleteSource (o->ctor, FALSE);

      if ((torrent = tr_torrentNew (o->ctor, &err, &duplicate_id)))
        {
          removeOldTorrent (o);
          o->tor = torrent;
        }
      else if (new_file)
        {
          tr_torrent * tor;

          if (duplicate_id)
            tor = gtr_core_find_torrent (o->core, duplicate_id);
          else
            tor = NULL;

          gtr_add_torrent_error_dialog (GTK_WIDGET (b), err, tor, o->filename);
        }

      updateTorrent (o);
    }

  g_free (filename);
}
예제 #6
0
/**
 * When the source .torrent file is deleted
 * (such as, if it was a temp file that a web browser passed to us),
 * gtk invokes this callback and `filename' will be NULL.
 * The `filename' tests here are to prevent us from losing the current
 * metadata when that happens.
 */
static void
sourceChanged( GtkFileChooserButton * b, gpointer gdata )
{
    struct OpenData * data = gdata;
    char * filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( b ) );

    /* maybe instantiate a torrent */
    if( filename || !data->gtor )
    {
        int err = 0;
        int new_file = 0;
        tr_torrent * torrent;

        if( filename && ( !data->filename || !tr_is_same_file( filename, data->filename ) ) )
        {
            g_free( data->filename );
            data->filename = g_strdup( filename );
            tr_ctorSetMetainfoFromFile( data->ctor, data->filename );
            new_file = 1;
        }

        tr_ctorSetDownloadDir( data->ctor, TR_FORCE, data->downloadDir );
        tr_ctorSetPaused( data->ctor, TR_FORCE, TRUE );
        tr_ctorSetDeleteSource( data->ctor, FALSE );

        if( ( torrent = tr_torrentNew( data->ctor, &err ) ) )
        {
            removeOldTorrent( data );
            data->gtor = tr_torrent_new_preexisting( torrent );
        }
        else if( new_file )
        {
            gtr_add_torrent_error_dialog( GTK_WIDGET( b ), err, data->filename );
        }

        updateTorrent( data );
    }

    g_free( filename );
}
예제 #7
0
파일: daemon.c 프로젝트: jaseg/transmission
static void
onFileAdded (tr_session * session, const char * dir, const char * file)
{
    char * filename = tr_buildPath (dir, file, NULL);
    tr_ctor * ctor = tr_ctorNew (session);
    int err = tr_ctorSetMetainfoFromFile (ctor, filename);

    if (!err)
    {
        tr_torrentNew (ctor, &err, NULL);

        if (err == TR_PARSE_ERR)
            tr_logAddError ("Error parsing .torrent file \"%s\"", file);
        else
        {
            bool trash = false;
            int test = tr_ctorGetDeleteSource (ctor, &trash);

            tr_logAddInfo ("Parsing .torrent file successful \"%s\"", file);

            if (!test && trash)
            {
                tr_logAddInfo ("Deleting input .torrent file \"%s\"", file);
                if (tr_remove (filename))
                    tr_logAddError ("Error deleting .torrent file: %s", tr_strerror (errno));
            }
            else
            {
                char * new_filename = tr_strdup_printf ("%s.added", filename);
                tr_rename (filename, new_filename);
                tr_free (new_filename);
            }
        }
    }

    tr_ctorFree (ctor);
    tr_free (filename);
}
예제 #8
0
static int
test_single_file_impl (const tr_tracker_info * trackers,
                       const size_t            trackerCount,
                       const void            * payload,
                       const size_t            payloadSize,
                       const char            * comment,
                       bool                    isPrivate)
{
  char* sandbox;
  char* input_file;
  char* torrent_file;
  tr_metainfo_builder* builder;
  tr_ctor * ctor;
  tr_parse_result parse_result;
  tr_info inf;
  char * tmpstr;

  /* set up our local test sandbox */
  sandbox = libtest_sandbox_create();

  /* create a single input file */
  input_file = tr_buildPath (sandbox, "test.XXXXXX", NULL);
  libtest_create_tmpfile_with_contents (input_file, payload, payloadSize);
  builder = tr_metaInfoBuilderCreate (input_file);
  check_streq (input_file, builder->top);
  check_int_eq (1, builder->fileCount);
  check_streq (input_file, builder->files[0].filename);
  check_int_eq (payloadSize, builder->files[0].size);
  check_int_eq (payloadSize, builder->totalSize);
  check (!builder->isFolder);
  check (!builder->abortFlag);

  /* have tr_makeMetaInfo() build the .torrent file */
  torrent_file = tr_strdup_printf ("%s.torrent", input_file);
  tr_makeMetaInfo (builder, torrent_file, trackers, trackerCount, comment, isPrivate);
  check (isPrivate == builder->isPrivate);
  check_streq (torrent_file, builder->outputFile);
  check_streq (comment, builder->comment);
  check_int_eq (trackerCount, builder->trackerCount);
  while (!builder->isDone)
    tr_wait_msec (100);

  /* now let's check our work: parse the  .torrent file */
  ctor = tr_ctorNew (NULL);
  libttest_sync ();
  tr_ctorSetMetainfoFromFile (ctor, torrent_file);
  parse_result = tr_torrentParse (ctor, &inf);
  check_int_eq (TR_PARSE_OK, parse_result);

  /* quick check of some of the parsed metainfo */
  check_int_eq (payloadSize, inf.totalSize);
  tmpstr = tr_sys_path_basename (input_file, NULL);
  check_streq (tmpstr, inf.name);
  tr_free (tmpstr);
  check_streq (comment, inf.comment);
  check_int_eq (1, inf.fileCount);
  check_int_eq (isPrivate, inf.isPrivate);
  check (!inf.isFolder);
  check_int_eq (trackerCount, inf.trackerCount);

  /* cleanup */
  tr_free (torrent_file);
  tr_free (input_file);
  tr_ctorFree (ctor);
  tr_metainfoFree (&inf);
  tr_metaInfoBuilderFree (builder);
  libtest_sandbox_destroy (sandbox);
  tr_free (sandbox);
  return 0;
}
예제 #9
0
static int
test_single_directory_impl (const tr_tracker_info * trackers,
                            const size_t            trackerCount,
                            const void           ** payloads,
                            const size_t          * payloadSizes,
                            const size_t            payloadCount,
                            const char            * comment,
                            const bool              isPrivate)
{
  char* sandbox;
  char* torrent_file;
  tr_metainfo_builder* builder;
  tr_ctor * ctor;
  tr_parse_result parse_result;
  tr_info inf;
  char * top;
  char ** files;
  size_t totalSize;
  size_t i;
  char* tmpstr;


  /* set up our local test sandbox */
  sandbox = libtest_sandbox_create();

  /* create the top temp directory */
  top = tr_buildPath (sandbox, "folder.XXXXXX", NULL);
  tr_sys_dir_create_temp (top, NULL);

  /* build the payload files that go into the top temp directory */
  files = tr_new (char*, payloadCount);
  totalSize = 0;
  for (i=0; i<payloadCount; i++)
    {
      char tmpl[16];
      tr_snprintf (tmpl, sizeof(tmpl), "file.%04zu%s", i, "XXXXXX");
      files[i] = tr_buildPath (top, tmpl, NULL);
      libtest_create_tmpfile_with_contents (files[i], payloads[i], payloadSizes[i]);
      totalSize += payloadSizes[i];
    }
  libttest_sync ();

  /* init the builder */
  builder = tr_metaInfoBuilderCreate (top);
  check (!builder->abortFlag);
  check_streq (top, builder->top);
  check_int_eq (payloadCount, builder->fileCount);
  check_int_eq (totalSize, builder->totalSize);
  check (builder->isFolder);
  for (i=0; i<builder->fileCount; i++)
    {
      check_streq (files[i], builder->files[i].filename);
      check_int_eq (payloadSizes[i], builder->files[i].size);
    }

  /* call tr_makeMetaInfo() to build the .torrent file */
  torrent_file = tr_strdup_printf ("%s.torrent", top);
  tr_makeMetaInfo (builder, torrent_file, trackers, trackerCount, comment, isPrivate);
  check (isPrivate == builder->isPrivate);
  check_streq (torrent_file, builder->outputFile);
  check_streq (comment, builder->comment);
  check_int_eq (trackerCount, builder->trackerCount);
  while (!builder->isDone)
    tr_wait_msec (100);

  /* now let's check our work: parse the  .torrent file */
  ctor = tr_ctorNew (NULL);
  libttest_sync ();
  tr_ctorSetMetainfoFromFile (ctor, torrent_file);
  parse_result = tr_torrentParse (ctor, &inf);
  check_int_eq (TR_PARSE_OK, parse_result);

  /* quick check of some of the parsed metainfo */
  check_int_eq (totalSize, inf.totalSize);
  tmpstr = tr_sys_path_basename (top, NULL);
  check_streq (tmpstr, inf.name);
  tr_free (tmpstr);
  check_streq (comment, inf.comment);
  check_int_eq (payloadCount, inf.fileCount);
  check_int_eq (isPrivate, inf.isPrivate);
  check_int_eq (builder->isFolder, inf.isFolder);
  check_int_eq (trackerCount, inf.trackerCount);

  /* cleanup */
  tr_free (torrent_file);
  tr_ctorFree (ctor);
  tr_metainfoFree (&inf);
  tr_metaInfoBuilderFree (builder);
  for (i=0; i<payloadCount; i++)
    tr_free (files[i]);
  tr_free (files);
  libtest_sandbox_destroy (sandbox);
  tr_free (sandbox);
  tr_free (top);

  return 0;
}
예제 #10
0
int
tr_main (int    argc,
         char * argv[])
{
  int err;
  tr_info inf;
  tr_ctor * ctor;

  tr_logSetLevel (TR_LOG_ERROR);
  tr_formatter_mem_init (MEM_K, MEM_K_STR, MEM_M_STR, MEM_G_STR, MEM_T_STR);
  tr_formatter_size_init (DISK_K, DISK_K_STR, DISK_M_STR, DISK_G_STR, DISK_T_STR);
  tr_formatter_speed_init (SPEED_K, SPEED_K_STR, SPEED_M_STR, SPEED_G_STR, SPEED_T_STR);

  if (parseCommandLine (argc, (const char* const *)argv))
    return EXIT_FAILURE;

  if (showVersion)
    {
      fprintf (stderr, MY_NAME" "LONG_VERSION_STRING"\n");
      return EXIT_SUCCESS;
    }

  /* make sure the user specified a filename */
  if (!filename)
    {
      fprintf (stderr, "ERROR: No .torrent file specified.\n");
      tr_getopt_usage (MY_NAME, getUsage (), options);
      fprintf (stderr, "\n");
      return EXIT_FAILURE;
    }

  /* try to parse the .torrent file */
  ctor = tr_ctorNew (NULL);
  tr_ctorSetMetainfoFromFile (ctor, filename);
  err = tr_torrentParse (ctor, &inf);
  tr_ctorFree (ctor);
  if (err)
    {
      fprintf (stderr, "Error parsing .torrent file \"%s\"\n", filename);
      return EXIT_FAILURE;
    }

  if (magnetFlag)
    {
      doShowMagnet (&inf);
    }
  else
    {
      printf ("Name: %s\n", inf.name);
      printf ("File: %s\n", filename);
      printf ("\n");
      fflush (stdout);

      if (scrapeFlag)
        doScrape (&inf);
      else
        showInfo (&inf);
    }

  /* cleanup */
  putc ('\n', stdout);
  tr_metainfoFree (&inf);
  return EXIT_SUCCESS;
}