示例#1
0
static int
test1 (void)
{
    tr_info inf;
    tr_ctor * ctor;
    const char * magnet_link;
    tr_parse_result parse_result;

    /* background info @ http://wiki.theory.org/BitTorrent_Magnet-URI_Webseeding */
    magnet_link = "magnet:?"
                  "xt=urn:btih:14FFE5DD23188FD5CB53A1D47F1289DB70ABF31E"
                  "&dn=ubuntu+12+04+1+desktop+32+bit"
                  "&tr=http%3A%2F%2Ftracker.publicbt.com%2Fannounce"
                  "&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80"
                  "&ws=http://transmissionbt.com ";
    ctor = tr_ctorNew (NULL);
    tr_ctorSetMetainfoFromMagnetLink (ctor, magnet_link);
    parse_result = tr_torrentParse (ctor, &inf);
    check_int_eq (inf.fileCount, 0); /* cos it's a magnet link */
    check_int_eq (parse_result, TR_PARSE_OK);
    check_int_eq (inf.trackerCount, 2);
    check_streq ("http://tracker.publicbt.com/announce", inf.trackers[0].announce);
    check_streq ("udp://tracker.publicbt.com:80", inf.trackers[1].announce);
    check_int_eq (inf.webseedCount, 1);
    check_streq ("http://transmissionbt.com", inf.webseeds[0]);

    /* cleanup */
    tr_metainfoFree (&inf);
    tr_ctorFree (ctor);
    return 0;
}
示例#2
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;
}
示例#3
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;
}
示例#4
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 );
}
tr_torrent *
libttest_zero_torrent_init (tr_session * session)
{
  int err;
  int metainfo_len;
  char * metainfo;
  const char * metainfo_base64;
  tr_torrent * tor;
  tr_ctor * ctor;

  /* 
     1048576 files-filled-with-zeroes/1048576
        4096 files-filled-with-zeroes/4096
         512 files-filled-with-zeroes/512
   */
  metainfo_base64 =
    "ZDg6YW5ub3VuY2UzMTpodHRwOi8vd3d3LmV4YW1wbGUuY29tL2Fubm91bmNlMTA6Y3JlYXRlZCBi"
    "eTI1OlRyYW5zbWlzc2lvbi8yLjYxICgxMzQwNykxMzpjcmVhdGlvbiBkYXRlaTEzNTg3MDQwNzVl"
    "ODplbmNvZGluZzU6VVRGLTg0OmluZm9kNTpmaWxlc2xkNjpsZW5ndGhpMTA0ODU3NmU0OnBhdGhs"
    "NzoxMDQ4NTc2ZWVkNjpsZW5ndGhpNDA5NmU0OnBhdGhsNDo0MDk2ZWVkNjpsZW5ndGhpNTEyZTQ6"
    "cGF0aGwzOjUxMmVlZTQ6bmFtZTI0OmZpbGVzLWZpbGxlZC13aXRoLXplcm9lczEyOnBpZWNlIGxl"
    "bmd0aGkzMjc2OGU2OnBpZWNlczY2MDpRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJtGExUv1726aj"
    "/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJtGExUv17"
    "26aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJtGEx"
    "Uv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GIQxhJ"
    "tGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZCS1GI"
    "QxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8KT9ZC"
    "S1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9umo/8K"
    "T9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9e9um"
    "o/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRhMVL9"
    "e9umo/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMYSbRh"
    "MVL9e9umo/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLUYhDGEm0YTFS/XvbpqP/Ck/WQktRiEMY"
    "SbRhMVL9e9umo/8KT9ZCS1GIQxhJtGExUv1726aj/wpP1kJLOlf5A+Tz30nMBVuNM2hpV3wg/103"
    "OnByaXZhdGVpMGVlZQ==";

  /* create the torrent ctor */
  metainfo = tr_base64_decode (metainfo_base64, -1, &metainfo_len);
  assert (metainfo != NULL);
  assert (metainfo_len > 0);
  assert (session != NULL);
  ctor = tr_ctorNew (session);
  tr_ctorSetMetainfo (ctor, (uint8_t*)metainfo, metainfo_len);
  tr_ctorSetPaused (ctor, TR_FORCE, true);

  /* create the torrent */
  err = 0;
  tor = tr_torrentNew (ctor, &err, NULL);
  assert (!err);

  /* cleanup */
  tr_free (metainfo);
  tr_ctorFree (ctor);
  return tor;
}
示例#6
0
static int
test_metainfo (void)
{
  size_t i;
  const struct {
    int expected_benc_err;
    int expected_parse_result;
    const void * benc;
  } metainfo[] = {
    { 0,      TR_PARSE_OK,  BEFORE_PATH "5:a.txt"     AFTER_PATH },

    /* allow empty components, but not =all= empty components, see bug #5517 */
    { 0,      TR_PARSE_OK,  BEFORE_PATH "0:5:a.txt"   AFTER_PATH },
    { 0,      TR_PARSE_ERR, BEFORE_PATH "0:0:"        AFTER_PATH },

    /* don't allow path components in a filename */
    { 0,      TR_PARSE_ERR, BEFORE_PATH "7:a/a.txt"   AFTER_PATH },

    /* fail on "." components */
    { 0,      TR_PARSE_ERR, BEFORE_PATH "1:.5:a.txt"  AFTER_PATH },
    { 0,      TR_PARSE_ERR, BEFORE_PATH "5:a.txt1:."  AFTER_PATH },

    /* fail on ".." components */
    { 0,      TR_PARSE_ERR, BEFORE_PATH "2:..5:a.txt" AFTER_PATH },
    { 0,      TR_PARSE_ERR, BEFORE_PATH "5:a.txt2:.." AFTER_PATH },

    /* fail on empty string */
    { EILSEQ, TR_PARSE_ERR, "" }
  };

  tr_logSetLevel(0); /* yes, we already know these will generate errors, thank you... */


  for (i=0; i<(sizeof(metainfo) / sizeof(metainfo[0])); i++)
    {
      tr_ctor * ctor = tr_ctorNew (NULL);
      const int err = tr_ctorSetMetainfo (ctor, metainfo[i].benc, strlen(metainfo[i].benc));
      check_int_eq (metainfo[i].expected_benc_err, err);
      if (!err)
        {
          const tr_parse_result parse_result = tr_torrentParse (ctor, NULL);
          check_int_eq (metainfo[i].expected_parse_result, parse_result);
        }
      tr_ctorFree (ctor);
    }

  return 0;
}
示例#7
0
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
int
main( int argc, char ** argv )
{
    int c;
    const char * optarg;
    tr_benc settings;
    tr_bool boolVal;
    tr_bool loaded;
    tr_bool foreground = FALSE;
    tr_bool dumpSettings = FALSE;
    const char * configDir = NULL;
    const char * pid_filename;
    dtr_watchdir * watchdir = NULL;
    FILE * logfile = NULL;
    tr_bool pidfile_created = FALSE;

    signal( SIGINT, gotsig );
    signal( SIGTERM, gotsig );
#ifndef WIN32
    signal( SIGHUP, gotsig );
#endif

    /* load settings from defaults + config file */
    tr_bencInitDict( &settings, 0 );
    tr_bencDictAddBool( &settings, TR_PREFS_KEY_RPC_ENABLED, TRUE );
    configDir = getConfigDir( argc, (const char**)argv );
    loaded = tr_sessionLoadSettings( &settings, configDir, MY_NAME );

    /* overwrite settings from the comamndline */
    tr_optind = 1;
    while(( c = tr_getopt( getUsage(), argc, (const char**)argv, options, &optarg ))) {
        switch( c ) {
            case 'a': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_WHITELIST, optarg );
                      tr_bencDictAddBool( &settings, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, TRUE );
                      break;
            case 'b': tr_bencDictAddBool( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, TRUE );
                      break;
            case 'B': tr_bencDictAddBool( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, FALSE );
                      break;
            case 'c': tr_bencDictAddStr( &settings, PREF_KEY_DIR_WATCH, optarg );
                      tr_bencDictAddBool( &settings, PREF_KEY_DIR_WATCH_ENABLED, TRUE );
                      break;
            case 'C': tr_bencDictAddBool( &settings, PREF_KEY_DIR_WATCH_ENABLED, FALSE );
                      break;
            case 941: tr_bencDictAddStr( &settings, TR_PREFS_KEY_INCOMPLETE_DIR, optarg );
                      tr_bencDictAddBool( &settings, TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED, TRUE );
                      break;
            case 942: tr_bencDictAddBool( &settings, TR_PREFS_KEY_INCOMPLETE_DIR_ENABLED, FALSE );
                      break;
            case 'd': dumpSettings = TRUE;
                      break;
            case 'e': logfile = fopen( optarg, "a+" );
                      if( logfile == NULL )
                          fprintf( stderr, "Couldn't open \"%s\": %s\n", optarg, tr_strerror( errno ) );
                      break;
            case 'f': foreground = TRUE;
                      break;
            case 'g': /* handled above */
                      break;
            case 'V': /* version */
                      fprintf(stderr, "%s %s\n", MY_NAME, LONG_VERSION_STRING);
                      exit( 0 );
            case 'o': tr_bencDictAddBool( &settings, TR_PREFS_KEY_DHT_ENABLED, TRUE );
                      break;
            case 'O': tr_bencDictAddBool( &settings, TR_PREFS_KEY_DHT_ENABLED, FALSE );
                      break;
            case 'p': tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_PORT, atoi( optarg ) );
                      break;
            case 't': tr_bencDictAddBool( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, TRUE );
                      break;
            case 'T': tr_bencDictAddBool( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, FALSE );
                      break;
            case 'u': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_USERNAME, optarg );
                      break;
            case 'v': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_PASSWORD, optarg );
                      break;
            case 'w': tr_bencDictAddStr( &settings, TR_PREFS_KEY_DOWNLOAD_DIR, optarg );
                      break;
            case 'P': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_PORT, atoi( optarg ) );
                      break;
            case 'm': tr_bencDictAddBool( &settings, TR_PREFS_KEY_PORT_FORWARDING, TRUE );
                      break;
            case 'M': tr_bencDictAddBool( &settings, TR_PREFS_KEY_PORT_FORWARDING, FALSE );
                      break;
            case 'L': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, atoi( optarg ) );
                      break;
            case 'l': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_LIMIT_TORRENT, atoi( optarg ) );
                      break;
            case 800: paused = TRUE;
                      break;
            case 910: tr_bencDictAddInt( &settings, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_REQUIRED );
                      break;
            case 911: tr_bencDictAddInt( &settings, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_PREFERRED );
                      break;
            case 912: tr_bencDictAddInt( &settings, TR_PREFS_KEY_ENCRYPTION, TR_CLEAR_PREFERRED );
                      break;
            case 'i': tr_bencDictAddStr( &settings, TR_PREFS_KEY_BIND_ADDRESS_IPV4, optarg );
                      break;
            case 'I': tr_bencDictAddStr( &settings, TR_PREFS_KEY_BIND_ADDRESS_IPV6, optarg );
                      break;
            case 'r': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_BIND_ADDRESS, optarg );
                      break;
            case 953: tr_bencDictAddReal( &settings, TR_PREFS_KEY_RATIO, atof(optarg) );
                      tr_bencDictAddBool( &settings, TR_PREFS_KEY_RATIO_ENABLED, TRUE );
                      break;
            case 954: tr_bencDictAddBool( &settings, TR_PREFS_KEY_RATIO_ENABLED, FALSE );
                      break;
            case 'x': tr_bencDictAddStr( &settings, PREF_KEY_PIDFILE, optarg );
                      break;
            case 'y': tr_bencDictAddBool( &settings, TR_PREFS_KEY_LPD_ENABLED, TRUE );
                      break;
            case 'Y': tr_bencDictAddBool( &settings, TR_PREFS_KEY_LPD_ENABLED, FALSE );
                      break;
            case 810: tr_bencDictAddInt( &settings,  TR_PREFS_KEY_MSGLEVEL, TR_MSG_ERR );
                      break;
            case 811: tr_bencDictAddInt( &settings,  TR_PREFS_KEY_MSGLEVEL, TR_MSG_INF );
                      break;
            case 812: tr_bencDictAddInt( &settings,  TR_PREFS_KEY_MSGLEVEL, TR_MSG_DBG );
                      break;
            default:  showUsage( );
                      break;
        }
    }

    if( foreground && !logfile )
        logfile = stderr;

    if( !loaded )
    {
        printMessage( logfile, TR_MSG_ERR, MY_NAME, "Error loading config file -- exiting.", __FILE__, __LINE__ );
        return -1;
    }

    if( dumpSettings )
    {
        char * str = tr_bencToStr( &settings, TR_FMT_JSON, NULL );
        fprintf( stderr, "%s", str );
        tr_free( str );
        return 0;
    }

    if( !foreground && tr_daemon( TRUE, FALSE ) < 0 )
    {
        char buf[256];
        tr_snprintf( buf, sizeof( buf ), "Failed to daemonize: %s", tr_strerror( errno ) );
        printMessage( logfile, TR_MSG_ERR, MY_NAME, buf, __FILE__, __LINE__ );
        exit( 1 );
    }

    /* start the session */
    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 );
    mySession = tr_sessionInit( "daemon", configDir, TRUE, &settings );
    tr_ninf( NULL, "Using settings from \"%s\"", configDir );
    tr_sessionSaveSettings( mySession, configDir, &settings );

    pid_filename = NULL;
    tr_bencDictFindStr( &settings, PREF_KEY_PIDFILE, &pid_filename );
    if( pid_filename && *pid_filename )
    {
        FILE * fp = fopen( pid_filename, "w+" );
        if( fp != NULL )
        {
            fprintf( fp, "%d", (int)getpid() );
            fclose( fp );
            tr_inf( "Saved pidfile \"%s\"", pid_filename );
            pidfile_created = TRUE;
        }
        else
            tr_err( "Unable to save pidfile \"%s\": %s", pid_filename, strerror( errno ) );
    }

    if( tr_bencDictFindBool( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, &boolVal ) && boolVal )
        tr_ninf( MY_NAME, "requiring authentication" );

    /* maybe add a watchdir */
    {
        const char * dir;

        if( tr_bencDictFindBool( &settings, PREF_KEY_DIR_WATCH_ENABLED, &boolVal )
            && boolVal
            && tr_bencDictFindStr( &settings, PREF_KEY_DIR_WATCH, &dir )
            && dir
            && *dir )
        {
            tr_inf( "Watching \"%s\" for new .torrent files", dir );
            watchdir = dtr_watchdir_new( mySession, dir, onFileAdded );
        }
    }

    /* load the torrents */
    {
        tr_torrent ** torrents;
        tr_ctor * ctor = tr_ctorNew( mySession );
        if( paused )
            tr_ctorSetPaused( ctor, TR_FORCE, TRUE );
        torrents = tr_sessionLoadTorrents( mySession, ctor, NULL );
        tr_free( torrents );
        tr_ctorFree( ctor );
    }

#ifdef HAVE_SYSLOG
    if( !foreground )
        openlog( MY_NAME, LOG_CONS|LOG_PID, LOG_DAEMON );
#endif

    while( !closing ) {
        tr_wait_msec( 1000 ); /* sleep one second */
        dtr_watchdir_update( watchdir );
        pumpLogMessages( logfile );
    }

    /* shutdown */
#if HAVE_SYSLOG
    if( !foreground )
    {
        syslog( LOG_INFO, "%s", "Closing session" );
        closelog( );
    }
#endif

    printf( "Closing transmission session..." );
    tr_sessionSaveSettings( mySession, configDir, &settings );
    dtr_watchdir_free( watchdir );
    tr_sessionClose( mySession );
    printf( " done.\n" );

    /* cleanup */
    if( pidfile_created )
        remove( pid_filename );
    tr_bencFree( &settings );
    return 0;
}
示例#9
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;
}
示例#10
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;
}
示例#11
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;
}