Changeset 6302 for trunk/cli/cli.c
- Timestamp:
- Jul 9, 2008, 1:48:29 AM (14 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/cli/cli.c
r6301 r6302 37 37 #include <libtransmission/web.h> /* tr_webRun */ 38 38 39 #define LINEWIDTH 80 39 40 #define MY_NAME "transmission-cli" 40 41 … … 65 66 static void sigHandler ( int signal ); 66 67 67 static char * 68 getStringRatio( float ratio ) 69 { 70 static char string[20]; 71 72 if( ratio == TR_RATIO_NA ) 73 return "n/a"; 74 snprintf( string, sizeof string, "%.3f", ratio ); 75 return string; 68 char* 69 tr_strlratio( char * buf, double ratio, size_t buflen ) 70 { 71 if( (int)ratio == TR_RATIO_NA ) 72 tr_strlcpy( buf, _( "None" ), buflen ); 73 else if( (int)ratio == TR_RATIO_INF ) 74 tr_strlcpy( buf, "Inf", buflen ); 75 else if( ratio < 10.0 ) 76 snprintf( buf, buflen, "%'.2f", ratio ); 77 else if( ratio < 100.0 ) 78 snprintf( buf, buflen, "%'.1f", ratio ); 79 else 80 snprintf( buf, buflen, "%'.0f", ratio ); 81 return buf; 76 82 } 77 83 … … 95 101 *out = '\0'; 96 102 } 97 98 99 #define LINEWIDTH 80100 103 101 104 static void … … 137 140 } 138 141 142 static void 143 dumpInfo( FILE * out, const tr_info * inf ) 144 { 145 int i; 146 int prevTier = -1; 147 tr_file_index_t ff; 148 149 fprintf( out, "hash:\t" ); 150 for( i=0; i<SHA_DIGEST_LENGTH; ++i ) 151 fprintf( out, "%02x", inf->hash[i] ); 152 fprintf( out, "\n" ); 153 154 fprintf( out, "name:\t%s\n", inf->name ); 155 156 for( i=0; i<inf->trackerCount; ++i ) { 157 if( prevTier != inf->trackers[i].tier ) { 158 prevTier = inf->trackers[i].tier; 159 fprintf( out, "\ntracker tier #%d:\n", (prevTier+1) ); 160 } 161 fprintf( out, "\tannounce:\t%s\n", inf->trackers[i].announce ); 162 } 163 164 fprintf( out, "size:\t%"PRIu64" (%"PRIu64" * %d + %"PRIu64")\n", 165 inf->totalSize, inf->totalSize / inf->pieceSize, 166 inf->pieceSize, inf->totalSize % inf->pieceSize ); 167 168 if( inf->comment[0] ) 169 fprintf( out, "comment:\t%s\n", inf->comment ); 170 if( inf->creator[0] ) 171 fprintf( out, "creator:\t%s\n", inf->creator ); 172 if( inf->isPrivate ) 173 fprintf( out, "private flag set\n" ); 174 175 fprintf( out, "file(s):\n" ); 176 for( ff=0; ff<inf->fileCount; ++ff ) 177 fprintf( out, "\t%s (%"PRIu64")\n", inf->files[ff].name, inf->files[ff].length ); 178 } 179 180 static void 181 getStatusStr( const tr_stat * st, char * buf, size_t buflen ) 182 { 183 if( st->status & TR_STATUS_CHECK_WAIT ) 184 { 185 snprintf( buf, buflen, "Waiting to verify local files" ); 186 } 187 else if( st->status & TR_STATUS_CHECK ) 188 { 189 snprintf( buf, buflen, "Verifying local files (%.2f%%, %.2f%% valid)", 190 100 * st->recheckProgress, 100.0 * st->percentDone ); 191 } 192 else if( st->status & TR_STATUS_DOWNLOAD ) 193 { 194 char ratioStr[80]; 195 tr_strlratio( ratioStr, st->ratio, sizeof( ratioStr ) ); 196 snprintf( buf, buflen, 197 "Progress: %.1f%%, dl from %d of %d peers (%.0f KB/s), " 198 "ul to %d (%.0f KB/s) [%s]", 199 st->percentDone * 100.0, 200 st->peersSendingToUs, 201 st->peersConnected, 202 st->rateDownload, 203 st->peersGettingFromUs, 204 st->rateUpload, 205 ratioStr ); 206 } 207 else if( st->status & TR_STATUS_SEED ) 208 { 209 char ratioStr[80]; 210 tr_strlratio( ratioStr, st->ratio, sizeof( ratioStr ) ); 211 snprintf( buf, buflen, 212 "Seeding, uploading to %d of %d peer(s), %.0f KB/s [%s]", 213 st->peersGettingFromUs, st->peersConnected, 214 st->rateUpload, ratioStr ); 215 } 216 else if( st->status & TR_STATUS_STOPPED ) 217 { 218 *buf = '\0'; 219 } 220 } 221 139 222 int 140 223 main( int argc, char ** argv ) 141 224 { 142 int i,error;225 int error; 143 226 tr_handle * h; 144 227 tr_ctor * ctor; … … 274 357 if( !tr_torrentParse( h, ctor, &info ) ) 275 358 { 276 int prevTier = -1; 277 tr_file_index_t ff; 278 279 printf( "hash:\t" ); 280 for( i=0; i<SHA_DIGEST_LENGTH; ++i ) 281 printf( "%02x", info.hash[i] ); 282 printf( "\n" ); 283 284 printf( "name:\t%s\n", info.name ); 285 286 for( i=0; i<info.trackerCount; ++i ) { 287 if( prevTier != info.trackers[i].tier ) { 288 prevTier = info.trackers[i].tier; 289 printf( "\ntracker tier #%d:\n", (prevTier+1) ); 290 } 291 printf( "\tannounce:\t%s\n", info.trackers[i].announce ); 292 } 293 294 printf( "size:\t%"PRIu64" (%"PRIu64" * %d + %"PRIu64")\n", 295 info.totalSize, info.totalSize / info.pieceSize, 296 info.pieceSize, info.totalSize % info.pieceSize ); 297 298 if( info.comment[0] ) 299 printf( "comment:\t%s\n", info.comment ); 300 if( info.creator[0] ) 301 printf( "creator:\t%s\n", info.creator ); 302 if( info.isPrivate ) 303 printf( "private flag set\n" ); 304 305 printf( "file(s):\n" ); 306 for( ff=0; ff<info.fileCount; ++ff ) 307 printf( "\t%s (%"PRIu64")\n", info.files[ff].name, info.files[ff].length ); 308 359 dumpInfo( stdout, &info ); 309 360 tr_metainfoFree( &info ); 310 361 } … … 316 367 tor = tr_torrentNew( h, ctor, &error ); 317 368 tr_ctorFree( ctor ); 318 if( tor == NULL)369 if( !tor ) 319 370 { 320 371 printf( "Failed opening torrent file `%s'\n", torrentPath ); … … 329 380 tr_torrentStart( tor ); 330 381 382 if( verify ) { 383 verify = 0; 384 tr_torrentVerify( tor ); 385 } 386 331 387 for( ;; ) 332 388 { 333 char string[LINEWIDTH]; 334 int chars = 0; 335 const struct tr_stat * s; 389 char line[LINEWIDTH]; 390 const tr_stat * st; 336 391 337 392 tr_wait( 1000 ); 338 393 339 if( gotsig ) 340 { 394 if( gotsig ) { 341 395 gotsig = 0; 396 fprintf( stderr, "stopping torrent...\n" ); 342 397 tr_torrentStop( tor ); 343 tr_sessionSetPortForwardingEnabled( h, 0 );344 398 } 345 399 346 if( manualUpdate ) 347 { 400 if( manualUpdate ) { 348 401 manualUpdate = 0; 349 402 if ( !tr_torrentCanManualUpdate( tor ) ) … … 354 407 } 355 408 } 356 357 if( verify ) 358 { 359 verify = 0; 360 tr_torrentVerify( tor ); 361 } 362 363 s = tr_torrentStat( tor ); 364 365 if( s->status & TR_STATUS_CHECK_WAIT ) 366 { 367 chars = snprintf( string, sizeof string, 368 "Waiting to verify local files..." ); 369 } 370 else if( s->status & TR_STATUS_CHECK ) 371 { 372 chars = snprintf( string, sizeof string, 373 "Verifying local files... %.2f%%, found %.2f%% valid", 100 * s->recheckProgress, 100.0 * s->percentDone ); 374 } 375 else if( s->status & TR_STATUS_DOWNLOAD ) 376 { 377 chars = snprintf( string, sizeof string, 378 "Progress: %.2f %%, %d peer%s, dl from %d (%.2f KB/s), " 379 "ul to %d (%.2f KB/s) [%s]", 100.0 * s->percentDone, 380 s->peersConnected, ( s->peersConnected == 1 ) ? "" : "s", 381 s->peersSendingToUs, s->rateDownload, 382 s->peersGettingFromUs, s->rateUpload, 383 getStringRatio(s->ratio) ); 384 } 385 else if( s->status & TR_STATUS_SEED ) 386 { 387 chars = snprintf( string, sizeof string, 388 "Seeding, uploading to %d of %d peer(s), %.2f KB/s [%s]", 389 s->peersGettingFromUs, s->peersConnected, 390 s->rateUpload, getStringRatio(s->ratio) ); 391 } 392 else if( s->status & TR_STATUS_STOPPED ) 393 { 409 410 st = tr_torrentStat( tor ); 411 if( st->status & TR_STATUS_STOPPED ) 394 412 break; 395 } 396 if( ( signed )sizeof string > chars ) 397 { 398 memset( &string[chars], ' ', sizeof string - 1 - chars ); 399 } 400 string[sizeof string - 1] = '\0'; 401 fprintf( stderr, "\r%s", string ); 402 403 if( s->error ) 404 { 405 fprintf( stderr, "\n%s\n", s->errorString ); 406 } 407 else if( verboseLevel > 0 ) 408 { 409 fprintf( stderr, "\n" ); 410 } 411 } 412 fprintf( stderr, "\n" ); 413 414 /* try for 5 seconds to delete any port mappings for nat traversal */ 415 tr_sessionSetPortForwardingEnabled( h, 0 ); 416 for( i=0; i<10; ++i ) { 417 const tr_port_forwarding f = tr_sessionGetPortForwarding( h ); 418 if( f == TR_PORT_UNMAPPED ) 419 break; 420 tr_wait( 500 ); 421 } 422 413 414 getStatusStr( st, line, sizeof( line ) ); 415 printf( "%-*s\n", LINEWIDTH, line ); 416 if( st->error ) 417 printf( "%s\n", st->errorString ); 418 } 419 423 420 cleanup: 421 printf( "\n" ); 424 422 tr_sessionClose( h ); 425 426 423 return EXIT_SUCCESS; 427 424 } … … 442 439 443 440 const struct tr_option options[] = { 444 { 'a', "announce", "When creating a new torrent, set its announce URL", "a", 1, "<url>" }, 445 { 'b', "blocklist", "Enable peer blocklists", "b", 0, NULL }, 446 { 'B', "no-blocklist", "Disable peer blocklists", "B", 0, NULL }, 447 { 'c', "comment", "When creating a new torrent, set its comment field", "c", 1, "<comment>" }, 448 { 'd', "downlimit", "Set the maxiumum download speed in KB/s", "d", 1, "<number>" }, 449 { 'D', "no-downlimit", "Don't limit the download speed", "D", 0, NULL }, 450 { 'e', "encryption", "Set encryption mode [required, preferred, tolerated]", "e", 1, "<mode>" }, 451 { 'f', "finish", "Set a script to run when the torrent finishes", "f", 1, "<script>" }, 452 { 'g', "config-dir", "Where to look for configuration files", "g", 1, "<path>" }, 453 { 'i', "info", "Show torrent details and exit", "i", 0, NULL }, 454 { 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", 0, NULL }, 455 { 'M', "no-portmap", "Disable portmapping", "M", 0, NULL }, 456 { 'n', "new", "Create a new torrent from a file or directory", "n", 1, "<path>" }, 457 { 'p', "port", "Port to listen for incoming peers (Default: "TR_DEFAULT_PORT_STR")", "p", 1, "<port>" }, 458 { 'r', "private", "When creating a new torrent, set its 'private' flag", "r", 0, NULL }, 459 { 's', "scrape", "Scrape the torrent and exit", "s", 0, NULL }, 460 { 't', "tos", "Peer socket TOS (0 to 255, default="TR_DEFAULT_PEER_SOCKET_TOS_STR")", "t", 1, "<number>"}, 461 { 'u', "uplimit", "Set the maxiumum upload speed in KB/s", "u", 1, "<number>" }, 462 { 'U', "no-uplimit", "Don't limit the upload speed", "U", 0, NULL }, 463 { 'v', "verify", "Verify the specified torrent", "v", 0, NULL }, 464 { 'w', "download-dir", "Where to save downloaded data", "w", 1, "<path>" }, 441 { 'a', "announce", "Set the new torrent's announce URL", "a", 1, "<url>" }, 442 { 'b', "blocklist", "Enable peer blocklists", "b", 0, NULL }, 443 { 'B', "no-blocklist", "Disable peer blocklists", "B", 0, NULL }, 444 { 'c', "comment", "Set the new torrent's comment", "c", 1, "<comment>" }, 445 { 'd', "downlimit", "Set max download speed in KB/s", "d", 1, "<number>" }, 446 { 'D', "no-downlimit", "Don't limit the download speed", "D", 0, NULL }, 447 { 'e', "encryption", "Set encryption mode (required, preferred, tolerated)", 448 "e", 1, "<mode>" }, 449 { 'f', "finish", "Set a script to run when the torrent finishes", 450 "f", 1, "<script>" }, 451 { 'g', "config-dir", "Where to find configuration files", 452 "g", 1, "<path>" }, 453 { 'i', "info", "Show torrent details and exit", "i", 0, NULL }, 454 { 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", 0, NULL }, 455 { 'M', "no-portmap", "Disable portmapping", "M", 0, NULL }, 456 { 'n', "new", "Create a new torrent from a file or directory", 457 "n", 1, "<path>" }, 458 { 'p', "port", 459 "Port to listen for incoming peers (Default: "TR_DEFAULT_PORT_STR")", 460 "p", 1, "<port>" }, 461 { 'r', "private", "Set the new torrent's 'private' flag", "r", 0, NULL }, 462 { 's', "scrape", "Scrape the torrent and exit", "s", 0, NULL }, 463 { 't', "tos", 464 "Peer socket TOS (0 to 255, default="TR_DEFAULT_PEER_SOCKET_TOS_STR")", 465 "t", 1, "<number>" }, 466 { 'u', "uplimit", "Set max upload speed in KB/s", "u", 1, "<number>" }, 467 { 'U', "no-uplimit", "Don't limit the upload speed", "U", 0, NULL }, 468 { 'v', "verify", "Verify the specified torrent", "v", 0, NULL }, 469 { 'w', "download-dir", "Where to save downloaded data", "w", 1, "<path>" }, 465 470 { 0, NULL, NULL, NULL, 0, NULL } 466 471 };
Note: See TracChangeset
for help on using the changeset viewer.