]> granicus.if.org Git - transmission/commitdiff
get tr_ctorSetMetainfoFromHash() working again.
authorCharles Kerr <charles@transmissionbt.com>
Mon, 14 Apr 2008 14:39:13 +0000 (14:39 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Mon, 14 Apr 2008 14:39:13 +0000 (14:39 +0000)
libtransmission/metainfo.c
libtransmission/metainfo.h
libtransmission/resume.c
libtransmission/session.c
libtransmission/session.h
libtransmission/torrent-ctor.c
libtransmission/torrent.c

index e36c3ac90585274c34fa265e19e34f8c65586ead..3a7c1912b086b101e4c2b9ddd6789b6ff71dbea2 100644 (file)
@@ -157,8 +157,8 @@ getTorrentOldFilename( const tr_handle * handle,
 }
 
 void
-tr_metainfoMigrate( const tr_handle * handle,
-                    const tr_info   * inf )
+tr_metainfoMigrate( tr_handle * handle,
+                    tr_info   * inf )
 {
     struct stat new_sb;
     char new_name[MAX_PATH_LENGTH];
@@ -176,7 +176,12 @@ tr_metainfoMigrate( const tr_handle * handle,
         {
             FILE * out = fopen( new_name, "wb+" );
             if( fwrite( content, sizeof( uint8_t ), contentLen, out ) == contentLen )
+            {
+                tr_free( inf->torrent );
+                inf->torrent = tr_strdup( new_name );
+                tr_sessionSetTorrentFile( handle, inf->hashString, new_name );
                 unlink( old_name );
+            }
             fclose( out );
         }
 
@@ -314,7 +319,6 @@ tr_metainfoParse( const tr_handle  * handle,
     getTorrentFilename( handle, inf, buf, sizeof( buf ) );
     tr_free( inf->torrent );
     inf->torrent = tr_strdup( buf );
-fprintf( stderr, "inf->torrent is [%s]\n", inf->torrent );
 
     return TR_OK;
 
index b7dfd0227f92f74f9fbe9a617fd284d9b07e8b28..752ef81a06529cb1e243f1eb8ccdd1dbb75c5c95 100644 (file)
@@ -38,7 +38,7 @@ void tr_metainfoFree( tr_info * inf );
 void tr_metainfoRemoveSaved( const tr_handle  * handle,
                              const tr_info    * info );
 
-void tr_metainfoMigrate( const tr_handle * handle,
-                         const tr_info   * inf );
+void tr_metainfoMigrate( tr_handle * handle,
+                         tr_info   * inf );
 
 #endif
index f3d95503f0a81c677b30fd90944c831d0da176f5..d98e5cae84f0bb6e4b2cbf78d8f4efbcf15a10ae 100644 (file)
@@ -40,7 +40,7 @@
 #define KEY_SPEEDLIMIT_UP_SPEED   "up-speed"
 #define KEY_SPEEDLIMIT_UP_MODE    "up-mode"
 
-#define KEY_PROGRESS_MTIMES "mtimes"
+#define KEY_PROGRESS_MTIMES   "mtimes"
 #define KEY_PROGRESS_BITFIELD "bitfield"
 
 static void
@@ -61,14 +61,13 @@ getResumeFilename( char * buf, size_t buflen, const tr_torrent * tor )
 static void
 savePeers( tr_benc * dict, const tr_torrent * tor )
 {
-    tr_pex * pex;
+    tr_pex * pex = NULL;
     const int count = tr_peerMgrGetPeers( tor->handle->peerMgr,
                                           tor->info.hash, &pex );
-    if( count > 0 ) {
-        tr_benc * child = tr_bencDictAdd( dict, KEY_PEERS );
-        tr_bencInitStrDupLen( child, (const char*)pex, sizeof(tr_pex)*count );
-        tr_free( pex );
-    }
+    if( count > 0 )
+        tr_bencInitStrDupLen( tr_bencDictAdd( dict, KEY_PEERS ),
+                              (const char*)pex, sizeof(tr_pex)*count );
+    tr_free( pex );
 }
 
 static uint64_t
@@ -180,6 +179,8 @@ loadSpeedLimits( tr_benc * dict, tr_torrent * tor )
 ****
 ***/
 
+static const time_t verifyNeeded = ~(time_t)0;
+
 static void
 saveProgress( tr_benc * dict, const tr_torrent * tor )
 {
@@ -197,11 +198,9 @@ saveProgress( tr_benc * dict, const tr_torrent * tor )
     /* add the mtimes */
     mtimes = tr_torrentGetMTimes( tor, &n );
     m = tr_bencDictAddList( p, KEY_PROGRESS_MTIMES, n );
-    for( i=0; i<n; ++i ) {
-        if( !tr_torrentIsFileChecked( tor, i ) )
-            mtimes[i] = ~(time_t)0; /* force a recheck next time */
-        tr_bencListAddInt( m, mtimes[i] );
-    }
+    for( i=0; i<n; ++i )
+        tr_bencListAddInt( m, tr_torrentIsFileChecked( tor, i )
+                              ? mtimes[i] : verifyNeeded );
 
     /* add the bitfield */
     bitfield = tr_cpBlockBitfield( tor->completion );
@@ -230,12 +229,12 @@ loadProgress( tr_benc * dict, tr_torrent * tor )
             && ( m->val.l.count == n ) )
         {
             int i;
-            const time_t recheck = ~(time_t)0;
             for( i=0; i<m->val.l.count; ++i ) 
             {
                 int64_t x;
-                time_t t = tr_bencGetInt( &m->val.l.vals[i], &x ) ? x : recheck;
-                if( ( t != recheck ) && ( curMTimes[i] == t ) )
+                const time_t t = tr_bencGetInt( &m->val.l.vals[i], &x )
+                                 ? x : verifyNeeded;
+                if( ( t != verifyNeeded ) && ( t == curMTimes[i] ) )
                     tr_torrentSetFileChecked( tor, i, TRUE );
                 else {
                     tr_torrentSetFileChecked( tor, i, FALSE );
@@ -282,16 +281,19 @@ tr_torrentSaveResume( const tr_torrent * tor )
     tr_benc top;
     char filename[MAX_PATH_LENGTH];
 
-    /* populate the bencoded data */
     tr_bencInitDict( &top, 10 );
-    tr_bencDictAddInt( &top, KEY_CORRUPT, tor->corruptPrev + tor->corruptCur );
-    tr_bencDictAddStr( &top, KEY_DESTINATION, tor->destination );
+    tr_bencDictAddInt( &top, KEY_CORRUPT,
+                             tor->corruptPrev + tor->corruptCur );
+    tr_bencDictAddStr( &top, KEY_DESTINATION,
+                             tor->destination );
     tr_bencDictAddInt( &top, KEY_DOWNLOADED,
-                       tor->downloadedPrev + tor->downloadedCur );
+                             tor->downloadedPrev + tor->downloadedCur );
     tr_bencDictAddInt( &top, KEY_UPLOADED,
                              tor->uploadedPrev + tor->uploadedCur );
-    tr_bencDictAddInt( &top, KEY_MAX_PEERS, tor->maxConnectedPeers );
-    tr_bencDictAddInt( &top, KEY_PAUSED, tor->isRunning?0:1 );
+    tr_bencDictAddInt( &top, KEY_MAX_PEERS,
+                             tor->maxConnectedPeers );
+    tr_bencDictAddInt( &top, KEY_PAUSED,
+                             tor->isRunning ? 0 : 1 );
     savePeers( &top, tor );
     savePriorities( &top, tor );
     saveProgress( &top, tor );
index d7515915a0f6e79a04e02758a6d795f2ce9d01b2..75134ca8e8146886c550ac7fa1b706d9a7d454ae 100644 (file)
@@ -36,6 +36,7 @@
 #include "blocklist.h"
 #include "fdlimit.h"
 #include "list.h"
+#include "metainfo.h" /* tr_metainfoFree */
 #include "net.h"
 #include "peer-mgr.h"
 #include "platform.h" /* tr_lock */
@@ -113,6 +114,8 @@ tr_setEncryptionMode( tr_handle * handle, tr_encryption_mode mode )
 ****
 ***/
 
+static void metainfoLookupRescan( tr_handle * h );
+
 tr_handle *
 tr_initFull( const char * configDir,
              const char * tag,
@@ -194,6 +197,8 @@ tr_initFull( const char * configDir,
 
     tr_statsInit( h );
 
+    metainfoLookupRescan( h );
+
     return h;
 }
 
@@ -463,7 +468,7 @@ tr_loadTorrents ( tr_handle   * h,
                 tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
                 tr_ctorSetMetainfoFromFile( ctor, filename );
                 tor = tr_torrentNew( h, ctor, NULL );
-                if( tor != NULL ) {
+                if( tor ) {
                     tr_list_append( &list, tor );
                     n++;
                 }
@@ -541,3 +546,130 @@ tr_blocklistHasAddress( tr_handle * handle, const struct in_addr * addr )
 {
     return _tr_blocklistHasAddress( handle->blocklist, addr );
 }
+
+/***
+****
+***/
+
+static int
+compareLookupEntries( const void * va, const void * vb )
+{
+    const struct tr_metainfo_lookup * a = va;
+    const struct tr_metainfo_lookup * b = vb;
+    return strcmp( a->hashString, b->hashString );
+}
+
+static void
+metainfoLookupResort( tr_handle * h )
+{
+    qsort( h->metainfoLookup, 
+           h->metainfoLookupCount,
+           sizeof( struct tr_metainfo_lookup ),
+           compareLookupEntries );
+}
+
+static int
+compareHashStringToLookupEntry( const void * va, const void * vb )
+{
+    const char * a = va;
+    const struct tr_metainfo_lookup * b = vb;
+    return strcmp( a, b->hashString );
+}
+
+const char*
+tr_sessionFindTorrentFile( const tr_handle  * h,
+                           const char       * hashStr )
+{
+    struct tr_metainfo_lookup * l = bsearch( hashStr,
+                                             h->metainfoLookup,
+                                             h->metainfoLookupCount,
+                                             sizeof( struct tr_metainfo_lookup ),
+                                             compareHashStringToLookupEntry );
+    return l ? l->filename : NULL;
+}
+
+static void
+metainfoLookupRescan( tr_handle * h )
+{
+    int i;
+    int n;
+    struct stat sb;
+    const char * dirname = tr_getTorrentDir( h );
+    DIR * odir = NULL;
+    tr_ctor * ctor = NULL;
+    tr_list * list = NULL;
+
+    /* walk through the directory and find the mappings */
+    ctor = tr_ctorNew( h );
+    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 filename[MAX_PATH_LENGTH];
+                tr_buildPath( filename, sizeof(filename), dirname, d->d_name, NULL );
+                tr_ctorSetMetainfoFromFile( ctor, filename );
+                if( !tr_torrentParse( h, ctor, &inf ) )
+                {
+                    tr_list_append( &list, tr_strdup( inf.hashString ) );
+                    tr_list_append( &list, tr_strdup( filename ) );
+                    tr_metainfoFree( &inf );
+                }
+            }
+        }
+        closedir( odir );
+    }
+    tr_ctorFree( ctor );
+
+    n = tr_list_size( list ) / 2;
+    h->metainfoLookup = tr_new0( struct tr_metainfo_lookup, n );
+    h->metainfoLookupCount = n;
+    for( i=0; i<n; ++i )
+    {
+        char * hashString = tr_list_pop_front( &list );
+        char * filename = tr_list_pop_front( &list );
+
+        memcpy( h->metainfoLookup[i].hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
+        tr_free( hashString );
+        h->metainfoLookup[i].filename = filename;
+    }
+
+    metainfoLookupResort( h );
+    tr_dbg( "Found %d torrents in \"%s\"", n, dirname );
+}
+
+void
+tr_sessionSetTorrentFile( tr_handle    * h,
+                          const char   * hashString,
+                          const char   * filename )
+{
+    struct tr_metainfo_lookup * l = bsearch( hashString,
+                                             h->metainfoLookup,
+                                             h->metainfoLookupCount,
+                                             sizeof( struct tr_metainfo_lookup ),
+                                             compareHashStringToLookupEntry );
+    if( l != NULL )
+    {
+        if( l->filename != filename )
+        {
+            tr_free( l->filename );
+            l->filename = tr_strdup( filename );
+        }
+    }
+    else
+    {
+        const int n = h->metainfoLookupCount++;
+        struct tr_metainfo_lookup * node;
+        h->metainfoLookup = tr_renew( struct tr_metainfo_lookup,
+                                      h->metainfoLookup,
+                                      h->metainfoLookupCount );
+        node = h->metainfoLookup + n;
+        memcpy( node->hashString, hashString, 2*SHA_DIGEST_LENGTH+1 );
+        node->filename = tr_strdup( filename );
+        metainfoLookupResort( h );
+    }
+}
index 3857ca4bc9120c0e35cc8af51f71c98f1d63085a..8fc57f8284987fa53654eeb1adad0de04847ba6c 100644 (file)
@@ -53,43 +53,59 @@ uint8_t* tr_peerIdNew( void );
 
 const uint8_t* tr_getPeerId( void );
 
+struct tr_metainfo_lookup
+{
+    char hashString[2*SHA_DIGEST_LENGTH+1];
+    char * filename;
+};
+
+const char * tr_sessionFindTorrentFile( const tr_handle  * h,
+                                        const char       * hashString );
+
+void tr_sessionSetTorrentFile( tr_handle    * h,
+                               const char   * hashString,
+                               const char   * filename );
+
 struct tr_handle
 {
-    unsigned int               isPortSet        : 1;
-    unsigned int               isPexEnabled     : 1;
-    unsigned int               isClosed         : 1;
-    unsigned int               useUploadLimit   : 1;
-    unsigned int               useDownloadLimit : 1;
+    unsigned int                 isPortSet        : 1;
+    unsigned int                 isPexEnabled     : 1;
+    unsigned int                 isClosed         : 1;
+    unsigned int                 useUploadLimit   : 1;
+    unsigned int                 useDownloadLimit : 1;
+
+    tr_encryption_mode           encryptionMode;
 
-    tr_encryption_mode         encryptionMode;
+    struct tr_event_handle     * events;
 
-    struct tr_event_handle   * events;
+    int                          peerSocketTOS;
 
-    int                        peerSocketTOS;
+    int                          torrentCount;
+    tr_torrent                 * torrentList;
 
-    int                        torrentCount;
-    tr_torrent               * torrentList;
+    char                       * tag;
 
-    char                     * tag;
+    char                       * configDir;
+    char                       * torrentDir;
+    char                       * resumeDir;
 
-    char                     * configDir;
-    char                     * torrentDir;
-    char                     * resumeDir;
+    struct tr_ratecontrol      * upload;
+    struct tr_ratecontrol      * download;
 
-    struct tr_ratecontrol    * upload;
-    struct tr_ratecontrol    * download;
+    struct tr_blocklist        * blocklist;
+    struct tr_peerMgr          * peerMgr;
+    struct tr_shared           * shared;
 
-    struct tr_blocklist      * blocklist;
-    struct tr_peerMgr        * peerMgr;
-    struct tr_shared         * shared;
+    struct tr_lock             * lock;
 
-    struct tr_lock           * lock;
+    tr_handle_status             stats[2];
+    int                          statCur;
 
-    tr_handle_status           stats[2];
-    int                        statCur;
+    struct tr_stats_handle     * sessionStats;
+    struct tr_tracker_handle   * tracker;
 
-    struct tr_stats_handle   * sessionStats;
-    struct tr_tracker_handle * tracker;
+    struct tr_metainfo_lookup  * metainfoLookup;
+    int                          metainfoLookupCount;
 };
 
 void tr_globalLock       ( struct tr_handle * );
index d4e3f391ede97509a711c7c160f4db39508c11df..c970711997a70aec4a339cf86970191db1ea3396 100644 (file)
@@ -14,6 +14,7 @@
 #include "transmission.h"
 #include "bencode.h"
 #include "platform.h"
+#include "session.h" /* tr_sessionFindTorrentFile */
 #include "trcompat.h" /* strlcpy */
 #include "utils.h"
 
@@ -125,20 +126,13 @@ int
 tr_ctorSetMetainfoFromHash( tr_ctor        * ctor,
                             const char     * hashString )
 {
-    int err = -1;
-    char basename[2048];
-    char filename[MAX_PATH_LENGTH];
-
-    if( err && ( ctor->handle->tag != NULL ) ) {
-        snprintf( basename, sizeof(basename), "%s-%s", hashString, ctor->handle->tag );
-        tr_buildPath( filename, sizeof(filename), tr_getTorrentDir( ctor->handle ), basename, NULL );
-        err = tr_ctorSetMetainfoFromFile( ctor, filename );
-    }
+    int err;
+    const char * filename;
 
-    if( err ) {
-        tr_buildPath( filename, sizeof(filename), tr_getTorrentDir( ctor->handle ), hashString, NULL );
-        err = tr_ctorSetMetainfoFromFile( ctor, filename );
-    }
+    if(( filename = tr_sessionFindTorrentFile( ctor->handle, hashString )))
+        err = tr_ctorSetMetainfoFromFile( ctor, filename ); 
+    else
+        err = TR_ERROR;
 
     return err;
 }
index 4a416f182c8c20abc89fac165ed556b7b66c6e75..55af43848fe6edbe059383a1b4ad4918179ccdb6 100644 (file)
@@ -387,6 +387,7 @@ torrentRealInit( tr_handle     * h,
         if( !tr_ctorGetMetainfo( ctor, &val ) ) {
             const char * filename = tor->info.torrent;
             tr_bencSaveFile( filename, val );
+            tr_sessionSetTorrentFile( tor->handle, tor->info.hashString, filename );
         }
     }