]> granicus.if.org Git - transmission/commitdiff
#684: Use XDG basedir spec for configuration and cache files in $HOME
authorCharles Kerr <charles@transmissionbt.com>
Sat, 5 Apr 2008 20:12:11 +0000 (20:12 +0000)
committerCharles Kerr <charles@transmissionbt.com>
Sat, 5 Apr 2008 20:12:11 +0000 (20:12 +0000)
17 files changed:
cli/transmissioncli.c
daemon/misc.c
daemon/torrents.c
gtk/conf.c
gtk/main.c
gtk/tr-core.c
libtransmission/fastresume.c
libtransmission/internal.h
libtransmission/metainfo.c
libtransmission/metainfo.h
libtransmission/platform.c
libtransmission/platform.h
libtransmission/stats.c
libtransmission/torrent-ctor.c
libtransmission/torrent.c
libtransmission/transmission.c
libtransmission/transmission.h

index dd2691b9e9a8481f6c46a7565aa4fcac975c5b16..f5597673c4f5b1ba51da810e69a7361336bdf35c 100644 (file)
@@ -140,7 +140,8 @@ main( int argc, char ** argv )
     }
 
     /* Initialize libtransmission */
-    h = tr_initFull( "cli",
+    h = tr_initFull( tr_getDefaultConfigDir(),
+                     "cli",                   /* tag */
                      1,                       /* pex enabled */
                      natTraversal,            /* nat enabled */
                      bindPort,                /* public port */
index 2820f104e2e69a52a01a6a07890451f5575786f3..5ebabff107b0513ce4e9804ed1fac614159883aa 100644 (file)
@@ -79,7 +79,7 @@ pushdir( char * path, const char * file, size_t size )
 void
 confpath( char * buf, size_t len, const char * file, enum confpathtype type )
 {
-    strlcpy( buf, tr_getPrefsDirectory(), len );
+    strlcpy( buf, tr_getDefaultConfigDir(), len );
 
     switch( type )
     {
index d094311b56183b6fdae028e74cca1df4d54a1e75..e0c9cf3ab609026bc675a02e0fa30e85309212a1 100644 (file)
@@ -109,7 +109,7 @@ torrent_init( struct event_base * base )
     assert( NULL == gl_handle && NULL == gl_base );
 
     gl_base   = base;
-    gl_handle = tr_init( "daemon" );
+    gl_handle = tr_init( tr_getDefaultConfigDir(), "daemon" );
 
     confpath( gl_state, sizeof gl_state, CONF_FILE_STATE, 0 );
     strlcpy( gl_newstate, gl_state, sizeof gl_state );
index fd9bd99f9e12a82967b01e477f2592392b66893c..bde9c665f9b7a07885b28093dcfacd27ce5cd670 100644 (file)
@@ -258,7 +258,14 @@ static char*
 getCompat08PrefsFilename( void )
 {
     assert( gl_confdir != NULL );
-    return g_build_filename( gl_confdir, "prefs", NULL );
+    return g_build_filename( g_get_home_dir(), ".transmission", "gtk", "prefs", NULL );
+}
+
+static char*
+getCompat09PrefsFilename( void )
+{
+    assert( gl_confdir != NULL );
+    return g_build_filename( g_get_home_dir(), ".transmission", "gtk", "prefs.ini", NULL );
 }
 
 static void
@@ -317,11 +324,17 @@ cf_check_older_configs( void )
 {
     char * cfn = getPrefsFilename( );
     char * cfn08 = getCompat08PrefsFilename( );
+    char * cfn09 = getCompat09PrefsFilename( );
+
+    if( !g_file_test( cfn,   G_FILE_TEST_IS_REGULAR )
+      && g_file_test( cfn09, G_FILE_TEST_IS_REGULAR ) )
+      g_rename( cfn09, cfn );
 
     if( !g_file_test( cfn,   G_FILE_TEST_IS_REGULAR )
       && g_file_test( cfn08, G_FILE_TEST_IS_REGULAR ) )
         translate_08_to_09( cfn08, cfn );
 
+    g_free( cfn09 );
     g_free( cfn08 );
     g_free( cfn );
 }
index fddfd58375f86a8922eff46a8071a4ccd9ed1342..299fb657eff2d8c407597c9d6264ae7bc20bbdb2 100644 (file)
@@ -272,6 +272,8 @@ main( int argc, char ** argv )
     gboolean startpaused = FALSE;
     gboolean startminimized = FALSE;
     char * domain = "transmission";
+    const char * configDir = tr_getDefaultConfigDir( );
+
     GOptionEntry entries[] = {
         { "paused", 'p', 0, G_OPTION_ARG_NONE, &startpaused,
           _("Start with all torrents paused"), NULL },
@@ -305,7 +307,7 @@ main( int argc, char ** argv )
 
     tr_notify_init( );
 
-    didinit = cf_init( tr_getPrefsDirectory(), NULL ); /* must come before actions_init */
+    didinit = cf_init( configDir, NULL ); /* must come before actions_init */
     tr_prefs_init_global( );
     myUIManager = gtk_ui_manager_new ();
     actions_init ( myUIManager, cbdata );
@@ -317,7 +319,7 @@ main( int argc, char ** argv )
     didlock = didinit && sendremote( argfiles, sendquit );
     setupsighandlers( ); /* set up handlers for fatal signals */
 
-    if( ( didinit || cf_init( tr_getPrefsDirectory(), &err ) ) &&
+    if( ( didinit || cf_init( configDir, &err ) ) &&
         ( didlock || cf_lock( &err ) ) )
     {
         cbdata->core = tr_core_new( );
index ce01d0e0bf490c1152f667db91fbb2154e809870..6800a14443f14c9d247cd1055db4115dd1ee5a3b 100644 (file)
@@ -449,7 +449,8 @@ tr_core_init( GTypeInstance * instance, gpointer g_class UNUSED )
                                                   struct TrCorePrivate );
 
 
-    h = tr_initFull( "gtk",
+    h = tr_initFull( tr_getDefaultConfigDir( ),
+                     "gtk",
                      pref_flag_get( PREF_KEY_PEX ),
                      pref_flag_get( PREF_KEY_NAT ),
                      pref_int_get( PREF_KEY_PORT ),
index 2064752882ffd8b209e3b881a43ef9c8dc4a8cc1..ba9c807d4b5024578e9beca7b93493995317fb4f 100644 (file)
@@ -123,7 +123,7 @@ enum
 static void
 fastResumeFileName( char * buf, size_t buflen, const tr_torrent * tor, int tag )
 {
-    const char * cacheDir = tr_getCacheDirectory ();
+    const char * cacheDir = tr_getResumeDir( tor->handle );
     const char * hash = tor->info.hashString;
 
     if( !tag )
@@ -603,7 +603,7 @@ loadResumeFile( const tr_torrent * tor, size_t * len )
 {
     uint8_t * ret = NULL;
     char path[MAX_PATH_LENGTH];
-    const char * cacheDir = tr_getCacheDirectory ();
+    const char * cacheDir = tr_getResumeDir( tor->handle );
     const char * hash = tor->info.hashString;
 
     if( !ret && tor->handle->tag )
@@ -714,7 +714,7 @@ void
 tr_fastResumeRemove( const tr_torrent * tor )
 {
     char path[MAX_PATH_LENGTH];
-    const char * cacheDir = tr_getCacheDirectory ();
+    const char * cacheDir = tr_getResumeDir( tor->handle );
     const char * hash = tor->info.hashString;
 
     if( tor->handle->tag )
index 34d46e54491e799cd91a2583c3fc16a69947e07d..951fa7923180629b0b3bf9d4adf55ef6ba96fdec 100644 (file)
@@ -71,6 +71,10 @@ struct tr_handle
 
     char                     * tag;
 
+    char                     * configDir;
+    char                     * torrentDir;
+    char                     * resumeDir;
+
     struct tr_ratecontrol    * upload;
     struct tr_ratecontrol    * download;
 
index 6b85cb8a4e2a85058a4c9441f3214f455069df4c..26dd5bc6d0cd4e1c2e3c78d252176ef0bb55b683 100644 (file)
@@ -125,25 +125,30 @@ strlcat_utf8( void * dest, const void * src, size_t len, char skip )
 }
 
 static void
-savedname( char * name, size_t len, const char * hash, const char * tag )
+savedname( const tr_handle * handle,
+           char            * name,
+           size_t            len,
+           const char      * hash )
 {
-    const char * torDir = tr_getTorrentsDirectory ();
+    const char * torDir = tr_getTorrentDir( handle );
 
-    if( tag == NULL )
+    if( !handle->tag )
     {
         tr_buildPath( name, len, torDir, hash, NULL );
     }
     else
     {
         char base[1024];
-        snprintf( base, sizeof(base), "%s-%s", hash, tag );
+        snprintf( base, sizeof(base), "%s-%s", hash, handle->tag );
         tr_buildPath( name, len, torDir, base, NULL );
     }
 }
 
 
 int
-tr_metainfoParse( tr_info * inf, const tr_benc * meta_in, const char * tag )
+tr_metainfoParse( const tr_handle  * handle,
+                  tr_info          * inf,
+                  const tr_benc    * meta_in )
 {
     tr_piece_index_t i;
     tr_benc * beInfo, * val, * val2;
@@ -167,7 +172,7 @@ tr_metainfoParse( tr_info * inf, const tr_benc * meta_in, const char * tag )
     }
 
     tr_sha1_to_hex( inf->hashString, inf->hash );
-    savedname( buf, sizeof( buf ), inf->hashString, tag );
+    savedname( handle, buf, sizeof( buf ), inf->hashString );
     tr_free( inf->torrent );
     inf->torrent = tr_strdup( buf );
 
@@ -563,22 +568,25 @@ tr_trackerInfoClear( tr_tracker_info * info )
 }
 
 void
-tr_metainfoRemoveSaved( const char * hashString, const char * tag )
+tr_metainfoRemoveSaved( const tr_handle * handle,
+                        const char      * hashString )
 {
     char file[MAX_PATH_LENGTH];
-    savedname( file, sizeof file, hashString, tag );
+    savedname( handle, file, sizeof file, hashString );
     unlink( file );
 }
 
 /* Save a copy of the torrent file in the saved torrent directory */
 int
-tr_metainfoSave( const char * hash, const char * tag,
-                 const uint8_t * buf, size_t buflen )
+tr_metainfoSave( const tr_handle  * handle,
+                 const char       * hash,
+                 const uint8_t    * buf,
+                 size_t             buflen )
 {
     char   path[MAX_PATH_LENGTH];
     FILE * file;
 
-    savedname( path, sizeof path, hash, tag );
+    savedname( handle, path, sizeof path, hash );
     file = fopen( path, "wb+" );
     if( !file )
     {
index aa9f322b1f49350cf708988093cef100f607a68d..e056d7b57c2746dfc4dd3b9da9e5a0485ee582c8 100644 (file)
 
 struct tr_benc;
 
-int tr_metainfoParse( tr_info *, const struct tr_benc *, const char * tag );
+int tr_metainfoParse( const tr_handle       * handle,
+                      tr_info               * info,
+                      const struct tr_benc  * benc );
+
 void tr_metainfoFree( tr_info * inf );
-void tr_metainfoRemoveSaved( const char * hashString, const char * tag );
 
-int tr_metainfoSave( const char *hashString, const char * tag, const uint8_t * metainfo, size_t len );
+void tr_metainfoRemoveSaved( const tr_handle  * handle,
+                             const char       * hashString );
+
+int tr_metainfoSave( const tr_handle  * handle,
+                     const char       * hashString,
+                     const uint8_t    * metainfo,
+                     size_t             len );
 
 #endif
index b3a3755029b53eda731833d59b2dbbaef0c4dc33..e7dfd26d848068ae1734b87cc4f6ca7aad5d9a00 100644 (file)
@@ -284,172 +284,245 @@ tr_lockUnlock( tr_lock * l )
 #endif
 
 static const char *
-tr_getHomeDirectory( void )
+getHomeDir( void )
 {
-    static char buf[MAX_PATH_LENGTH];
-    static int init = 0;
-    const char * envHome;
+    static char * home = NULL;
 
-    if( init )
-        return buf;
+    if( !home )
+    {
+        home = tr_strdup( getenv( "HOME" ) );
 
-    envHome = getenv( "HOME" );
-    if( envHome )
-        snprintf( buf, sizeof(buf), "%s", envHome );
-    else {
+        if( !home )
+        {
 #ifdef WIN32
-        SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, buf );
+            SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, buf );
 #elif defined(__BEOS__) || defined(__AMIGAOS4__)
-        *buf = '\0';
+            home = tr_strdup( "" );
 #else
-        struct passwd * pw = getpwuid( getuid() );
-        endpwent();
-        if( pw != NULL )
-            snprintf( buf, sizeof(buf), "%s", pw->pw_dir );
+            struct passwd * pw = getpwuid( getuid() );
+            endpwent( );
+            if( pw )
+                home = tr_strdup( pw->pw_dir );
 #endif
-    }
-
-    init = 1;
-    return buf;
-}
-
-
-static void
-tr_migrateResume( const char *oldDirectory, const char *newDirectory )
-{
-    DIR * dirh = opendir( oldDirectory );
-
-    if( dirh != NULL )
-    {
-        struct dirent * dirp;
-
-        while( ( dirp = readdir( dirh ) ) )
-        {
-            if( !strncmp( "resume.", dirp->d_name, 7 ) )
-            {
-                char o[MAX_PATH_LENGTH];
-                char n[MAX_PATH_LENGTH];
-                tr_buildPath( o, sizeof(o), oldDirectory, dirp->d_name, NULL );
-                tr_buildPath( n, sizeof(n), newDirectory, dirp->d_name, NULL );
-                rename( o, n );
-            }
         }
 
-        closedir( dirh );
+        if( !home )
+            home = tr_strdup( "" );
     }
+
+    return home;
 }
 
-const char *
-tr_getPrefsDirectory( void )
+static const char *
+getOldConfigDir( void )
 {
-    static char   buf[MAX_PATH_LENGTH];
-    static int    init = 0;
-    const char * trhome;
-
-    if( init )
-        return buf;
+    static char * path = NULL;
 
-    trhome = getenv( "TRANSMISSION_HOME" );
-    if( trhome != NULL )
-    {
-        strlcpy( buf, trhome, sizeof( buf ) );
-    }
-    else
+    if( !path )
     {
+        char buf[MAX_PATH_LENGTH];
 #ifdef __BEOS__
         find_directory( B_USER_SETTINGS_DIRECTORY,
                         dev_for_path("/boot"), true,
                         buf, sizeof( buf ) );
         strcat( buf, "/Transmission" );
 #elif defined( SYS_DARWIN )
-        tr_buildPath ( buf, sizeof( buf ),
-                       tr_getHomeDirectory( ),
-                       "Library",
-                       "Application Support",
-                       "Transmission",
-                       NULL );
+        tr_buildPath ( buf, sizeof( buf ), getHomeDir( ),
+                       "Library", "Application Support",
+                       "Transmission", NULL );
 #elif defined(__AMIGAOS4__)
         strlcpy( buf, "PROGDIR:.transmission", sizeof( buf ) );
 #elif defined(WIN32)
         char appdata[MAX_PATH_LENGTH];
         SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
         tr_buildPath( buf, sizeof(buf),
-                      appdata,
-                      "Transmission",
-                      NULL );
+                      appdata, "Transmission", NULL );
 #else
-        tr_buildPath ( buf, sizeof(buf), tr_getHomeDirectory( ), ".transmission", NULL );
+        tr_buildPath ( buf, sizeof(buf),
+                       getHomeDir( ), ".transmission", NULL );
 #endif
+        path = tr_strdup( buf );
     }
 
-    tr_mkdirp( buf, 0777 );
-    init = 1;
+    return path;
+}
 
-#ifdef SYS_DARWIN
-    char old[MAX_PATH_LENGTH];
-    tr_buildPath ( old, sizeof(old),
-                   tr_getHomeDirectory(), ".transmission", NULL );
-    tr_migrateResume( old, buf );
-    rmdir( old );
+static const char *
+getOldTorrentsDir( void )
+{
+    static char * path = NULL;
+
+    if( !path )
+    {
+        char buf[MAX_PATH_LENGTH];
+        const char * p = getOldConfigDir();
+#if defined(__BEOS__) || defined(WIN32) || defined(SYS_DARWIN)
+        tr_buildPath( buf, sizeof( buf ), p, "Torrents", NULL );
+#else
+        tr_buildPath( buf, sizeof( buf ), p, "torrents", NULL );
 #endif
 
-    return buf;
-}
+        path = tr_strdup( buf );
+    }
 
-const char *
-tr_getCacheDirectory( void )
+    return path;
+}
+static const char *
+getOldCacheDir( void )
 {
-    static char buf[MAX_PATH_LENGTH];
-    static int  init = 0;
-    static const size_t buflen = sizeof(buf);
-    const char * p;
-
-    if( init )
-        return buf;
+    static char * path = NULL;
 
-    p = tr_getPrefsDirectory();
+    if( !path )
+    {
+        char buf[MAX_PATH_LENGTH];
+        const char * p = getOldConfigDir( );
 #if defined(__BEOS__) || defined(WIN32)
-    tr_buildPath( buf, buflen, p, "Cache", NULL );
+        tr_buildPath( buf, sizeof( buf ), p, "Cache", NULL );
 #elif defined( SYS_DARWIN )
-    tr_buildPath( buf, buflen, tr_getHomeDirectory(),
-                  "Library", "Caches", "Transmission", NULL );
+        tr_buildPath( buf, sizeof( buf ), getHomeDir(),
+                      "Library", "Caches", "Transmission", NULL );
+#else
+        tr_buildPath( buf, sizeof( buf ), p, "cache", NULL );
+#endif
+        path = tr_strdup( buf );
+    }
+
+    return path;
+}
+
+static void
+moveFiles( const char * oldDir, const char * newDir )
+{
+    if( oldDir && newDir && strcmp( oldDir, newDir ) )
+    {
+        DIR * dirh = opendir( oldDir );
+        if( dirh )
+        {
+            int count = 0;
+            struct dirent * dirp;
+            while(( dirp = readdir( dirh )))
+            {
+                if( strcmp( dirp->d_name, "." ) && strcmp( dirp->d_name, ".." ) )
+                {
+                    char o[MAX_PATH_LENGTH];
+                    char n[MAX_PATH_LENGTH];
+                    tr_buildPath( o, sizeof(o), oldDir, dirp->d_name, NULL );
+                    tr_buildPath( n, sizeof(n), newDir, dirp->d_name, NULL );
+                    rename( o, n );
+                    ++count;
+                }
+            }
+            tr_inf( _( "Migrated %1$d files from \"%2$s\" to \"%3$s\"" ),
+                    count, oldDir, newDir );
+            closedir( dirh );
+        }
+    }
+}
+
+static void
+migrateFiles( const tr_handle * handle )
+{
+    static int migrated = FALSE;
+
+    if( !migrated )
+    {
+        const char * oldDir;
+        const char * newDir;
+        migrated = TRUE;
+
+        oldDir = getOldTorrentsDir( );
+        newDir = tr_getTorrentDir( handle );
+        moveFiles( oldDir, newDir );
+
+        oldDir = getOldCacheDir( );
+        newDir = tr_getResumeDir( handle );
+        moveFiles( oldDir, newDir );
+    }
+}
+
+#ifdef SYS_DARWIN
+#define RESUME_SUBDIR  "Resume"
+#define TORRENT_SUBDIR "Torrents"
 #else
-    tr_buildPath( buf, buflen, p, "cache", NULL );
+#define RESUME_SUBDIR  "resume"
+#define TORRENT_SUBDIR "torrents"
 #endif
 
+void
+tr_setConfigDir( tr_handle * handle, const char * configDir )
+{
+    char buf[MAX_PATH_LENGTH];
+
+    handle->configDir = tr_strdup( configDir );
+
+    tr_buildPath( buf, sizeof( buf ), configDir, RESUME_SUBDIR, NULL );
+    tr_mkdirp( buf, 0777 );
+    handle->resumeDir = tr_strdup( buf );
+
+    tr_buildPath( buf, sizeof( buf ), configDir, TORRENT_SUBDIR, NULL );
     tr_mkdirp( buf, 0777 );
-    init = 1;
+    handle->torrentDir = tr_strdup( buf );
 
-    if( strcmp( p, buf ) )
-        tr_migrateResume( p, buf );
+    migrateFiles( handle );
+}
 
-    return buf;
+const char *
+tr_getConfigDir( const tr_handle * handle )
+{
+    return handle->configDir;
 }
 
+
 const char *
-tr_getTorrentsDirectory( void )
+tr_getTorrentDir( const tr_handle * handle )
 {
-    static char buf[MAX_PATH_LENGTH];
-    static int  init = 0;
-    static const size_t buflen = sizeof(buf);
-    const char * p;
+    return handle->torrentDir;
+}
 
-    if( init )
-        return buf;
+const char *
+tr_getResumeDir( const tr_handle * handle )
+{
+    return handle->resumeDir;
+}
 
-    p = tr_getPrefsDirectory ();
+const char*
+tr_getDefaultConfigDir( void )
+{
+    static char * s = NULL;
 
-#if defined(__BEOS__) || defined(WIN32)
-    tr_buildPath( buf, buflen, p, "Torrents", NULL );
-#elif defined( SYS_DARWIN )
-    tr_buildPath( buf, buflen, p, "Torrents", NULL );
+    if( !s )
+    {
+        char path[MAX_PATH_LENGTH];
+
+        if(( s = getenv( "TRANSMISSION_HOME" )))
+        {
+            snprintf( path, sizeof( path ), s );
+        }
+        else
+        {
+#ifdef DARWIN
+            tr_buildPath( path, sizeof( path ),
+                          getHomeDir( ), "Library", "Application Support",
+                          "Transmission", NULL );
+#elif defined(WIN32)
+            char appdata[MAX_PATH_LENGTH];
+            SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
+            tr_buildPath( path, sizeof( path ),
+                          appdata, "Transmission", NULL );
 #else
-    tr_buildPath( buf, buflen, p, "torrents", NULL );
+            if(( s = getenv( "XDG_CONFIG_HOME" )))
+                tr_buildPath( path, sizeof( path ),
+                              s, "transmission", NULL );
+            else
+                tr_buildPath( path, sizeof( path ),
+                              getHomeDir(), ".config", "transmission", NULL );
 #endif
+        }
 
-    tr_mkdirp( buf, 0777 );
-    init = 1;
-    return buf;
+        s = tr_strdup( path );
+    }
+
+    return s;
 }
 
 /***
index b18b852f0139b8e369d79d858c7dd96894f40138..6c99bd8adbe79d21f0f9afaddc408fb5fa44711e 100644 (file)
 typedef struct tr_lock   tr_lock;
 typedef struct tr_thread tr_thread;
 
-const char * tr_getCacheDirectory( void );
-const char * tr_getTorrentsDirectory( void );
+struct tr_handle;
+
+void tr_setConfigDir  ( struct tr_handle * handle,
+                        const char       * configDir );
+
+const char * tr_getResumeDir  ( const struct tr_handle * );
+
+const char * tr_getTorrentDir ( const struct tr_handle * );
 
 tr_thread*   tr_threadNew  ( void (*func)(void *), void * arg, const char * name );
 void         tr_threadJoin ( tr_thread * );
index 4c97c3c71c7d39d9b8627dae8917ce819d8da498..c4e68709c11ad6b5f9deda67b47c2b0f586146e0 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "transmission.h"
 #include "bencode.h"
-#include "platform.h" /* tr_getPrefsDirectory */
+#include "platform.h" /* tr_getConfigDir() */
 #include "utils.h" /* tr_buildPath */
 
 /***
@@ -59,20 +59,20 @@ parseCumulativeStats( tr_session_stats  * setme,
 }
 
 static char*
-getFilename( char * buf, size_t buflen )
+getFilename( const tr_handle * handle, char * buf, size_t buflen )
 {
-    tr_buildPath( buf, buflen, tr_getPrefsDirectory(), "stats.benc", NULL );
+    tr_buildPath( buf, buflen, tr_getConfigDir(handle), "stats.benc", NULL );
     return buf;
 }
 
 static void
-loadCumulativeStats( tr_session_stats * setme )
+loadCumulativeStats( const tr_handle * handle, tr_session_stats * setme )
 {
     size_t len;
     uint8_t * content;
     char filename[MAX_PATH_LENGTH];
 
-    getFilename( filename, sizeof(filename) );
+    getFilename( handle, filename, sizeof(filename) );
     content = tr_loadFile( filename, &len );
     if( content != NULL )
         parseCumulativeStats( setme, content, len );
@@ -81,7 +81,7 @@ loadCumulativeStats( tr_session_stats * setme )
 }
 
 static void
-saveCumulativeStats( const tr_session_stats * stats )
+saveCumulativeStats( const tr_handle * handle, const tr_session_stats * stats )
 {
     FILE * fp;
     char * str;
@@ -97,7 +97,7 @@ saveCumulativeStats( const tr_session_stats * stats )
     tr_bencInitInt( tr_bencDictAdd( &top, "seconds-active" ), stats->secondsActive );
 
     str = tr_bencSave( &top, &len );
-    getFilename( filename, sizeof(filename) );
+    getFilename( handle, filename, sizeof(filename) );
     fp = fopen( filename, "wb+" );
     fwrite( str, 1, len, fp );
     fclose( fp );
@@ -114,7 +114,7 @@ void
 tr_statsInit( tr_handle * handle )
 {
     struct tr_stats_handle * stats = tr_new0( struct tr_stats_handle, 1 );
-    loadCumulativeStats( &stats->old );
+    loadCumulativeStats( handle, &stats->old );
     stats->single.sessionCount = 1;
     stats->startTime = time( NULL );
     handle->sessionStats = stats;
@@ -125,7 +125,7 @@ tr_statsClose( tr_handle * handle )
 {
     tr_session_stats cumulative;
     tr_getCumulativeSessionStats( handle, &cumulative );
-    saveCumulativeStats( &cumulative );
+    saveCumulativeStats( handle, &cumulative );
 
     tr_free( handle->sessionStats );
     handle->sessionStats = NULL;
index 9a80d2a3f704813e1a9c9ee6ff2d7815e98b8959..d4e3f391ede97509a711c7c160f4db39508c11df 100644 (file)
@@ -131,12 +131,12 @@ tr_ctorSetMetainfoFromHash( tr_ctor        * ctor,
 
     if( err && ( ctor->handle->tag != NULL ) ) {
         snprintf( basename, sizeof(basename), "%s-%s", hashString, ctor->handle->tag );
-        tr_buildPath( filename, sizeof(filename), tr_getTorrentsDirectory(), basename, NULL );
+        tr_buildPath( filename, sizeof(filename), tr_getTorrentDir( ctor->handle ), basename, NULL );
         err = tr_ctorSetMetainfoFromFile( ctor, filename );
     }
 
     if( err ) {
-        tr_buildPath( filename, sizeof(filename), tr_getTorrentsDirectory(), hashString, NULL );
+        tr_buildPath( filename, sizeof(filename), tr_getTorrentDir( ctor->handle ), hashString, NULL );
         err = tr_ctorSetMetainfoFromFile( ctor, filename );
     }
 
index 3f6140a88b021a0b0d0a96bdeeb890fda383fdfb..8c3256b4b69a8181695d294d5aaaa4d9b65cfa34 100644 (file)
@@ -383,8 +383,8 @@ torrentRealInit( tr_handle     * h,
         if( !tr_ctorGetMetainfo( ctor, &val ) ) {
             int len;
             uint8_t * text = (uint8_t*) tr_bencSave( val, &len );
-            tr_metainfoSave( tor->info.hashString,
-                             tor->handle->tag,
+            tr_metainfoSave( tor->handle,
+                             tor->info.hashString,
                              text, len );
             tr_free( text );
         }
@@ -424,7 +424,7 @@ tr_torrentParse( const tr_handle  * handle,
     if( !err && tr_ctorGetMetainfo( ctor, &metainfo ) )
         return TR_EINVALID;
 
-    err = tr_metainfoParse( setmeInfo, metainfo, handle->tag );
+    err = tr_metainfoParse( handle, setmeInfo, metainfo );
     doFree = !err && ( setmeInfo == &tmp );
 
     if( !err && hashExists( handle, setmeInfo->hash ) )
@@ -826,7 +826,7 @@ tr_torrentSetHasPiece( tr_torrent * tor, tr_piece_index_t pieceIndex, int has )
 void
 tr_torrentRemoveSaved( tr_torrent * tor )
 {
-    tr_metainfoRemoveSaved( tor->info.hashString, tor->handle->tag );
+    tr_metainfoRemoveSaved( tor->handle, tor->info.hashString );
 
     tr_fastResumeRemove( tor );
 }
index e989136a5614a61bfd7a465721785be5a47044e1..268103bd0b7bfc7bccee92e322a53401361a5ca1 100644 (file)
@@ -114,7 +114,8 @@ tr_setEncryptionMode( tr_handle * handle, tr_encryption_mode mode )
 ***/
 
 tr_handle *
-tr_initFull( const char * tag,
+tr_initFull( const char * configDir,
+             const char * tag,
              int          isPexEnabled,
              int          isNatEnabled,
              int          publicPort,
@@ -137,6 +138,9 @@ tr_initFull( const char * tag,
     signal( SIGPIPE, SIG_IGN );
 #endif
 
+    if( configDir == NULL )
+        configDir = tr_getDefaultConfigDir( );
+
     tr_msgInit( );
     tr_setMessageLevel( messageLevel );
     tr_setMessageQueuing( isMessageQueueingEnabled );
@@ -145,6 +149,9 @@ tr_initFull( const char * tag,
     h->lock = tr_lockNew( );
     h->isPexEnabled = isPexEnabled ? 1 : 0;
     h->encryptionMode = encryptionMode;
+    h->configDir = tr_strdup( configDir );
+
+    tr_setConfigDir( h, configDir );
 
     tr_netInit(); /* must go before tr_eventInit */
 
@@ -181,9 +188,9 @@ tr_initFull( const char * tag,
     tr_inf( "%s", buf );
 
     /* initialize the blocklist */
-    tr_buildPath( filename, sizeof( filename ), tr_getPrefsDirectory(), "blocklists", NULL );
+    tr_buildPath( filename, sizeof( filename ), h->configDir, "blocklists", NULL );
     tr_mkdirp( filename, 0777 );
-    tr_buildPath( filename, sizeof( filename ), tr_getPrefsDirectory(), "blocklists", "level1.bin", NULL );
+    tr_buildPath( filename, sizeof( filename ), h->configDir, "blocklists", "level1.bin", NULL );
     h->blocklist = _tr_blocklistNew( filename, isBlocklistEnabled );
 
     tr_statsInit( h );
@@ -191,9 +198,12 @@ tr_initFull( const char * tag,
     return h;
 }
 
-tr_handle * tr_init( const char * tag )
+tr_handle *
+tr_init( const char * configDir,
+         const char * tag )
 {
-    return tr_initFull( tag,
+    return tr_initFull( configDir,
+                        tag,
                         TRUE, /* pex enabled */
                         FALSE, /* nat enabled */
                         -1, /* public port */
@@ -433,7 +443,7 @@ tr_loadTorrents ( tr_handle   * h,
     int i, n = 0;
     struct stat sb;
     DIR * odir = NULL;
-    const char * dirname = tr_getTorrentsDirectory( );
+    const char * dirname = tr_getTorrentDir( h );
     tr_torrent ** torrents;
     tr_list *l=NULL, *list=NULL;
 
index f4293e862d6e600b7a7e2bff3c79c9564e989edb..9c0dcd4c95f8ca8736ac88db1dee9f7984c063ac 100644 (file)
@@ -76,7 +76,10 @@ enum
 
 typedef struct tr_handle tr_handle;
 
-tr_handle * tr_initFull( const char * tag,
+const char* tr_getDefaultConfigDir( void );
+
+tr_handle * tr_initFull( const char * configDir,
+                         const char * tag,
                          int          isPexEnabled,
                          int          isNatEnabled,
                          int          publicPort,
@@ -93,7 +96,8 @@ tr_handle * tr_initFull( const char * tag,
 /**
  * Like tr_initFull() but with default values supplied.
  */ 
-tr_handle * tr_init( const char * tag );
+tr_handle * tr_init( const char * configDir,
+                     const char * tag );
 
 /**
  * Shut down a libtransmission instance created by tr_init*()
@@ -147,7 +151,7 @@ void tr_setEncryptionMode( tr_handle * handle, tr_encryption_mode mode );
  * Returns the full path to a directory which can be used to store
  * preferences. The string belongs to libtransmission, do not free it.
  **********************************************************************/
-const char * tr_getPrefsDirectory( void );
+const char * tr_getConfigDir( const tr_handle * );
 
 
 
@@ -501,7 +505,7 @@ tr_torrent * tr_torrentNew( tr_handle      * handle,
 
 
 /**
- *  Load all the torrents in tr_getTorrentsDirectory().
+ *  Load all the torrents in tr_getTorrentDir().
  *  This can be used at startup to kickstart all the torrents
  *  from the previous session.
  */
@@ -649,7 +653,7 @@ void tr_torrentAmountFinished( const tr_torrent * tor, float * tab, int size );
  * tr_torrentRemoveSaved
  ***********************************************************************
  * delete's Transmission's copy of the torrent's metadata from
- * tr_getTorrentsDirectory().
+ * tr_getTorrentDir().
  **********************************************************************/
 void tr_torrentRemoveSaved( tr_torrent * );