Changeset 6892
- Timestamp:
- Oct 13, 2008, 10:26:02 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cli/cli.c
r6825 r6892 62 62 static const char * sourceFile = NULL; 63 63 static const char * comment = NULL; 64 65 static int parseCommandLine( int argc,66 const char ** argv );67 68 static void sigHandler( int signal );69 70 static char*71 tr_strlratio( char * buf,72 double ratio,73 size_t buflen )74 {75 if( (int)ratio == TR_RATIO_NA )76 tr_strlcpy( buf, _( "None" ), buflen );77 else if( (int)ratio == TR_RATIO_INF )78 tr_strlcpy( buf, "Inf", buflen );79 else if( ratio < 10.0 )80 tr_snprintf( buf, buflen, "%.2f", ratio );81 else if( ratio < 100.0 )82 tr_snprintf( buf, buflen, "%.1f", ratio );83 else84 tr_snprintf( buf, buflen, "%.0f", ratio );85 return buf;86 }87 88 static int89 is_rfc2396_alnum( char ch )90 {91 return ( '0' <= ch && ch <= '9' )92 || ( 'A' <= ch && ch <= 'Z' )93 || ( 'a' <= ch && ch <= 'z' );94 }95 96 static void97 escape( char * out,98 const uint8_t * in,99 int in_len ) /* rfc2396 */100 {101 const uint8_t *end = in + in_len;102 103 while( in != end )104 if( is_rfc2396_alnum( *in ) )105 *out++ = (char) *in++;106 else107 out += tr_snprintf( out, 4, "%%%02X", (unsigned int)*in++ );108 109 *out = '\0';110 }111 112 static void113 torrentStateChanged( tr_torrent * torrent UNUSED,114 cp_status_t status UNUSED,115 void * user_data UNUSED )116 {117 system( finishCall );118 }119 120 static int leftToScrape = 0;121 122 static void123 scrapeDoneFunc( struct tr_handle * session UNUSED,124 long response_code,125 const void * response,126 size_t response_byte_count,127 void * host )128 {129 tr_benc top, *files;130 131 if( !tr_bencLoad( response, response_byte_count, &top, NULL )132 && tr_bencDictFindDict( &top, "files", &files )133 && files->val.l.count >= 2 )134 {135 int64_t complete = -1, incomplete = -1, downloaded = -1;136 tr_benc * hash = &files->val.l.vals[1];137 tr_bencDictFindInt( hash, "complete", &complete );138 tr_bencDictFindInt( hash, "incomplete", &incomplete );139 tr_bencDictFindInt( hash, "downloaded", &downloaded );140 printf( "%4d seeders, %4d leechers, %5d downloads at %s\n",141 (int)complete, (int)incomplete, (int)downloaded,142 (char*)host );143 tr_bencFree( &top );144 }145 else146 fprintf( stderr, "Unable to parse response (http code %lu) at %s",147 response_code,148 (char*)host );149 150 --leftToScrape;151 }152 153 static void154 dumpInfo( FILE * out,155 const tr_info * inf )156 {157 int i;158 int prevTier = -1;159 tr_file_index_t ff;160 161 fprintf( out, "hash:\t" );162 for( i = 0; i < SHA_DIGEST_LENGTH; ++i )163 fprintf( out, "%02x", inf->hash[i] );164 fprintf( out, "\n" );165 166 fprintf( out, "name:\t%s\n", inf->name );167 168 for( i = 0; i < inf->trackerCount; ++i )169 {170 if( prevTier != inf->trackers[i].tier )171 {172 prevTier = inf->trackers[i].tier;173 fprintf( out, "\ntracker tier #%d:\n", ( prevTier + 1 ) );174 }175 fprintf( out, "\tannounce:\t%s\n", inf->trackers[i].announce );176 }177 178 fprintf( out, "size:\t%" PRIu64 " (%" PRIu64 " * %d + %" PRIu64 ")\n",179 inf->totalSize, inf->totalSize / inf->pieceSize,180 inf->pieceSize, inf->totalSize % inf->pieceSize );181 182 if( inf->comment && *inf->comment )183 fprintf( out, "comment:\t%s\n", inf->comment );184 if( inf->creator && *inf->creator )185 fprintf( out, "creator:\t%s\n", inf->creator );186 if( inf->isPrivate )187 fprintf( out, "private flag set\n" );188 189 fprintf( out, "file(s):\n" );190 for( ff = 0; ff < inf->fileCount; ++ff )191 fprintf( out, "\t%s (%" PRIu64 ")\n", inf->files[ff].name,192 inf->files[ff].length );193 }194 195 static void196 getStatusStr( const tr_stat * st,197 char * buf,198 size_t buflen )199 {200 if( st->status & TR_STATUS_CHECK_WAIT )201 {202 tr_snprintf( buf, buflen, "Waiting to verify local files" );203 }204 else if( st->status & TR_STATUS_CHECK )205 {206 tr_snprintf( buf, buflen,207 "Verifying local files (%.2f%%, %.2f%% valid)",208 100 * st->recheckProgress,209 100.0 * st->percentDone );210 }211 else if( st->status & TR_STATUS_DOWNLOAD )212 {213 char ratioStr[80];214 tr_strlratio( ratioStr, st->ratio, sizeof( ratioStr ) );215 tr_snprintf(216 buf, buflen,217 "Progress: %.1f%%, dl from %d of %d peers (%.0f KB/s), "218 "ul to %d (%.0f KB/s) [%s]",219 st->percentDone * 100.0,220 st->peersSendingToUs,221 st->peersConnected,222 st->rateDownload,223 st->peersGettingFromUs,224 st->rateUpload,225 ratioStr );226 }227 else if( st->status & TR_STATUS_SEED )228 {229 char ratioStr[80];230 tr_strlratio( ratioStr, st->ratio, sizeof( ratioStr ) );231 tr_snprintf(232 buf, buflen,233 "Seeding, uploading to %d of %d peer(s), %.0f KB/s [%s]",234 st->peersGettingFromUs, st->peersConnected,235 st->rateUpload, ratioStr );236 }237 else *buf = '\0';238 }239 240 int241 main( int argc,242 char ** argv )243 {244 int error;245 tr_handle * h;246 tr_ctor * ctor;247 tr_torrent * tor = NULL;248 char cwd[MAX_PATH_LENGTH];249 250 printf( "Transmission %s - http://www.transmissionbt.com/\n",251 LONG_VERSION_STRING );252 253 /* Get options */254 if( parseCommandLine( argc, (const char**)argv ) )255 return EXIT_FAILURE;256 257 /* Check the options for validity */258 if( !torrentPath )259 {260 fprintf( stderr, "No torrent specified!\n" );261 return EXIT_FAILURE;262 }263 if( peerPort < 1 || peerPort > 65535 )264 {265 fprintf( stderr, "Error: Port must between 1 and 65535; got %d\n",266 peerPort );267 return EXIT_FAILURE;268 }269 if( peerSocketTOS < 0 || peerSocketTOS > 255 )270 {271 fprintf( stderr, "Error: value must between 0 and 255; got %d\n",272 peerSocketTOS );273 return EXIT_FAILURE;274 }275 276 /* don't bind the port if we're just running the CLI277 * to get metainfo or to create a torrent */278 if( showInfo || showScrape || ( sourceFile != NULL ) )279 peerPort = -1;280 281 if( configdir == NULL )282 configdir = tr_getDefaultConfigDir( );283 284 /* if no download directory specified, use cwd instead */285 if( !downloadDir )286 {287 getcwd( cwd, sizeof( cwd ) );288 downloadDir = cwd;289 }290 291 292 /* Initialize libtransmission */293 h = tr_sessionInitFull(294 configdir,295 "cli", /* tag */296 downloadDir, /* where to download torrents */297 TR_DEFAULT_PEX_ENABLED,298 natTraversal, /* nat enabled */299 peerPort,300 encryptionMode,301 TR_DEFAULT_LAZY_BITFIELD_ENABLED,302 uploadLimit >= 0,303 uploadLimit,304 downloadLimit >= 0,305 downloadLimit,306 TR_DEFAULT_GLOBAL_PEER_LIMIT,307 verboseLevel + 1, /* messageLevel */308 0, /* is message queueing enabled? */309 blocklistEnabled,310 peerSocketTOS,311 TR_DEFAULT_RPC_ENABLED,312 TR_DEFAULT_RPC_PORT,313 TR_DEFAULT_RPC_WHITELIST_ENABLED,314 TR_DEFAULT_RPC_WHITELIST,315 FALSE, "fnord", "potzrebie",316 TR_DEFAULT_PROXY_ENABLED,317 TR_DEFAULT_PROXY,318 TR_DEFAULT_PROXY_PORT,319 TR_DEFAULT_PROXY_TYPE,320 TR_DEFAULT_PROXY_AUTH_ENABLED,321 TR_DEFAULT_PROXY_USERNAME,322 TR_DEFAULT_PROXY_PASSWORD );323 324 if( sourceFile && *sourceFile ) /* creating a torrent */325 {326 int err;327 tr_metainfo_builder * b = tr_metaInfoBuilderCreate( h, sourceFile );328 tr_tracker_info ti;329 ti.tier = 0;330 ti.announce = (char*) announce;331 tr_makeMetaInfo( b, torrentPath, &ti, 1, comment, isPrivate );332 while( !b->isDone )333 {334 tr_wait( 1000 );335 printf( "." );336 }337 338 err = b->result;339 tr_metaInfoBuilderFree( b );340 return err;341 }342 343 ctor = tr_ctorNew( h );344 tr_ctorSetMetainfoFromFile( ctor, torrentPath );345 tr_ctorSetPaused( ctor, TR_FORCE, showScrape );346 tr_ctorSetDownloadDir( ctor, TR_FORCE, downloadDir );347 348 if( showScrape )349 {350 tr_info info;351 352 if( !tr_torrentParse( h, ctor, &info ) )353 {354 int i;355 const time_t start = time( NULL );356 for( i = 0; i < info.trackerCount; ++i )357 {358 if( info.trackers[i].scrape )359 {360 const char * scrape = info.trackers[i].scrape;361 char escaped[SHA_DIGEST_LENGTH * 3 + 1];362 char * url, *host;363 escape( escaped, info.hash, SHA_DIGEST_LENGTH );364 url = tr_strdup_printf( "%s%cinfo_hash=%s",365 scrape,366 strchr( scrape,367 '?' ) ? '&' : '?',368 escaped );369 tr_httpParseURL( scrape, -1, &host, NULL, NULL );370 ++leftToScrape;371 tr_webRun( h, url, NULL, scrapeDoneFunc, host );372 tr_free( host );373 tr_free( url );374 }375 }376 377 fprintf( stderr, "scraping %d trackers:\n", leftToScrape );378 379 while( leftToScrape > 0 && ( ( time( NULL ) - start ) < 20 ) )380 tr_wait( 250 );381 }382 goto cleanup;383 }384 385 if( showInfo )386 {387 tr_info info;388 389 if( !tr_torrentParse( h, ctor, &info ) )390 {391 dumpInfo( stdout, &info );392 tr_metainfoFree( &info );393 }394 395 tr_ctorFree( ctor );396 goto cleanup;397 }398 399 tor = tr_torrentNew( h, ctor, &error );400 tr_ctorFree( ctor );401 if( !tor )402 {403 fprintf( stderr, "Failed opening torrent file `%s'\n", torrentPath );404 tr_sessionClose( h );405 return EXIT_FAILURE;406 }407 408 signal( SIGINT, sigHandler );409 #ifndef WIN32410 signal( SIGHUP, sigHandler );411 #endif412 tr_torrentSetStatusCallback( tor, torrentStateChanged, NULL );413 tr_torrentStart( tor );414 415 if( verify )416 {417 verify = 0;418 tr_torrentVerify( tor );419 }420 421 for( ; ; )422 {423 char line[LINEWIDTH];424 const tr_stat * st;425 426 tr_wait( 200 );427 428 if( gotsig )429 {430 gotsig = 0;431 printf( "\nStopping torrent...\n" );432 tr_torrentStop( tor );433 }434 435 if( manualUpdate )436 {437 manualUpdate = 0;438 if( !tr_torrentCanManualUpdate( tor ) )439 fprintf(440 stderr,441 "\nReceived SIGHUP, but can't send a manual update now\n" );442 else443 {444 fprintf( stderr,445 "\nReceived SIGHUP: manual update scheduled\n" );446 tr_torrentManualUpdate( tor );447 }448 }449 450 st = tr_torrentStat( tor );451 if( st->status & TR_STATUS_STOPPED )452 break;453 454 getStatusStr( st, line, sizeof( line ) );455 printf( "\r%-*s", LINEWIDTH, line );456 if( st->error )457 fprintf( stderr, "\n%s\n", st->errorString );458 }459 460 cleanup:461 printf( "\n" );462 tr_sessionClose( h );463 return EXIT_SUCCESS;464 }465 466 /***467 ****468 ****469 ****470 ***/471 472 static const char *473 getUsage( void )474 {475 return "A fast and easy BitTorrent client\n"476 "\n"477 "Usage: " MY_NAME " [options] <torrent-filename>";478 }479 64 480 65 static const struct tr_option options[] = … … 533 118 }; 534 119 120 static const char * 121 getUsage( void ) 122 { 123 return "A fast and easy BitTorrent client\n" 124 "\n" 125 "Usage: " MY_NAME " [options] <torrent-filename>"; 126 } 127 128 static int parseCommandLine( int argc, 129 const char ** argv ); 130 131 static void sigHandler( int signal ); 132 133 static char* 134 tr_strlratio( char * buf, 135 double ratio, 136 size_t buflen ) 137 { 138 if( (int)ratio == TR_RATIO_NA ) 139 tr_strlcpy( buf, _( "None" ), buflen ); 140 else if( (int)ratio == TR_RATIO_INF ) 141 tr_strlcpy( buf, "Inf", buflen ); 142 else if( ratio < 10.0 ) 143 tr_snprintf( buf, buflen, "%.2f", ratio ); 144 else if( ratio < 100.0 ) 145 tr_snprintf( buf, buflen, "%.1f", ratio ); 146 else 147 tr_snprintf( buf, buflen, "%.0f", ratio ); 148 return buf; 149 } 150 151 static int 152 is_rfc2396_alnum( char ch ) 153 { 154 return ( '0' <= ch && ch <= '9' ) 155 || ( 'A' <= ch && ch <= 'Z' ) 156 || ( 'a' <= ch && ch <= 'z' ); 157 } 158 159 static void 160 escape( char * out, 161 const uint8_t * in, 162 int in_len ) /* rfc2396 */ 163 { 164 const uint8_t *end = in + in_len; 165 166 while( in != end ) 167 if( is_rfc2396_alnum( *in ) ) 168 *out++ = (char) *in++; 169 else 170 out += tr_snprintf( out, 4, "%%%02X", (unsigned int)*in++ ); 171 172 *out = '\0'; 173 } 174 175 static void 176 torrentStateChanged( tr_torrent * torrent UNUSED, 177 cp_status_t status UNUSED, 178 void * user_data UNUSED ) 179 { 180 system( finishCall ); 181 } 182 183 static int leftToScrape = 0; 184 185 static void 186 scrapeDoneFunc( struct tr_handle * session UNUSED, 187 long response_code, 188 const void * response, 189 size_t response_byte_count, 190 void * host ) 191 { 192 tr_benc top, *files; 193 194 if( !tr_bencLoad( response, response_byte_count, &top, NULL ) 195 && tr_bencDictFindDict( &top, "files", &files ) 196 && files->val.l.count >= 2 ) 197 { 198 int64_t complete = -1, incomplete = -1, downloaded = -1; 199 tr_benc * hash = &files->val.l.vals[1]; 200 tr_bencDictFindInt( hash, "complete", &complete ); 201 tr_bencDictFindInt( hash, "incomplete", &incomplete ); 202 tr_bencDictFindInt( hash, "downloaded", &downloaded ); 203 printf( "%4d seeders, %4d leechers, %5d downloads at %s\n", 204 (int)complete, (int)incomplete, (int)downloaded, 205 (char*)host ); 206 tr_bencFree( &top ); 207 } 208 else 209 fprintf( stderr, "Unable to parse response (http code %lu) at %s", 210 response_code, 211 (char*)host ); 212 213 --leftToScrape; 214 } 215 216 static void 217 dumpInfo( FILE * out, 218 const tr_info * inf ) 219 { 220 int i; 221 int prevTier = -1; 222 tr_file_index_t ff; 223 224 fprintf( out, "hash:\t" ); 225 for( i = 0; i < SHA_DIGEST_LENGTH; ++i ) 226 fprintf( out, "%02x", inf->hash[i] ); 227 fprintf( out, "\n" ); 228 229 fprintf( out, "name:\t%s\n", inf->name ); 230 231 for( i = 0; i < inf->trackerCount; ++i ) 232 { 233 if( prevTier != inf->trackers[i].tier ) 234 { 235 prevTier = inf->trackers[i].tier; 236 fprintf( out, "\ntracker tier #%d:\n", ( prevTier + 1 ) ); 237 } 238 fprintf( out, "\tannounce:\t%s\n", inf->trackers[i].announce ); 239 } 240 241 fprintf( out, "size:\t%" PRIu64 " (%" PRIu64 " * %d + %" PRIu64 ")\n", 242 inf->totalSize, inf->totalSize / inf->pieceSize, 243 inf->pieceSize, inf->totalSize % inf->pieceSize ); 244 245 if( inf->comment && *inf->comment ) 246 fprintf( out, "comment:\t%s\n", inf->comment ); 247 if( inf->creator && *inf->creator ) 248 fprintf( out, "creator:\t%s\n", inf->creator ); 249 if( inf->isPrivate ) 250 fprintf( out, "private flag set\n" ); 251 252 fprintf( out, "file(s):\n" ); 253 for( ff = 0; ff < inf->fileCount; ++ff ) 254 fprintf( out, "\t%s (%" PRIu64 ")\n", inf->files[ff].name, 255 inf->files[ff].length ); 256 } 257 258 static void 259 getStatusStr( const tr_stat * st, 260 char * buf, 261 size_t buflen ) 262 { 263 if( st->status & TR_STATUS_CHECK_WAIT ) 264 { 265 tr_snprintf( buf, buflen, "Waiting to verify local files" ); 266 } 267 else if( st->status & TR_STATUS_CHECK ) 268 { 269 tr_snprintf( buf, buflen, 270 "Verifying local files (%.2f%%, %.2f%% valid)", 271 100 * st->recheckProgress, 272 100.0 * st->percentDone ); 273 } 274 else if( st->status & TR_STATUS_DOWNLOAD ) 275 { 276 char ratioStr[80]; 277 tr_strlratio( ratioStr, st->ratio, sizeof( ratioStr ) ); 278 tr_snprintf( 279 buf, buflen, 280 "Progress: %.1f%%, dl from %d of %d peers (%.0f KB/s), " 281 "ul to %d (%.0f KB/s) [%s]", 282 st->percentDone * 100.0, 283 st->peersSendingToUs, 284 st->peersConnected, 285 st->rateDownload, 286 st->peersGettingFromUs, 287 st->rateUpload, 288 ratioStr ); 289 } 290 else if( st->status & TR_STATUS_SEED ) 291 { 292 char ratioStr[80]; 293 tr_strlratio( ratioStr, st->ratio, sizeof( ratioStr ) ); 294 tr_snprintf( 295 buf, buflen, 296 "Seeding, uploading to %d of %d peer(s), %.0f KB/s [%s]", 297 st->peersGettingFromUs, st->peersConnected, 298 st->rateUpload, ratioStr ); 299 } 300 else *buf = '\0'; 301 } 302 303 int 304 main( int argc, 305 char ** argv ) 306 { 307 int error; 308 tr_handle * h; 309 tr_ctor * ctor; 310 tr_torrent * tor = NULL; 311 char cwd[MAX_PATH_LENGTH]; 312 313 printf( "Transmission %s - http://www.transmissionbt.com/\n", 314 LONG_VERSION_STRING ); 315 316 /* user needs to pass in at least one argument */ 317 if( argc < 2 ) { 318 tr_getopt_usage( MY_NAME, getUsage( ), options ); 319 return EXIT_FAILURE; 320 } 321 322 /* Get options */ 323 if( parseCommandLine( argc, (const char**)argv ) ) 324 return EXIT_FAILURE; 325 326 /* Check the options for validity */ 327 if( !torrentPath ) 328 { 329 fprintf( stderr, "No torrent specified!\n" ); 330 return EXIT_FAILURE; 331 } 332 if( peerPort < 1 || peerPort > 65535 ) 333 { 334 fprintf( stderr, "Error: Port must between 1 and 65535; got %d\n", 335 peerPort ); 336 return EXIT_FAILURE; 337 } 338 if( peerSocketTOS < 0 || peerSocketTOS > 255 ) 339 { 340 fprintf( stderr, "Error: value must between 0 and 255; got %d\n", 341 peerSocketTOS ); 342 return EXIT_FAILURE; 343 } 344 345 /* don't bind the port if we're just running the CLI 346 * to get metainfo or to create a torrent */ 347 if( showInfo || showScrape || ( sourceFile != NULL ) ) 348 peerPort = -1; 349 350 if( configdir == NULL ) 351 configdir = tr_getDefaultConfigDir( ); 352 353 /* if no download directory specified, use cwd instead */ 354 if( !downloadDir ) 355 { 356 tr_getcwd( cwd, sizeof( cwd ) ); 357 downloadDir = cwd; 358 } 359 360 361 /* Initialize libtransmission */ 362 h = tr_sessionInitFull( 363 configdir, 364 "cli", /* tag */ 365 downloadDir, /* where to download torrents */ 366 TR_DEFAULT_PEX_ENABLED, 367 natTraversal, /* nat enabled */ 368 peerPort, 369 encryptionMode, 370 TR_DEFAULT_LAZY_BITFIELD_ENABLED, 371 uploadLimit >= 0, 372 uploadLimit, 373 downloadLimit >= 0, 374 downloadLimit, 375 TR_DEFAULT_GLOBAL_PEER_LIMIT, 376 verboseLevel + 1, /* messageLevel */ 377 0, /* is message queueing enabled? */ 378 blocklistEnabled, 379 peerSocketTOS, 380 TR_DEFAULT_RPC_ENABLED, 381 TR_DEFAULT_RPC_PORT, 382 TR_DEFAULT_RPC_WHITELIST_ENABLED, 383 TR_DEFAULT_RPC_WHITELIST, 384 FALSE, "fnord", "potzrebie", 385 TR_DEFAULT_PROXY_ENABLED, 386 TR_DEFAULT_PROXY, 387 TR_DEFAULT_PROXY_PORT, 388 TR_DEFAULT_PROXY_TYPE, 389 TR_DEFAULT_PROXY_AUTH_ENABLED, 390 TR_DEFAULT_PROXY_USERNAME, 391 TR_DEFAULT_PROXY_PASSWORD ); 392 393 if( sourceFile && *sourceFile ) /* creating a torrent */ 394 { 395 int err; 396 tr_metainfo_builder * b = tr_metaInfoBuilderCreate( h, sourceFile ); 397 tr_tracker_info ti; 398 ti.tier = 0; 399 ti.announce = (char*) announce; 400 tr_makeMetaInfo( b, torrentPath, &ti, 1, comment, isPrivate ); 401 while( !b->isDone ) 402 { 403 tr_wait( 1000 ); 404 printf( "." ); 405 } 406 407 err = b->result; 408 tr_metaInfoBuilderFree( b ); 409 return err; 410 } 411 412 ctor = tr_ctorNew( h ); 413 tr_ctorSetMetainfoFromFile( ctor, torrentPath ); 414 tr_ctorSetPaused( ctor, TR_FORCE, showScrape ); 415 tr_ctorSetDownloadDir( ctor, TR_FORCE, downloadDir ); 416 417 if( showScrape ) 418 { 419 tr_info info; 420 421 if( !tr_torrentParse( h, ctor, &info ) ) 422 { 423 int i; 424 const time_t start = time( NULL ); 425 for( i = 0; i < info.trackerCount; ++i ) 426 { 427 if( info.trackers[i].scrape ) 428 { 429 const char * scrape = info.trackers[i].scrape; 430 char escaped[SHA_DIGEST_LENGTH * 3 + 1]; 431 char * url, *host; 432 escape( escaped, info.hash, SHA_DIGEST_LENGTH ); 433 url = tr_strdup_printf( "%s%cinfo_hash=%s", 434 scrape, 435 strchr( scrape, 436 '?' ) ? '&' : '?', 437 escaped ); 438 tr_httpParseURL( scrape, -1, &host, NULL, NULL ); 439 ++leftToScrape; 440 tr_webRun( h, url, NULL, scrapeDoneFunc, host ); 441 tr_free( host ); 442 tr_free( url ); 443 } 444 } 445 446 fprintf( stderr, "scraping %d trackers:\n", leftToScrape ); 447 448 while( leftToScrape > 0 && ( ( time( NULL ) - start ) < 20 ) ) 449 tr_wait( 250 ); 450 } 451 goto cleanup; 452 } 453 454 if( showInfo ) 455 { 456 tr_info info; 457 458 if( !tr_torrentParse( h, ctor, &info ) ) 459 { 460 dumpInfo( stdout, &info ); 461 tr_metainfoFree( &info ); 462 } 463 464 tr_ctorFree( ctor ); 465 goto cleanup; 466 } 467 468 tor = tr_torrentNew( h, ctor, &error ); 469 tr_ctorFree( ctor ); 470 if( !tor ) 471 { 472 fprintf( stderr, "Failed opening torrent file `%s'\n", torrentPath ); 473 tr_sessionClose( h ); 474 return EXIT_FAILURE; 475 } 476 477 signal( SIGINT, sigHandler ); 478 #ifndef WIN32 479 signal( SIGHUP, sigHandler ); 480 #endif 481 tr_torrentSetStatusCallback( tor, torrentStateChanged, NULL ); 482 tr_torrentStart( tor ); 483 484 if( verify ) 485 { 486 verify = 0; 487 tr_torrentVerify( tor ); 488 } 489 490 for( ; ; ) 491 { 492 char line[LINEWIDTH]; 493 const tr_stat * st; 494 495 tr_wait( 200 ); 496 497 if( gotsig ) 498 { 499 gotsig = 0; 500 printf( "\nStopping torrent...\n" ); 501 tr_torrentStop( tor ); 502 } 503 504 if( manualUpdate ) 505 { 506 manualUpdate = 0; 507 if( !tr_torrentCanManualUpdate( tor ) ) 508 fprintf( 509 stderr, 510 "\nReceived SIGHUP, but can't send a manual update now\n" ); 511 else 512 { 513 fprintf( stderr, 514 "\nReceived SIGHUP: manual update scheduled\n" ); 515 tr_torrentManualUpdate( tor ); 516 } 517 } 518 519 st = tr_torrentStat( tor ); 520 if( st->status & TR_STATUS_STOPPED ) 521 break; 522 523 getStatusStr( st, line, sizeof( line ) ); 524 printf( "\r%-*s", LINEWIDTH, line ); 525 if( st->error ) 526 fprintf( stderr, "\n%s\n", st->errorString ); 527 } 528 529 cleanup: 530 printf( "\n" ); 531 tr_sessionClose( h ); 532 return EXIT_SUCCESS; 533 } 534 535 /*** 536 **** 537 **** 538 **** 539 ***/ 540 535 541 static void 536 542 showUsage( void ) -
trunk/daemon/daemon.c
r6825 r6892 19 19 #include <fcntl.h> /* open */ 20 20 #include <signal.h> 21 #include <unistd.h> /* daemon , getcwd*/21 #include <unistd.h> /* daemon */ 22 22 23 23 #include <libtransmission/transmission.h> … … 191 191 ***/ 192 192 193 getcwd( mycwd, sizeof( mycwd ) );193 tr_getcwd( mycwd, sizeof( mycwd ) ); 194 194 getConfigStr( dict, KEY_DOWNLOAD_DIR, &downloadDir, mycwd ); 195 195 getConfigInt( dict, KEY_PEX_ENABLED, &pexEnabled, … … 468 468 469 469 signal( SIGINT, gotsig ); 470 signal( SIGTERM, gotsig ); 471 #ifndef WIN32 470 472 signal( SIGQUIT, gotsig ); 471 signal( SIGTERM, gotsig );472 473 signal( SIGPIPE, SIG_IGN ); 473 474 signal( SIGHUP, SIG_IGN ); 475 #endif 474 476 475 477 readargs( argc, (const char**)argv, &nofork, &configDir, &downloadDir, … … 496 498 497 499 while( !closing ) 498 sleep( 1 );500 tr_wait( 1000 ); /* sleep one second */ 499 501 500 502 saveState( mySession ); -
trunk/daemon/remote.c
r6866 r6892 15 15 #include <stdlib.h> 16 16 #include <string.h> /* strcmp */ 17 18 #include <unistd.h> /* getcwd */19 17 20 18 #include <libevent/event.h> … … 156 154 { 157 155 char cwd[MAX_PATH_LENGTH]; 158 getcwd( cwd, sizeof( cwd ) );156 tr_getcwd( cwd, sizeof( cwd ) ); 159 157 tr_buildPath( buf, len, cwd, path, NULL ); 160 158 } -
trunk/libtransmission/bencode.c
r6851 r6892 105 105 else 106 106 { 107 *setme_end = end + 1;107 *setme_end = (const uint8_t*)end + 1; 108 108 *setme_val = val; 109 109 } … … 147 147 return EILSEQ; 148 148 149 *setme_end = end + 1 + len;150 *setme_str = end + 1;149 *setme_end = (const uint8_t*)end + 1 + len; 150 *setme_str = (const uint8_t*)end + 1; 151 151 *setme_strlen = len; 152 152 return 0; -
trunk/libtransmission/list.c
r6795 r6892 79 79 80 80 void 81 tr_list_insert_sorted( tr_list ** list,82 void *data,83 int compare(const void*, const void*))81 tr_list_insert_sorted( tr_list ** list, 82 void * data, 83 TrListCompareFunc compare ) 84 84 { 85 85 /* find l, the node that we'll insert this data before */ -
trunk/libtransmission/platform.c
r6861 r6892 19 19 #elif defined( WIN32 ) 20 20 #include <windows.h> 21 #include <shlobj.h> /* for CSIDL_APPDATA, CSIDL_ PROFILE*/21 #include <shlobj.h> /* for CSIDL_APPDATA, CSIDL_MYDOCUMENTS */ 22 22 #else 23 23 #ifdef SYS_DARWIN … … 39 39 #include <sys/stat.h> 40 40 #include <sys/types.h> 41 #ifdef WIN32 42 #include <libgen.h> 43 #endif 41 44 #include <dirent.h> 42 45 #include <fcntl.h> … … 268 271 { 269 272 #ifdef WIN32 270 SHGetFolderPath( NULL, CSIDL_ PROFILE, NULL, 0, home );273 SHGetFolderPath( NULL, CSIDL_MYDOCUMENTS, NULL, 0, home ); 271 274 #elif defined( __BEOS__ ) || defined( __AMIGAOS4__ ) 272 275 home = tr_strdup( "" ); … … 421 424 } 422 425 423 #if def SYS_DARWIN426 #if defined(SYS_DARWIN) || defined(WIN32) 424 427 #define RESUME_SUBDIR "Resume" 425 428 #define TORRENT_SUBDIR "Torrents" -
trunk/libtransmission/utils.c
r6877 r6892 35 35 #include <sys/types.h> 36 36 #include <sys/stat.h> 37 #include <unistd.h> /* usleep, stat */37 #include <unistd.h> /* usleep, stat, getcwd */ 38 38 39 39 #include "event.h" 40 40 41 41 #ifdef WIN32 42 #include <windows.h> /* for Sleep */ 42 #include <direct.h> /* _getcwd */ 43 #include <windows.h> /* Sleep */ 43 44 #elif defined( __BEOS__ ) 44 45 #include <kernel/OS.h> … … 453 454 *size = sb.st_size; 454 455 return buf; 456 } 457 458 char* 459 tr_getcwd( char * buffer, 460 int maxlen ) 461 { 462 #ifdef WIN32 463 return _getcwd( buffer, maxlen ); 464 #else 465 return getcwd( buffer, maxlen ); 466 #endif 455 467 } 456 468 -
trunk/libtransmission/utils.h
r6842 r6892 146 146 char* tr_getLogTimeStr( char * buf, 147 147 int buflen ); 148 149 /** 150 * a portability wrapper around getcwd(). 151 */ 152 char* tr_getcwd( char * buffer, 153 int maxlen ); 148 154 149 155 /** -
trunk/libtransmission/web.c
r6795 r6892 221 221 const char * url, 222 222 const char * range, 223 tr_web_done_func *done_func,223 tr_web_done_func done_func, 224 224 void * done_func_user_data ) 225 225 {
Note: See TracChangeset
for help on using the changeset viewer.