Changeset 10084
- Timestamp:
- Feb 2, 2010, 10:45:22 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cli/cli.c
r10048 r10084 382 382 tr_ctorSetMetainfo( ctor, fileContents, fileLength ); 383 383 } else if( !memcmp( torrentPath, "magnet:?", 8 ) ) { 384 tr_ctorSetM agnet( ctor, torrentPath );384 tr_ctorSetMetainfoFromMagnetLink( ctor, torrentPath ); 385 385 } else if( !memcmp( torrentPath, "http", 4 ) ) { 386 386 tr_webRun( h, torrentPath, NULL, onTorrentFileDownloaded, ctor ); -
trunk/gtk/tr-core.c
r9890 r10084 1053 1053 url = tmp = g_strdup_printf( "magnet:?xt=urn:btih:%s", url ); 1054 1054 1055 err = tr_ctorSetM agnet( ctor, url );1055 err = tr_ctorSetMetainfoFromMagnetLink( ctor, url ); 1056 1056 1057 1057 if( !err ) -
trunk/libtransmission/bencode.c
r10070 r10084 672 672 673 673 tr_benc * 674 tr_bencListAddInt( tr_benc * list, 675 int64_t val ) 674 tr_bencListAddInt( tr_benc * list, int64_t val ) 676 675 { 677 676 tr_benc * node = tr_bencListAdd( list ); … … 682 681 683 682 tr_benc * 684 tr_bencListAddStr( tr_benc * list, 685 const char * val ) 683 tr_bencListAddReal( tr_benc * list, double val ) 686 684 { 687 685 tr_benc * node = tr_bencListAdd( list ); 688 686 tr_bencInitReal( node, val ); 687 return node; 688 } 689 690 tr_benc * 691 tr_bencListAddBool( tr_benc * list, tr_bool val ) 692 { 693 tr_benc * node = tr_bencListAdd( list ); 694 tr_bencInitBool( node, val ); 695 return node; 696 } 697 698 tr_benc * 699 tr_bencListAddStr( tr_benc * list, const char * val ) 700 { 701 tr_benc * node = tr_bencListAdd( list ); 689 702 tr_bencInitStr( node, val, -1 ); 703 return node; 704 } 705 706 tr_benc * 707 tr_bencListAddRaw( tr_benc * list, const uint8_t * val, size_t len ) 708 { 709 tr_benc * node = tr_bencListAdd( list ); 710 tr_bencInitRaw( node, val, len ); 690 711 return node; 691 712 } … … 804 825 805 826 tr_benc* 827 tr_bencDictAddRaw( tr_benc * dict, 828 const char * key, 829 const void * src, 830 size_t len ) 831 { 832 tr_benc * child; 833 834 /* see if it already exists, and if so, try to reuse it */ 835 if(( child = tr_bencDictFind( dict, key ))) { 836 if( tr_bencIsString( child ) ) { 837 if( stringIsAlloced( child ) ) 838 tr_free( child->val.s.str.ptr ); 839 } else { 840 tr_bencDictRemove( dict, key ); 841 child = NULL; 842 } 843 } 844 845 /* if it doesn't exist, create it */ 846 if( child == NULL ) 847 child = tr_bencDictAdd( dict, key ); 848 849 /* set it */ 850 tr_bencInitRaw( child, src, len ); 851 852 return child; 853 } 854 855 tr_benc* 806 856 tr_bencDictAddList( tr_benc * dict, 807 857 const char * key, … … 822 872 823 873 tr_bencInitDict( child, reserveCount ); 824 return child;825 }826 827 tr_benc*828 tr_bencDictAddRaw( tr_benc * dict,829 const char * key,830 const void * src,831 size_t len )832 {833 tr_benc * child = tr_bencDictAdd( dict, key );834 835 tr_bencInitRaw( child, src, len );836 874 return child; 837 875 } … … 1404 1442 **** 1405 1443 ***/ 1444 1445 static void 1446 tr_bencListCopy( tr_benc * target, const tr_benc * src ) 1447 { 1448 int i = 0; 1449 const tr_benc * val; 1450 1451 while(( val = tr_bencListChild( (tr_benc*)src, i++ ))) 1452 { 1453 if( tr_bencIsBool( val ) ) 1454 { 1455 tr_bool boolVal = 0; 1456 tr_bencGetBool( val, &boolVal ); 1457 tr_bencListAddBool( target, boolVal ); 1458 } 1459 else if( tr_bencIsReal( val ) ) 1460 { 1461 double realVal = 0; 1462 tr_bencGetReal( val, &realVal ); 1463 tr_bencListAddReal( target, realVal ); 1464 } 1465 else if( tr_bencIsInt( val ) ) 1466 { 1467 int64_t intVal = 0; 1468 tr_bencGetInt( val, &intVal ); 1469 tr_bencListAddInt( target, intVal ); 1470 } 1471 else if( tr_bencIsString( val ) ) 1472 { 1473 tr_bencListAddRaw( target, (const uint8_t*)getStr( val ), val->val.s.len ); 1474 } 1475 else if( tr_bencIsDict( val ) ) 1476 { 1477 tr_bencMergeDicts( tr_bencListAddDict( target, 0 ), val ); 1478 } 1479 else if ( tr_bencIsList( val ) ) 1480 { 1481 tr_bencListCopy( tr_bencListAddList( target, 0 ), val ); 1482 } 1483 else 1484 { 1485 tr_err( "tr_bencListCopy skipping item" ); 1486 } 1487 } 1488 } 1406 1489 1407 1490 static size_t … … 1471 1554 else if( tr_bencIsString( val ) ) 1472 1555 { 1473 const char * strVal = NULL; 1474 tr_bencGetStr( val, &strVal ); 1475 tr_bencDictAddStr( target, key, strVal ); 1556 tr_bencDictAddRaw( target, key, getStr( val ), val->val.s.len ); 1476 1557 } 1477 1558 else if( tr_bencIsDict( val ) && tr_bencDictFindDict( target, key, &t ) ) 1478 1559 { 1479 1560 tr_bencMergeDicts( t, val ); 1561 } 1562 else if( tr_bencIsList( val ) ) 1563 { 1564 if( tr_bencDictFind( target, key ) == NULL ) 1565 { 1566 tr_bencListCopy( tr_bencDictAddList( target, key, tr_bencListSize( val ) ), val ); 1567 } 1480 1568 } 1481 1569 else -
trunk/libtransmission/bencode.h
r9965 r10084 139 139 tr_benc * tr_bencListAdd( tr_benc * ); 140 140 141 tr_benc * tr_bencListAddBool( tr_benc *, tr_bool val ); 142 141 143 tr_benc * tr_bencListAddInt( tr_benc *, int64_t val ); 142 144 145 tr_benc * tr_bencListAddReal( tr_benc *, double val ); 146 143 147 tr_benc * tr_bencListAddStr( tr_benc *, const char * val ); 148 149 tr_benc * tr_bencListAddRaw( tr_benc *, const uint8_t * val, size_t len ); 144 150 145 151 tr_benc * tr_bencListAddList( tr_benc *, size_t reserveCount ); -
trunk/libtransmission/magnet.c
r9979 r10084 15 15 16 16 #include "transmission.h" 17 #include "bencode.h" 17 18 #include "magnet.h" 18 19 #include "utils.h" … … 194 195 } 195 196 } 197 198 void 199 tr_magnetCreateMetainfo( const tr_magnet_info * info, tr_benc * top ) 200 { 201 int i; 202 tr_benc * d; 203 tr_bencInitDict( top, 4 ); 204 205 /* announce list */ 206 if( info->trackerCount == 1 ) 207 tr_bencDictAddStr( top, "announce", info->trackers[0] ); 208 else { 209 tr_benc * trackers = tr_bencDictAddList( top, "announce-list", info->trackerCount ); 210 for( i=0; i<info->trackerCount; ++i ) 211 tr_bencListAddStr( tr_bencListAddList( trackers, 1 ), info->trackers[i] ); 212 } 213 214 /* webseeds */ 215 if( info->webseedCount > 0 ) { 216 tr_benc * urls = tr_bencDictAddList( top, "url-list", info->webseedCount ); 217 for( i=0; i<info->webseedCount; ++i ) 218 tr_bencListAddStr( urls, info->webseeds[i] ); 219 } 220 221 /* nonstandard keys */ 222 d = tr_bencDictAddDict( top, "magnet-info", 2 ); 223 tr_bencDictAddRaw( d, "info_hash", info->hash, 20 ); 224 if( info->displayName != NULL ) 225 tr_bencDictAddStr( d, "display-name", info->displayName ); 226 } 227 228 -
trunk/libtransmission/magnet.h
r9931 r10084 36 36 tr_magnet_info * tr_magnetParse( const char * uri ); 37 37 38 struct tr_benc; 39 40 void tr_magnetCreateMetainfo( const tr_magnet_info *, struct tr_benc * ); 41 38 42 void tr_magnetFree( tr_magnet_info * info ); 39 43 -
trunk/libtransmission/metainfo.c
r9927 r10084 27 27 #include "bencode.h" 28 28 #include "crypto.h" /* tr_sha1 */ 29 #include "magnet.h"30 29 #include "metainfo.h" 31 30 #include "platform.h" … … 385 384 386 385 static const char* 387 tr_metainfoParseImpl( const tr_session * session, 388 tr_info * inf, 389 int * infoDictOffset, 390 int * infoDictLength, 391 const tr_benc * meta_in ) 386 tr_metainfoParseImpl( const tr_session * session, 387 tr_info * inf, 388 tr_bool * hasInfoDict, 389 int * infoDictOffset, 390 int * infoDictLength, 391 const tr_benc * meta_in ) 392 392 { 393 393 int64_t i; … … 395 395 const char * str; 396 396 const uint8_t * raw; 397 tr_benc * beInfo; 397 tr_benc * d; 398 tr_benc * infoDict = NULL; 398 399 tr_benc * meta = (tr_benc *) meta_in; 399 400 tr_bool err; 401 tr_bool b; 402 tr_bool isMagnet = FALSE; 400 403 401 404 /* info_hash: urlencoded 20-byte SHA1 hash of the value of the info key 402 405 * from the Metainfo file. Note that the value will be a bencoded 403 406 * dictionary, given the definition of the info key above. */ 404 if( !tr_bencDictFindDict( meta, "info", &beInfo ) ) 405 return "info"; 407 b = tr_bencDictFindDict( meta, "info", &infoDict ); 408 if( hasInfoDict != NULL ) 409 *hasInfoDict = b; 410 if( !b ) 411 { 412 /* no info dictionary... is this a magnet link? */ 413 if( tr_bencDictFindDict( meta, "magnet-info", &d ) ) 414 { 415 isMagnet = TRUE; 416 417 /* get the info-hash */ 418 if( !tr_bencDictFindRaw( d, "info_hash", &raw, &raw_len ) ) 419 return "info_hash"; 420 if( raw_len != SHA_DIGEST_LENGTH ) 421 return "info_hash"; 422 memcpy( inf->hash, raw, raw_len ); 423 tr_sha1_to_hex( inf->hashString, inf->hash ); 424 escape( inf->hashEscaped, inf->hash, SHA_DIGEST_LENGTH ); 425 426 /* maybe get the display name */ 427 if( tr_bencDictFindStr( d, "display-name", &str ) ) { 428 tr_free( inf->name ); 429 inf->name = tr_strdup( str ); 430 } 431 } 432 else /* not a magnet link and has no info dict... */ 433 { 434 return "info"; 435 } 436 } 406 437 else 407 438 { 408 439 int len; 409 char * bstr = tr_bencToStr( beInfo, TR_FMT_BENC, &len );440 char * bstr = tr_bencToStr( infoDict, TR_FMT_BENC, &len ); 410 441 tr_sha1( inf->hash, bstr, len, NULL ); 411 442 tr_sha1_to_hex( inf->hashString, inf->hash ); … … 431 462 432 463 /* name */ 433 if( !tr_bencDictFindStr( beInfo, "name.utf-8", &str ) ) 434 if( !tr_bencDictFindStr( beInfo, "name", &str ) ) 435 str = ""; 436 if( !str || !*str ) 437 return "name"; 438 tr_free( inf->name ); 439 inf->name = tr_utf8clean( str, -1, &err ); 464 if( !isMagnet ) { 465 if( !tr_bencDictFindStr( infoDict, "name.utf-8", &str ) ) 466 if( !tr_bencDictFindStr( infoDict, "name", &str ) ) 467 str = ""; 468 if( !str || !*str ) 469 return "name"; 470 tr_free( inf->name ); 471 inf->name = tr_utf8clean( str, -1, &err ); 472 } 440 473 441 474 /* comment */ … … 459 492 460 493 /* private */ 461 if( !tr_bencDictFindInt( beInfo, "private", &i ) )494 if( !tr_bencDictFindInt( infoDict, "private", &i ) ) 462 495 if( !tr_bencDictFindInt( meta, "private", &i ) ) 463 496 i = 0; … … 465 498 466 499 /* piece length */ 467 if( !tr_bencDictFindInt( beInfo, "piece length", &i ) || ( i < 1 ) ) 468 return "piece length"; 469 inf->pieceSize = i; 500 if( !isMagnet ) { 501 if( !tr_bencDictFindInt( infoDict, "piece length", &i ) || ( i < 1 ) ) 502 return "piece length"; 503 inf->pieceSize = i; 504 } 470 505 471 506 /* pieces */ 472 if( !tr_bencDictFindRaw( beInfo, "pieces", &raw, 473 &raw_len ) || ( raw_len % SHA_DIGEST_LENGTH ) ) 474 return "pieces"; 475 inf->pieceCount = raw_len / SHA_DIGEST_LENGTH; 476 inf->pieces = tr_new0( tr_piece, inf->pieceCount ); 477 for( i = 0; i < inf->pieceCount; ++i ) 478 memcpy( inf->pieces[i].hash, &raw[i * SHA_DIGEST_LENGTH], 479 SHA_DIGEST_LENGTH ); 507 if( !isMagnet ) { 508 if( !tr_bencDictFindRaw( infoDict, "pieces", &raw, &raw_len ) ) 509 return "pieces"; 510 if( raw_len % SHA_DIGEST_LENGTH ) 511 return "pieces"; 512 inf->pieceCount = raw_len / SHA_DIGEST_LENGTH; 513 inf->pieces = tr_new0( tr_piece, inf->pieceCount ); 514 for( i = 0; i < inf->pieceCount; ++i ) 515 memcpy( inf->pieces[i].hash, &raw[i * SHA_DIGEST_LENGTH], 516 SHA_DIGEST_LENGTH ); 517 } 480 518 481 519 /* files */ 482 if( ( str = parseFiles( inf, tr_bencDictFind( beInfo, "files" ), 483 tr_bencDictFind( beInfo, "length" ) ) ) ) 484 return str; 485 if( !inf->fileCount || !inf->totalSize ) 486 return "files"; 487 if( (uint64_t) inf->pieceCount != 488 ( inf->totalSize + inf->pieceSize - 1 ) / inf->pieceSize ) 489 return "files"; 520 if( !isMagnet ) { 521 if( ( str = parseFiles( inf, tr_bencDictFind( infoDict, "files" ), 522 tr_bencDictFind( infoDict, "length" ) ) ) ) 523 return str; 524 if( !inf->fileCount || !inf->totalSize ) 525 return "files"; 526 if( (uint64_t) inf->pieceCount != 527 ( inf->totalSize + inf->pieceSize - 1 ) / inf->pieceSize ) 528 return "files"; 529 } 490 530 491 531 /* get announce or announce-list */ … … 505 545 tr_bool 506 546 tr_metainfoParse( const tr_session * session, 547 const tr_benc * meta_in, 507 548 tr_info * inf, 549 tr_bool * hasInfoDict, 508 550 int * infoDictOffset, 509 int * infoDictLength, 510 const tr_benc * meta_in ) 551 int * infoDictLength ) 511 552 { 512 553 const char * badTag = tr_metainfoParseImpl( session, 513 554 inf, 555 hasInfoDict, 514 556 infoDictOffset, 515 557 infoDictLength, … … 570 612 tr_free( filename ); 571 613 } 572 573 /***574 ****575 ***/576 577 void578 tr_metainfoSetFromMagnet( tr_info * inf, const tr_magnet_info * m )579 {580 /* hash */581 memcpy( inf->hash, m->hash, 20 );582 tr_sha1_to_hex( inf->hashString, inf->hash );583 escape( inf->hashEscaped, inf->hash, SHA_DIGEST_LENGTH );584 585 /* name */586 if( m->displayName && *m->displayName )587 inf->name = tr_strdup( m->displayName );588 else589 inf->name = tr_strdup( inf->hashString );590 591 /* trackers */592 if(( inf->trackerCount = m->trackerCount ))593 {594 int i;595 const int n = m->trackerCount;596 597 inf->trackers = tr_new0( tr_tracker_info, n );598 for( i=0; i<n; ++i ) {599 const char * url = m->trackers[i];600 inf->trackers[i].tier = i;601 inf->trackers[i].announce = tr_strdup( url );602 inf->trackers[i].scrape = tr_convertAnnounceToScrape( url );603 inf->trackers[i].id = i;604 }605 }606 607 /* webseeds */608 if(( inf->webseedCount = m->webseedCount ))609 {610 int i;611 const int n = m->webseedCount;612 613 inf->webseeds = tr_new0( char*, n );614 for( i=0; i<n; ++i )615 inf->webseeds[i] = tr_strdup( m->webseeds[i] );616 }617 } -
trunk/libtransmission/metainfo.h
r9868 r10084 21 21 22 22 struct tr_benc; 23 struct tr_magnet_info;24 23 25 24 tr_bool tr_metainfoParse( const tr_session * session, 25 const struct tr_benc * benc, 26 26 tr_info * setmeInfo, 27 tr_bool * setmeHasInfoDict, 27 28 int * setmeInfoDictOffset, 28 int * setmeInfoDictLength, 29 const struct tr_benc * benc ); 29 int * setmeInfoDictLength ); 30 30 31 31 void tr_metainfoRemoveSaved( const tr_session * session, … … 35 35 tr_info * inf ); 36 36 37 void tr_metainfoSetFromMagnet( tr_info * inf, const struct tr_magnet_info * m );38 39 37 40 38 #endif -
trunk/libtransmission/resume.c
r9868 r10084 518 518 tr_bencDictAddBool( &top, KEY_PAUSED, !tor->isRunning ); 519 519 savePeers( &top, tor ); 520 saveFilePriorities( &top, tor ); 521 saveDND( &top, tor ); 522 saveProgress( &top, tor ); 520 if( tr_torrentHasMetadata( tor ) ) 521 { 522 saveFilePriorities( &top, tor ); 523 saveDND( &top, tor ); 524 saveProgress( &top, tor ); 525 } 523 526 saveSpeedLimits( &top, tor ); 524 527 saveRatioLimits( &top, tor ); -
trunk/libtransmission/rpcimpl.c
r10083 r10084 1119 1119 else if( !strncmp( fname, "magnet:?", 8 ) ) 1120 1120 { 1121 tr_ctorSetM agnet( ctor, fname );1121 tr_ctorSetMetainfoFromMagnetLink( ctor, fname ); 1122 1122 } 1123 1123 else -
trunk/libtransmission/torrent-ctor.c
r10081 r10084 45 45 char * sourceFile; 46 46 47 tr_magnet_info * magnetInfo;48 49 47 struct optional_args optionalArgs[2]; 50 48 … … 107 105 108 106 int 109 tr_ctorSetM agnet( tr_ctor * ctor, const char * uri)107 tr_ctorSetMetainfoFromMagnetLink( tr_ctor * ctor, const char * magnet_link ) 110 108 { 111 109 int err; 112 113 if( ctor->magnetInfo != NULL ) 114 tr_magnetFree( ctor->magnetInfo ); 115 116 ctor->magnetInfo = tr_magnetParse( uri ); 117 118 err = ctor->magnetInfo == NULL; 110 tr_magnet_info * magnet_info = tr_magnetParse( magnet_link ); 111 112 if( magnet_info == NULL ) 113 err = -1; 114 else { 115 int len; 116 tr_benc tmp; 117 char * str; 118 119 tr_magnetCreateMetainfo( magnet_info, &tmp ); 120 str = tr_bencToStr( &tmp, TR_FMT_BENC, &len ); 121 err = tr_ctorSetMetainfo( ctor, (const uint8_t*)str, len ); 122 123 tr_free( str ); 124 tr_magnetFree( magnet_info ); 125 } 126 119 127 return err; 120 128 } … … 391 399 392 400 int 393 tr_ctorGetMagnet( const tr_ctor * ctor, const tr_magnet_info ** setme )394 {395 int err = 0;396 397 if( ctor->magnetInfo == NULL )398 err = 1;399 else400 *setme = ctor->magnetInfo;401 402 return err;403 }404 405 int406 401 tr_ctorGetMetainfo( const tr_ctor * ctor, 407 402 const tr_benc ** setme ) -
trunk/libtransmission/torrent-magnet.c
r9868 r10084 139 139 140 140 void 141 tr_torrentSetMetadataPiece( tr_torrent * tor, 142 int piece, 143 const void * data, 144 int len ) 141 tr_torrentSetMetadataPiece( tr_torrent * tor, int piece, const void * data, int len ) 145 142 { 146 143 int i; … … 180 177 { 181 178 tr_bool success = FALSE; 179 tr_bool checksumPassed = FALSE; 180 tr_bool metainfoParsed = FALSE; 182 181 uint8_t sha1[SHA_DIGEST_LENGTH]; 182 183 /* we've got a complete set of metainfo... see if it passes the checksum test */ 183 184 dbgmsg( tor, "metainfo piece %d was the last one", piece ); 184 185 tr_sha1( sha1, m->metadata, m->metadata_size, NULL ); 185 if( !memcmp( sha1, tor->info.hash, SHA_DIGEST_LENGTH ) ) 186 { 187 int err; 188 tr_benc dict; 189 struct evbuffer * buf = evbuffer_new( ); 190 dbgmsg( tor, "metadata checksum passed! (length: %d)", (int)m->metadata_size ); 191 192 /* add a wrapper dictionary to the benc. 193 * include the announce-list too, 194 * so we can save it in the .torrent for future sessions */ 195 evbuffer_add_printf( buf, "d" ); 196 evbuffer_add_printf( buf, "13:announce-list" ); 197 evbuffer_add_printf( buf, "l" ); 198 for( i=0; i<tor->info.trackerCount; ++i ) { 199 const char * url = tor->info.trackers[i].announce; 200 evbuffer_add_printf( buf, "l%zu:%se", strlen( url ), url ); 186 if(( checksumPassed = !memcmp( sha1, tor->info.hash, SHA_DIGEST_LENGTH ))) 187 { 188 /* checksum passed; now try to parse it as benc */ 189 tr_benc infoDict; 190 const int err = tr_bencLoad( m->metadata, m->metadata_size, &infoDict, NULL ); 191 dbgmsg( tor, "err is %d", err ); 192 if(( metainfoParsed = !err )) 193 { 194 /* yay we have bencoded metainfo... merge it into our .torrnet file */ 195 tr_benc newMetainfo; 196 const char * path = tor->info.torrent; 197 if( !tr_bencLoadFile( &newMetainfo, TR_FMT_BENC, path ) ) 198 { 199 tr_bool hasInfo; 200 tr_benc * tmp; 201 202 dbgmsg( tor, "Saving completed metadata to \"%s\"", path ); 203 assert( !tr_bencDictFindDict( &newMetainfo, "info", &tmp ) ); 204 tr_bencMergeDicts( tr_bencDictAddDict( &newMetainfo, "info", 0 ), &infoDict ); 205 tr_bencToFile( &newMetainfo, TR_FMT_BENC, path ); 206 207 success = tr_metainfoParse( tor->session, &newMetainfo, &tor->info, 208 &hasInfo, &tor->infoDictOffset, &tor->infoDictLength ); 209 210 assert( hasInfo ); 211 assert( success ); 212 213 tr_torrentGotNewInfoDict( tor ); 214 tr_torrentSetDirty( tor ); 215 216 tr_bencFree( &newMetainfo ); 217 } 218 219 tr_bencFree( &infoDict ); 201 220 } 202 evbuffer_add_printf( buf, "e" );203 evbuffer_add_printf( buf, "4:info" );204 evbuffer_add( buf, m->metadata, m->metadata_size );205 evbuffer_add_printf( buf, "e" );206 207 /* does it parse? */208 err = tr_bencLoad( EVBUFFER_DATA( buf ), EVBUFFER_LENGTH( buf ), &dict, NULL );209 dbgmsg( tor, "err is %d", err );210 if( !err )211 {212 if( tr_metainfoParse( tor->session,213 &tor->info,214 &tor->infoDictOffset,215 &tor->infoDictLength,216 &dict ) )217 {218 const char * path = tor->info.torrent;219 dbgmsg( tor, "saving completed metadata to \"%s\"", path );220 221 success = TRUE;222 tr_torrentGotNewInfoDict( tor );223 224 tr_bencToFile( &dict, TR_FMT_BENC, path );225 tr_sessionSetTorrentFile( tor->session,226 tor->info.hashString, path );227 tr_torrentSetDirty( tor );228 }229 230 tr_bencFree( &dict );231 }232 233 evbuffer_free( buf );234 221 } 235 222 … … 242 229 { 243 230 const int n = m->pieceCount; 244 for( i=0; i<n; ++i ) { 231 for( i=0; i<n; ++i ) 232 { 245 233 m->piecesNeeded[i].piece = i; 246 234 m->piecesNeeded[i].requestedAt = 0; … … 248 236 m->piecesNeededCount = n; 249 237 dbgmsg( tor, "metadata error; trying again. %d pieces left", n ); 238 239 tr_err( "magnet status: checksum passed %d, metainfo parsed %d", 240 (int)checksumPassed, (int)metainfoParsed ); 250 241 } 251 242 } -
trunk/libtransmission/torrent.c
r10078 r10084 713 713 static tr_parse_result 714 714 torrentParseImpl( const tr_ctor * ctor, tr_info * setmeInfo, 715 int * dictOffset, int * dictLength )715 tr_bool * setmeHasInfo, int * dictOffset, int * dictLength ) 716 716 { 717 717 int doFree; 718 718 tr_bool didParse; 719 tr_bool hasInfo = FALSE; 719 720 tr_info tmp; 720 721 const tr_benc * metainfo; … … 729 730 return TR_PARSE_ERR; 730 731 731 didParse = tr_metainfoParse( session, setmeInfo, dictOffset, dictLength, metainfo ); 732 didParse = tr_metainfoParse( session, metainfo, setmeInfo, 733 &hasInfo, dictOffset, dictLength ); 732 734 doFree = didParse && ( setmeInfo == &tmp ); 733 735 … … 735 737 result = TR_PARSE_ERR; 736 738 737 if( didParse && !getBlockSize( setmeInfo->pieceSize ) )739 if( didParse && hasInfo && !getBlockSize( setmeInfo->pieceSize ) ) 738 740 result = TR_PARSE_ERR; 739 741 … … 744 746 tr_metainfoFree( setmeInfo ); 745 747 748 if( setmeHasInfo != NULL ) 749 *setmeHasInfo = hasInfo; 750 746 751 return result; 747 752 } … … 750 755 tr_torrentParse( const tr_ctor * ctor, tr_info * setmeInfo ) 751 756 { 752 return torrentParseImpl( ctor, setmeInfo, NULL, NULL );757 return torrentParseImpl( ctor, setmeInfo, NULL, NULL, NULL ); 753 758 } 754 759 … … 756 761 tr_torrentNew( const tr_ctor * ctor, int * setmeError ) 757 762 { 763 int off, len; 764 tr_bool hasInfo; 758 765 tr_info tmpInfo; 766 tr_parse_result r; 759 767 tr_torrent * tor = NULL; 760 const tr_magnet_info * magnetInfo;761 768 tr_session * session = tr_ctorGetSession( ctor ); 762 769 … … 764 771 assert( tr_isSession( session ) ); 765 772 766 if( !tr_ctorGetMagnet( ctor, &magnetInfo ) ) 767 { 768 if( tr_torrentFindFromHash( session, magnetInfo->hash ) != NULL ) 773 r = torrentParseImpl( ctor, &tmpInfo, &hasInfo, &off, &len ); 774 if( r == TR_PARSE_OK ) 775 { 776 tor = tr_new0( tr_torrent, 1 ); 777 tor->info = tmpInfo; 778 if( hasInfo ) 769 779 { 770 if( setmeError )771 *setmeError = TR_PARSE_DUPLICATE;772 }773 else774 {775 tor = tr_new0( tr_torrent, 1 );776 tr_metainfoSetFromMagnet( &tor->info, magnetInfo );777 torrentInit( tor, ctor );778 }779 }780 else781 {782 int off, len;783 tr_parse_result r = torrentParseImpl( ctor, &tmpInfo, &off, &len );784 if( r == TR_PARSE_OK )785 {786 tor = tr_new0( tr_torrent, 1 );787 tor->info = tmpInfo;788 780 tor->infoDictOffset = off; 789 781 tor->infoDictLength = len; 790 torrentInit( tor, ctor );791 782 } 792 else if( setmeError ) 793 { 794 *setmeError = r; 795 } 783 torrentInit( tor, ctor ); 784 } 785 else if( setmeError ) 786 { 787 *setmeError = r; 796 788 } 797 789 … … 1470 1462 assert( tr_isTorrent( tor ) ); 1471 1463 1472 if( tor->isDirty && tr_torrentHasMetadata( tor ))1464 if( tor->isDirty ) 1473 1465 { 1474 1466 tor->isDirty = FALSE; … … 2132 2124 if( ok && !tr_bencLoadFile( &metainfo, TR_FMT_BENC, tor->info.torrent ) ) 2133 2125 { 2134 tr_info tmpInfo; 2126 tr_bool hasInfo; 2127 tr_info tmpInfo; 2135 2128 2136 2129 /* remove the old fields */ … … 2161 2154 /* try to parse it back again, to make sure it's good */ 2162 2155 memset( &tmpInfo, 0, sizeof( tr_info ) ); 2163 if( tr_metainfoParse( tor->session, &tmpInfo, 2164 &tor->infoDictOffset, 2165 &tor->infoDictLength, 2166 &metainfo ) ) 2156 if( tr_metainfoParse( tor->session, &metainfo, &tmpInfo, 2157 &hasInfo, &tor->infoDictOffset, &tor->infoDictLength ) ) 2167 2158 { 2168 2159 /* it's good, so keep these new trackers and free the old ones */ -
trunk/libtransmission/torrent.h
r9965 r10084 34 34 35 35 int tr_ctorGetSave( const tr_ctor * ctor ); 36 37 int tr_ctorGetMagnet( const tr_ctor * ctor, const struct tr_magnet_info ** setme );38 36 39 37 void tr_ctorInitTorrentPriorities( const tr_ctor * ctor, tr_torrent * tor ); -
trunk/libtransmission/transmission.h
r10078 r10084 880 880 void tr_ctorSetDeleteSource( tr_ctor * ctor, tr_bool doDelete ); 881 881 882 /** @brief Set the link for creating a tr_torrentfrom a magnet link */883 int tr_ctorSetM agnet( tr_ctor * ctor, const char * magnet_link );882 /** @brief Set the constructor's metainfo from a magnet link */ 883 int tr_ctorSetMetainfoFromMagnetLink( tr_ctor * ctor, const char * magnet_link ); 884 884 885 885 /** @brief Set the constructor's metainfo from a raw benc already in memory */ -
trunk/macosx/Torrent.m
r10067 r10084 1564 1564 1565 1565 if (result != TR_PARSE_OK && magnetAddress) 1566 result = tr_ctorSetM agnet(ctor, [magnetAddress UTF8String]);1566 result = tr_ctorSetMetainfoFromMagnetLink(ctor, [magnetAddress UTF8String]); 1567 1567 1568 1568 //backup - shouldn't be needed after upgrade to 1.70
Note: See TracChangeset
for help on using the changeset viewer.