Changeset 310 for trunk/libtransmission


Ignore:
Timestamp:
Jun 9, 2006, 7:53:35 PM (15 years ago)
Author:
joshe
Message:

Add support to libtransmission and the MacOS X GUI for saving private copies of

torrent files.

Location:
trunk/libtransmission
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/fastresume.h

    r261 r310  
    6464static char * fastResumeFileName( tr_io_t * io )
    6565{
    66     char * ret, * p;
    67     int i;
    68 
    69     asprintf( &ret, "%s/resume.%40d", tr_getPrefsDirectory(), 0 );
    70 
    71     p = &ret[ strlen( ret ) - 2 * SHA_DIGEST_LENGTH ];
    72     for( i = 0; i < SHA_DIGEST_LENGTH; i++ )
    73     {
    74         sprintf( p, "%02x", io->tor->info.hash[i] );
    75         p += 2;
    76     }
     66    char * ret;
     67
     68    asprintf( &ret, "%s/resume.%s", tr_getCacheDirectory(),
     69              io->tor->info.hashString );
    7770
    7871    return ret;
  • trunk/libtransmission/inout.c

    r261 r310  
    217217
    218218        /* Create folders */
    219         p = path;
    220         while( ( p = strchr( p, '/' ) ) )
     219        if( NULL != ( p = strrchr( path, '/' ) ) )
    221220        {
    222221            *p = '\0';
    223             if( stat( path, &sb ) )
     222            if( tr_mkdir( path ) )
    224223            {
    225                 /* Folder doesn't exist yet */
    226                 mkdir( path, 0777 );
    227             }
    228             else if( ( sb.st_mode & S_IFMT ) != S_IFDIR )
    229             {
    230                 /* Node exists but isn't a folder */
    231                 printf( "Remove %s, it's in the way.\n", path );
    232224                free( path );
    233225                return 1;
    234226            }
    235227            *p = '/';
    236             p++;
    237228        }
    238229
  • trunk/libtransmission/internal.h

    r261 r310  
    4646#include <netinet/in.h>
    4747#include <fcntl.h>
     48#include <assert.h>
    4849#ifdef BEOS_NETSERVER
    4950#  define in_port_t uint16_t
  • trunk/libtransmission/metainfo.c

    r261 r310  
    3535 *
    3636 **********************************************************************/
    37 int tr_metainfoParse( tr_info_t * inf, const char * path )
     37int tr_metainfoParse( tr_info_t * inf, const char * path,
     38                      const char * savedHash, int saveCopy )
    3839{
    3940    FILE       * file;
     
    4445    struct stat sb;
    4546
    46     snprintf( inf->torrent, MAX_PATH_LENGTH, "%s", path );
     47    assert( NULL == path || NULL == savedHash );
     48    /* if savedHash isn't null, saveCopy should be false */
     49    assert( NULL == savedHash || !saveCopy );
     50
     51    if ( NULL != savedHash )
     52    {
     53        snprintf( inf->torrent, MAX_PATH_LENGTH, "%s/%s",
     54                  tr_getTorrentsDirectory(), savedHash );
     55        path = inf->torrent;
     56    }
    4757
    4858    if( stat( path, &sb ) )
     
    98108    SHA1( (uint8_t *) beInfo->begin,
    99109          (long) beInfo->end - (long) beInfo->begin, inf->hash );
    100 
    101     /* No that we got the hash, we won't need this anymore */
     110    for( i = 0; i < SHA_DIGEST_LENGTH; i++ )
     111    {
     112        sprintf( inf->hashString + i * 2, "%02x", inf->hash[i] );
     113    }
     114
     115    if( saveCopy )
     116    {
     117        /* Save a copy of the torrent file in the private torrent directory */
     118        snprintf( inf->torrent, MAX_PATH_LENGTH, "%s/%s",
     119                  tr_getTorrentsDirectory(), inf->hashString );
     120        file = fopen( inf->torrent, "wb" );
     121        if( !file )
     122        {
     123            fprintf( stderr, "Could not open file (%s) (%s)\n", inf->torrent, strerror(errno) );
     124            tr_bencFree( &meta );
     125            free( buf );
     126            return 1;
     127        }
     128        fseek( file, 0, SEEK_SET );
     129        if( fwrite( buf, sb.st_size, 1, file ) != 1 )
     130        {
     131            fprintf( stderr, "Write error (%s)\n", inf->torrent );
     132            tr_bencFree( &meta );
     133            free( buf );
     134            fclose( file );
     135            return 1;
     136        }
     137        fclose( file );
     138    }
     139    else
     140    {
     141        snprintf( inf->torrent, MAX_PATH_LENGTH, "%s", path );
     142    }
     143
     144    /* We won't need this anymore */
    102145    free( buf );
    103146
     
    225268}
    226269
     270void tr_metainfoRemoveSaved( const char * hashString )
     271{
     272    char file[MAX_PATH_LENGTH];
     273
     274    snprintf( file, MAX_PATH_LENGTH, "%s/%s",
     275              tr_getTorrentsDirectory(), hashString );
     276    unlink(file);
     277}
     278
    227279/***********************************************************************
    228280 * strcatUTF8
  • trunk/libtransmission/metainfo.h

    r261 r310  
    2626#define TR_METAINFO_H 1
    2727
    28 int tr_metainfoParse( tr_info_t *, const char * );
     28int tr_metainfoParse( tr_info_t *, const char * path,
     29                      const char * savedHash, int saveCopy );
    2930
     31void tr_metainfoRemoveSaved( const char * hashString );
    3032#endif
  • trunk/libtransmission/platform.c

    r261 r310  
    2727  #include <FindDirectory.h>
    2828#endif
    29 #ifdef SYS_DARWIN
    30   #include <sys/types.h>
    31   #include <dirent.h>
    32 #endif
     29#include <sys/types.h>
     30#include <dirent.h>
    3331
    3432#include "transmission.h"
     33
     34static void
     35tr_migrateResume( const char *oldDirectory, const char *newDirectory )
     36{
     37    DIR * dirh;
     38    struct dirent * dirp;
     39    char oldFile[MAX_PATH_LENGTH];
     40    char newFile[MAX_PATH_LENGTH];
     41
     42    if( ( dirh = opendir( oldDirectory ) ) )
     43    {
     44        while( ( dirp = readdir( dirh ) ) )
     45        {
     46            if( strncmp( "resume.", dirp->d_name, 7 ) )
     47            {
     48                continue;
     49            }
     50            snprintf( oldFile, MAX_PATH_LENGTH, "%s/%s",
     51                      oldDirectory, dirp->d_name );
     52            snprintf( newFile, MAX_PATH_LENGTH, "%s/%s",
     53                      newDirectory, dirp->d_name );
     54            rename( oldFile, newFile );
     55        }
     56
     57        closedir( dirh );
     58    }
     59}
    3560
    3661char * tr_getPrefsDirectory()
     
    5681#endif
    5782
    58         mkdir( prefsDirectory, 0755 );
     83    tr_mkdir( prefsDirectory );
    5984    init = 1;
    6085
    6186#ifdef SYS_DARWIN
    62     DIR * dirh;
    63     struct dirent * dirp;
    6487    char oldDirectory[MAX_PATH_LENGTH];
    65     char oldFile[MAX_PATH_LENGTH];
    66     char newFile[MAX_PATH_LENGTH];
    6788    snprintf( oldDirectory, MAX_PATH_LENGTH, "%s/.transmission",
    6889              getenv( "HOME" ) );
    69     if( ( dirh = opendir( oldDirectory ) ) )
    70     {
    71         while( ( dirp = readdir( dirh ) ) )
    72         {
    73             if( !strcmp( ".", dirp->d_name ) ||
    74                 !strcmp( "..", dirp->d_name ) )
    75             {
    76                 continue;
    77             }
    78             snprintf( oldFile, MAX_PATH_LENGTH, "%s/%s",
    79                       oldDirectory, dirp->d_name );
    80             snprintf( newFile, MAX_PATH_LENGTH, "%s/%s",
    81                       prefsDirectory, dirp->d_name );
    82             rename( oldFile, newFile );
    83         }
    84 
    85         closedir( dirh );
    86         rmdir( oldDirectory );
    87     }
     90    tr_migrateResume( oldDirectory, prefsDirectory );
     91    rmdir( oldDirectory );
    8892#endif
    8993
    9094    return prefsDirectory;
     95}
     96
     97char * tr_getCacheDirectory()
     98{
     99    static char cacheDirectory[MAX_PATH_LENGTH];
     100    static int  init = 0;
     101
     102    if( init )
     103    {
     104        return cacheDirectory;
     105    }
     106
     107#ifdef SYS_BEOS
     108    /* XXX hey Bryan, is this fine with you? */
     109    snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s/Cache",
     110              tr_getPrefsDirectory() );
     111#elif defined( SYS_DARWIN )
     112    snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s",
     113              tr_getPrefsDirectory() );
     114#else
     115    snprintf( cacheDirectory, MAX_PATH_LENGTH, "%s/cache",
     116              tr_getPrefsDirectory() );
     117#endif
     118
     119    tr_mkdir( cacheDirectory );
     120    init = 1;
     121
     122    if( strcmp( tr_getPrefsDirectory(), cacheDirectory ) )
     123    {
     124        tr_migrateResume( tr_getPrefsDirectory(), cacheDirectory );
     125    }
     126
     127    return cacheDirectory;
     128}
     129
     130char * tr_getTorrentsDirectory()
     131{
     132    static char torrentsDirectory[MAX_PATH_LENGTH];
     133    static int  init = 0;
     134
     135    if( init )
     136    {
     137        return torrentsDirectory;
     138    }
     139
     140#ifdef SYS_BEOS
     141    /* XXX hey Bryan, is this fine with you? */
     142    snprintf( torrentsDirectory, MAX_PATH_LENGTH, "%s/Torrents",
     143              tr_getPrefsDirectory() );
     144#elif defined( SYS_DARWIN )
     145    snprintf( torrentsDirectory, MAX_PATH_LENGTH,
     146              "%s/Library/Application Support/Transmission/Torrents",
     147              getenv( "HOME" ) );
     148#else
     149    snprintf( torrentsDirectory, MAX_PATH_LENGTH, "%s/torrents",
     150              tr_getPrefsDirectory() );
     151#endif
     152
     153    tr_mkdir( torrentsDirectory );
     154    init = 1;
     155
     156    return torrentsDirectory;
    91157}
    92158
  • trunk/libtransmission/platform.h

    r261 r310  
    3535#endif
    3636
     37char * tr_getCacheDirectory();
     38char * tr_getTorrentsDirectory();
     39
    3740void tr_threadCreate ( tr_thread_t *, void (*func)(void *), void * arg );
    3841void tr_threadJoin   ( tr_thread_t * );
  • trunk/libtransmission/transmission.c

    r261 r310  
    2828 * Local prototypes
    2929 **********************************************************************/
     30static tr_torrent_t * torrentRealInit( tr_handle_t *, tr_torrent_t * tor,
     31                                       int flags, int * error );
    3032static void torrentReallyStop( tr_torrent_t * );
    3133static void  downloadLoop( void * );
     
    175177}
    176178
     179tr_torrent_t * tr_torrentInit( tr_handle_t * h, const char * path,
     180                               int flags, int * error )
     181{
     182    tr_torrent_t  * tor = calloc( sizeof( tr_torrent_t ), 1 );
     183    int             saveCopy = ( TR_FSAVEPRIVATE & flags );
     184
     185    /* Parse torrent file */
     186    if( tr_metainfoParse( &tor->info, path, NULL, saveCopy ) )
     187    {
     188        *error = TR_EINVALID;
     189        free( tor );
     190        return NULL;
     191    }
     192
     193    return torrentRealInit( h, tor, flags, error );
     194}
     195
     196tr_torrent_t * tr_torrentInitSaved( tr_handle_t * h, const char * hashStr,
     197                                    int flags, int * error )
     198{
     199    tr_torrent_t  * tor = calloc( sizeof( tr_torrent_t ), 1 );
     200
     201    /* Parse torrent file */
     202    if( tr_metainfoParse( &tor->info, NULL, hashStr, 0 ) )
     203    {
     204        *error = TR_EINVALID;
     205        free( tor );
     206        return NULL;
     207    }
     208
     209    return torrentRealInit( h, tor, ( TR_FSAVEPRIVATE | flags ), error );
     210}
     211
    177212/***********************************************************************
    178213 * tr_torrentInit
     
    181216 * to fill it.
    182217 **********************************************************************/
    183 tr_torrent_t * tr_torrentInit( tr_handle_t * h, const char * path,
    184                                int * error )
    185 {
    186     tr_torrent_t  * tor, * tor_tmp;
     218static tr_torrent_t * torrentRealInit( tr_handle_t * h, tr_torrent_t * tor,
     219                                       int flags, int * error )
     220{
     221    tr_torrent_t  * tor_tmp;
    187222    tr_info_t     * inf;
    188223    int             i;
    189224    char          * s1, * s2;
    190225
    191     tor = calloc( sizeof( tr_torrent_t ), 1 );
    192     inf = &tor->info;
    193 
    194     /* Parse torrent file */
    195     if( tr_metainfoParse( inf, path ) )
    196     {
    197         *error = TR_EINVALID;
    198         free( tor );
    199         return NULL;
    200     }
     226    inf        = &tor->info;
     227    inf->flags = flags;
    201228
    202229    /* Make sure this torrent is not already open */
     
    480507    }
    481508    tr_lockUnlock( &tor->lock );
     509}
     510
     511void tr_torrentRemoveSaved( tr_torrent_t * tor ) {
     512    tr_metainfoRemoveSaved( tor->info.hashString );
    482513}
    483514
  • trunk/libtransmission/transmission.h

    r264 r310  
    6060 * tr_getPrefsDirectory
    6161 ***********************************************************************
    62  * Returns the full path to the directory used by libtransmission to
    63  * store the resume files. The string belongs to libtransmission, do
    64  * not free it.
     62 * Returns the full path to a directory which can be used to store
     63 * preferences. The string belongs to libtransmission, do not free it.
    6564 **********************************************************************/
    6665char * tr_getPrefsDirectory();
     
    124123 * valid torrent file, returns an handle and adds it to the list of
    125124 * torrents (but doesn't start it). Returns NULL and sets *error
    126  * otherwise.
     125 * otherwise.  If the TR_FSAVEPRIVATE flag is passed then a private copy
     126 * of the torrent file will be saved.
    127127 **********************************************************************/
    128128#define TR_EINVALID     1
     
    131131#define TR_EOTHER       666
    132132tr_torrent_t * tr_torrentInit( tr_handle_t *, const char * path,
    133                                int * error );
     133                               int flags, int * error );
     134
     135/***********************************************************************
     136 * tr_torrentInitSaved
     137 ***********************************************************************
     138 * Opens and parses a torrent file as with tr_torrentInit, only taking
     139 * the hash string of a saved torrent file instead of a filename.  There
     140 * are currently no valid flags for this function.
     141 **********************************************************************/
     142tr_torrent_t * tr_torrentInitSaved( tr_handle_t *, const char * hashStr,
     143                                    int flags, int * error );
    134144
    135145typedef struct tr_info_s tr_info_t;
     
    202212
    203213/***********************************************************************
     214 * tr_torrentRemoveSaved
     215 ***********************************************************************
     216 * Removes the private saved copy of a torrent file for torrents which
     217 * the TR_FSAVEPRIVATE flag is set.
     218 **********************************************************************/
     219void tr_torrentRemoveSaved( tr_torrent_t * );
     220
     221/***********************************************************************
    204222 * tr_torrentClose
    205223 ***********************************************************************
     
    208226 **********************************************************************/
    209227void tr_torrentClose( tr_handle_t *, tr_torrent_t * );
    210 
    211228
    212229/***********************************************************************
     
    226243    /* General info */
    227244    uint8_t     hash[SHA_DIGEST_LENGTH];
     245    char        hashString[2*SHA_DIGEST_LENGTH+1];
    228246    char        name[MAX_PATH_LENGTH];
     247
     248    /* Flags */
     249#define TR_FSAVEPRIVATE 0x01    /* save a private copy of the torrent */
     250    int         flags;
    229251
    230252    /* Tracker info */
  • trunk/libtransmission/utils.c

    r261 r310  
    9494    return NULL;
    9595}
     96
     97int tr_mkdir( char * path )
     98{
     99    char      * p, * pp;
     100    struct stat sb;
     101    int done;
     102
     103    p = path;
     104    while( '/' == *p )
     105      p++;
     106    pp = p;
     107    done = 0;
     108    while( ( p = strchr( pp, '/' ) ) || ( p = strchr( pp, '\0' ) ) )
     109    {
     110        if( '\0' == *p)
     111        {
     112            done = 1;
     113        }
     114        else
     115        {
     116            *p = '\0';
     117        }
     118        if( stat( path, &sb ) )
     119        {
     120            /* Folder doesn't exist yet */
     121            if( mkdir( path, 0777 ) )
     122            {
     123                tr_err( "Could not create directory %s (%s)", path,
     124                        strerror( errno ) );
     125                *p = '/';
     126                return 1;
     127            }
     128        }
     129        else if( ( sb.st_mode & S_IFMT ) != S_IFDIR )
     130        {
     131            /* Node exists but isn't a folder */
     132            tr_err( "Remove %s, it's in the way.", path );
     133            *p = '/';
     134            return 1;
     135        }
     136        if( done )
     137        {
     138            break;
     139        }
     140        *p = '/';
     141        p++;
     142        pp = p;
     143    }
     144
     145    return 0;
     146}
  • trunk/libtransmission/utils.h

    r261 r310  
    3737
    3838void * tr_memmem( const void *, size_t, const void *, size_t );
     39
     40/***********************************************************************
     41 * tr_mkdir
     42 ***********************************************************************
     43 * Create a directory and any needed parent directories.
     44 * Note that the string passed in must be writable!
     45 **********************************************************************/
     46int tr_mkdir( char * path );
    3947
    4048/***********************************************************************
Note: See TracChangeset for help on using the changeset viewer.