#684: Use XDG basedir spec for configuration and cache files in $HOME
This commit is contained in:
parent
16880cee99
commit
b71a2985b3
|
@ -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 */
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
15
gtk/conf.c
15
gtk/conf.c
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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( );
|
||||
|
|
|
@ -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 ),
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -71,6 +71,10 @@ struct tr_handle
|
|||
|
||||
char * tag;
|
||||
|
||||
char * configDir;
|
||||
char * torrentDir;
|
||||
char * resumeDir;
|
||||
|
||||
struct tr_ratecontrol * upload;
|
||||
struct tr_ratecontrol * download;
|
||||
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -29,10 +29,18 @@
|
|||
|
||||
struct tr_benc;
|
||||
|
||||
int tr_metainfoParse( tr_info *, const struct tr_benc *, const char * tag );
|
||||
void tr_metainfoFree( tr_info * inf );
|
||||
void tr_metainfoRemoveSaved( const char * hashString, const char * tag );
|
||||
int tr_metainfoParse( const tr_handle * handle,
|
||||
tr_info * info,
|
||||
const struct tr_benc * benc );
|
||||
|
||||
int tr_metainfoSave( const char *hashString, const char * tag, const uint8_t * metainfo, size_t len );
|
||||
void tr_metainfoFree( tr_info * inf );
|
||||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
||||
envHome = getenv( "HOME" );
|
||||
if( envHome )
|
||||
snprintf( buf, sizeof(buf), "%s", envHome );
|
||||
else {
|
||||
#ifdef WIN32
|
||||
SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, buf );
|
||||
#elif defined(__BEOS__) || defined(__AMIGAOS4__)
|
||||
*buf = '\0';
|
||||
#else
|
||||
struct passwd * pw = getpwuid( getuid() );
|
||||
endpwent();
|
||||
if( pw != NULL )
|
||||
snprintf( buf, sizeof(buf), "%s", 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 )
|
||||
if( !home )
|
||||
{
|
||||
struct dirent * dirp;
|
||||
home = tr_strdup( getenv( "HOME" ) );
|
||||
|
||||
while( ( dirp = readdir( dirh ) ) )
|
||||
if( !home )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
#ifdef WIN32
|
||||
SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, buf );
|
||||
#elif defined(__BEOS__) || defined(__AMIGAOS4__)
|
||||
home = tr_strdup( "" );
|
||||
#else
|
||||
struct passwd * pw = getpwuid( getuid() );
|
||||
endpwent( );
|
||||
if( pw )
|
||||
home = tr_strdup( pw->pw_dir );
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
static char * path = NULL;
|
||||
|
||||
if( init )
|
||||
return buf;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
path = tr_strdup( buf );
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
static const char *
|
||||
getOldCacheDir( void )
|
||||
{
|
||||
static char * path = NULL;
|
||||
|
||||
if( !path )
|
||||
{
|
||||
char buf[MAX_PATH_LENGTH];
|
||||
const char * p = getOldConfigDir( );
|
||||
#if defined(__BEOS__) || defined(WIN32)
|
||||
tr_buildPath( buf, sizeof( buf ), p, "Cache", NULL );
|
||||
#elif defined( SYS_DARWIN )
|
||||
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
|
||||
char old[MAX_PATH_LENGTH];
|
||||
tr_buildPath ( old, sizeof(old),
|
||||
tr_getHomeDirectory(), ".transmission", NULL );
|
||||
tr_migrateResume( old, buf );
|
||||
rmdir( old );
|
||||
#define RESUME_SUBDIR "Resume"
|
||||
#define TORRENT_SUBDIR "Torrents"
|
||||
#else
|
||||
#define RESUME_SUBDIR "resume"
|
||||
#define TORRENT_SUBDIR "torrents"
|
||||
#endif
|
||||
|
||||
return buf;
|
||||
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 );
|
||||
handle->torrentDir = tr_strdup( buf );
|
||||
|
||||
migrateFiles( handle );
|
||||
}
|
||||
|
||||
const char *
|
||||
tr_getCacheDirectory( void )
|
||||
tr_getConfigDir( 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->configDir;
|
||||
}
|
||||
|
||||
if( init )
|
||||
return buf;
|
||||
|
||||
p = tr_getPrefsDirectory();
|
||||
#if defined(__BEOS__) || defined(WIN32)
|
||||
tr_buildPath( buf, buflen, p, "Cache", NULL );
|
||||
#elif defined( SYS_DARWIN )
|
||||
tr_buildPath( buf, buflen, tr_getHomeDirectory(),
|
||||
"Library", "Caches", "Transmission", NULL );
|
||||
#else
|
||||
tr_buildPath( buf, buflen, p, "cache", NULL );
|
||||
#endif
|
||||
|
||||
tr_mkdirp( buf, 0777 );
|
||||
init = 1;
|
||||
|
||||
if( strcmp( p, buf ) )
|
||||
tr_migrateResume( p, buf );
|
||||
|
||||
return buf;
|
||||
const char *
|
||||
tr_getTorrentDir( const tr_handle * handle )
|
||||
{
|
||||
return handle->torrentDir;
|
||||
}
|
||||
|
||||
const char *
|
||||
tr_getTorrentsDirectory( void )
|
||||
tr_getResumeDir( 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->resumeDir;
|
||||
}
|
||||
|
||||
if( init )
|
||||
return buf;
|
||||
const char*
|
||||
tr_getDefaultConfigDir( void )
|
||||
{
|
||||
static char * s = NULL;
|
||||
|
||||
p = tr_getPrefsDirectory ();
|
||||
if( !s )
|
||||
{
|
||||
char path[MAX_PATH_LENGTH];
|
||||
|
||||
#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 = 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;
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
@ -35,8 +35,14 @@
|
|||
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 * );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 * );
|
||||
|
||||
|
|
Loading…
Reference in New Issue