~ubuntu-branches/ubuntu/jaunty/transmission/jaunty-security

« back to all changes in this revision

Viewing changes to libtransmission/resume.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2008-11-28 15:33:48 UTC
  • mfrom: (1.1.19 upstream)
  • Revision ID: james.westby@ubuntu.com-20081128153348-it70trfnxiroblmc
Tags: 1.40-0ubuntu1
* New upstream release (LP: #302672)
  - Tracker communication uses fewer resources
  - More accurate bandwidth limits
  - Reduce disk fragmentation by preallocating files (LP: #287726)
  - Stability, security and performance improvements to the RPC /
    Web UI server (closes LP: #290423)
  - Support compression when serving Web UI and RPC responses
  - Simplify the RPC whitelist
  - Fix bug that prevented handshakes with encrypted BitComet peers
  - Fix 1.3x bug that could re-download some data unnecessarily
    (LP: #295040)
  - Option to automatically update the blocklist weekly
  - Added off-hour bandwidth scheduling
  - Simplify file/priority selection in the details dialog
  - Fix a couple of crashes
  - New / updated translations
  - Don't inhibit hibernation by default (LP: #292929)
  - Use "close" animation when sending to notification area (LP: #130811)
  - Fix resize problems (LP: #269872)
  - Support "--version" option when launching from command line
    (LP: #292011)
  - Correctly parse announce URLs that have leading or trailing
    spaces (LP: #262411)
  - Display an error when "Open Torrent" fails (LP: #281463)
* Dropped 10_fix_crasher_from_upstream.dpatch: Fix is in this
  upstream release.
* debian/control: Don't just build-depend on libcurl-dev, which is
  a virtual package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 * This file is licensed by the GPL version 2.  Works owned by the
5
5
 * Transmission project are granted a special exemption to clause 2(b)
6
 
 * so that the bulk of its code can remain under the MIT license. 
 
6
 * so that the bulk of its code can remain under the MIT license.
7
7
 * This exemption does not extend to derived works not owned by
8
8
 * the Transmission project.
9
9
 *
10
 
 * $Id: resume.c 6334 2008-07-15 17:16:57Z charles $
 
10
 * $Id: resume.c 6840 2008-10-02 23:37:58Z charles $
11
11
 */
12
12
 
13
13
#include <unistd.h> /* unlink */
47
47
#define KEY_PROGRESS_MTIMES   "mtimes"
48
48
#define KEY_PROGRESS_BITFIELD "bitfield"
49
49
 
50
 
static void
51
 
getResumeFilename( char * buf, size_t buflen, const tr_torrent * tor )
 
50
static char*
 
51
getResumeFilename( const tr_torrent * tor )
52
52
{
53
 
    const char * dir = tr_getResumeDir( tor->handle );
54
 
    char base[MAX_PATH_LENGTH];
55
 
    tr_snprintf( base, sizeof( base ), "%s.%16.16s.resume",
56
 
                 tor->info.name,
57
 
                 tor->info.hashString );
58
 
    tr_buildPath( buf, buflen, dir, base, NULL );
 
53
    return tr_strdup_printf( "%s%c%s.%16.16s.resume",
 
54
                             tr_getResumeDir( tor->session ),
 
55
                             TR_PATH_DELIMITER,
 
56
                             tor->info.name,
 
57
                             tor->info.hashString );
59
58
}
60
59
 
61
60
/***
63
62
***/
64
63
 
65
64
static void
66
 
savePeers( tr_benc * dict, const tr_torrent * tor )
 
65
savePeers( tr_benc *          dict,
 
66
           const tr_torrent * tor )
67
67
{
68
 
    tr_pex * pex = NULL;
69
 
    const int count = tr_peerMgrGetPeers( tor->handle->peerMgr,
 
68
    tr_pex *  pex = NULL;
 
69
    const int count = tr_peerMgrGetPeers( tor->session->peerMgr,
70
70
                                          tor->info.hash, &pex );
 
71
 
71
72
    if( count > 0 )
72
 
        tr_bencDictAddRaw( dict, KEY_PEERS, pex, sizeof(tr_pex)*count );
 
73
        tr_bencDictAddRaw( dict, KEY_PEERS, pex, sizeof( tr_pex ) * count );
73
74
    tr_free( pex );
74
75
}
75
76
 
76
77
static uint64_t
77
 
loadPeers( tr_benc * dict, tr_torrent * tor )
 
78
loadPeers( tr_benc *    dict,
 
79
           tr_torrent * tor )
78
80
{
79
 
    uint64_t ret = 0;
80
 
    tr_benc * p;
 
81
    uint64_t        ret = 0;
 
82
    const uint8_t * str;
 
83
    size_t          len;
81
84
 
82
 
    if(( p = tr_bencDictFindType( dict, KEY_PEERS, TYPE_STR )))
 
85
    if( tr_bencDictFindRaw( dict, KEY_PEERS, &str, &len ) )
83
86
    {
84
 
        int i;
85
 
        const char * str = p->val.s.s;
86
 
        const size_t len = p->val.s.i;
 
87
        int       i;
87
88
        const int count = len / sizeof( tr_pex );
88
 
        for( i=0; i<count; ++i ) {
 
89
        for( i = 0; i < count; ++i )
 
90
        {
89
91
            tr_pex pex;
90
 
            memcpy( &pex, str + (i*sizeof(tr_pex)), sizeof(tr_pex) );
91
 
            tr_peerMgrAddPex( tor->handle->peerMgr,
 
92
            memcpy( &pex, str + ( i * sizeof( tr_pex ) ), sizeof( tr_pex ) );
 
93
            tr_peerMgrAddPex( tor->session->peerMgr,
92
94
                              tor->info.hash, TR_PEER_FROM_CACHE, &pex );
93
95
        }
94
96
        tr_tordbg( tor, "Loaded %d peers from resume file", count );
103
105
***/
104
106
 
105
107
static void
106
 
saveDND( tr_benc * dict, const tr_torrent * tor )
 
108
saveDND( tr_benc *          dict,
 
109
         const tr_torrent * tor )
107
110
{
108
 
    const tr_info * inf = tr_torrentInfo( tor );
 
111
    const tr_info *       inf = tr_torrentInfo( tor );
109
112
    const tr_file_index_t n = inf->fileCount;
110
 
    tr_file_index_t i;
111
 
    tr_benc * list;
 
113
    tr_file_index_t       i;
 
114
    tr_benc *             list;
112
115
 
113
116
    list = tr_bencDictAddList( dict, KEY_DND, n );
114
 
    for( i=0; i<n; ++i )
 
117
    for( i = 0; i < n; ++i )
115
118
        tr_bencListAddInt( list, inf->files[i].dnd ? 1 : 0 );
116
119
}
117
120
 
118
121
static uint64_t
119
 
loadDND( tr_benc * dict, tr_torrent * tor )
 
122
loadDND( tr_benc *    dict,
 
123
         tr_torrent * tor )
120
124
{
121
 
    uint64_t ret = 0;
122
 
    tr_info * inf = &tor->info;
 
125
    uint64_t              ret = 0;
 
126
    tr_info *             inf = &tor->info;
123
127
    const tr_file_index_t n = inf->fileCount;
124
 
    tr_benc * list = NULL;
 
128
    tr_benc *             list = NULL;
125
129
 
126
130
    if( tr_bencDictFindList( dict, KEY_DND, &list )
127
 
        && ( list->val.l.count == (int)n ) )
 
131
      && ( tr_bencListSize( list ) == n ) )
128
132
    {
129
 
        int64_t tmp;
 
133
        int64_t           tmp;
130
134
        tr_file_index_t * dl = tr_new( tr_file_index_t, n );
131
135
        tr_file_index_t * dnd = tr_new( tr_file_index_t, n );
132
 
        tr_file_index_t i, dlCount=0, dndCount=0;
 
136
        tr_file_index_t   i, dlCount = 0, dndCount = 0;
133
137
 
134
 
        for( i=0; i<n; ++i ) {
135
 
            if( tr_bencGetInt( &list->val.l.vals[i], &tmp ) && tmp )
 
138
        for( i = 0; i < n; ++i )
 
139
        {
 
140
            if( tr_bencGetInt( tr_bencListChild( list, i ), &tmp ) && tmp )
136
141
                dnd[dndCount++] = i;
137
142
            else
138
143
                dl[dlCount++] = i;
139
144
        }
140
145
 
141
 
        if( dndCount ) {
 
146
        if( dndCount )
 
147
        {
142
148
            tr_torrentInitFileDLs ( tor, dnd, dndCount, FALSE );
143
 
            tr_tordbg( tor, "Resume file found %d files listed as dnd", dndCount );
 
149
            tr_tordbg( tor, "Resume file found %d files listed as dnd",
 
150
                       dndCount );
144
151
        }
145
 
        if( dlCount ) {
 
152
        if( dlCount )
 
153
        {
146
154
            tr_torrentInitFileDLs ( tor, dl, dlCount, TRUE );
147
 
            tr_tordbg( tor, "Resume file found %d files marked for download", dlCount );
 
155
            tr_tordbg( tor,
 
156
                       "Resume file found %d files marked for download",
 
157
                       dlCount );
148
158
        }
149
159
 
150
160
        tr_free( dnd );
153
163
    }
154
164
    else
155
165
    {
156
 
        tr_tordbg( tor, "Couldn't load DND flags.  dnd list (%p) has %d children; torrent has %d files",
157
 
                   list, ( list ? list->val.l.count : -1 ), (int)n );
 
166
        tr_tordbg(
 
167
            tor,
 
168
            "Couldn't load DND flags.  dnd list (%p) has %zu children; torrent has %d files",
 
169
            list, tr_bencListSize( list ), (int)n );
158
170
    }
159
171
 
160
172
    return ret;
165
177
***/
166
178
 
167
179
static void
168
 
savePriorities( tr_benc * dict, const tr_torrent * tor )
 
180
savePriorities( tr_benc *          dict,
 
181
                const tr_torrent * tor )
169
182
{
170
 
    const tr_info * inf = tr_torrentInfo( tor );
 
183
    const tr_info *       inf = tr_torrentInfo( tor );
171
184
    const tr_file_index_t n = inf->fileCount;
172
 
    tr_file_index_t i;
173
 
    tr_benc * list;
 
185
    tr_file_index_t       i;
 
186
    tr_benc *             list;
174
187
 
175
188
    list = tr_bencDictAddList( dict, KEY_PRIORITY, n );
176
 
    for( i=0; i<n; ++i )
 
189
    for( i = 0; i < n; ++i )
177
190
        tr_bencListAddInt( list, inf->files[i].priority );
178
191
}
179
192
 
180
193
static uint64_t
181
 
loadPriorities( tr_benc * dict, tr_torrent * tor )
 
194
loadPriorities( tr_benc *    dict,
 
195
                tr_torrent * tor )
182
196
{
183
 
    uint64_t ret = 0;
184
 
    tr_info * inf = &tor->info;
 
197
    uint64_t              ret = 0;
 
198
    tr_info *             inf = &tor->info;
185
199
    const tr_file_index_t n = inf->fileCount;
186
 
    tr_benc * list;
 
200
    tr_benc *             list;
187
201
 
188
202
    if( tr_bencDictFindList( dict, KEY_PRIORITY, &list )
189
 
        && ( list->val.l.count == (int)n ) )
 
203
      && ( tr_bencListSize( list ) == n ) )
190
204
    {
191
 
        int64_t tmp;
 
205
        int64_t         tmp;
192
206
        tr_file_index_t i;
193
 
        for( i=0; i<n; ++i )
194
 
            if( tr_bencGetInt( &list->val.l.vals[i], &tmp ) )
 
207
        for( i = 0; i < n; ++i )
 
208
            if( tr_bencGetInt( tr_bencListChild( list, i ), &tmp ) )
195
209
                inf->files[i].priority = tmp;
196
210
        ret = TR_FR_PRIORITY;
197
211
    }
204
218
***/
205
219
 
206
220
static void
207
 
saveSpeedLimits( tr_benc * dict, const tr_torrent * tor )
 
221
saveSpeedLimits( tr_benc *          dict,
 
222
                 const tr_torrent * tor )
208
223
{
209
224
    tr_benc * d = tr_bencDictAddDict( dict, KEY_SPEEDLIMIT, 4 );
 
225
 
210
226
    tr_bencDictAddInt( d, KEY_SPEEDLIMIT_DOWN_SPEED,
211
 
                       tr_torrentGetSpeedLimit( tor, TR_DOWN ) );
 
227
                      tr_torrentGetSpeedLimit( tor, TR_DOWN ) );
212
228
    tr_bencDictAddInt( d, KEY_SPEEDLIMIT_DOWN_MODE,
213
 
                       tr_torrentGetSpeedMode( tor, TR_DOWN ) );
 
229
                      tr_torrentGetSpeedMode( tor, TR_DOWN ) );
214
230
    tr_bencDictAddInt( d, KEY_SPEEDLIMIT_UP_SPEED,
215
 
                       tr_torrentGetSpeedLimit( tor, TR_UP ) );
 
231
                      tr_torrentGetSpeedLimit( tor, TR_UP ) );
216
232
    tr_bencDictAddInt( d, KEY_SPEEDLIMIT_UP_MODE,
217
 
                       tr_torrentGetSpeedMode( tor, TR_UP ) );
 
233
                      tr_torrentGetSpeedMode( tor, TR_UP ) );
218
234
}
219
235
 
220
236
static uint64_t
221
 
loadSpeedLimits( tr_benc * dict, tr_torrent * tor )
 
237
loadSpeedLimits( tr_benc *    dict,
 
238
                 tr_torrent * tor )
222
239
{
223
 
    uint64_t ret = 0;
 
240
    uint64_t  ret = 0;
224
241
    tr_benc * d;
225
242
 
226
243
    if( tr_bencDictFindDict( dict, KEY_SPEEDLIMIT, &d ) )
245
262
***/
246
263
 
247
264
static void
248
 
saveProgress( tr_benc * dict, const tr_torrent * tor )
 
265
saveProgress( tr_benc *          dict,
 
266
              const tr_torrent * tor )
249
267
{
250
 
    int i;
251
 
    int n;
252
 
    time_t * mtimes;
253
 
    tr_benc * p;
254
 
    tr_benc * m;
 
268
    size_t              i, n;
 
269
    time_t *            mtimes;
 
270
    tr_benc *           p;
 
271
    tr_benc *           m;
255
272
    const tr_bitfield * bitfield;
256
273
 
257
274
    p = tr_bencDictAdd( dict, KEY_PROGRESS );
260
277
    /* add the mtimes */
261
278
    mtimes = tr_torrentGetMTimes( tor, &n );
262
279
    m = tr_bencDictAddList( p, KEY_PROGRESS_MTIMES, n );
263
 
    for( i=0; i<n; ++i ) {
 
280
    for( i = 0; i < n; ++i )
 
281
    {
264
282
        if( !tr_torrentIsFileChecked( tor, i ) )
265
283
            mtimes[i] = ~(time_t)0; /* force a recheck */
266
284
        tr_bencListAddInt( m, mtimes[i] );
276
294
}
277
295
 
278
296
static uint64_t
279
 
loadProgress( tr_benc * dict, tr_torrent * tor )
 
297
loadProgress( tr_benc *    dict,
 
298
              tr_torrent * tor )
280
299
{
281
 
    uint64_t ret = 0;
 
300
    uint64_t  ret = 0;
282
301
    tr_benc * p;
283
302
 
284
303
    if( tr_bencDictFindDict( dict, KEY_PROGRESS, &p ) )
285
304
    {
286
 
        tr_benc * m;
287
 
        tr_benc * b;
288
 
        int n;
289
 
        time_t * curMTimes = tr_torrentGetMTimes( tor, &n );
 
305
        const uint8_t * raw;
 
306
        size_t          rawlen;
 
307
        tr_benc *       m;
 
308
        size_t          n;
 
309
        time_t *        curMTimes = tr_torrentGetMTimes( tor, &n );
290
310
 
291
311
        if( tr_bencDictFindList( p, KEY_PROGRESS_MTIMES, &m )
292
 
            && ( m->val.l.count == (int64_t)tor->info.fileCount )
293
 
            && ( m->val.l.count == n ) )
 
312
          && ( n == tor->info.fileCount )
 
313
          && ( n == tr_bencListSize( m ) ) )
294
314
        {
295
 
            int i;
296
 
            for( i=0; i<n; ++i )
 
315
            size_t i;
 
316
            for( i = 0; i < n; ++i )
297
317
            {
298
318
                int64_t tmp;
299
 
                if( !tr_bencGetInt( &m->val.l.vals[i], &tmp ) ) {
300
 
                    tr_tordbg( tor, "File #%d needs to be verified - couldn't find benc entry", i );
 
319
                if( !tr_bencGetInt( tr_bencListChild( m, i ), &tmp ) )
 
320
                {
 
321
                    tr_tordbg(
 
322
                        tor,
 
323
                        "File #%zu needs to be verified - couldn't find benc entry",
 
324
                        i );
301
325
                    tr_torrentSetFileChecked( tor, i, FALSE );
302
 
                } else {
 
326
                }
 
327
                else
 
328
                {
303
329
                    const time_t t = (time_t) tmp;
304
330
                    if( t == curMTimes[i] )
305
331
                        tr_torrentSetFileChecked( tor, i, TRUE );
306
 
                    else {
307
 
                        tr_tordbg( tor, "File #%d needs to be verified - times %lu and %lu don't match", i, t, curMTimes[i] );
 
332
                    else
 
333
                    {
 
334
                        tr_tordbg(
 
335
                            tor,
 
336
                            "File #%zu needs to be verified - times %lu and %lu don't match",
 
337
                            i, t, curMTimes[i] );
308
338
                        tr_torrentSetFileChecked( tor, i, FALSE );
309
339
                    }
310
340
                }
313
343
        else
314
344
        {
315
345
            tr_torrentUncheck( tor );
316
 
            tr_tordbg( tor, "Torrent needs to be verified - unable to find mtimes" );
 
346
            tr_tordbg(
 
347
                tor, "Torrent needs to be verified - unable to find mtimes" );
317
348
        }
318
349
 
319
 
        if(( b = tr_bencDictFindType( p, KEY_PROGRESS_BITFIELD, TYPE_STR )))
 
350
        if( tr_bencDictFindRaw( p, KEY_PROGRESS_BITFIELD, &raw, &rawlen ) )
320
351
        {
321
352
            tr_bitfield tmp;
322
 
            tmp.byteCount = b->val.s.i;
 
353
            tmp.byteCount = rawlen;
323
354
            tmp.bitCount = tmp.byteCount * 8;
324
 
            tmp.bits = (uint8_t*) b->val.s.s;
325
 
            if( tr_cpBlockBitfieldSet( tor->completion, &tmp ) ) {
 
355
            tmp.bits = (uint8_t*) raw;
 
356
            if( !tr_cpBlockBitfieldSet( tor->completion, &tmp ) )
 
357
            {
326
358
                tr_torrentUncheck( tor );
327
 
                tr_tordbg( tor, "Torrent needs to be verified - error loading bitfield" );
 
359
                tr_tordbg(
 
360
                    tor,
 
361
                    "Torrent needs to be verified - error loading bitfield" );
328
362
            }
329
363
        }
330
364
        else
331
365
        {
332
366
            tr_torrentUncheck( tor );
333
 
            tr_tordbg( tor, "Torrent needs to be verified - unable to find bitfield" );
 
367
            tr_tordbg(
 
368
                tor,
 
369
                "Torrent needs to be verified - unable to find bitfield" );
334
370
        }
335
 
       
 
371
 
336
372
        tr_free( curMTimes );
337
373
        ret = TR_FR_PROGRESS;
338
374
    }
348
384
tr_torrentSaveResume( const tr_torrent * tor )
349
385
{
350
386
    tr_benc top;
351
 
    char filename[MAX_PATH_LENGTH];
 
387
    char *  filename;
352
388
 
353
389
    if( !tor )
354
390
        return;
355
391
 
356
392
    tr_bencInitDict( &top, 14 );
357
393
    tr_bencDictAddInt( &top, KEY_ACTIVITY_DATE,
358
 
                             tor->activityDate );
 
394
                       tor->activityDate );
359
395
    tr_bencDictAddInt( &top, KEY_ADDED_DATE,
360
 
                             tor->addedDate );
 
396
                       tor->addedDate );
361
397
    tr_bencDictAddInt( &top, KEY_CORRUPT,
362
 
                             tor->corruptPrev + tor->corruptCur );
 
398
                       tor->corruptPrev + tor->corruptCur );
363
399
    tr_bencDictAddInt( &top, KEY_DONE_DATE,
364
 
                             tor->doneDate );
 
400
                       tor->doneDate );
365
401
    tr_bencDictAddStr( &top, KEY_DOWNLOAD_DIR,
366
 
                             tor->downloadDir );
 
402
                       tor->downloadDir );
367
403
    tr_bencDictAddInt( &top, KEY_DOWNLOADED,
368
 
                             tor->downloadedPrev + tor->downloadedCur );
 
404
                       tor->downloadedPrev + tor->downloadedCur );
369
405
    tr_bencDictAddInt( &top, KEY_UPLOADED,
370
 
                             tor->uploadedPrev + tor->uploadedCur );
 
406
                       tor->uploadedPrev + tor->uploadedCur );
371
407
    tr_bencDictAddInt( &top, KEY_MAX_PEERS,
372
 
                             tor->maxConnectedPeers );
 
408
                       tor->maxConnectedPeers );
373
409
    tr_bencDictAddInt( &top, KEY_PAUSED,
374
 
                             tor->isRunning ? 0 : 1 );
 
410
                       tor->isRunning ? 0 : 1 );
375
411
    savePeers( &top, tor );
376
412
    savePriorities( &top, tor );
377
413
    saveDND( &top, tor );
378
414
    saveProgress( &top, tor );
379
415
    saveSpeedLimits( &top, tor );
380
416
 
381
 
    getResumeFilename( filename, sizeof( filename ), tor );
 
417
    filename = getResumeFilename( tor );
382
418
    tr_bencSaveFile( filename, &top );
 
419
    tr_free( filename );
383
420
 
384
421
    tr_bencFree( &top );
385
422
}
386
423
 
387
424
static uint64_t
388
 
loadFromFile( tr_torrent    * tor,
389
 
              uint64_t        fieldsToLoad )
 
425
loadFromFile( tr_torrent * tor,
 
426
              uint64_t     fieldsToLoad )
390
427
{
391
 
    int64_t i;
 
428
    int64_t      i;
392
429
    const char * str;
393
 
    uint64_t fieldsLoaded = 0;
394
 
    char filename[MAX_PATH_LENGTH];
395
 
    tr_benc top;
 
430
    uint64_t     fieldsLoaded = 0;
 
431
    char *       filename;
 
432
    tr_benc      top;
396
433
 
397
 
    getResumeFilename( filename, sizeof( filename ), tor );
 
434
    filename = getResumeFilename( tor );
398
435
 
399
436
    if( tr_bencLoadFile( filename, &top ) )
400
437
    {
401
 
        tr_tordbg( tor, "Couldn't read \"%s\"; trying old format.", filename );
 
438
        tr_tordbg( tor, "Couldn't read \"%s\"; trying old format.",
 
439
                   filename );
402
440
        fieldsLoaded = tr_fastResumeLoad( tor, fieldsToLoad );
403
441
 
404
442
        if( ( fieldsLoaded != 0 ) && ( fieldsToLoad == ~(uint64_t)0 ) )
408
446
            tr_tordbg( tor, "Migrated resume file to \"%s\"", filename );
409
447
        }
410
448
 
 
449
        tr_free( filename );
411
450
        return fieldsLoaded;
412
451
    }
413
452
 
414
453
    tr_tordbg( tor, "Read resume file \"%s\"", filename );
415
454
 
416
455
    if( ( fieldsToLoad & TR_FR_CORRUPT )
417
 
            && tr_bencDictFindInt( &top, KEY_CORRUPT, &i ) ) {
 
456
      && tr_bencDictFindInt( &top, KEY_CORRUPT, &i ) )
 
457
    {
418
458
        tor->corruptPrev = i;
419
459
        fieldsLoaded |= TR_FR_CORRUPT;
420
460
    }
421
461
 
422
462
    if( ( fieldsToLoad & ( TR_FR_PROGRESS | TR_FR_DOWNLOAD_DIR ) )
423
 
            && tr_bencDictFindStr( &top, KEY_DOWNLOAD_DIR, &str ) ) {
 
463
      && tr_bencDictFindStr( &top, KEY_DOWNLOAD_DIR, &str ) )
 
464
    {
424
465
        tr_free( tor->downloadDir );
425
466
        tor->downloadDir = tr_strdup( str );
426
467
        fieldsLoaded |= TR_FR_DOWNLOAD_DIR;
427
468
    }
428
469
 
429
470
    if( ( fieldsToLoad & TR_FR_DOWNLOADED )
430
 
            && tr_bencDictFindInt( &top, KEY_DOWNLOADED, &i ) ) {
 
471
      && tr_bencDictFindInt( &top, KEY_DOWNLOADED, &i ) )
 
472
    {
431
473
        tor->downloadedPrev = i;
432
474
        fieldsLoaded |= TR_FR_DOWNLOADED;
433
475
    }
434
476
 
435
477
    if( ( fieldsToLoad & TR_FR_UPLOADED )
436
 
            && tr_bencDictFindInt( &top, KEY_UPLOADED, &i ) ) {
 
478
      && tr_bencDictFindInt( &top, KEY_UPLOADED, &i ) )
 
479
    {
437
480
        tor->uploadedPrev = i;
438
481
        fieldsLoaded |= TR_FR_UPLOADED;
439
482
    }
440
483
 
441
484
    if( ( fieldsToLoad & TR_FR_MAX_PEERS )
442
 
            && tr_bencDictFindInt( &top, KEY_MAX_PEERS, &i ) ) {
 
485
      && tr_bencDictFindInt( &top, KEY_MAX_PEERS, &i ) )
 
486
    {
443
487
        tor->maxConnectedPeers = i;
444
488
        fieldsLoaded |= TR_FR_MAX_PEERS;
445
489
    }
446
490
 
447
491
    if( ( fieldsToLoad & TR_FR_RUN )
448
 
            && tr_bencDictFindInt( &top, KEY_PAUSED, &i ) ) {
 
492
      && tr_bencDictFindInt( &top, KEY_PAUSED, &i ) )
 
493
    {
449
494
        tor->isRunning = i ? 0 : 1;
450
495
        fieldsLoaded |= TR_FR_RUN;
451
496
    }
452
497
 
453
498
    if( ( fieldsToLoad & TR_FR_ADDED_DATE )
454
 
        && tr_bencDictFindInt( &top, KEY_ADDED_DATE, &i ) ) {
 
499
      && tr_bencDictFindInt( &top, KEY_ADDED_DATE, &i ) )
 
500
    {
455
501
        tor->addedDate = i;
456
502
        fieldsLoaded |= TR_FR_ADDED_DATE;
457
503
    }
458
504
 
459
505
    if( ( fieldsToLoad & TR_FR_DONE_DATE )
460
 
        && tr_bencDictFindInt( &top, KEY_DONE_DATE, &i ) ) {
 
506
      && tr_bencDictFindInt( &top, KEY_DONE_DATE, &i ) )
 
507
    {
461
508
        tor->doneDate = i;
462
509
        fieldsLoaded |= TR_FR_DONE_DATE;
463
510
    }
464
511
 
465
512
    if( ( fieldsToLoad & TR_FR_ACTIVITY_DATE )
466
 
        && tr_bencDictFindInt( &top, KEY_ACTIVITY_DATE, &i ) ) {
 
513
      && tr_bencDictFindInt( &top, KEY_ACTIVITY_DATE, &i ) )
 
514
    {
467
515
        tor->activityDate = i;
468
516
        fieldsLoaded |= TR_FR_ACTIVITY_DATE;
469
517
    }
484
532
        fieldsLoaded |= loadSpeedLimits( &top, tor );
485
533
 
486
534
    tr_bencFree( &top );
 
535
    tr_free( filename );
487
536
    return fieldsLoaded;
488
537
}
489
538
 
490
539
static uint64_t
491
 
setFromCtor( tr_torrent * tor, uint64_t fields, const tr_ctor * ctor, int mode )
 
540
setFromCtor( tr_torrent *    tor,
 
541
             uint64_t        fields,
 
542
             const tr_ctor * ctor,
 
543
             int             mode )
492
544
{
493
545
    uint64_t ret = 0;
494
546
 
495
 
    if( fields & TR_FR_RUN ) {
 
547
    if( fields & TR_FR_RUN )
 
548
    {
496
549
        uint8_t isPaused;
497
 
        if( !tr_ctorGetPaused( ctor, mode, &isPaused ) ) {
 
550
        if( !tr_ctorGetPaused( ctor, mode, &isPaused ) )
 
551
        {
498
552
            tor->isRunning = !isPaused;
499
553
            ret |= TR_FR_RUN;
500
554
        }
501
555
    }
502
556
 
503
 
    if( fields & TR_FR_MAX_PEERS ) 
 
557
    if( fields & TR_FR_MAX_PEERS )
504
558
        if( !tr_ctorGetPeerLimit( ctor, mode, &tor->maxConnectedPeers ) )
505
559
            ret |= TR_FR_MAX_PEERS;
506
560
 
507
 
    if( fields & TR_FR_DOWNLOAD_DIR ) {
 
561
    if( fields & TR_FR_DOWNLOAD_DIR )
 
562
    {
508
563
        const char * downloadDir;
509
 
        if( !tr_ctorGetDownloadDir( ctor, mode, &downloadDir ) ) {
 
564
        if( !tr_ctorGetDownloadDir( ctor, mode, &downloadDir ) )
 
565
        {
510
566
            ret |= TR_FR_DOWNLOAD_DIR;
511
567
            tr_free( tor->downloadDir );
512
568
            tor->downloadDir = tr_strdup( downloadDir );
517
573
}
518
574
 
519
575
static uint64_t
520
 
useManditoryFields( tr_torrent * tor, uint64_t fields, const tr_ctor * ctor )
 
576
useManditoryFields( tr_torrent *    tor,
 
577
                    uint64_t        fields,
 
578
                    const tr_ctor * ctor )
521
579
{
522
580
    return setFromCtor( tor, fields, ctor, TR_FORCE );
523
581
}
524
582
 
525
583
static uint64_t
526
 
useFallbackFields( tr_torrent * tor, uint64_t fields, const tr_ctor * ctor )
 
584
useFallbackFields( tr_torrent *    tor,
 
585
                   uint64_t        fields,
 
586
                   const tr_ctor * ctor )
527
587
{
528
588
    return setFromCtor( tor, fields, ctor, TR_FALLBACK );
529
589
}
530
590
 
531
591
uint64_t
532
 
tr_torrentLoadResume( tr_torrent    * tor,
 
592
tr_torrentLoadResume( tr_torrent *    tor,
533
593
                      uint64_t        fieldsToLoad,
534
594
                      const tr_ctor * ctor )
535
595
{
547
607
void
548
608
tr_torrentRemoveResume( const tr_torrent * tor )
549
609
{
550
 
    char filename[MAX_PATH_LENGTH];
551
 
    getResumeFilename( filename, sizeof( filename ), tor );
 
610
    char * filename = getResumeFilename( tor );
 
611
 
552
612
    unlink( filename );
553
613
    tr_fastResumeRemove( tor );
 
614
    tr_free( filename );
554
615
}
 
616