Ignore:
Timestamp:
Apr 5, 2008, 8:12:11 PM (13 years ago)
Author:
charles
Message:

#684: Use XDG basedir spec for configuration and cache files in $HOME

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/platform.c

    r5171 r5517  
    285285
    286286static const char *
    287 tr_getHomeDirectory( void )
    288 {
    289     static char buf[MAX_PATH_LENGTH];
    290     static int init = 0;
    291     const char * envHome;
    292 
    293     if( init )
    294         return buf;
    295 
    296     envHome = getenv( "HOME" );
    297     if( envHome )
    298         snprintf( buf, sizeof(buf), "%s", envHome );
    299     else {
     287getHomeDir( void )
     288{
     289    static char * home = NULL;
     290
     291    if( !home )
     292    {
     293        home = tr_strdup( getenv( "HOME" ) );
     294
     295        if( !home )
     296        {
    300297#ifdef WIN32
    301         SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, buf );
     298            SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, buf );
    302299#elif defined(__BEOS__) || defined(__AMIGAOS4__)
    303         *buf = '\0';
    304 #else
    305         struct passwd * pw = getpwuid( getuid() );
    306         endpwent();
    307         if( pw != NULL )
    308             snprintf( buf, sizeof(buf), "%s", pw->pw_dir );
    309 #endif
    310     }
    311 
    312     init = 1;
    313     return buf;
    314 }
    315 
    316 
    317 static void
    318 tr_migrateResume( const char *oldDirectory, const char *newDirectory )
    319 {
    320     DIR * dirh = opendir( oldDirectory );
    321 
    322     if( dirh != NULL )
    323     {
    324         struct dirent * dirp;
    325 
    326         while( ( dirp = readdir( dirh ) ) )
    327         {
    328             if( !strncmp( "resume.", dirp->d_name, 7 ) )
    329             {
    330                 char o[MAX_PATH_LENGTH];
    331                 char n[MAX_PATH_LENGTH];
    332                 tr_buildPath( o, sizeof(o), oldDirectory, dirp->d_name, NULL );
    333                 tr_buildPath( n, sizeof(n), newDirectory, dirp->d_name, NULL );
    334                 rename( o, n );
    335             }
     300            home = tr_strdup( "" );
     301#else
     302            struct passwd * pw = getpwuid( getuid() );
     303            endpwent( );
     304            if( pw )
     305                home = tr_strdup( pw->pw_dir );
     306#endif
    336307        }
    337308
    338         closedir( dirh );
    339     }
    340 }
    341 
    342 const char *
    343 tr_getPrefsDirectory( void )
    344 {
    345     static char   buf[MAX_PATH_LENGTH];
    346     static int    init = 0;
    347     const char * trhome;
    348 
    349     if( init )
    350         return buf;
    351 
    352     trhome = getenv( "TRANSMISSION_HOME" );
    353     if( trhome != NULL )
    354     {
    355         strlcpy( buf, trhome, sizeof( buf ) );
    356     }
    357     else
    358     {
     309        if( !home )
     310            home = tr_strdup( "" );
     311    }
     312
     313    return home;
     314}
     315
     316static const char *
     317getOldConfigDir( void )
     318{
     319    static char * path = NULL;
     320
     321    if( !path )
     322    {
     323        char buf[MAX_PATH_LENGTH];
    359324#ifdef __BEOS__
    360325        find_directory( B_USER_SETTINGS_DIRECTORY,
     
    363328        strcat( buf, "/Transmission" );
    364329#elif defined( SYS_DARWIN )
    365         tr_buildPath ( buf, sizeof( buf ),
    366                        tr_getHomeDirectory( ),
    367                        "Library",
    368                        "Application Support",
    369                        "Transmission",
    370                        NULL );
     330        tr_buildPath ( buf, sizeof( buf ), getHomeDir( ),
     331                       "Library", "Application Support",
     332                       "Transmission", NULL );
    371333#elif defined(__AMIGAOS4__)
    372334        strlcpy( buf, "PROGDIR:.transmission", sizeof( buf ) );
     
    375337        SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
    376338        tr_buildPath( buf, sizeof(buf),
    377                       appdata,
    378                       "Transmission",
    379                       NULL );
    380 #else
    381         tr_buildPath ( buf, sizeof(buf), tr_getHomeDirectory( ), ".transmission", NULL );
    382 #endif
    383     }
    384 
     339                      appdata, "Transmission", NULL );
     340#else
     341        tr_buildPath ( buf, sizeof(buf),
     342                       getHomeDir( ), ".transmission", NULL );
     343#endif
     344        path = tr_strdup( buf );
     345    }
     346
     347    return path;
     348}
     349
     350static const char *
     351getOldTorrentsDir( void )
     352{
     353    static char * path = NULL;
     354
     355    if( !path )
     356    {
     357        char buf[MAX_PATH_LENGTH];
     358        const char * p = getOldConfigDir();
     359#if defined(__BEOS__) || defined(WIN32) || defined(SYS_DARWIN)
     360        tr_buildPath( buf, sizeof( buf ), p, "Torrents", NULL );
     361#else
     362        tr_buildPath( buf, sizeof( buf ), p, "torrents", NULL );
     363#endif
     364
     365        path = tr_strdup( buf );
     366    }
     367
     368    return path;
     369}
     370static const char *
     371getOldCacheDir( void )
     372{
     373    static char * path = NULL;
     374
     375    if( !path )
     376    {
     377        char buf[MAX_PATH_LENGTH];
     378        const char * p = getOldConfigDir( );
     379#if defined(__BEOS__) || defined(WIN32)
     380        tr_buildPath( buf, sizeof( buf ), p, "Cache", NULL );
     381#elif defined( SYS_DARWIN )
     382        tr_buildPath( buf, sizeof( buf ), getHomeDir(),
     383                      "Library", "Caches", "Transmission", NULL );
     384#else
     385        tr_buildPath( buf, sizeof( buf ), p, "cache", NULL );
     386#endif
     387        path = tr_strdup( buf );
     388    }
     389
     390    return path;
     391}
     392
     393static void
     394moveFiles( const char * oldDir, const char * newDir )
     395{
     396    if( oldDir && newDir && strcmp( oldDir, newDir ) )
     397    {
     398        DIR * dirh = opendir( oldDir );
     399        if( dirh )
     400        {
     401            int count = 0;
     402            struct dirent * dirp;
     403            while(( dirp = readdir( dirh )))
     404            {
     405                if( strcmp( dirp->d_name, "." ) && strcmp( dirp->d_name, ".." ) )
     406                {
     407                    char o[MAX_PATH_LENGTH];
     408                    char n[MAX_PATH_LENGTH];
     409                    tr_buildPath( o, sizeof(o), oldDir, dirp->d_name, NULL );
     410                    tr_buildPath( n, sizeof(n), newDir, dirp->d_name, NULL );
     411                    rename( o, n );
     412                    ++count;
     413                }
     414            }
     415            tr_inf( _( "Migrated %1$d files from \"%2$s\" to \"%3$s\"" ),
     416                    count, oldDir, newDir );
     417            closedir( dirh );
     418        }
     419    }
     420}
     421
     422static void
     423migrateFiles( const tr_handle * handle )
     424{
     425    static int migrated = FALSE;
     426
     427    if( !migrated )
     428    {
     429        const char * oldDir;
     430        const char * newDir;
     431        migrated = TRUE;
     432
     433        oldDir = getOldTorrentsDir( );
     434        newDir = tr_getTorrentDir( handle );
     435        moveFiles( oldDir, newDir );
     436
     437        oldDir = getOldCacheDir( );
     438        newDir = tr_getResumeDir( handle );
     439        moveFiles( oldDir, newDir );
     440    }
     441}
     442
     443#ifdef SYS_DARWIN
     444#define RESUME_SUBDIR  "Resume"
     445#define TORRENT_SUBDIR "Torrents"
     446#else
     447#define RESUME_SUBDIR  "resume"
     448#define TORRENT_SUBDIR "torrents"
     449#endif
     450
     451void
     452tr_setConfigDir( tr_handle * handle, const char * configDir )
     453{
     454    char buf[MAX_PATH_LENGTH];
     455
     456    handle->configDir = tr_strdup( configDir );
     457
     458    tr_buildPath( buf, sizeof( buf ), configDir, RESUME_SUBDIR, NULL );
    385459    tr_mkdirp( buf, 0777 );
    386     init = 1;
    387 
    388 #ifdef SYS_DARWIN
    389     char old[MAX_PATH_LENGTH];
    390     tr_buildPath ( old, sizeof(old),
    391                    tr_getHomeDirectory(), ".transmission", NULL );
    392     tr_migrateResume( old, buf );
    393     rmdir( old );
    394 #endif
    395 
    396     return buf;
     460    handle->resumeDir = tr_strdup( buf );
     461
     462    tr_buildPath( buf, sizeof( buf ), configDir, TORRENT_SUBDIR, NULL );
     463    tr_mkdirp( buf, 0777 );
     464    handle->torrentDir = tr_strdup( buf );
     465
     466    migrateFiles( handle );
    397467}
    398468
    399469const char *
    400 tr_getCacheDirectory( void )
    401 {
    402     static char buf[MAX_PATH_LENGTH];
    403     static int  init = 0;
    404     static const size_t buflen = sizeof(buf);
    405     const char * p;
    406 
    407     if( init )
    408         return buf;
    409 
    410     p = tr_getPrefsDirectory();
    411 #if defined(__BEOS__) || defined(WIN32)
    412     tr_buildPath( buf, buflen, p, "Cache", NULL );
    413 #elif defined( SYS_DARWIN )
    414     tr_buildPath( buf, buflen, tr_getHomeDirectory(),
    415                   "Library", "Caches", "Transmission", NULL );
    416 #else
    417     tr_buildPath( buf, buflen, p, "cache", NULL );
    418 #endif
    419 
    420     tr_mkdirp( buf, 0777 );
    421     init = 1;
    422 
    423     if( strcmp( p, buf ) )
    424         tr_migrateResume( p, buf );
    425 
    426     return buf;
    427 }
     470tr_getConfigDir( const tr_handle * handle )
     471{
     472    return handle->configDir;
     473}
     474
    428475
    429476const char *
    430 tr_getTorrentsDirectory( void )
    431 {
    432     static char buf[MAX_PATH_LENGTH];
    433     static int  init = 0;
    434     static const size_t buflen = sizeof(buf);
    435     const char * p;
    436 
    437     if( init )
    438         return buf;
    439 
    440     p = tr_getPrefsDirectory ();
    441 
    442 #if defined(__BEOS__) || defined(WIN32)
    443     tr_buildPath( buf, buflen, p, "Torrents", NULL );
    444 #elif defined( SYS_DARWIN )
    445     tr_buildPath( buf, buflen, p, "Torrents", NULL );
    446 #else
    447     tr_buildPath( buf, buflen, p, "torrents", NULL );
    448 #endif
    449 
    450     tr_mkdirp( buf, 0777 );
    451     init = 1;
    452     return buf;
     477tr_getTorrentDir( const tr_handle * handle )
     478{
     479    return handle->torrentDir;
     480}
     481
     482const char *
     483tr_getResumeDir( const tr_handle * handle )
     484{
     485    return handle->resumeDir;
     486}
     487
     488const char*
     489tr_getDefaultConfigDir( void )
     490{
     491    static char * s = NULL;
     492
     493    if( !s )
     494    {
     495        char path[MAX_PATH_LENGTH];
     496
     497        if(( s = getenv( "TRANSMISSION_HOME" )))
     498        {
     499            snprintf( path, sizeof( path ), s );
     500        }
     501        else
     502        {
     503#ifdef DARWIN
     504            tr_buildPath( path, sizeof( path ),
     505                          getHomeDir( ), "Library", "Application Support",
     506                          "Transmission", NULL );
     507#elif defined(WIN32)
     508            char appdata[MAX_PATH_LENGTH];
     509            SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, appdata );
     510            tr_buildPath( path, sizeof( path ),
     511                          appdata, "Transmission", NULL );
     512#else
     513            if(( s = getenv( "XDG_CONFIG_HOME" )))
     514                tr_buildPath( path, sizeof( path ),
     515                              s, "transmission", NULL );
     516            else
     517                tr_buildPath( path, sizeof( path ),
     518                              getHomeDir(), ".config", "transmission", NULL );
     519#endif
     520        }
     521
     522        s = tr_strdup( path );
     523    }
     524
     525    return s;
    453526}
    454527
Note: See TracChangeset for help on using the changeset viewer.