Changeset 7664
- Timestamp:
- Jan 11, 2009, 5:46:51 PM (13 years ago)
- Location:
- branches/1.5x
- Files:
-
- 3 added
- 145 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/1.5x/AUTHORS
r6969 r7664 6 6 Mitchell Livingston <livings124@transmissionbt.com> (Mac OS X client) 7 7 8 Web Client Developers 9 Malcom Jarvis 10 Dave Perrett 11 Kendall Hopkins <SoftwareElves@gmail.com> 12 Charles Kerr 8 Project Contributors 9 Tomas Carnecky (Profiling, patches, and detection of sneaky bugs) 10 John Clay (Website maintenance and troubleshooting) 11 Rashid Eissing (Mac OS X Transfers preferences icon) 12 Hugo van Heuven, madebysofa (Main icon design) 13 Kendall Hopkins <SoftwareElves@gmail.com> (Web Interface) 14 Malcolm Jarvis <mjarvis@transmissionbt.com> (Web Interface) 15 Rick Patrick (Mac OS X images) 16 Nick Pucius (Help documentation) 17 Jonas Rask (Mac OS X Globe icon) 18 Erick Turnquist <jhujhiti@adjectivism.org> (IPv6 code, support) 19 Maarten Van Coile (Wiki Wrangler, troubleshooting, support) 13 20 14 21 Previous Developers 15 Eric Petit <titer@m0k.org> ( Creator)22 Eric Petit <titer@m0k.org> (Project originator) 16 23 Josh Elsasser <josh@elsasser.org> (Daemon, Backend, GTK+ client) 17 24 Bryan Varner <bryan@varnernet.com> (BeOS client) 18 19 Project Contributors20 John Clay (Website maintenance and troubleshooting)21 Hugo van Heuven, madebysofa (Main icon design)22 Nick Pucius (Help documentation)23 Rick Patrick (Mac OS X images)24 Jonas Rask (Mac OS X Globe icon)25 Rashid Eissing (Mac OS X Transfers preferences icon)26 25 27 26 Mac OS X Translators, current release: -
branches/1.5x/COPYING
r6286 r7664 12 12 portions of Transmission. 13 13 14 Copyright 2005-200 8. All code is copyrighted by the respective authors.14 Copyright 2005-2009. All code is copyrighted by the respective authors. 15 15 16 16 MIT LICENSE: -
branches/1.5x/Makefile.am
r6926 r7664 1 1 ACLOCAL_AMFLAGS = -I m4 2 2 3 if BUILD_BEOS4 BEOS_DIR = beos5 endif6 3 if BUILD_CLI 7 4 CLI_DIR = cli -
branches/1.5x/README
r7303 r7664 4 4 Transmission is a fast, easy, and free BitTorrent client. 5 5 6 It runs on Mac OS X (Cocoa interface) ,7 Linux/NetBSD/FreeBSD/OpenBSD (GTK+ interface) 6 It runs on Mac OS X (Cocoa interface) and 7 Linux/NetBSD/FreeBSD/OpenBSD (GTK+ interface). 8 8 9 9 Visit http://www.transmissionbt.com/ for more information. -
branches/1.5x/cli/cli.c
r7229 r7664 32 32 #include <libtransmission/bencode.h> 33 33 #include <libtransmission/makemeta.h> 34 #include <libtransmission/metainfo.h> /* tr_metainfoFree */35 34 #include <libtransmission/tr-getopt.h> 36 35 #include <libtransmission/utils.h> /* tr_wait */ … … 40 39 #define MY_NAME "transmission-cli" 41 40 42 static int showInfo = 0; 43 static int showScrape = 0; 44 static int isPrivate = 0; 45 static int verboseLevel = 0; 46 static int encryptionMode = TR_DEFAULT_ENCRYPTION; 47 static int peerPort = TR_DEFAULT_PORT; 48 static int peerSocketTOS = TR_DEFAULT_PEER_SOCKET_TOS; 49 static int blocklistEnabled = TR_DEFAULT_BLOCKLIST_ENABLED; 50 static int uploadLimit = 20; 51 static int downloadLimit = -1; 52 static int natTraversal = TR_DEFAULT_PORT_FORWARDING_ENABLED; 53 static int verify = 0; 41 static tr_bool showInfo = 0; 42 static tr_bool showScrape = 0; 43 static tr_bool isPrivate = 0; 44 static tr_bool verify = 0; 54 45 static sig_atomic_t gotsig = 0; 55 46 static sig_atomic_t manualUpdate = 0; 56 47 57 48 static const char * torrentPath = NULL; 58 static const char * downloadDir = NULL;59 49 static const char * finishCall = NULL; 60 50 static const char * announce = NULL; 61 static const char * configdir = NULL;62 51 static const char * sourceFile = NULL; 63 52 static const char * comment = NULL; … … 65 54 static const struct tr_option options[] = 66 55 { 67 { 'a', "announce", "Set the new torrent's announce URL", 68 "a", 1, "<url>" }, 69 { 'b', "blocklist", "Enable peer blocklists", 70 "b", 0, NULL }, 71 { 'B', "no-blocklist", "Disable peer blocklists", 72 "B", 0, NULL }, 73 { 'c', "comment", "Set the new torrent's comment", 74 "c", 1, "<comment>" }, 75 { 'd', "downlimit", "Set max download speed in KB/s", 76 "d", 1, "<speed>" }, 77 { 'D', "no-downlimit", "Don't limit the download speed", 78 "D", 0, NULL }, 79 { 910, "encryption-required", "Encrypt all peer connections", 80 "er", 0, NULL }, 81 { 911, "encryption-preferred", "Prefer encrypted peer connections", 82 "ep", 0, NULL }, 83 { 912, "encryption-tolerated", "Prefer unencrypted peer connections", 84 "et", 0, NULL }, 85 { 'f', "finish", "Run a script when the torrent finishes", 86 "f", 1, "<script>" }, 87 { 'g', "config-dir", "Where to find configuration files", 88 "g", 1, "<path>" }, 89 { 'i', "info", "Show torrent details and exit", 90 "i", 0, NULL }, 91 { 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", 92 "m", 0, NULL }, 93 { 'M', "no-portmap", "Disable portmapping", 94 "M", 0, NULL }, 95 { 'n', "new", "Create a new torrent", 96 "n", 1, "<source>" }, 97 { 'p', "port", 98 "Port for incoming peers (Default: " TR_DEFAULT_PORT_STR ")", 99 "p", 1, "<port>" }, 100 { 'r', "private", "Set the new torrent's 'private' flag", 101 "r", 0, NULL }, 102 { 's', "scrape", "Scrape the torrent and exit", 103 "s", 0, NULL }, 104 { 't', "tos", 105 "Peer socket TOS (0 to 255, default=" TR_DEFAULT_PEER_SOCKET_TOS_STR 106 ")", 107 "t", 1, "<tos>" }, 108 { 'u', "uplimit", "Set max upload speed in KB/s", 109 "u", 1, "<speed>" }, 110 { 'U', "no-uplimit", "Don't limit the upload speed", 111 "U", 0, NULL }, 112 { 'v', "verify", "Verify the specified torrent", 113 "v", 0, NULL }, 114 { 'w', "download-dir", "Where to save downloaded data", 115 "w", 1, "<path>" }, 116 { 0, NULL, NULL, 117 NULL, 0, NULL } 56 { 'a', "announce", "Set the new torrent's announce URL", "a", 1, "<url>" }, 57 { 'b', "blocklist", "Enable peer blocklists", "b", 0, NULL }, 58 { 'B', "no-blocklist", "Disable peer blocklists", "B", 0, NULL }, 59 { 'c', "comment", "Set the new torrent's comment", "c", 1, "<comment>" }, 60 { 'd', "downlimit", "Set max download speed in KB/s", "d", 1, "<speed>" }, 61 { 'D', "no-downlimit", "Don't limit the download speed", "D", 0, NULL }, 62 { 910, "encryption-required", "Encrypt all peer connections", "er", 0, NULL }, 63 { 911, "encryption-preferred", "Prefer encrypted peer connections", "ep", 0, NULL }, 64 { 912, "encryption-tolerated", "Prefer unencrypted peer connections", "et", 0, NULL }, 65 { 'f', "finish", "Run a script when the torrent finishes", "f", 1, "<script>" }, 66 { 'g', "config-dir", "Where to find configuration files", "g", 1, "<path>" }, 67 { 'i', "info", "Show torrent details and exit", "i", 0, NULL }, 68 { 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", 0, NULL }, 69 { 'M', "no-portmap", "Disable portmapping", "M", 0, NULL }, 70 { 'n', "new", "Create a new torrent", "n", 1, "<source>" }, 71 { 'p', "port", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "p", 1, "<port>" }, 72 { 'r', "private", "Set the new torrent's 'private' flag", "r", 0, NULL }, 73 { 's', "scrape", "Scrape the torrent and exit", "s", 0, NULL }, 74 { 't', "tos", "Peer socket TOS (0 to 255, default=" TR_DEFAULT_PEER_SOCKET_TOS_STR ")", "t", 1, "<tos>" }, 75 { 'u', "uplimit", "Set max upload speed in KB/s", "u", 1, "<speed>" }, 76 { 'U', "no-uplimit", "Don't limit the upload speed", "U", 0, NULL }, 77 { 'v', "verify", "Verify the specified torrent", "v", 0, NULL }, 78 { 'w', "download-dir", "Where to save downloaded data", "w", 1, "<path>" }, 79 { 0, NULL, NULL, NULL, 0, NULL } 118 80 }; 119 81 … … 126 88 } 127 89 128 static int parseCommandLine( int argc, 129 const char ** argv ); 90 static int parseCommandLine( tr_benc*, int argc, const char ** argv ); 130 91 131 92 static void sigHandler( int signal ); … … 303 264 } 304 265 266 static const char* 267 getConfigDir( int argc, const char ** argv ) 268 { 269 int c; 270 const char * configDir = NULL; 271 const char * optarg; 272 const int ind = tr_optind; 273 274 while(( c = tr_getopt( getUsage( ), argc, argv, options, &optarg ))) { 275 if( c == 'g' ) { 276 configDir = optarg; 277 break; 278 } 279 } 280 281 tr_optind = ind; 282 283 if( configDir == NULL ) 284 configDir = tr_getDefaultConfigDir( MY_NAME ); 285 286 return configDir; 287 } 288 305 289 int 306 290 main( int argc, … … 311 295 tr_ctor * ctor; 312 296 tr_torrent * tor = NULL; 297 tr_benc settings; 298 const char * configDir; 313 299 314 300 printf( "Transmission %s - http://www.transmissionbt.com/\n", … … 321 307 } 322 308 323 /* Get options */ 324 if( parseCommandLine( argc, (const char**)argv ) ) 309 /* load the defaults from config file + libtransmission defaults */ 310 tr_bencInitDict( &settings, 0 ); 311 configDir = getConfigDir( argc, (const char**)argv ); 312 tr_sessionLoadSettings( &settings, configDir, MY_NAME ); 313 314 /* the command line overrides defaults */ 315 if( parseCommandLine( &settings, argc, (const char**)argv ) ) 325 316 return EXIT_FAILURE; 326 317 327 318 /* Check the options for validity */ 328 if( !torrentPath ) 329 { 319 if( !torrentPath ) { 330 320 fprintf( stderr, "No torrent specified!\n" ); 331 321 return EXIT_FAILURE; 332 322 } 333 if( peerPort < 1 || peerPort > 65535 )334 {335 fprintf( stderr, "Error: Port must between 1 and 65535; got %d\n",336 peerPort );337 return EXIT_FAILURE;338 }339 if( peerSocketTOS < 0 || peerSocketTOS > 255 )340 {341 fprintf( stderr, "Error: value must between 0 and 255; got %d\n",342 peerSocketTOS );343 return EXIT_FAILURE;344 }345 323 346 324 /* don't bind the port if we're just running the CLI 347 *to get metainfo or to create a torrent */325 to get metainfo or to create a torrent */ 348 326 if( showInfo || showScrape || ( sourceFile != NULL ) ) 349 peerPort = -1; 350 351 if( configdir == NULL ) 352 configdir = tr_getDefaultConfigDir( ); 353 354 /* if no download directory specified, use cwd instead */ 355 if( !downloadDir ) 356 downloadDir = tr_strdup( tr_getcwd( ) ); 357 358 /* Initialize libtransmission */ 359 h = tr_sessionInitFull( 360 configdir, 361 "cli", /* tag */ 362 downloadDir, /* where to download torrents */ 363 TR_DEFAULT_PEX_ENABLED, 364 natTraversal, /* nat enabled */ 365 peerPort, 366 encryptionMode, 367 TR_DEFAULT_LAZY_BITFIELD_ENABLED, 368 uploadLimit >= 0, 369 uploadLimit, 370 downloadLimit >= 0, 371 downloadLimit, 372 TR_DEFAULT_GLOBAL_PEER_LIMIT, 373 verboseLevel + 1, /* messageLevel */ 374 0, /* is message queueing enabled? */ 375 blocklistEnabled, 376 peerSocketTOS, 377 TR_DEFAULT_RPC_ENABLED, 378 TR_DEFAULT_RPC_PORT, 379 TR_DEFAULT_RPC_WHITELIST_ENABLED, 380 TR_DEFAULT_RPC_WHITELIST, 381 FALSE, "fnord", "potzrebie", 382 TR_DEFAULT_PROXY_ENABLED, 383 TR_DEFAULT_PROXY, 384 TR_DEFAULT_PROXY_PORT, 385 TR_DEFAULT_PROXY_TYPE, 386 TR_DEFAULT_PROXY_AUTH_ENABLED, 387 TR_DEFAULT_PROXY_USERNAME, 388 TR_DEFAULT_PROXY_PASSWORD ); 327 tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_PORT, -1 ); 328 329 h = tr_sessionInit( "cli", configDir, FALSE, &settings ); 389 330 390 331 if( sourceFile && *sourceFile ) /* creating a torrent */ … … 410 351 tr_ctorSetMetainfoFromFile( ctor, torrentPath ); 411 352 tr_ctorSetPaused( ctor, TR_FORCE, showScrape ); 412 tr_ctorSetDownloadDir( ctor, TR_FORCE, downloadDir );413 353 414 354 if( showScrape ) … … 524 464 525 465 cleanup: 466 467 tr_sessionSaveSettings( h, configDir, &settings ); 468 526 469 printf( "\n" ); 470 tr_bencFree( &settings ); 527 471 tr_sessionClose( h ); 528 472 return EXIT_SUCCESS; … … 535 479 ***/ 536 480 537 static void538 showUsage( void )539 {540 tr_getopt_usage( MY_NAME, getUsage( ), options );541 exit( 0 );542 }543 544 481 static int 545 numarg( const char * arg ) 546 { 547 char * end = NULL; 548 const long num = strtol( arg, &end, 10 ); 549 550 if( *end ) 551 { 552 fprintf( stderr, "Not a number: \"%s\"\n", arg ); 553 showUsage( ); 554 } 555 return num; 556 } 557 558 static int 559 parseCommandLine( int argc, 560 const char ** argv ) 482 parseCommandLine( tr_benc * d, int argc, const char ** argv ) 561 483 { 562 484 int c; 563 485 const char * optarg; 564 486 565 while( ( c = tr_getopt( getUsage( ), argc, argv, options, &optarg ) ))487 while(( c = tr_getopt( getUsage( ), argc, argv, options, &optarg ))) 566 488 { 567 489 switch( c ) … … 570 492 announce = optarg; break; 571 493 572 case 'b': 573 blocklistEnabled = 1; break; 574 575 case 'B': 576 blocklistEnabled = 0; break; 577 578 case 'c': 579 comment = optarg; break; 580 581 case 'd': 582 downloadLimit = numarg( optarg ); break; 583 584 case 'D': 585 downloadLimit = -1; break; 586 587 case 'f': 588 finishCall = optarg; break; 589 590 case 'g': 591 configdir = optarg; break; 592 593 case 'i': 594 showInfo = 1; break; 595 596 case 'm': 597 natTraversal = 1; break; 598 599 case 'M': 600 natTraversal = 0; break; 601 602 case 'n': 603 sourceFile = optarg; break; 604 605 case 'p': 606 peerPort = numarg( optarg ); break; 607 608 case 'r': 609 isPrivate = 1; break; 610 611 case 's': 612 showScrape = 1; break; 613 614 case 't': 615 peerSocketTOS = numarg( optarg ); break; 616 617 case 'u': 618 uploadLimit = numarg( optarg ); break; 619 620 case 'U': 621 uploadLimit = -1; break; 622 623 case 'v': 624 verify = 1; break; 625 626 case 'w': 627 downloadDir = optarg; break; 628 629 case 910: 630 encryptionMode = TR_ENCRYPTION_REQUIRED; break; 631 632 case 911: 633 encryptionMode = TR_CLEAR_PREFERRED; break; 634 635 case 912: 636 encryptionMode = TR_ENCRYPTION_PREFERRED; break; 637 494 case 'b': tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, 1 ); 495 break; 496 case 'B': tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, 0 ); 497 break; 498 case 'c': comment = optarg; 499 break; 500 case 'd': tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, atoi( optarg ) ); 501 tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, 1 ); 502 break; 503 case 'D': tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, 0 ); 504 break; 505 case 'f': finishCall = optarg; 506 break; 507 case 'g': /* handled above */ 508 break; 509 case 'i': showInfo = 1; 510 break; 511 case 'm': tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, 1 ); 512 break; 513 case 'M': tr_bencDictAddInt( d, TR_PREFS_KEY_PORT_FORWARDING, 0 ); 514 break; 515 case 'n': sourceFile = optarg; break; 516 case 'p': tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_PORT, atoi( optarg ) ); 517 break; 518 case 'r': isPrivate = 1; 519 break; 520 case 's': showScrape = 1; 521 break; 522 case 't': tr_bencDictAddInt( d, TR_PREFS_KEY_PEER_SOCKET_TOS, atoi( optarg ) ); 523 break; 524 case 'u': tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, atoi( optarg ) ); 525 tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 1 ); 526 break; 527 case 'U': tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 0 ); 528 break; 529 case 'v': verify = 1; 530 break; 531 case 'w': tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, optarg ); 532 break; 533 case 910: tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_REQUIRED ); 534 break; 535 case 911: tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_PREFERRED ); 536 break; 537 case 912: tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, TR_CLEAR_PREFERRED ); 538 break; 638 539 case TR_OPT_UNK: 639 torrentPath = optarg; break; 640 641 default: 642 return 1; 540 torrentPath = optarg; 541 break; 542 default: return 1; 643 543 } 644 544 } -
branches/1.5x/configure.ac
r7494 r7664 4 4 dnl "0" for stable, supported releases 5 5 dnl these should be the only two lines you need to change 6 m4_define([user_agent_prefix],[1.42]) 7 m4_define([peer_id_prefix],[-TR1420-]) 8 9 AC_INIT([transmission],[user_agent_prefix],[http://trac.transmissionbt.com/newticket]) 6 m4_define([user_agent_prefix],[1.42+]) 7 m4_define([peer_id_prefix],[-TR142Z-]) 8 9 AC_INIT([transmission], 10 [user_agent_prefix], 11 [http://trac.transmissionbt.com/newticket]) 10 12 AC_SUBST(USERAGENT_PREFIX,[user_agent_prefix]) 11 13 AC_SUBST(PEERID_PREFIX,[peer_id_prefix]) … … 21 23 AC_DEFINE(TR_UNSTABLE, 1, [Define to 1 if this is an unstable version of Transmission]) 22 24 TR_UNSTABLE=yes 25 enable_debug=yes 26 else 27 enable_debug=no 23 28 fi 24 29 AM_CONDITIONAL(TR_UNSTABLE, test "x$TR_UNSTABLE" = "xyes") … … 43 48 AC_PROG_CC 44 49 AC_PROG_CXX 50 AC_C_INLINE 45 51 if test "x$GCC" = "xyes" ; then 46 CFLAGS="- g -Wall -Wformat-security -W -Wmissing-prototypes -Wdeclaration-after-statement -O3 -funroll-loops"47 CXXFLAGS="- g -Wall -Wformat-security -W -O3 -funroll-loops"52 CFLAGS="-std=gnu99 -ggdb3 -Wall -Wextra -Wredundant-decls -Wpointer-arith -Wformat-security -W -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Winit-self -Wundef -Wnested-externs -Wmissing-format-attribute" 53 CXXFLAGS="-Wall -Wformat-security -W" 48 54 fi 49 55 … … 89 95 dnl ---------------------------------------------------------------------------- 90 96 dnl 97 dnl debugging support 98 AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug],[build with debugging support]),,,) 99 if test "x$enable_debug" = "xyes" ; then 100 CFLAGS="$CFLAGS -g -O0" 101 CXXFLAGS="$CXXFLAGS -g -O0" 102 else 103 CFLAGS="$CFLAGS -g -O3 -funroll-loops -DNDEBUG " 104 CXXFLAGS="$CXXFLAGS -g -O3 -funroll-loops -DNDEBUG " 105 fi 106 107 108 dnl ---------------------------------------------------------------------------- 109 dnl 91 110 dnl libevent fun 92 111 … … 109 128 [have_gtk=no]) 110 129 AC_ARG_ENABLE([gtk], 111 A C_HELP_STRING([--enable-gtk],[build gtk client]),130 AS_HELP_STRING([--enable-gtk],[build gtk client]), 112 131 [want_gtk=${enableval}], 113 132 [want_gtk=${have_gtk}]) … … 174 193 fi 175 194 176 AC_CHECK_HEADERS([libintl.h]) 177 IT_PROG_INTLTOOL([0.23],[no-xml]) 178 GETTEXT_PACKAGE=transmission 179 AC_SUBST(GETTEXT_PACKAGE) 180 AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[Gettext package]) 181 AM_GLIB_GNU_GETTEXT 182 transmissionlocaledir='${prefix}/${DATADIRNAME}/locale' 183 AC_SUBST(transmissionlocaledir) 184 195 AC_ARG_ENABLE([nls], 196 AS_HELP_STRING([--enable-nls],[enable native language support]),, 197 [enable_nls=yes]) 198 199 if test "x$build_gtk" = "xyes" -a "x$enable_nls" = "xno" ; then 200 AC_MSG_ERROR("The gtk client cannot be built without nls support. Try adding either --enable-nls or --disable-gtk" ) 201 fi 202 203 use_nls=no 204 if test "x$enable_nls" = "xyes" ; then 205 use_nls=yes 206 IT_PROG_INTLTOOL([0.23],[no-xml]) 207 AC_CHECK_HEADERS([libintl.h]) 208 GETTEXT_PACKAGE=transmission 209 AC_SUBST(GETTEXT_PACKAGE) 210 AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[Gettext package]) 211 AM_GLIB_GNU_GETTEXT 212 transmissionlocaledir='${prefix}/${DATADIRNAME}/locale' 213 AC_SUBST(transmissionlocaledir) 214 fi 185 215 186 216 dnl ---------------------------------------------------------------------------- … … 190 220 build_wx=no 191 221 AC_ARG_ENABLE([wx], 192 A C_HELP_STRING([--enable-wx],[build wxWidgets client]),222 AS_HELP_STRING([--enable-wx],[build wxWidgets client]), 193 223 [want_wx=${enableval}], 194 [want_wx= maybe])224 [want_wx=no]) 195 225 if test "x$want_wx" != "xno"; then 196 226 AM_OPTIONS_WXCONFIG … … 211 241 212 242 AC_CANONICAL_HOST 213 have_beos="no"214 243 have_darwin="no" 215 244 have_msw="no" … … 230 259 ;; 231 260 232 *beos*)233 have_beos="yes"234 RELEASE=`uname -r`235 case $RELEASE in236 6.*|5.0.4) # Zeta or R5 / BONE beta 7237 ;;238 5.0*) # R5 / net_server239 CPPFLAGS="$CPPFLAGS -DBEOS_NETSERVER"240 ;;241 *)242 AC_MSG_ERROR("Unsupported BeOS version")243 ;;244 esac245 GCCVER=`$CC -dumpversion`246 case $GCCVER in247 2.95.3*|3*|4*)248 ;;249 2.9*)250 BEOS_OLDCC=yes251 ;;252 *)253 AC_MSG_ERROR("Unsupported gcc version")254 ;;255 esac256 ;;257 258 261 *darwin*) 259 262 have_darwin="yes" … … 274 277 esac 275 278 276 AC_ARG_ENABLE([beos],277 [AC_HELP_STRING([--enable-beos],[build OS X client])],278 [build_beos=${enableval}],279 [build_beos=${have_beos}])280 AM_CONDITIONAL([BUILD_BEOS],[test "x$build_beos" = "xyes"])281 282 279 AC_ARG_ENABLE([cli], 283 [A C_HELP_STRING([--enable-cli],[build command-line client])],280 [AS_HELP_STRING([--enable-cli],[build command-line client])], 284 281 [build_cli=${enableval}], 285 282 [build_cli="yes"]) … … 287 284 288 285 AC_ARG_ENABLE([mac], 289 [A C_HELP_STRING([--enable-mac],[build OS X client])],286 [AS_HELP_STRING([--enable-mac],[build OS X client])], 290 287 [build_mac=${enableval}], 291 288 [build_mac=${have_darwin}]) … … 293 290 294 291 AC_ARG_ENABLE([daemon], 295 [A C_HELP_STRING([--enable-daemon],[build daemon])],292 [AS_HELP_STRING([--enable-daemon],[build daemon])], 296 293 [build_daemon=${enableval}], 297 294 [build_daemon="yes"]) … … 299 296 300 297 301 if test "x$have_beos" = "xyes"; then302 AC_DEFINE([HAVE_BEOS], 1)303 fi304 298 if test "x$have_darwin" = "xyes"; then 305 299 AC_DEFINE([HAVE_DARWIN], 1) … … 316 310 AC_CONFIG_FILES([Makefile 317 311 transmission.spec 318 beos/Makefile319 312 cli/Makefile 320 313 daemon/Makefile … … 340 333 Source code location: ${srcdir} 341 334 Compiler: ${CXX} 335 Debugging support ${enable_debug} 342 336 Build Command-Line client: ${build_cli} 343 337 Build Daemon: ${build_daemon} 344 Build BeOS client: ${build_beos}345 338 Build GTK+ client: ${build_gtk} 346 339 ... gio support: ${use_gio} -
branches/1.5x/daemon/daemon.c
r7346 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 17 17 #include <string.h> /* strcmp */ 18 18 19 #include <sys/types.h> /* umask*/ 20 #include <sys/stat.h> /* umask*/ 21 19 22 #include <fcntl.h> /* open */ 20 23 #include <signal.h> 21 24 #include <unistd.h> /* daemon */ 22 25 26 #include <event.h> 27 23 28 #include <libtransmission/transmission.h> 24 29 #include <libtransmission/bencode.h> 25 #include <libtransmission/rpcimpl.h>26 30 #include <libtransmission/tr-getopt.h> 27 31 #include <libtransmission/utils.h> … … 32 36 static int closing = FALSE; 33 37 static tr_session * mySession = NULL; 34 static char * myConfigFilename = NULL;35 36 #define KEY_BLOCKLIST "blocklist-enabled"37 #define KEY_DOWNLOAD_DIR "download-dir"38 #define KEY_ENCRYPTION "encryption"39 #define KEY_LAZY_BITFIELD "lazy-bitfield-enabled"40 #define KEY_PEER_LIMIT "max-peers-global"41 #define KEY_PEER_PORT "peer-port"42 #define KEY_PORT_FORWARDING "port-forwarding-enabled"43 #define KEY_PEX_ENABLED "pex-enabled"44 #define KEY_AUTH_REQUIRED "rpc-authentication-required"45 #define KEY_USERNAME "rpc-username"46 #define KEY_PASSWORD "rpc-password"47 #define KEY_WHITELIST "rpc-whitelist"48 #define KEY_WHITELIST_ENABLED "rpc-whitelist-enabled"49 #define KEY_RPC_PORT "rpc-port"50 #define KEY_DSPEED "download-limit"51 #define KEY_DSPEED_ENABLED "download-limit-enabled"52 #define KEY_USPEED "upload-limit"53 #define KEY_USPEED_ENABLED "upload-limit-enabled"54 55 #define CONFIG_FILE "settings.json"56 38 57 39 /*** 58 40 **** Config File 59 41 ***/ 60 61 static void62 replaceInt( tr_benc * dict,63 const char * key,64 int64_t value )65 {66 tr_bencDictRemove( dict, key );67 tr_bencDictAddInt( dict, key, value );68 }69 70 static void71 replaceStr( tr_benc * dict,72 const char * key,73 const char* value )74 {75 tr_bencDictRemove( dict, key );76 tr_bencDictAddStr( dict, key, value );77 }78 79 static void80 saveState( tr_session * s )81 {82 int i, n = 0;83 char * strs[4];84 85 tr_benc d;86 87 if( tr_bencLoadJSONFile( myConfigFilename, &d ) )88 tr_bencInitDict( &d, 16 );89 90 replaceInt( &d, KEY_BLOCKLIST, tr_blocklistIsEnabled( s ) );91 replaceStr( &d, KEY_DOWNLOAD_DIR, tr_sessionGetDownloadDir( s ) );92 replaceInt( &d, KEY_PEER_LIMIT, tr_sessionGetPeerLimit( s ) );93 replaceInt( &d, KEY_PEER_PORT, tr_sessionGetPeerPort( s ) );94 replaceInt( &d, KEY_PORT_FORWARDING, tr_sessionIsPortForwardingEnabled( s ) );95 replaceInt( &d, KEY_PEX_ENABLED, tr_sessionIsPexEnabled( s ) );96 replaceStr( &d, KEY_USERNAME, strs[n++] = tr_sessionGetRPCUsername( s ) );97 replaceStr( &d, KEY_PASSWORD, strs[n++] = tr_sessionGetRPCPassword( s ) );98 replaceStr( &d, KEY_WHITELIST, strs[n++] = tr_sessionGetRPCWhitelist( s ) );99 replaceInt( &d, KEY_RPC_PORT, tr_sessionGetRPCPort( s ) );100 replaceInt( &d, KEY_AUTH_REQUIRED, tr_sessionIsRPCPasswordEnabled( s ) );101 replaceInt( &d, KEY_DSPEED, tr_sessionGetSpeedLimit( s, TR_DOWN ) );102 replaceInt( &d, KEY_DSPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) );103 replaceInt( &d, KEY_USPEED, tr_sessionGetSpeedLimit( s, TR_UP ) );104 replaceInt( &d, KEY_USPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_UP ) );105 replaceInt( &d, KEY_ENCRYPTION, tr_sessionGetEncryption( s ) );106 107 tr_bencSaveJSONFile( myConfigFilename, &d );108 tr_bencFree( &d );109 tr_ninf( MY_NAME, "saved \"%s\"", myConfigFilename );110 111 for( i = 0; i < n; ++i )112 tr_free( strs[i] );113 }114 115 static void116 getConfigInt( tr_benc * dict,117 const char * key,118 int * setme,119 int defaultVal )120 {121 if( *setme < 0 )122 {123 int64_t i;124 if( tr_bencDictFindInt( dict, key, &i ) )125 *setme = i;126 else127 *setme = defaultVal;128 }129 }130 131 static void132 getConfigStr( tr_benc * dict,133 const char * key,134 const char ** setme,135 const char * defaultVal )136 {137 if( !*setme )138 {139 const char * s;140 if( tr_bencDictFindStr( dict, key, &s ) )141 *setme = s;142 else143 *setme = defaultVal;144 }145 }146 147 /**148 * @param port port number, or -1 if not set in the command line149 * @param auth TRUE, FALSE, or -1 if not set on the command line150 * @param blocklist TRUE, FALSE, or -1 if not set on the command line151 */152 static void153 session_init( const char * configDir,154 const char * downloadDir,155 int rpcPort,156 const char * whitelist,157 int authRequired,158 const char * username,159 const char * password,160 int blocklistEnabled )161 {162 char * mycwd;163 tr_benc state, *dict = NULL;164 int peerPort = -1, peers = -1;165 int whitelistEnabled = -1;166 int pexEnabled = -1;167 int fwdEnabled = -1;168 int upLimit = -1, upLimited = -1, downLimit = -1,169 downLimited = -1;170 int encryption = -1;171 int useLazyBitfield = -1;172 tr_ctor * ctor;173 tr_torrent ** torrents;174 175 if( !tr_bencLoadJSONFile( myConfigFilename, &state ) )176 dict = &state;177 178 /***179 **** Decide on which values to pass into tr_sessionInitFull().180 **** The command-line arguments are given precedence and181 **** the state file from the previous session is used as a fallback.182 **** If neither of those can be found, the TR_DEFAULT fields are used .183 ***/184 185 mycwd = tr_getcwd( );186 getConfigStr( dict, KEY_DOWNLOAD_DIR, &downloadDir, mycwd );187 getConfigInt( dict, KEY_PEX_ENABLED, &pexEnabled, TR_DEFAULT_PEX_ENABLED );188 getConfigInt( dict, KEY_PORT_FORWARDING, &fwdEnabled, TR_DEFAULT_PORT_FORWARDING_ENABLED );189 getConfigInt( dict, KEY_PEER_PORT, &peerPort, TR_DEFAULT_PORT );190 getConfigInt( dict, KEY_DSPEED, &downLimit, 100 );191 getConfigInt( dict, KEY_DSPEED_ENABLED, &downLimited, FALSE );192 getConfigInt( dict, KEY_USPEED, &upLimit, 100 );193 getConfigInt( dict, KEY_USPEED_ENABLED, &upLimited, FALSE );194 getConfigInt( dict, KEY_LAZY_BITFIELD, &useLazyBitfield, TR_DEFAULT_LAZY_BITFIELD_ENABLED );195 getConfigInt( dict, KEY_PEER_LIMIT, &peers, TR_DEFAULT_GLOBAL_PEER_LIMIT );196 getConfigInt( dict, KEY_BLOCKLIST, &blocklistEnabled, TR_DEFAULT_BLOCKLIST_ENABLED );197 getConfigInt( dict, KEY_RPC_PORT, &rpcPort, TR_DEFAULT_RPC_PORT );198 getConfigStr( dict, KEY_WHITELIST, &whitelist, TR_DEFAULT_RPC_WHITELIST );199 getConfigInt( dict, KEY_AUTH_REQUIRED, &authRequired, FALSE );200 getConfigStr( dict, KEY_USERNAME, &username, NULL );201 getConfigStr( dict, KEY_PASSWORD, &password, NULL );202 getConfigInt( dict, KEY_ENCRYPTION, &encryption, TR_DEFAULT_ENCRYPTION );203 204 whitelistEnabled = whitelist && *whitelist;205 206 /***207 ****208 ***/209 210 /* start the session */211 mySession = tr_sessionInitFull( configDir, "daemon", downloadDir,212 pexEnabled, fwdEnabled, peerPort,213 encryption,214 useLazyBitfield,215 upLimited, upLimit,216 downLimited, downLimit,217 peers,218 TR_MSG_INF, 0,219 blocklistEnabled,220 TR_DEFAULT_PEER_SOCKET_TOS,221 TRUE, rpcPort,222 whitelistEnabled, whitelist,223 authRequired, username, password,224 TR_DEFAULT_PROXY_ENABLED,225 TR_DEFAULT_PROXY,226 TR_DEFAULT_PROXY_PORT,227 TR_DEFAULT_PROXY_TYPE,228 TR_DEFAULT_PROXY_AUTH_ENABLED,229 TR_DEFAULT_PROXY_USERNAME,230 TR_DEFAULT_PROXY_PASSWORD );231 232 233 if( authRequired )234 tr_ninf( MY_NAME, "requiring authentication" );235 236 /* load the torrents */237 ctor = tr_ctorNew( mySession );238 torrents = tr_sessionLoadTorrents( mySession, ctor, NULL );239 tr_free( torrents );240 tr_ctorFree( ctor );241 242 if( dict )243 tr_bencFree( &state );244 245 tr_free( mycwd );246 }247 42 248 43 static const char * … … 254 49 "\n" 255 50 MY_NAME " is a headless Transmission session\n" 256 257 258 51 "that can be controlled via transmission-remote or Clutch.\n" 52 "\n" 53 "Usage: " MY_NAME " [options]"; 259 54 } 260 55 261 56 static const struct tr_option options[] = 262 57 { 263 { 'a', "allowed", 264 "Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a", 265 1, "<list>" }, 266 { 'b', "blocklist", "Enable peer blocklists", 267 "b", 0, NULL }, 268 { 'B', "no-blocklist", "Disable peer blocklists", 269 "B", 0, NULL }, 270 { 'f', "foreground", "Run in the foreground instead of daemonizing", 271 "f", 0, NULL }, 272 { 'g', "config-dir", "Where to look for configuration files", 273 "g", 1, "<path>" }, 274 { 'p', "port", 275 "RPC port (Default: " TR_DEFAULT_RPC_PORT_STR ")", "p", 276 1, "<port>" }, 277 { 't', "auth", "Require authentication", 278 "t", 0, NULL }, 279 { 'T', "no-auth", "Don't require authentication", 280 "T", 0, NULL }, 281 { 'u', "username", "Set username for authentication", 282 "u", 1, "<username>" }, 283 { 'v', "password", "Set password for authentication", 284 "v", 1, "<password>" }, 285 { 'w', "download-dir", "Where to save downloaded data", 286 "w", 1, "<path>" }, 287 { 0, NULL, NULL, 288 NULL, 0, NULL } 58 { 'a', "allowed", "Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a", 1, "<list>" }, 59 { 'b', "blocklist", "Enable peer blocklists", "b", 0, NULL }, 60 { 'B', "no-blocklist", "Disable peer blocklists", "B", 0, NULL }, 61 { 'd', "dump-settings", "Dump the settings and exit", "d", 0, NULL }, 62 { 'f', "foreground", "Run in the foreground instead of daemonizing", "f", 0, NULL }, 63 { 'g', "config-dir", "Where to look for configuration files", "g", 1, "<path>" }, 64 { 'p', "port", "RPC port (Default: " TR_DEFAULT_RPC_PORT_STR ")", "p", 1, "<port>" }, 65 { 't', "auth", "Require authentication", "t", 0, NULL }, 66 { 'T', "no-auth", "Don't require authentication", "T", 0, NULL }, 67 { 'u', "username", "Set username for authentication", "u", 1, "<username>" }, 68 { 'v', "password", "Set password for authentication", "v", 1, "<password>" }, 69 { 'w', "download-dir", "Where to save downloaded data", "w", 1, "<path>" }, 70 { 'P', "peerport", "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", "P", 1, "<port>" }, 71 { 'm', "portmap", "Enable portmapping via NAT-PMP or UPnP", "m", 0, NULL }, 72 { 'M', "no-portmap", "Disable portmapping", "M", 0, NULL }, 73 { 'L', "peerlimit-global", "Maximum overall number of peers (Default: " TR_DEFAULT_PEER_LIMIT_GLOBAL_STR ")", "L", 1, "<limit>" }, 74 { 'l', "peerlimit-torrent", "Maximum number of peers per torrent (Default: " TR_DEFAULT_PEER_LIMIT_TORRENT_STR ")", "l", 1, "<limit>" }, 75 { 910, "encryption-required", "Encrypt all peer connections", "er", 0, NULL }, 76 { 911, "encryption-preferred", "Prefer encrypted peer connections", "ep", 0, NULL }, 77 { 912, "encryption-tolerated", "Prefer unencrypted peer connections", "et", 0, NULL }, 78 { 0, NULL, NULL, NULL, 0, NULL } 289 79 }; 290 80 … … 297 87 298 88 static void 299 readargs( int argc, 300 const char ** argv, 301 int * nofork, 302 const char ** configDir, 303 const char ** downloadDir, 304 int * rpcPort, 305 const char ** whitelist, 306 int * authRequired, 307 const char ** username, 308 const char ** password, 309 int * blocklistEnabled ) 310 { 311 int c; 89 gotsig( int sig UNUSED ) 90 { 91 closing = TRUE; 92 } 93 94 #if defined(WIN32) 95 #define USE_NO_DAEMON 96 #elif !defined(HAVE_DAEMON) || defined(__MIPSEL__) || defined(__UCLIBC__) 97 #define USE_TR_DAEMON 98 #else 99 #define USE_OS_DAEMON 100 #endif 101 102 static int 103 tr_daemon( int nochdir, int noclose ) 104 { 105 #if defined(USE_OS_DAEMON) 106 return daemon( nochdir, noclose ); 107 #elif defined(USE_TR_DAEMON) 108 pid_t pid = fork( ); 109 if( pid < 0 ) 110 return -1; 111 else if( pid > 0 ) 112 _exit( 0 ); 113 else { 114 pid = setsid( ); 115 if( pid < 0 ) 116 return -1; 117 118 pid = fork( ); 119 if( pid < 0 ) 120 return -1; 121 else if( pid > 0 ) 122 _exit( 0 ); 123 else { 124 125 if( !nochdir ) 126 if( chdir( "/" ) < 0 ) 127 return -1; 128 129 umask( (mode_t)0 ); 130 131 if( !noclose ) { 132 /* send stdin, stdout, and stderr to /dev/null */ 133 int i; 134 int fd = open( "/dev/null", O_RDWR, 0 ); 135 for( i=0; i<3; ++i ) { 136 if( close( i ) ) 137 return -1; 138 dup2( fd, i ); 139 } 140 close( fd ); 141 } 142 143 return 0; 144 } 145 } 146 #else /* USE_NO_DAEMON */ 147 return 0; 148 #endif 149 } 150 151 static const char* 152 getConfigDir( int argc, const char ** argv ) 153 { 154 int c; 155 const char * configDir = NULL; 312 156 const char * optarg; 313 314 while( ( c = tr_getopt( getUsage( ), argc, argv, options, &optarg ) ) ) 315 { 316 switch( c ) 317 { 318 case 'a': 319 *whitelist = optarg; break; 320 321 case 'b': 322 *blocklistEnabled = 1; break; 323 324 case 'B': 325 *blocklistEnabled = 0; break; 326 327 case 'f': 328 *nofork = 1; break; 329 330 case 'g': 331 *configDir = optarg; break; 332 333 case 'p': 334 *rpcPort = atoi( optarg ); break; 335 336 case 't': 337 *authRequired = TRUE; break; 338 339 case 'T': 340 *authRequired = FALSE; break; 341 342 case 'u': 343 *username = optarg; break; 344 345 case 'v': 346 *password = optarg; break; 347 348 case 'w': 349 *downloadDir = optarg; break; 350 351 default: 352 showUsage( ); break; 157 const int ind = tr_optind; 158 159 while(( c = tr_getopt( getUsage( ), argc, argv, options, &optarg ))) { 160 if( c == 'g' ) { 161 configDir = optarg; 162 break; 353 163 } 354 164 } 355 } 356 357 static void 358 gotsig( int sig UNUSED ) 359 { 360 closing = TRUE; 361 } 362 363 #if !defined( WIN32 ) 364 #if !defined( HAVE_DAEMON ) 365 static int 366 daemon( int nochdir, 367 int noclose ) 368 { 369 switch( fork( ) ) 370 { 371 case 0: 372 break; 373 374 case - 1: 375 tr_nerr( MY_NAME, "Error daemonizing (fork)! %d - %s", errno, 376 strerror( 377 errno ) ); 378 return -1; 379 380 default: 381 _exit( 0 ); 382 } 383 384 if( setsid( ) < 0 ) 385 { 386 tr_nerr( MY_NAME, "Error daemonizing (setsid)! %d - %s", errno, 387 strerror( 388 errno ) ); 389 return -1; 390 } 391 392 switch( fork( ) ) 393 { 394 case 0: 395 break; 396 397 case - 1: 398 tr_nerr( MY_NAME, "Error daemonizing (fork2)! %d - %s", errno, 399 strerror( 400 errno ) ); 401 return -1; 402 403 default: 404 _exit( 0 ); 405 } 406 407 if( !nochdir && 0 > chdir( "/" ) ) 408 { 409 tr_nerr( MY_NAME, "Error daemonizing (chdir)! %d - %s", errno, 410 strerror( 411 errno ) ); 412 return -1; 413 } 414 415 if( !noclose ) 416 { 417 int fd; 418 if( ( ( fd = open( "/dev/null", O_RDONLY ) ) ) != 0 ) 419 { 420 dup2( fd, 0 ); 421 close( fd ); 422 } 423 if( ( ( fd = open( "/dev/null", O_WRONLY ) ) ) != 1 ) 424 { 425 dup2( fd, 1 ); 426 close( fd ); 427 } 428 if( ( ( fd = open( "/dev/null", O_WRONLY ) ) ) != 2 ) 429 { 430 dup2( fd, 2 ); 431 close( fd ); 432 } 433 } 434 435 return 0; 436 } 437 #endif 438 #endif 165 166 tr_optind = ind; 167 168 if( configDir == NULL ) 169 configDir = tr_getDefaultConfigDir( MY_NAME ); 170 171 return configDir; 172 } 173 439 174 440 175 int … … 442 177 char ** argv ) 443 178 { 444 int nofork = 0; 445 int rpcPort = -1; 446 int authRequired = -1; 447 int blocklistEnabled = -1; 448 char * freeme = NULL; 179 int c; 180 int64_t i; 181 const char * optarg; 182 tr_benc settings; 183 tr_bool foreground = FALSE; 184 tr_bool dumpSettings = FALSE; 449 185 const char * configDir = NULL; 450 const char * downloadDir = NULL;451 const char * whitelist = NULL;452 const char * username = NULL;453 const char * password = NULL;454 186 455 187 signal( SIGINT, gotsig ); … … 461 193 #endif 462 194 463 readargs( argc, (const char**)argv, &nofork, &configDir, &downloadDir, 464 &rpcPort, &whitelist, &authRequired, &username, &password, 465 &blocklistEnabled ); 466 if( configDir == NULL ) 467 configDir = getenv( "TRANSMISSION_HOME" ); 468 if( configDir == NULL ) 469 configDir = freeme = tr_strdup_printf( "%s-daemon", 470 tr_getDefaultConfigDir( ) ); 471 myConfigFilename = tr_buildPath( configDir, CONFIG_FILE, NULL ); 472 473 #ifndef WIN32 474 if( !nofork ) 195 /* load settings from defaults + config file */ 196 tr_bencInitDict( &settings, 0 ); 197 configDir = getConfigDir( argc, (const char**)argv ); 198 tr_sessionLoadSettings( &settings, configDir, MY_NAME ); 199 tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_ENABLED, 1 ); 200 201 /* overwrite settings from the comamndline */ 202 tr_optind = 1; 203 while(( c = tr_getopt( getUsage(), argc, (const char**)argv, options, &optarg ))) { 204 switch( c ) { 205 case 'a': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_WHITELIST, optarg ); 206 tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, 1 ); 207 break; 208 case 'b': tr_bencDictAddInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, 1 ); 209 break; 210 case 'B': tr_bencDictAddInt( &settings, TR_PREFS_KEY_BLOCKLIST_ENABLED, 0 ); 211 break; 212 case 'd': dumpSettings = TRUE; 213 break; 214 case 'f': foreground = TRUE; 215 break; 216 case 'g': /* handled above */ 217 break; 218 case 'p': tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_PORT, atoi( optarg ) ); 219 break; 220 case 't': tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, 1 ); 221 break; 222 case 'T': tr_bencDictAddInt( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, 0 ); 223 break; 224 case 'u': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_USERNAME, optarg ); 225 break; 226 case 'v': tr_bencDictAddStr( &settings, TR_PREFS_KEY_RPC_PASSWORD, optarg ); 227 break; 228 case 'w': tr_bencDictAddStr( &settings, TR_PREFS_KEY_DOWNLOAD_DIR, optarg ); 229 break; 230 case 'P': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_PORT, atoi( optarg ) ); 231 break; 232 case 'm': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PORT_FORWARDING, 1 ); 233 break; 234 case 'M': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PORT_FORWARDING, 0 ); 235 break; 236 case 'L': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, atoi( optarg ) ); 237 break; 238 case 'l': tr_bencDictAddInt( &settings, TR_PREFS_KEY_PEER_LIMIT_TORRENT, atoi( optarg ) ); 239 break; 240 case 910: tr_bencDictAddInt( &settings, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_REQUIRED ); 241 break; 242 case 911: tr_bencDictAddInt( &settings, TR_PREFS_KEY_ENCRYPTION, TR_ENCRYPTION_PREFERRED ); 243 break; 244 case 912: tr_bencDictAddInt( &settings, TR_PREFS_KEY_ENCRYPTION, TR_CLEAR_PREFERRED ); 245 break; 246 default: showUsage( ); 247 break; 248 } 249 } 250 251 if( dumpSettings ) 475 252 { 476 if( 0 > daemon( 1, 0 ) ) 477 { 478 fprintf( stderr, "failed to daemonize: %s\n", strerror( errno ) ); 479 exit( 1 ); 480 } 481 } 482 #endif 483 484 session_init( configDir, downloadDir, 485 rpcPort, whitelist, authRequired, username, password, 486 blocklistEnabled ); 253 struct evbuffer * buf = tr_getBuffer( ); 254 255 tr_bencSaveAsJSON( &settings, buf ); 256 fprintf( stderr, "%s", (char*)EVBUFFER_DATA(buf) ); 257 258 tr_releaseBuffer( buf ); 259 return 0; 260 } 261 262 if( !foreground && tr_daemon( TRUE, FALSE ) < 0 ) 263 { 264 fprintf( stderr, "failed to daemonize: %s\n", strerror( errno ) ); 265 exit( 1 ); 266 } 267 268 /* start the session */ 269 mySession = tr_sessionInit( "daemon", configDir, FALSE, &settings ); 270 271 if( tr_bencDictFindInt( &settings, TR_PREFS_KEY_RPC_AUTH_REQUIRED, &i ) && i!=0 ) 272 tr_ninf( MY_NAME, "requiring authentication" ); 273 274 /* load the torrents */ 275 { 276 tr_ctor * ctor = tr_ctorNew( mySession ); 277 tr_torrent ** torrents = tr_sessionLoadTorrents( mySession, ctor, NULL ); 278 tr_free( torrents ); 279 tr_ctorFree( ctor ); 280 } 487 281 488 282 while( !closing ) 489 283 tr_wait( 1000 ); /* sleep one second */ 490 284 491 saveState( mySession );285 /* shutdown */ 492 286 printf( "Closing transmission session..." ); 287 tr_sessionSaveSettings( mySession, configDir, &settings ); 493 288 tr_sessionClose( mySession ); 494 289 printf( " done.\n" ); 495 290 496 tr_free( freeme );497 tr_ free( myConfigFilename);291 /* cleanup */ 292 tr_bencFree( &settings ); 498 293 return 0; 499 294 } 500 -
branches/1.5x/daemon/remote.c
r7201 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 16 16 #include <string.h> /* strcmp */ 17 17 18 #ifdef WIN32 19 #include <direct.h> /* getcwd */ 20 #else 21 #include <unistd.h> /* getcwd */ 22 #endif 23 18 24 #include <libevent/event.h> 19 25 #include <curl/curl.h> … … 29 35 #define MY_NAME "transmission-remote" 30 36 #define DEFAULT_HOST "localhost" 31 #define DEFAULT_PORT TR_DEFAULT_RPC_PORT37 #define DEFAULT_PORT atoi(TR_DEFAULT_RPC_PORT_STR) 32 38 33 39 enum { TAG_LIST, TAG_DETAILS, TAG_FILES, TAG_PEERS }; … … 57 63 { 'b', "debug", "Print debugging information", 58 64 "b", 0, NULL }, 59 { 'd', "downlimit", "Set the maximum download speed in KB/s",65 { 'd', "downlimit", "Set the maximum global download speed in KB/s", 60 66 "d", 1, "<speed>" }, 61 { 'D', "no-downlimit", "Don't limit the download speed",67 { 'D', "no-downlimit", "Don't limit the global download speed", 62 68 "D", 0, NULL }, 63 69 { 910, "encryption-required", "Encrypt all peer connections", … … 84 90 "n", 1, "<username:password>" }, 85 91 { 'p', "port", 86 "Port for incoming peers (Default: " TR_DEFAULT_P ORT_STR ")",92 "Port for incoming peers (Default: " TR_DEFAULT_PEER_PORT_STR ")", 87 93 "p", 1, "<port>" }, 88 94 { 900, "priority-high", "Set the files' priorities as high", … … 94 100 { 'r', "remove", "Remove the current torrent(s)", 95 101 "r", 0, NULL }, 102 { 'R', "remove-and-delete", "Remove the current torrent(s) and delete local data", 103 NULL, 0, NULL }, 96 104 { 's', "start", "Start the current torrent(s)", 97 105 "s", 0, NULL }, … … 100 108 { 't', "torrent", "Set the current torrent(s)", 101 109 "t", 1, "<torrent>" }, 102 { 'u', "uplimit", "Set the maximum upload speed in KB/s",110 { 'u', "uplimit", "Set the maximum global upload speed in KB/s", 103 111 "u", 1, "<speed>" }, 104 { 'U', "no-uplimit", "Don't limit the upload speed",112 { 'U', "no-uplimit", "Don't limit the global upload speed", 105 113 "U", 0, NULL }, 106 114 { 'v', "verify", "Verify the current torrent(s)", … … 143 151 static int debug = 0; 144 152 static char * auth = NULL; 153 154 static char* 155 tr_getcwd( void ) 156 { 157 char buf[2048]; 158 *buf = '\0'; 159 #ifdef WIN32 160 _getcwd( buf, sizeof( buf ) ); 161 #else 162 getcwd( buf, sizeof( buf ) ); 163 #endif 164 return tr_strdup( buf ); 165 } 145 166 146 167 static char* … … 396 417 break; 397 418 419 case 'R': 420 tr_bencDictAddStr( &top, "method", "torrent-remove" ); 421 addIdArg( args, id ); 422 tr_bencDictAddInt( args, "delete-local-data", 1 ); 423 break; 424 398 425 case 's': 399 426 tr_bencDictAddStr( &top, "method", "torrent-start" ); … … 498 525 499 526 if( addArg ) 500 reqs[reqCount++] = tr_bencSaveAsJSON( &top, NULL ); 527 { 528 struct evbuffer * buf = tr_getBuffer( ); 529 reqs[reqCount++] = tr_strdup( tr_bencSaveAsJSON( &top, buf ) ); 530 tr_releaseBuffer( buf ); 531 } 532 501 533 tr_bencFree( &top ); 502 534 } … … 688 720 } 689 721 722 static const char* 723 getTrackerDateStr( const time_t t, tr_bool isStopped ) 724 { 725 const char * str; 726 switch( t ) { 727 case 0: str = isStopped ? "None (Stopped)\n" : "None\n"; break; 728 case 1: str = "In Progress\n"; break; 729 default: str = ctime( &t ); break; 730 } 731 return str; 732 } 733 690 734 static void 691 735 printDetails( tr_benc * top ) … … 706 750 char buf2[512]; 707 751 int64_t i, j, k; 752 tr_bool isStopped; 753 754 isStopped = tr_bencDictFindInt( t, "status", &i ) && (i==TR_STATUS_STOPPED); 708 755 709 756 printf( "NAME\n" ); … … 819 866 820 867 printf( "TRACKER\n" ); 821 if( tr_bencDictFindInt( t, "lastAnnounceTime", &i ) && i ) 822 { 823 const time_t tt = i; 824 printf( " Latest announce: %s", ctime( &tt ) ); 825 } 868 if( tr_bencDictFindInt( t, "lastAnnounceTime", &i ) ) 869 printf( " Latest announce: %s", getTrackerDateStr( (time_t)i, isStopped ) ); 826 870 if( tr_bencDictFindStr( t, "announceURL", &str ) ) 827 871 printf( " Announce URL: %s\n", str ); 828 if( tr_bencDictFindStr( t, "announceResponse", 829 &str ) && str && *str ) 872 if( tr_bencDictFindStr( t, "announceResponse", &str ) && str && *str ) 830 873 printf( " Announce response: %s\n", str ); 831 if( tr_bencDictFindInt( t, "nextAnnounceTime", &i ) && i ) 832 { 833 const time_t tt = i; 834 printf( " Next announce: %s", ctime( &tt ) ); 835 } 836 if( tr_bencDictFindInt( t, "lastScrapeTime", &i ) && i ) 837 { 838 const time_t tt = i; 839 printf( " Latest scrape: %s", ctime( &tt ) ); 840 } 874 if( tr_bencDictFindInt( t, "nextAnnounceTime", &i ) ) 875 printf( " Next announce: %s", getTrackerDateStr( (time_t)i, isStopped ) ); 876 if( tr_bencDictFindInt( t, "lastScrapeTime", &i ) ) 877 printf( " Latest scrape: %s", getTrackerDateStr( (time_t)i, isStopped ) ); 841 878 if( tr_bencDictFindStr( t, "scrapeResponse", &str ) ) 842 879 printf( " Scrape response: %s\n", str ); 843 if( tr_bencDictFindInt( t, "nextScrapeTime", &i ) && i ) 844 { 845 const time_t tt = i; 846 printf( " Next scrape: %s", ctime( &tt ) ); 847 } 848 if( tr_bencDictFindInt( t, "seeders", &i ) 849 && tr_bencDictFindInt( t, "leechers", &j ) ) 850 printf( 851 " Tracker knows of %" PRId64 " seeders and %" PRId64 852 " leechers\n", i, j ); 880 if( tr_bencDictFindInt( t, "nextScrapeTime", &i ) ) 881 printf( " Next scrape: %s", getTrackerDateStr( (time_t)i, isStopped ) ); 882 if( tr_bencDictFindInt( t, "seeders", &i ) && tr_bencDictFindInt( t, "leechers", &j ) ) 883 printf( " Tracker knows of %" PRId64 " seeders and %" PRId64 " leechers\n", i, j ); 853 884 if( tr_bencDictFindInt( t, "timesCompleted", &i ) ) 854 printf( 855 " Tracker has seen %" PRId64 856 " clients complete this torrent\n", i ); 885 printf( " Tracker has seen %" PRId64 " clients complete this torrent\n", i ); 857 886 printf( "\n" ); 858 887 … … 1056 1085 1057 1086 if( debug ) 1058 fprintf( stderr, "got response:\n--------\n%*.*s\n--------\n", 1087 fprintf( stderr, "got response:\n--------\n%*.*s\n--------\n", 1059 1088 (int)len, (int)len, (const char*) response ); 1060 1089 … … 1125 1154 curl_easy_setopt( curl, CURLOPT_POSTFIELDS, reqs[i] ); 1126 1155 if( debug ) 1127 fprintf( stderr, "posting:\n--------\n%s\n--------\n", reqs[i] ); 1156 fprintf( stderr, "posting:\n--------\n%s\n--------\n", reqs[i] ); 1128 1157 if( ( res = curl_easy_perform( curl ) ) ) 1129 1158 tr_nerr( MY_NAME, "(%s:%d) %s", host, port, -
branches/1.5x/daemon/transmission-daemon.1
r7481 r7664 19 19 .Op Fl u Ar username 20 20 .Op Fl v Ar password 21 .Op Fl P Ar port 22 .Op Fl m | M 23 .Op Fl l Ar limit 24 .Op Fl L Ar limit 25 .Op Fl er | ep | et 21 26 .Op Fl w Ar download-dir 22 27 .Ek … … 50 55 Where to look for .torrent and config files on startup. 51 56 57 .It Fl er Fl -encryption-required 58 Encrypt all peer connections. 59 .It Fl ep Fl -encryption-preferred 60 Prefer encrypted peer connections. 61 .It Fl et Fl -encryption-tolerated 62 Prefer unencrypted peer connections. 63 52 64 .It Fl h Fl -help 53 65 Print command-line option descriptions. 54 66 67 .It Fl L Fl -peerlimit-global Ar limit 68 Overall peer limit. Useful on embedded systems where the default might be unsuitable. Default: 240 69 .It Fl l Fl -peerlimit-torrent Ar limit 70 Peer limit per torrent. Useful on embedded systems where the default might be unsuitable. Default: 60 71 72 .It Fl m Fl -portmap 73 Enable portmapping via NAT-PMP or UPnP 74 .It Fl M Fl -no-portmap 75 Disable portmapping 76 55 77 .It Fl p Fl -port Ar port 56 78 Port to open and listen for RPC requests on. Default: 9091 79 80 .It Fl P, -peerport Ar port 81 Port to listen for incoming peers on. Default: 51413 57 82 58 83 .It Fl t Fl -auth -
branches/1.5x/daemon/transmission-remote.1
r7038 r7664 29 29 .Op Fl pn Ar files 30 30 .Op Fl r 31 .Op Fl R 31 32 .Op Fl s | S 32 33 .Op Fl t Ar all | Ar id | Ar hash … … 60 61 61 62 .It Fl d Fl -downlimit Ar limit 62 Limit the download speed to63 Limit the global download speed to 63 64 .Ar limit 64 65 kilobytes per second. 65 66 66 67 .It Fl D Fl -no-downlimit 67 Remove the download limit.68 Remove the global download limit. 68 69 69 70 .It Fl er Fl -encryption-required … … 135 136 Remove the current torrent(s). This does not delete the downloaded data. 136 137 138 .It Fl -remove-and-delete 139 Remove the current torrent(s) and delete their downloaded data. 140 137 141 .It Fl s Fl -start 138 142 Start the current torrent(s) … … 152 156 153 157 .It Fl u Fl -uplimit Ar limit 154 Limit the upload speed to158 Limit the global upload speed to 155 159 .Ar limit 156 160 kilobytes per second. 157 161 .It Fl U Fl -no-uplimit 158 Remove the upload limit.162 Remove the global upload limit. 159 163 160 164 .It Fl v Fl -verify -
branches/1.5x/gtk/actions.c
r6949 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 109 109 static GtkActionEntry entries[] = 110 110 { 111 { "torrent-menu", NULL, N_( 112 "_Torrent" ), 113 NULL, NULL, NULL }, 114 { "view-menu", NULL, N_( "_View" ), 115 NULL, NULL, NULL }, 116 { "sort-menu", NULL, N_( 117 "_Sort Torrents By" ), NULL, NULL, 118 NULL }, 119 { "edit-menu", NULL, N_( "_Edit" ), 120 NULL, NULL, NULL }, 121 { "help-menu", NULL, N_( "_Help" ), 122 NULL, NULL, NULL }, 123 { "add-torrent-toolbar", GTK_STOCK_ADD, NULL, 124 NULL, N_( "Add a torrent" ), G_CALLBACK( action_cb ) }, 125 { "add-torrent-menu", GTK_STOCK_ADD, N_( "_Add..." ), 126 "<control>D", N_( "Add a torrent" ), G_CALLBACK( action_cb ) }, 127 { "start-torrent", GTK_STOCK_MEDIA_PLAY, 128 N_( "_Start" ), "<control>S", N_( "Start torrent" ), G_CALLBACK( 129 action_cb ) }, 130 { "show-stats", NULL, N_( "_Statistics" ), 131 NULL, NULL, G_CALLBACK( action_cb ) }, 132 { "verify-torrent", NULL, 133 N_( "_Verify Local Data" ), NULL, NULL, G_CALLBACK( action_cb ) }, 134 { "pause-torrent", GTK_STOCK_MEDIA_PAUSE, 135 N_( "_Pause" ), "<control>P", N_( "Pause torrent" ), G_CALLBACK( 136 action_cb ) }, 137 { "remove-torrent", GTK_STOCK_REMOVE, NULL, 138 "Delete", N_( "Remove torrent" ), G_CALLBACK( action_cb ) }, 139 { "delete-torrent", GTK_STOCK_DELETE, N_( 140 "_Delete Files and Remove" ), "<shift>Delete", NULL, 141 G_CALLBACK( action_cb ) }, 142 { "new-torrent", GTK_STOCK_NEW, N_( "_New..." ), 143 NULL, 144 N_( "Create a torrent" ), 145 G_CALLBACK( action_cb ) }, 146 { "quit", GTK_STOCK_QUIT, N_( "_Quit" ), 147 NULL, NULL, G_CALLBACK( action_cb ) }, 148 { "select-all", GTK_STOCK_SELECT_ALL, 149 N_( "Select _All" ), "<control>A", NULL, G_CALLBACK( action_cb ) }, 150 { "deselect-all", NULL, 151 N_( "Dese_lect All" ), "<shift><control>A", NULL, G_CALLBACK( 152 action_cb ) }, 153 { "edit-preferences", GTK_STOCK_PREFERENCES, NULL, 154 NULL, NULL, G_CALLBACK( action_cb ) }, 155 { "show-torrent-details", GTK_STOCK_INFO, 156 N_( "_Details" ), "<alt>Return", N_( "Torrent details" ), G_CALLBACK( 157 action_cb ) }, 158 { "open-torrent-folder", GTK_STOCK_OPEN, 159 N_( "_Open Folder" ), NULL, NULL, G_CALLBACK( action_cb ) }, 160 { "show-about-dialog", GTK_STOCK_ABOUT, NULL, 161 NULL, NULL, G_CALLBACK( action_cb ) }, 162 { "help", GTK_STOCK_HELP, N_( "_Contents" ), 163 "F1", NULL, G_CALLBACK( action_cb ) }, 164 { "update-tracker", GTK_STOCK_NETWORK, 165 N_( "Ask Tracker for _More Peers" ), NULL, NULL, G_CALLBACK( 166 action_cb ) }, 167 { "present-main-window", NULL, NULL, 168 NULL, NULL, G_CALLBACK( action_cb ) }, 111 { "torrent-menu", NULL, N_( "_Torrent" ), NULL, NULL, NULL }, 112 { "view-menu", NULL, N_( "_View" ), NULL, NULL, NULL }, 113 { "sort-menu", NULL, N_( "_Sort Torrents By" ), NULL, NULL, NULL }, 114 { "edit-menu", NULL, N_( "_Edit" ), NULL, NULL, NULL }, 115 { "help-menu", NULL, N_( "_Help" ), NULL, NULL, NULL }, 116 { "add-torrent-toolbar", GTK_STOCK_ADD, NULL, NULL, N_( "Add a torrent" ), G_CALLBACK( action_cb ) }, 117 { "add-torrent-menu", GTK_STOCK_ADD, N_( "_Add..." ), "<control>D", N_( "Add a torrent" ), G_CALLBACK( action_cb ) }, 118 { "start-torrent", GTK_STOCK_MEDIA_PLAY, N_( "_Start" ), "<control>S", N_( "Start torrent" ), G_CALLBACK( action_cb ) }, 119 { "show-stats", NULL, N_( "_Statistics" ), NULL, NULL, G_CALLBACK( action_cb ) }, 120 { "verify-torrent", NULL, N_( "_Verify Local Data" ), NULL, NULL, G_CALLBACK( action_cb ) }, 121 { "pause-torrent", GTK_STOCK_MEDIA_PAUSE, N_( "_Pause" ), "<control>P", N_( "Pause torrent" ), G_CALLBACK( action_cb ) }, 122 { "pause-all-torrents", GTK_STOCK_MEDIA_PAUSE, N_( "_Pause All" ), NULL, N_( "Pause all torrents" ), G_CALLBACK( action_cb ) }, 123 { "remove-torrent", GTK_STOCK_REMOVE, NULL, "Delete", N_( "Remove torrent" ), G_CALLBACK( action_cb ) }, 124 { "delete-torrent", GTK_STOCK_DELETE, N_( "_Delete Files and Remove" ), "<shift>Delete", NULL, G_CALLBACK( action_cb ) }, 125 { "new-torrent", GTK_STOCK_NEW, N_( "_New..." ), NULL, N_( "Create a torrent" ), G_CALLBACK( action_cb ) }, 126 { "quit", GTK_STOCK_QUIT, N_( "_Quit" ), NULL, NULL, G_CALLBACK( action_cb ) }, 127 { "select-all", GTK_STOCK_SELECT_ALL, N_( "Select _All" ), "<control>A", NULL, G_CALLBACK( action_cb ) }, 128 { "deselect-all", NULL, N_( "Dese_lect All" ), "<shift><control>A", NULL, G_CALLBACK( action_cb ) }, 129 { "edit-preferences", GTK_STOCK_PREFERENCES, NULL, NULL, NULL, G_CALLBACK( action_cb ) }, 130 { "show-torrent-properties", GTK_STOCK_PROPERTIES, NULL, "<alt>Return", N_( "Torrent properties" ), G_CALLBACK( action_cb ) }, 131 { "open-torrent-folder", GTK_STOCK_OPEN, N_( "_Open Folder" ), NULL, NULL, G_CALLBACK( action_cb ) }, 132 { "show-about-dialog", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK( action_cb ) }, 133 { "help", GTK_STOCK_HELP, N_( "_Contents" ), "F1", NULL, G_CALLBACK( action_cb ) }, 134 { "update-tracker", GTK_STOCK_NETWORK, N_( "Ask Tracker for _More Peers" ), NULL, NULL, G_CALLBACK( action_cb ) }, 135 { "present-main-window", NULL, NULL, NULL, NULL, G_CALLBACK( action_cb ) }, 169 136 }; 170 137 -
branches/1.5x/gtk/actions.h
r6795 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/add-dialog.c
r6998 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 43 43 44 44 static void 45 save_recent_destination( const char * dir )45 save_recent_destination( TrCore * core, const char * dir ) 46 46 { 47 47 int i; … … 71 71 pref_string_set( key, l->data ); 72 72 } 73 pref_save( );73 pref_save( tr_core_session( core ) ); 74 74 75 75 /* cleanup */ … … 117 117 { 118 118 if( response != GTK_RESPONSE_ACCEPT ) 119 { 119 120 removeOldTorrent( data ); 121 } 120 122 else 121 123 { 122 if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data-> 123 run_check ) ) ) 124 if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->run_check ) ) ) 124 125 tr_torrentStart( tr_torrent_handle( data->gtor ) ); 126 125 127 tr_core_add_torrent( data->core, data->gtor ); 126 if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data-> 127 trash_check ) ) ) 128 129 if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->trash_check ) ) ) 130 128 131 tr_file_trash_or_unlink( data->filename ); 129 save_recent_destination( data-> downloadDir );132 save_recent_destination( data->core, data->downloadDir ); 130 133 } 131 134 } -
branches/1.5x/gtk/add-dialog.h
r6998 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/conf.c
r6862 r7664 42 42 #include "util.h" 43 43 44 #define MY_NAME "transmission" 45 44 46 static char * gl_confdir = NULL; 45 47 static char * gl_lockpath = NULL; … … 47 49 /* errstr may be NULL, this might be called before GTK is initialized */ 48 50 gboolean 49 cf_init( const char *dir,50 char **errstr )51 cf_init( const char * configDir, 52 char ** errstr ) 51 53 { 52 54 if( errstr != NULL ) 53 55 *errstr = NULL; 54 56 55 gl_confdir = g_strdup( dir );57 gl_confdir = g_strdup( configDir ); 56 58 57 59 if( mkdir_p( gl_confdir, 0755 ) ) … … 152 154 getPrefs( void ) 153 155 { 154 static tr_benc dict;156 static tr_benc settings; 155 157 static gboolean loaded = FALSE; 156 158 157 159 if( !loaded ) 158 160 { 159 char * filename = getPrefsFilename( ); 160 if( tr_bencLoadJSONFile( filename, &dict ) ) 161 tr_bencInitDict( &dict, 100 ); 162 g_free( filename ); 161 tr_bencInitDict( &settings, 0 ); 162 tr_sessionLoadSettings( &settings, gl_confdir, MY_NAME ); 163 163 loaded = TRUE; 164 164 } 165 165 166 return &dict; 167 } 168 169 /*** 170 **** 171 ***/ 166 return &settings; 167 } 168 169 /*** 170 **** 171 ***/ 172 173 tr_benc* 174 pref_get_all( void ) 175 { 176 return getPrefs( ); 177 } 172 178 173 179 int64_t … … 184 190 int64_t value ) 185 191 { 186 tr_benc * d = getPrefs( ); 187 188 tr_bencDictRemove( d, key ); 189 tr_bencDictAddInt( d, key, value ); 192 tr_bencDictAddInt( getPrefs( ), key, value ); 190 193 } 191 194 … … 259 262 const char * value ) 260 263 { 261 tr_benc * d = getPrefs( ); 262 263 tr_bencDictRemove( d, key ); 264 tr_bencDictAddStr( d, key, value ); 264 tr_bencDictAddStr( getPrefs( ), key, value ); 265 265 } 266 266 … … 278 278 279 279 void 280 pref_save( void ) 281 { 282 char * filename = getPrefsFilename( ); 283 char * path = g_path_get_dirname( filename ); 284 285 mkdir_p( path, 0755 ); 286 tr_bencSaveJSONFile( filename, getPrefs( ) ); 287 288 g_free( path ); 289 g_free( filename ); 280 pref_save( tr_session * session ) 281 { 282 tr_sessionSaveSettings( session, gl_confdir, getPrefs( ) ); 290 283 } 291 284 … … 317 310 { 318 311 assert( gl_confdir != NULL ); 319 return g_build_filename( 320 312 313 return g_build_filename( g_get_home_dir( ), ".transmission", "gtk", "prefs", NULL ); 321 314 } 322 315 … … 325 318 { 326 319 assert( gl_confdir != NULL ); 327 return g_build_filename( 328 320 321 return g_build_filename( g_get_home_dir( ), ".transmission", "gtk", "prefs.ini", NULL ); 329 322 } 330 323 … … 332 325 getCompat121PrefsFilename( void ) 333 326 { 334 return g_build_filename( 335 g_get_user_config_dir( ), "transmission", "gtk", "prefs.ini", 336 NULL ); 327 return g_build_filename( g_get_user_config_dir( ), "transmission", "gtk", "prefs.ini", NULL ); 337 328 } 338 329 … … 341 332 const char* newfile ) 342 333 { 343 static struct pref_entry 344 { 334 static struct pref_entry { 345 335 const char* oldkey; 346 336 const char* newkey; -
branches/1.5x/gtk/conf.h
r6795 r7664 23 23 *****************************************************************************/ 24 24 25 struct tr_benc; 26 25 27 /** 26 28 *** … … 30 32 #define TG_CONF_H 31 33 32 int64_t pref_int_get( const char * key ); 34 int64_t pref_int_get ( const char * key ); 35 void pref_int_set ( const char * key, int64_t value ); 36 void pref_int_set_default ( const char * key, int64_t value ); 33 37 34 void pref_int_set( const char * key, 35 int64_t value ); 38 gboolean pref_flag_get ( const char * key ); 39 void pref_flag_set ( const char * key, gboolean value ); 40 void pref_flag_set_default ( const char * key, gboolean value ); 36 41 37 void pref_int_set_default( const char * key, 38 int64_t value ); 42 const char* pref_string_get ( const char * key ); 43 void pref_string_set ( const char * key, const char * value ); 44 void pref_string_set_default( const char * key, const char * value ); 39 45 40 gboolean pref_flag_get( const char * key ); 41 42 void pref_flag_set( const char * key, 43 gboolean value ); 44 45 void pref_flag_set_default( const char * key, 46 gboolean value ); 47 48 const char* pref_string_get( const char * key ); 49 50 void pref_string_set( const char * key, 51 const char * value ); 52 53 void pref_string_set_default( const char * key, 54 const char * value ); 55 56 void pref_save( void ); 46 void pref_save ( tr_session * ); 47 struct tr_benc* pref_get_all ( void ); 57 48 58 49 /** -
branches/1.5x/gtk/details.c
r7463 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 1479 1479 GtkWidget * d, *n, *w; 1480 1480 tr_torrent * tor = tr_torrent_handle ( gtor ); 1481 char sizeStr[64];1482 1481 char title[512]; 1483 1482 const tr_info * info = tr_torrent_info ( gtor ); 1484 1483 1485 1484 /* create the dialog */ 1486 tr_strlsize( sizeStr, info->totalSize, sizeof( sizeStr ) ); 1487 /* %1$s is torrent name 1488 %2$s its file size */ 1489 g_snprintf( title, sizeof( title ), _( 1490 "Details for %1$s (%2$s)" ), info->name, sizeStr ); 1485 g_snprintf( title, sizeof( title ), _( "%s Properties" ), info->name ); 1491 1486 d = gtk_dialog_new_with_buttons ( title, parent, 0, 1492 1487 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, -
branches/1.5x/gtk/details.h
r6998 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/dialogs.c
r6935 r7664 183 183 } 184 184 185 struct count_data 186 { 187 int incomplete; 188 int connected; 189 }; 190 185 191 static void 186 countBusyTorrents( gpointer gtor, 187 gpointer busyCount ) 192 countBusyTorrents( gpointer gtor, gpointer gdata ) 188 193 { 189 194 const tr_stat * stat = tr_torrent_stat( gtor ); 190 191 if( stat->leftUntilDone || stat->peersConnected ) 192 ++( *(int*)busyCount ); 195 struct count_data * data = gdata; 196 197 if( stat->leftUntilDone ) ++data->incomplete; 198 if( stat->peersConnected ) ++data->connected; 193 199 } 194 200 … … 200 206 { 201 207 GtkWidget * d; 208 const int count = g_slist_length( torrents ); 209 struct count_data counts; 210 const char * primary_text; 211 GString * secondary_text; 202 212 struct DeleteData * dd; 203 int busyCount;204 const int count = g_slist_length( torrents );205 const char * primary_text;206 const char * secondary_text;207 213 208 214 if( !count ) … … 214 220 dd->delete_files = delete_files; 215 221 216 busyCount = 0; 217 g_slist_foreach( torrents, countBusyTorrents, &busyCount ); 218 219 if( !busyCount && !delete_files ) /* don't prompt boring torrents */ 222 counts.incomplete = 0; 223 counts.connected = 0; 224 g_slist_foreach( torrents, countBusyTorrents, &counts ); 225 226 if( !counts.incomplete && !counts.connected && !delete_files ) /* don't prompt boring torrents */ 220 227 { 221 228 removeTorrents( dd ); … … 225 232 226 233 if( !delete_files ) 227 primary_text = ngettext( "Remove torrent?", "Remove torrents?", 234 { 235 primary_text = ngettext( "Remove torrent?", 236 "Remove torrents?", 228 237 count ); 238 } 229 239 else 240 { 230 241 primary_text = ngettext( "Delete this torrent's downloaded files?", 231 242 "Delete these torrents' downloaded files?", 232 243 count ); 233 234 if( busyCount > 1 ) 235 secondary_text = _( 236 "Some of these torrents are incomplete or connected to peers." ); 237 else if( busyCount == 0 ) 238 secondary_text = NULL; 244 } 245 246 secondary_text = g_string_new( NULL ); 247 248 if( !counts.incomplete && !counts.connected ) 249 { 250 /* boring -- no secondary text needed */ 251 } 252 else if( count == counts.incomplete ) 253 { 254 g_string_assign( secondary_text, ngettext( "This torrent has not finished downloading.", 255 "These torrents have not finished downloading.", 256 count ) ); 257 } 258 else if( count == counts.connected ) 259 { 260 g_string_assign( secondary_text, ngettext( "This torrent is connected to peers.", 261 "These torrents are connected to peers.", 262 count ) ); 263 } 239 264 else 240 secondary_text = ngettext( 241 "This torrent is incomplete or connected to peers.", 242 "One of these torrents is incomplete or connected to peers.", 243 count ); 265 { 266 if( counts.connected ) 267 g_string_append( secondary_text, ngettext( "One of these torrents is connected to peers.", 268 "Some of these torrents are connected to peers.", 269 counts.connected ) ); 270 if( counts.connected && counts.incomplete ) 271 g_string_append( secondary_text, "\n" ); 272 273 if( counts.incomplete ) 274 g_string_assign( secondary_text, ngettext( "One of these torrents has not finished downloading.", 275 "Some of these torrents have not finished downloading.", 276 counts.incomplete ) ); 277 } 244 278 245 279 d = gtk_message_dialog_new_with_markup( parent, … … 249 283 "<big><b>%s</b></big>", 250 284 primary_text ); 251 if( secondary_text )285 if( secondary_text->len ) 252 286 gtk_message_dialog_format_secondary_markup( GTK_MESSAGE_DIALOG( d ), 253 "%s", secondary_text );287 "%s", secondary_text->str ); 254 288 gtk_dialog_add_buttons( GTK_DIALOG( d ), 255 289 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, … … 265 299 g_signal_connect( d, "response", G_CALLBACK( removeResponse ), dd ); 266 300 gtk_widget_show_all( d ); 267 } 268 301 302 g_string_free( secondary_text, TRUE ); 303 } -
branches/1.5x/gtk/file-list.c
r7463 r7664 661 661 &path, &column, &cell_x, &cell_y ) ) 662 662 { 663 const char * column_title = gtk_tree_view_column_get_title( 664 column ); 665 const gboolean downloadColumn = 666 !strcmp( column_title, Q_( "filedetails|Download" ) ); 667 const gboolean priorityColumn = 668 !strcmp( column_title, _( "Priority" ) ); 663 const char * column_title = gtk_tree_view_column_get_title( column ); 664 const gboolean downloadColumn = !strcmp( column_title, _( "Download" ) ); 665 const gboolean priorityColumn = !strcmp( column_title, _( "Priority" ) ); 669 666 if( downloadColumn || priorityColumn ) 670 667 { … … 794 791 col = GTK_TREE_VIEW_COLUMN ( g_object_new ( GTK_TYPE_TREE_VIEW_COLUMN, 795 792 "expand", TRUE, 796 /* Translators: this is a column 797 header in Files tab, Details 798 dialog; 799 Don't include the prefix 800 "filedetails|" in the 801 translation. */ 802 "title", Q_( "filedetails|File" ), 793 "title", _( "File" ), 803 794 NULL ) ); 804 795 rend = gtk_cell_renderer_pixbuf_new( ); … … 809 800 g_object_set( rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL ); 810 801 gtk_tree_view_column_pack_start( col, rend, TRUE ); 811 gtk_tree_view_column_set_cell_data_func( col, rend, renderFilename, 812 NULL, 813 NULL ); 802 gtk_tree_view_column_set_cell_data_func( col, rend, renderFilename, NULL, NULL ); 814 803 gtk_tree_view_column_set_resizable( col, TRUE ); 815 804 gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col ); 816 805 817 818 806 rend = gtk_cell_renderer_progress_new( ); 819 /* Translators: this is a column header in Files tab, Details dialog; 820 Don't include the prefix "filedetails|" in the translation. */ 821 col = gtk_tree_view_column_new_with_attributes( Q_( "filedetails|Progress" ), rend, NULL ); 807 col = gtk_tree_view_column_new_with_attributes( _( "Progress" ), rend, NULL ); 822 808 gtk_tree_view_column_set_cell_data_func( col, rend, renderProgress, NULL, NULL ); 823 809 gtk_tree_view_column_set_resizable( col, FALSE ); … … 826 812 /* add "enabled" column */ 827 813 rend = gtk_cell_renderer_toggle_new( ); 828 /* Translators: this is a column header in Files tab, Details dialog; 829 Don't include the prefix "filedetails|" in the translation. 830 The items for this column are checkboxes (yes/no) */ 831 col = gtk_tree_view_column_new_with_attributes( Q_( "filedetails|Download" ), rend, NULL ); 814 col = gtk_tree_view_column_new_with_attributes( _( "Download" ), rend, NULL ); 832 815 gtk_tree_view_column_set_cell_data_func( col, rend, renderDownload, NULL, NULL ); 833 816 gtk_tree_view_column_set_resizable( col, FALSE ); -
branches/1.5x/gtk/hig.c
r6795 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/hig.h
r6998 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/main.c
r7463 r7664 43 43 44 44 #include <libtransmission/transmission.h> 45 #include <libtransmission/rpcimpl.h> 45 46 #include <libtransmission/utils.h> 46 47 #include <libtransmission/version.h> … … 67 68 #include <libtransmission/transmission.h> 68 69 #include <libtransmission/version.h> 70 71 #define MY_NAME "transmission" 69 72 70 73 /* interval in milliseconds to update the torrent list display */ … … 109 112 struct cbdata 110 113 { 111 gboolean minimized;112 gboolean closing;114 unsigned int isIconified : 1; 115 unsigned int isClosing : 1; 113 116 guint timer; 114 guint idle_hide_mainwindow_tag;115 117 gpointer icon; 116 118 GtkWindow * wind; … … 122 124 GHashTable * tor2details; 123 125 GHashTable * details2tor; 126 GtkTreeSelection * sel; 124 127 }; 125 128 … … 199 202 { 200 203 tr_torrent * tor; 201 202 204 gtk_tree_model_get( model, iter, MC_TORRENT_RAW, &tor, -1 ); 203 205 *(int*)accumulated_status |= tr_torrentCanManualUpdate( tor ); … … 205 207 206 208 static void 207 refreshTorrentActions( GtkTreeSelection * s)209 refreshTorrentActions( struct cbdata * data ) 208 210 { 209 211 int canUpdate; 210 212 struct counts_data counts; 213 GtkTreeSelection * s = data->sel; 211 214 212 215 counts.activeCount = 0; 213 216 counts.inactiveCount = 0; 214 217 counts.totalCount = 0; 215 gtk_tree_selection_selected_foreach( s, accumulateStatusForeach, 216 &counts ); 218 gtk_tree_selection_selected_foreach( s, accumulateStatusForeach, &counts ); 217 219 action_sensitize( "pause-torrent", counts.activeCount != 0 ); 218 220 action_sensitize( "start-torrent", counts.inactiveCount != 0 ); … … 221 223 action_sensitize( "verify-torrent", counts.totalCount != 0 ); 222 224 action_sensitize( "open-torrent-folder", counts.totalCount == 1 ); 223 action_sensitize( "show-torrent- details", counts.totalCount == 1 );225 action_sensitize( "show-torrent-properties", counts.totalCount == 1 ); 224 226 225 227 canUpdate = 0; 226 gtk_tree_selection_selected_foreach( s, accumulateCanUpdateForeach, 227 &canUpdate ); 228 gtk_tree_selection_selected_foreach( s, accumulateCanUpdateForeach, &canUpdate ); 228 229 action_sensitize( "update-tracker", canUpdate != 0 ); 229 230 … … 231 232 GtkTreeView * view = gtk_tree_selection_get_tree_view( s ); 232 233 GtkTreeModel * model = gtk_tree_view_get_model( view ); 233 const int torrentCount = gtk_tree_model_iter_n_children( model, 234 NULL ) 235 != 0; 234 const int torrentCount = gtk_tree_model_iter_n_children( model, NULL ) != 0; 236 235 action_sensitize( "select-all", torrentCount != 0 ); 237 236 action_sensitize( "deselect-all", torrentCount != 0 ); 238 237 } 239 } 240 241 static void 242 selectionChangedCB( GtkTreeSelection * s, 243 gpointer unused UNUSED ) 244 { 245 refreshTorrentActions( s ); 238 239 { 240 tr_torrent * tor = NULL; 241 tr_session * session = tr_core_session( data->core ); 242 int activeCount = 0; 243 while(( tor = tr_torrentNext( session, tor ))) 244 if( TR_STATUS_IS_ACTIVE( tr_torrentGetActivity( tor ))) 245 ++activeCount; 246 action_sensitize( "pause-all-torrents", activeCount != 0 ); 247 } 248 } 249 250 static void 251 selectionChangedCB( GtkTreeSelection * s UNUSED, gpointer data ) 252 { 253 refreshTorrentActions( data ); 246 254 } 247 255 … … 264 272 pref_int_set( PREF_KEY_MAIN_WINDOW_WIDTH, w ); 265 273 pref_int_set( PREF_KEY_MAIN_WINDOW_HEIGHT, h ); 266 }267 }268 269 static void270 windowStateChanged( GtkWidget * widget UNUSED,271 GdkEventWindowState * event,272 gpointer gdata )273 {274 if( event->changed_mask & GDK_WINDOW_STATE_ICONIFIED )275 {276 struct cbdata * cbdata = gdata;277 cbdata->minimized =278 ( event->new_window_state &279 GDK_WINDOW_STATE_ICONIFIED ) ? 1 : 0;280 274 } 281 275 } … … 361 355 gboolean startpaused = FALSE; 362 356 gboolean startminimized = FALSE; 363 char * domain = "transmission";357 char * domain = MY_NAME; 364 358 char * configDir = NULL; 365 359 tr_lockfile_state_t tr_state; … … 411 405 412 406 if( configDir == NULL ) 413 configDir = (char*) tr_getDefaultConfigDir( );407 configDir = (char*) tr_getDefaultConfigDir( MY_NAME ); 414 408 415 409 tr_notify_init( ); 416 417 410 didinit = cf_init( configDir, NULL ); /* must come before actions_init */ 418 411 tr_prefs_init_global( ); 412 419 413 myUIManager = gtk_ui_manager_new ( ); 420 414 actions_init ( myUIManager, cbdata ); 421 gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, 422 NULL ); 415 gtk_ui_manager_add_ui_from_string ( myUIManager, fallback_ui_file, -1, NULL ); 423 416 gtk_ui_manager_ensure_update ( myUIManager ); 424 gtk_window_set_default_icon_name ( "transmission");417 gtk_window_set_default_icon_name ( MY_NAME ); 425 418 426 419 setupsighandlers( ); /* set up handlers for fatal signals */ … … 449 442 { 450 443 GtkWindow * win; 451 452 tr_session * h = tr_sessionInitFull( 453 configDir, 454 "gtk", 455 pref_string_get( PREF_KEY_DOWNLOAD_DIR ), 456 pref_flag_get( PREF_KEY_PEX ), 457 pref_flag_get( PREF_KEY_PORT_FORWARDING ), 458 pref_int_get( PREF_KEY_PORT ), 459 pref_int_get( PREF_KEY_ENCRYPTION ), 460 pref_flag_get( PREF_KEY_LAZY_BITFIELD ), 461 pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ), 462 pref_int_get( PREF_KEY_UL_LIMIT ), 463 pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ), 464 pref_int_get( PREF_KEY_DL_LIMIT ), 465 pref_int_get( PREF_KEY_MAX_PEERS_GLOBAL ), 466 pref_int_get( PREF_KEY_MSGLEVEL ), 467 TRUE, /* message queueing */ 468 pref_flag_get( PREF_KEY_BLOCKLIST_ENABLED ), 469 pref_int_get( PREF_KEY_PEER_SOCKET_TOS ), 470 pref_flag_get( PREF_KEY_RPC_ENABLED ), 471 pref_int_get( PREF_KEY_RPC_PORT ), 472 pref_flag_get( PREF_KEY_RPC_WHITELIST_ENABLED ), 473 pref_string_get( PREF_KEY_RPC_WHITELIST ), 474 pref_flag_get( PREF_KEY_RPC_AUTH_ENABLED ), 475 pref_string_get( PREF_KEY_RPC_USERNAME ), 476 pref_string_get( PREF_KEY_RPC_PASSWORD ), 477 pref_flag_get( PREF_KEY_PROXY_SERVER_ENABLED ), 478 pref_string_get( PREF_KEY_PROXY_SERVER ), 479 pref_int_get( PREF_KEY_PROXY_PORT ), 480 pref_int_get( PREF_KEY_PROXY_TYPE ), 481 pref_flag_get( PREF_KEY_PROXY_AUTH_ENABLED ), 482 pref_string_get( PREF_KEY_PROXY_USERNAME ), 483 pref_string_get( PREF_KEY_PROXY_PASSWORD ) ); 484 485 cbdata->core = tr_core_new( h ); 444 tr_session * session; 445 446 /* initialize the libtransmission session */ 447 session = tr_sessionInit( "gtk", configDir, TRUE, pref_get_all( ) ); 448 cbdata->core = tr_core_new( session ); 486 449 487 450 /* create main window now to be a parent to any error dialogs */ 488 451 win = GTK_WINDOW( tr_window_new( myUIManager, cbdata->core ) ); 489 g_signal_connect( win, "window-state-event", 490 G_CALLBACK( windowStateChanged ), cbdata ); 491 g_signal_connect( win, "size-allocate", 492 G_CALLBACK( onMainWindowSizeAllocated ), cbdata ); 452 g_signal_connect( win, "size-allocate", G_CALLBACK( onMainWindowSizeAllocated ), cbdata ); 493 453 494 454 appsetup( win, argfiles, cbdata, startpaused, startminimized ); 495 tr_sessionSetRPCCallback( h, onRPCChanged, cbdata );455 tr_sessionSetRPCCallback( session, onRPCChanged, cbdata ); 496 456 gtr_blocklist_maybe_autoupdate( cbdata->core ); 497 457 … … 566 526 tr_inf ( _( "Ending use of scheduled bandwidth limits" ) ); 567 527 568 b = pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED );528 b = pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED ); 569 529 tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b ); 570 limit = pref_int_get( PREF_KEY_DL_LIMIT);530 limit = pref_int_get( TR_PREFS_KEY_DSPEED ); 571 531 tr_sessionSetSpeedLimit( tr, TR_DOWN, limit ); 572 b = pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED );532 b = pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED ); 573 533 tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b ); 574 limit = pref_int_get( PREF_KEY_UL_LIMIT);534 limit = pref_int_get( TR_PREFS_KEY_USPEED ); 575 535 tr_sessionSetSpeedLimit( tr, TR_UP, limit ); 576 536 } … … 604 564 struct cbdata * cbdata, 605 565 gboolean forcepause, 606 gboolean minimized )566 gboolean isIconified ) 607 567 { 608 568 const pref_flag_t start = … … 611 571 612 572 /* fill out cbdata */ 613 cbdata->wind = NULL;614 cbdata->icon = NULL;615 cbdata->msgwin = NULL;616 cbdata->prefs = NULL;617 cbdata->timer = 0;618 cbdata-> closing = FALSE;619 cbdata->errqueue = NULL;620 cbdata->dupqueue = NULL;621 cbdata-> minimized = minimized;622 623 if( minimized )573 cbdata->wind = NULL; 574 cbdata->icon = NULL; 575 cbdata->msgwin = NULL; 576 cbdata->prefs = NULL; 577 cbdata->timer = 0; 578 cbdata->isClosing = 0; 579 cbdata->errqueue = NULL; 580 cbdata->dupqueue = NULL; 581 cbdata->isIconified = isIconified; 582 583 if( isIconified ) 624 584 pref_flag_set( PREF_KEY_SHOW_TRAY_ICON, TRUE ); 625 585 … … 656 616 657 617 /* either show the window or iconify it */ 658 if( ! minimized )618 if( !isIconified ) 659 619 gtk_widget_show( GTK_WIDGET( wind ) ); 660 620 else … … 666 626 } 667 627 668 /** 669 * hideMainWindow, and the timeout hack in toggleMainWindow, 670 * are loosely cribbed from Colin Walters' rb-shell.c in Rhythmbox 671 */ 672 static gboolean 673 idle_hide_mainwindow( gpointer window ) 674 { 675 gtk_widget_hide( window ); 676 return FALSE; 677 } 678 679 static void 680 hideMainWindow( struct cbdata * cbdata ) 681 { 682 #if defined( STATUS_ICON_SUPPORTED ) && defined( GDK_WINDOWING_X11 ) 683 GdkRectangle bounds; 684 gulong data[4]; 685 Display * dpy; 686 GdkWindow * gdk_window; 687 688 gtk_status_icon_get_geometry( GTK_STATUS_ICON( 689 cbdata->icon ), NULL, &bounds, NULL ); 690 gdk_window = GTK_WIDGET ( cbdata->wind )->window; 691 dpy = gdk_x11_drawable_get_xdisplay ( gdk_window ); 692 693 data[0] = bounds.x; 694 data[1] = bounds.y; 695 data[2] = bounds.width; 696 data[3] = bounds.height; 697 698 XChangeProperty ( dpy, 699 GDK_WINDOW_XID ( gdk_window ), 700 gdk_x11_get_xatom_by_name_for_display ( 701 gdk_drawable_get_display ( gdk_window ), 702 "_NET_WM_ICON_GEOMETRY" ), 703 XA_CARDINAL, 32, PropModeReplace, 704 (guchar*)&data, 4 ); 705 706 gtk_window_set_skip_taskbar_hint( cbdata->wind, TRUE ); 628 static void 629 tr_window_present( GtkWindow * window ) 630 { 631 #if GTK_CHECK_VERSION( 2, 8, 0 ) 632 gtk_window_present_with_time( window, gtk_get_current_event_time( ) ); 633 #else 634 gtk_window_present( window ); 707 635 #endif 708 gtk_window_iconify( cbdata->wind );709 }710 711 static void712 clearTag( guint * tag )713 {714 if( *tag )715 g_source_remove( *tag );716 *tag = 0;717 636 } 718 637 719 638 static void 720 639 toggleMainWindow( struct cbdata * cbdata, 721 gboolean present )640 gboolean doPresent ) 722 641 { 723 642 GtkWindow * window = GTK_WINDOW( cbdata->wind ); 724 const int hide = !cbdata->minimized; 725 static int x = 0, y = 0; 726 727 if( ( !present ) && hide ) 643 const int doShow = cbdata->isIconified; 644 static int x = 0; 645 static int y = 0; 646 647 if( doShow || doPresent ) 648 { 649 cbdata->isIconified = 0; 650 gtk_window_set_skip_taskbar_hint( window, FALSE ); 651 gtk_window_move( window, x, y ); 652 gtk_widget_show( GTK_WIDGET( window ) ); 653 tr_window_present( window ); 654 } 655 else 728 656 { 729 657 gtk_window_get_position( window, &x, &y ); 730 clearTag( &cbdata->idle_hide_mainwindow_tag ); 731 hideMainWindow( cbdata ); 732 cbdata->idle_hide_mainwindow_tag = g_timeout_add( 733 100, idle_hide_mainwindow, window ); 734 } 735 else 736 { 737 gtk_window_set_skip_taskbar_hint( window, FALSE ); 738 if( x != 0 && y != 0 ) 739 gtk_window_move( window, x, y ); 740 gtk_widget_show( GTK_WIDGET( window ) ); 741 gtk_window_deiconify( window ); 742 #if GTK_CHECK_VERSION( 2, 8, 0 ) 743 gtk_window_present_with_time( window, gtk_get_current_event_time( ) ); 744 #else 745 gtk_window_present( window ); 746 #endif 658 gtk_window_set_skip_taskbar_hint( window, TRUE ); 659 gtk_widget_hide( GTK_WIDGET( window ) ); 660 cbdata->isIconified = 1; 747 661 } 748 662 } … … 765 679 static void 766 680 rowChangedCB( GtkTreeModel * model UNUSED, 767 GtkTreePath *path,681 GtkTreePath * path, 768 682 GtkTreeIter * iter UNUSED, 769 gpointer sel ) 770 { 771 if( gtk_tree_selection_path_is_selected ( sel, path ) ) 772 refreshTorrentActions( GTK_TREE_SELECTION( sel ) ); 683 gpointer gdata ) 684 { 685 struct cbdata * data = gdata; 686 if( gtk_tree_selection_path_is_selected ( data->sel, path ) ) 687 refreshTorrentActions( gdata ); 773 688 } 774 689 … … 782 697 g_assert( NULL == cbdata->wind ); 783 698 cbdata->wind = GTK_WINDOW( wind ); 784 785 sel = tr_window_get_selection( cbdata->wind ); 786 g_signal_connect( sel, "changed", G_CALLBACK( 787 selectionChangedCB ), NULL ); 788 selectionChangedCB( sel, NULL ); 699 cbdata->sel = sel = GTK_TREE_SELECTION( tr_window_get_selection( cbdata->wind ) ); 700 701 g_signal_connect( sel, "changed", G_CALLBACK( selectionChangedCB ), cbdata ); 702 selectionChangedCB( sel, cbdata ); 789 703 model = tr_core_model( cbdata->core ); 790 g_signal_connect( model, "row-changed", G_CALLBACK( rowChangedCB ), sel);704 g_signal_connect( model, "row-changed", G_CALLBACK( rowChangedCB ), cbdata ); 791 705 g_signal_connect( wind, "delete-event", G_CALLBACK( winclose ), cbdata ); 792 refreshTorrentActions( sel);706 refreshTorrentActions( cbdata ); 793 707 794 708 setupdrag( GTK_WIDGET( wind ), cbdata ); … … 1003 917 GtkWidget * w; 1004 918 1005 for( l = *files; l; l = l->next ) 1006 g_string_append_printf( s, "%s\n", (const char*)l->data ); 919 if( g_slist_length( *files ) > 1 ) { 920 for( l=*files; l!=NULL; l=l->next ) 921 g_string_append_printf( s, "\xE2\x88\x99 %s\n", (const char*)l->data ); 922 } else { 923 for( l=*files; l!=NULL; l=l->next ) 924 g_string_append_printf( s, "%s\n", (const char*)l->data ); 925 } 1007 926 w = gtk_message_dialog_new( window, 1008 927 GTK_DIALOG_DESTROY_WITH_PARENT, … … 1028 947 flushAddTorrentErrors( GTK_WINDOW( cbdata->wind ), 1029 948 ngettext( "Couldn't add corrupt torrent", 1030 "Couldn't add corrupt torrents",1031 g_slist_length( cbdata->errqueue ) ),949 "Couldn't add corrupt torrents", 950 g_slist_length( cbdata->errqueue ) ), 1032 951 &cbdata->errqueue ); 1033 952 … … 1035 954 flushAddTorrentErrors( GTK_WINDOW( cbdata->wind ), 1036 955 ngettext( "Couldn't add duplicate torrent", 1037 "Couldn't add duplicate torrents",1038 g_slist_length( cbdata->dupqueue ) ),956 "Couldn't add duplicate torrents", 957 g_slist_length( cbdata->dupqueue ) ), 1039 958 &cbdata->dupqueue ); 1040 959 } … … 1056 975 1057 976 case TR_EDUPLICATE: 1058 c->dupqueue = 1059 g_slist_append( c->dupqueue, g_path_get_basename( msg ) ); 977 c->dupqueue = g_slist_append( c->dupqueue, g_strdup( msg ) ); 1060 978 break; 1061 979 … … 1110 1028 tr_session * tr = tr_core_session( cbdata->core ); 1111 1029 1112 if( !strcmp( key, PREF_KEY_ENCRYPTION ) )1030 if( !strcmp( key, TR_PREFS_KEY_ENCRYPTION ) ) 1113 1031 { 1114 1032 const int encryption = pref_int_get( key ); … … 1116 1034 tr_sessionSetEncryption( tr, encryption ); 1117 1035 } 1118 else if( !strcmp( key, PREF_KEY_BLOCKLIST_ENABLED ) ) 1119 { 1120 tr_blocklistSetEnabled( tr, pref_flag_get( key ) ); 1121 } 1122 else if( !strcmp( key, PREF_KEY_DOWNLOAD_DIR ) ) 1036 else if( !strcmp( key, TR_PREFS_KEY_DOWNLOAD_DIR ) ) 1123 1037 { 1124 1038 tr_sessionSetDownloadDir( tr, pref_string_get( key ) ); 1125 1039 } 1126 else if( !strcmp( key, PREF_KEY_PORT ) ) 1040 else if( !strcmp( key, TR_PREFS_KEY_MSGLEVEL ) ) 1041 { 1042 tr_setMessageLevel( pref_int_get( key ) ); 1043 } 1044 else if( !strcmp( key, TR_PREFS_KEY_PEER_PORT_RANDOM_ENABLED ) ) 1045 { 1046 /* FIXME */ 1047 } 1048 else if( !strcmp( key, TR_PREFS_KEY_PEER_PORT ) ) 1127 1049 { 1128 1050 const int port = pref_int_get( key ); 1129 1051 tr_sessionSetPeerPort( tr, port ); 1052 } 1053 else if( !strcmp( key, TR_PREFS_KEY_BLOCKLIST_ENABLED ) ) 1054 { 1055 const gboolean flag = pref_flag_get( key ); 1056 tr_blocklistSetEnabled( tr, flag ); 1130 1057 } 1131 1058 else if( !strcmp( key, PREF_KEY_SHOW_TRAY_ICON ) ) … … 1140 1067 } 1141 1068 } 1142 else if( !strcmp( key, PREF_KEY_DL_LIMIT_ENABLED ) )1069 else if( !strcmp( key, TR_PREFS_KEY_DSPEED_ENABLED ) ) 1143 1070 { 1144 1071 const gboolean b = pref_flag_get( key ); 1145 1072 tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b ); 1146 1073 } 1147 else if( !strcmp( key, PREF_KEY_DL_LIMIT) )1074 else if( !strcmp( key, TR_PREFS_KEY_DSPEED ) ) 1148 1075 { 1149 1076 const int limit = pref_int_get( key ); 1150 1077 tr_sessionSetSpeedLimit( tr, TR_DOWN, limit ); 1151 1078 } 1152 else if( !strcmp( key, PREF_KEY_UL_LIMIT_ENABLED ) )1079 else if( !strcmp( key, TR_PREFS_KEY_USPEED_ENABLED ) ) 1153 1080 { 1154 1081 const gboolean b = pref_flag_get( key ); 1155 1082 tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b ); 1156 1083 } 1157 else if( !strcmp( key, PREF_KEY_UL_LIMIT) )1084 else if( !strcmp( key, TR_PREFS_KEY_USPEED ) ) 1158 1085 { 1159 1086 const int limit = pref_int_get( key ); … … 1164 1091 updateScheduledLimits( tr ); 1165 1092 } 1166 else if( !strcmp( key, PREF_KEY_PORT_FORWARDING ) )1093 else if( !strcmp( key, TR_PREFS_KEY_PORT_FORWARDING ) ) 1167 1094 { 1168 1095 tr_sessionSetPortForwardingEnabled( tr, pref_flag_get( key ) ); 1169 1096 } 1170 else if( !strcmp( key, PREF_KEY_PEX) )1097 else if( !strcmp( key, TR_PREFS_KEY_PEX_ENABLED ) ) 1171 1098 { 1172 1099 tr_sessionSetPexEnabled( tr, pref_flag_get( key ) ); 1173 1100 } 1174 else if( !strcmp( key, PREF_KEY_RPC_ENABLED ) ) 1101 else if( !strcmp( key, TR_PREFS_KEY_RPC_PORT ) ) 1102 { 1103 tr_sessionSetRPCPort( tr, pref_int_get( key ) ); 1104 } 1105 else if( !strcmp( key, TR_PREFS_KEY_RPC_ENABLED ) ) 1175 1106 { 1176 1107 tr_sessionSetRPCEnabled( tr, pref_flag_get( key ) ); 1177 1108 } 1178 else if( !strcmp( key, PREF_KEY_RPC_PORT ) ) 1179 { 1180 tr_sessionSetRPCPort( tr, pref_int_get( key ) ); 1181 } 1182 else if( !strcmp( key, PREF_KEY_RPC_ENABLED ) ) 1183 { 1184 tr_sessionSetRPCEnabled( tr, pref_flag_get( key ) ); 1185 } 1186 else if( !strcmp( key, PREF_KEY_RPC_WHITELIST ) ) 1109 else if( !strcmp( key, TR_PREFS_KEY_RPC_WHITELIST ) ) 1187 1110 { 1188 1111 const char * s = pref_string_get( key ); 1189 1112 tr_sessionSetRPCWhitelist( tr, s ); 1190 1113 } 1191 else if( !strcmp( key, PREF_KEY_RPC_WHITELIST_ENABLED ) )1114 else if( !strcmp( key, TR_PREFS_KEY_RPC_WHITELIST_ENABLED ) ) 1192 1115 { 1193 1116 tr_sessionSetRPCWhitelistEnabled( tr, pref_flag_get( key ) ); 1194 1117 } 1195 else if( !strcmp( key, PREF_KEY_RPC_USERNAME ) )1118 else if( !strcmp( key, TR_PREFS_KEY_RPC_USERNAME ) ) 1196 1119 { 1197 1120 const char * s = pref_string_get( key ); 1198 1121 tr_sessionSetRPCUsername( tr, s ); 1199 1122 } 1200 else if( !strcmp( key, PREF_KEY_RPC_PASSWORD ) )1123 else if( !strcmp( key, TR_PREFS_KEY_RPC_PASSWORD ) ) 1201 1124 { 1202 1125 const char * s = pref_string_get( key ); 1203 1126 tr_sessionSetRPCPassword( tr, s ); 1204 1127 } 1205 else if( !strcmp( key, PREF_KEY_RPC_AUTH_ENABLED ) )1128 else if( !strcmp( key, TR_PREFS_KEY_RPC_AUTH_REQUIRED ) ) 1206 1129 { 1207 1130 const gboolean enabled = pref_flag_get( key ); 1208 1131 tr_sessionSetRPCPasswordEnabled( tr, enabled ); 1209 1132 } 1210 else if( !strcmp( key, PREF_KEY_PROXY_SERVER) )1133 else if( !strcmp( key, TR_PREFS_KEY_PROXY ) ) 1211 1134 { 1212 1135 const char * s = pref_string_get( key ); 1213 1136 tr_sessionSetProxy( tr, s ); 1214 1137 } 1215 else if( !strcmp( key, PREF_KEY_PROXY_TYPE ) )1138 else if( !strcmp( key, TR_PREFS_KEY_PROXY_TYPE ) ) 1216 1139 { 1217 1140 const int i = pref_int_get( key ); 1218 1141 tr_sessionSetProxyType( tr, i ); 1219 1142 } 1220 else if( !strcmp( key, PREF_KEY_PROXY_SERVER_ENABLED ) )1143 else if( !strcmp( key, TR_PREFS_KEY_PROXY_ENABLED ) ) 1221 1144 { 1222 1145 const gboolean enabled = pref_flag_get( key ); 1223 1146 tr_sessionSetProxyEnabled( tr, enabled ); 1224 1147 } 1225 else if( !strcmp( key, PREF_KEY_PROXY_AUTH_ENABLED ) )1148 else if( !strcmp( key, TR_PREFS_KEY_PROXY_AUTH_ENABLED ) ) 1226 1149 { 1227 1150 const gboolean enabled = pref_flag_get( key ); 1228 1151 tr_sessionSetProxyAuthEnabled( tr, enabled ); 1229 1152 } 1230 else if( !strcmp( key, PREF_KEY_PROXY_USERNAME ) )1153 else if( !strcmp( key, TR_PREFS_KEY_PROXY_USERNAME ) ) 1231 1154 { 1232 1155 const char * s = pref_string_get( key ); 1233 1156 tr_sessionSetProxyUsername( tr, s ); 1234 1157 } 1235 else if( !strcmp( key, PREF_KEY_PROXY_PASSWORD ) )1158 else if( !strcmp( key, TR_PREFS_KEY_PROXY_PASSWORD ) ) 1236 1159 { 1237 1160 const char * s = pref_string_get( key ); 1238 1161 tr_sessionSetProxyPassword( tr, s ); 1239 1162 } 1240 else if( !strcmp( key, PREF_KEY_PORT ) )1163 else if( !strcmp( key, TR_PREFS_KEY_PROXY_PORT ) ) 1241 1164 { 1242 1165 tr_sessionSetProxyPort( tr, pref_int_get( key ) ); 1166 } 1167 else if( !strcmp( key, TR_PREFS_KEY_RPC_PASSWORD ) ) 1168 { 1169 const char * s = pref_string_get( key ); 1170 tr_sessionSetProxyPassword( tr, s ); 1243 1171 } 1244 1172 } … … 1248 1176 { 1249 1177 struct cbdata *data = gdata; 1250 const gboolean done = data-> closing || global_sigcount;1178 const gboolean done = data->isClosing || global_sigcount; 1251 1179 1252 1180 if( !done ) … … 1260 1188 1261 1189 /* update the actions */ 1262 refreshTorrentActions( tr_window_get_selection( data->wind ));1190 refreshTorrentActions( data ); 1263 1191 } 1264 1192 … … 1299 1227 "website-label", website_url, 1300 1228 "copyright", 1301 _( 1302 "Copyright 2005-2008 The Transmission Project" ), 1303 "logo-icon-name", "transmission", 1229 _( "Copyright 2005-2009 The Transmission Project" ), 1230 "logo-icon-name", MY_NAME, 1304 1231 #ifdef SHOW_LICENSE 1305 1232 "license", LICENSE, … … 1453 1380 } 1454 1381 1382 static void 1383 pauseAllTorrents( struct cbdata * data ) 1384 { 1385 tr_session * session = tr_core_session( data->core ); 1386 const char * cmd = "{ \"method\": \"torrent-stop\" }"; 1387 tr_rpc_request_exec_json( session, cmd, strlen( cmd ), NULL ); 1388 } 1389 1455 1390 void 1456 doAction( const char * action_name, 1457 gpointer user_data ) 1391 doAction( const char * action_name, gpointer user_data ) 1458 1392 { 1459 1393 struct cbdata * data = user_data; 1460 1394 gboolean changed = FALSE; 1461 1395 1462 if( !strcmp( action_name, "add-torrent-menu" )1396 if( !strcmp( action_name, "add-torrent-menu" ) 1463 1397 || !strcmp( action_name, "add-torrent-toolbar" ) ) 1464 1398 { 1465 1399 addDialog( data->wind, data->core ); 1466 1400 } 1467 else if( !strcmp ( action_name, "show-stats" ) ) 1468 { 1469 GtkWidget * dialog = stats_dialog_create( data->wind, 1470 data->core ); 1401 else if( !strcmp( action_name, "show-stats" ) ) 1402 { 1403 GtkWidget * dialog = stats_dialog_create( data->wind, data->core ); 1471 1404 gtk_widget_show( dialog ); 1472 1405 } 1473 else if( !strcmp 1406 else if( !strcmp( action_name, "start-torrent" ) ) 1474 1407 { 1475 1408 GtkTreeSelection * s = tr_window_get_selection( data->wind ); … … 1477 1410 changed |= gtk_tree_selection_count_selected_rows( s ) != 0; 1478 1411 } 1479 else if( !strcmp ( action_name, "pause-torrent" ) ) 1412 else if( !strcmp( action_name, "pause-all-torrents" ) ) 1413 { 1414 pauseAllTorrents( data ); 1415 } 1416 else if( !strcmp( action_name, "pause-torrent" ) ) 1480 1417 { 1481 1418 GtkTreeSelection * s = tr_window_get_selection( data->wind ); … … 1483 1420 changed |= gtk_tree_selection_count_selected_rows( s ) != 0; 1484 1421 } 1485 else if( !strcmp 1422 else if( !strcmp( action_name, "verify-torrent" ) ) 1486 1423 { 1487 1424 GtkTreeSelection * s = tr_window_get_selection( data->wind ); … … 1489 1426 changed |= gtk_tree_selection_count_selected_rows( s ) != 0; 1490 1427 } 1491 else if( !strcmp 1428 else if( !strcmp( action_name, "open-torrent-folder" ) ) 1492 1429 { 1493 1430 GtkTreeSelection * s = tr_window_get_selection( data->wind ); 1494 1431 gtk_tree_selection_selected_foreach( s, openFolderForeach, data ); 1495 1432 } 1496 else if( !strcmp ( action_name, "show-torrent-details" ) )1433 else if( !strcmp( action_name, "show-torrent-properties" ) ) 1497 1434 { 1498 1435 GtkTreeSelection * s = tr_window_get_selection( data->wind ); … … 1505 1442 data->wind ); 1506 1443 } 1507 else if( !strcmp 1444 else if( !strcmp( action_name, "new-torrent" ) ) 1508 1445 { 1509 1446 GtkWidget * w = make_meta_ui( GTK_WINDOW( data->wind ), … … 1519 1456 removeSelected( data, TRUE ); 1520 1457 } 1521 else if( !strcmp 1458 else if( !strcmp( action_name, "quit" ) ) 1522 1459 { 1523 1460 askquit( data->core, data->wind, wannaquit, data ); 1524 1461 } 1525 else if( !strcmp 1462 else if( !strcmp( action_name, "select-all" ) ) 1526 1463 { 1527 1464 GtkTreeSelection * s = tr_window_get_selection( data->wind ); 1528 1465 gtk_tree_selection_select_all( s ); 1529 1466 } 1530 else if( !strcmp 1467 else if( !strcmp( action_name, "deselect-all" ) ) 1531 1468 { 1532 1469 GtkTreeSelection * s = tr_window_get_selection( data->wind ); 1533 1470 gtk_tree_selection_unselect_all( s ); 1534 1471 } 1535 else if( !strcmp 1472 else if( !strcmp( action_name, "edit-preferences" ) ) 1536 1473 { 1537 1474 if( NULL == data->prefs ) … … 1544 1481 } 1545 1482 } 1546 else if( !strcmp 1483 else if( !strcmp( action_name, "toggle-message-log" ) ) 1547 1484 { 1548 1485 if( !data->msgwin ) … … 1560 1497 } 1561 1498 } 1562 else if( !strcmp 1499 else if( !strcmp( action_name, "show-about-dialog" ) ) 1563 1500 { 1564 1501 about( data->wind ); … … 1570 1507 g_free( url ); 1571 1508 } 1572 else if( !strcmp 1509 else if( !strcmp( action_name, "toggle-main-window" ) ) 1573 1510 { 1574 1511 toggleMainWindow( data, FALSE ); 1575 1512 } 1576 else if( !strcmp 1513 else if( !strcmp( action_name, "present-main-window" ) ) 1577 1514 { 1578 1515 toggleMainWindow( data, TRUE ); -
branches/1.5x/gtk/makemeta-ui.c
r6998 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/makemeta-ui.h
r6978 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/msgwin.c
r7463 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 69 69 70 70 tr_setMessageLevel( level ); 71 tr_core_set_pref_int( data->core, PREF_KEY_MSGLEVEL, level );71 tr_core_set_pref_int( data->core, TR_PREFS_KEY_MSGLEVEL, level ); 72 72 data->maxLevel = level; 73 73 gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( data->filter ) ); … … 406 406 store = gtk_list_store_new ( 2, G_TYPE_STRING, G_TYPE_INT ); 407 407 408 curlevel = pref_int_get( PREF_KEY_MSGLEVEL );408 curlevel = pref_int_get( TR_PREFS_KEY_MSGLEVEL ); 409 409 for( i = ii = 0; i < G_N_ELEMENTS( trLevels ); ++i ) 410 410 { … … 520 520 COL_SEQUENCE, 521 521 GTK_SORT_ASCENDING ); 522 data->maxLevel = pref_int_get( PREF_KEY_MSGLEVEL );522 data->maxLevel = pref_int_get( TR_PREFS_KEY_MSGLEVEL ); 523 523 gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER( data-> 524 524 filter ), -
branches/1.5x/gtk/msgwin.h
r6795 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/notify.c
r6795 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/notify.h
r6795 r7664 1 1 /* 2 * This file Copyright (C) 2008 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2008-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/stats.c
r7463 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/stats.h
r6998 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/torrent-cell-renderer.c
r7069 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 114 114 115 115 if( haveDown && haveUp ) 116 /* Translators: do not translate the "speed|" disambiguation prefix.116 /* Translators: "speed|" is here for disambiguation. Please remove it from your translation. 117 117 %1$s is the download speed 118 118 %2$s is the upload speed */ … … 468 468 my_bg.y = tmp_bg.y + tmp_bg.height; 469 469 my_cell.y = tmp_cell.y + tmp_cell.height; 470 my_expose.y += tmp_expose.y + tmp_cell.height;470 my_expose.y = tmp_expose.y + tmp_cell.height; 471 471 472 472 g_free( str ); -
branches/1.5x/gtk/torrent-cell-renderer.h
r6998 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/tr-core.c
r7463 r7664 164 164 GObjectClass * parent; 165 165 166 pref_save( );167 166 core->priv = NULL; 168 167 … … 450 449 if( tr_ctorGetPeerLimit( ctor, TR_FORCE, NULL ) ) 451 450 tr_ctorSetPeerLimit( ctor, TR_FORCE, 452 pref_int_get( PREF_KEY_MAX_PEERS_PER_TORRENT ) );451 pref_int_get( TR_PREFS_KEY_PEER_LIMIT_TORRENT ) ); 453 452 454 453 if( tr_ctorGetDownloadDir( ctor, TR_FORCE, NULL ) ) 455 454 { 456 const char * path = pref_string_get( PREF_KEY_DOWNLOAD_DIR );455 const char * path = pref_string_get( TR_PREFS_KEY_DOWNLOAD_DIR ); 457 456 tr_ctorSetDownloadDir( ctor, TR_FORCE, path ); 458 457 } … … 584 583 setSort( core, mode, isReversed ); 585 584 } 586 else if( !strcmp( key, PREF_KEY_MAX_PEERS_GLOBAL ) )585 else if( !strcmp( key, TR_PREFS_KEY_PEER_LIMIT_GLOBAL ) ) 587 586 { 588 587 const uint16_t val = pref_int_get( key ); 589 588 tr_sessionSetPeerLimit( tr_core_session( core ), val ); 589 } 590 else if( !strcmp( key, TR_PREFS_KEY_PEER_LIMIT_TORRENT ) ) 591 { 592 const uint16_t val = pref_int_get( key ); 593 tr_sessionSetPeerLimitPerTorrent( tr_core_session( core ), val ); 590 594 } 591 595 else if( !strcmp( key, PREF_KEY_INHIBIT_HIBERNATION ) ) … … 684 688 prefsChanged( core, PREF_KEY_SORT_REVERSED, NULL ); 685 689 prefsChanged( core, PREF_KEY_DIR_WATCH_ENABLED, NULL ); 686 prefsChanged( core, PREF_KEY_MAX_PEERS_GLOBAL, NULL );690 prefsChanged( core, TR_PREFS_KEY_PEER_LIMIT_GLOBAL, NULL ); 687 691 prefsChanged( core, PREF_KEY_INHIBIT_HIBERNATION, NULL ); 688 g_signal_connect( core, "prefs-changed", G_CALLBACK( 689 prefsChanged ), NULL ); 692 g_signal_connect( core, "prefs-changed", G_CALLBACK( prefsChanged ), NULL ); 690 693 691 694 return core; … … 700 703 { 701 704 core->priv->session = NULL; 705 pref_save( session ); 702 706 tr_sessionClose( session ); 703 707 } … … 819 823 tr_ctorSetPaused( ctor, TR_FORCE, TRUE ); 820 824 tr_ctorSetPeerLimit( ctor, TR_FALLBACK, 821 pref_int_get( PREF_KEY_MAX_PEERS_PER_TORRENT ) );825 pref_int_get( TR_PREFS_KEY_PEER_LIMIT_TORRENT ) ); 822 826 823 827 torrents = tr_sessionLoadTorrents ( tr_core_session( self ), ctor, &count ); … … 858 862 if( filename && session ) 859 863 { 860 int err; 861 tr_ctor * ctor = tr_ctorNew( session ); 864 tr_ctor * ctor; 865 866 ctor = tr_ctorNew( session ); 862 867 tr_core_apply_defaults( ctor ); 863 868 tr_ctorSetPaused( ctor, TR_FORCE, !doStart ); 869 864 870 if( tr_ctorSetMetainfoFromFile( ctor, filename ) ) 865 871 { … … 867 873 tr_ctorFree( ctor ); 868 874 } 869 else if( ( err = tr_torrentParse( session, ctor, NULL ) ) )870 {871 /* don't complain about .torrent files in the watch directory872 that have already been added... that gets annoying, and we873 don't want to nag about cleaning up the watch dir */874 const gboolean quiet = ( err == TR_EDUPLICATE )875 && ( core->priv->adding_from_watch_dir );876 if( !quiet )877 tr_core_errsig( core, err, filename );878 879 tr_ctorFree( ctor );880 }881 else if( doPrompt )882 g_signal_emit( core, TR_CORE_GET_CLASS(883 core )->promptsig, 0, ctor );884 875 else 885 876 { 886 tr_torrent * tor = tr_torrentNew( session, ctor, &err ); 887 if( err ) 888 tr_core_errsig( core, err, filename ); 889 else 890 tr_core_add_torrent( core, tr_torrent_new_preexisting( tor ) ); 877 tr_info inf; 878 int err = tr_torrentParse( session, ctor, &inf ); 879 880 switch( err ) 881 { 882 case TR_EINVALID: 883 tr_core_errsig( core, err, filename ); 884 break; 885 886 case TR_EDUPLICATE: 887 /* don't complain about .torrent files in the watch directory 888 * that have already been added... that gets annoying and we 889 * don't want to be naggign users to clean up their watch dirs */ 890 if( !core->priv->adding_from_watch_dir ) 891 tr_core_errsig( core, err, inf.name ); 892 tr_metainfoFree( &inf ); 893 break; 894 895 default: 896 if( doPrompt ) 897 g_signal_emit( core, TR_CORE_GET_CLASS( core )->promptsig, 0, ctor ); 898 else { 899 tr_torrent * tor = tr_torrentNew( session, ctor, &err ); 900 if( err ) 901 tr_core_errsig( core, err, filename ); 902 else 903 tr_core_add_torrent( core, tr_torrent_new_preexisting( tor ) ); 904 } 905 tr_metainfoFree( &inf ); 906 break; 907 } 891 908 } 892 909 } … … 900 917 { 901 918 add_filename( core, filename, 902 pref_flag_get( PREF_KEY_START ),903 pref_flag_get( PREF_KEY_OPTIONS_PROMPT ) );919 pref_flag_get( PREF_KEY_START ), 920 pref_flag_get( PREF_KEY_OPTIONS_PROMPT ) ); 904 921 *success = TRUE; 905 922 return TRUE; … … 1213 1230 { 1214 1231 g_signal_emit( core, TR_CORE_GET_CLASS( core )->prefsig, 0, key ); 1215 pref_save( );1232 pref_save( tr_core_session( core ) ); 1216 1233 } 1217 1234 -
branches/1.5x/gtk/tr-icon.c
r7463 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/tr-prefs.c
r7478 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 36 36 tr_prefs_init_global( void ) 37 37 { 38 int i;39 char pw[32];40 38 const char * str; 41 const char * pool = "abcdefghijklmnopqrstuvwxyz"42 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"43 "1234567890";44 GRand * rand;45 39 46 40 cf_check_older_configs( ); … … 49 43 str = NULL; 50 44 if( !str ) str = g_get_user_special_dir( G_USER_DIRECTORY_DESKTOP ); 51 if( !str ) str = g_get_home_dir( );45 if( !str ) str = tr_getDefaultDownloadDir( ); 52 46 pref_string_set_default ( PREF_KEY_DIR_WATCH, str ); 53 47 pref_flag_set_default ( PREF_KEY_DIR_WATCH_ENABLED, FALSE ); 54 48 #endif 55 49 56 pref_int_set_default ( PREF_KEY_PEER_SOCKET_TOS,57 TR_DEFAULT_PEER_SOCKET_TOS );58 50 pref_flag_set_default ( PREF_KEY_INHIBIT_HIBERNATION, FALSE ); 59 pref_flag_set_default ( PREF_KEY_BLOCKLIST_ENABLED, TRUE );60 51 pref_flag_set_default ( PREF_KEY_BLOCKLIST_UPDATES_ENABLED, TRUE ); 61 52 62 53 pref_string_set_default ( PREF_KEY_OPEN_DIALOG_FOLDER, g_get_home_dir( ) ); 63 64 pref_int_set_default ( PREF_KEY_MAX_PEERS_GLOBAL,65 TR_DEFAULT_GLOBAL_PEER_LIMIT );66 pref_int_set_default ( PREF_KEY_MAX_PEERS_PER_TORRENT, 50 );67 54 68 55 pref_flag_set_default ( PREF_KEY_TOOLBAR, TRUE ); … … 72 59 pref_string_set_default ( PREF_KEY_STATUSBAR_STATS, "total-ratio" ); 73 60 74 pref_flag_set_default ( PREF_KEY_DL_LIMIT_ENABLED, FALSE );75 pref_int_set_default ( PREF_KEY_DL_LIMIT, 100 );76 pref_flag_set_default ( PREF_KEY_UL_LIMIT_ENABLED, FALSE );77 pref_int_set_default ( PREF_KEY_UL_LIMIT, 50 );78 61 pref_flag_set_default ( PREF_KEY_SCHED_LIMIT_ENABLED, FALSE ); 79 62 pref_int_set_default ( PREF_KEY_SCHED_BEGIN, 60 * 23 ); /* 11pm */ 80 63 pref_int_set_default ( PREF_KEY_SCHED_END, 60 * 7 ); /* 7am */ 81 pref_int_set_default ( PREF_KEY_SCHED_DL_LIMIT, 200 ); /* 2x the other 82 limit */ 83 pref_int_set_default ( PREF_KEY_SCHED_UL_LIMIT, 100 ); /* 2x the other 84 limit */ 64 pref_int_set_default ( PREF_KEY_SCHED_DL_LIMIT, 200 ); /* 2x the other limit */ 65 pref_int_set_default ( PREF_KEY_SCHED_UL_LIMIT, 100 ); /* 2x the other limit */ 85 66 86 67 pref_flag_set_default ( PREF_KEY_OPTIONS_PROMPT, TRUE ); … … 90 71 pref_int_set_default ( PREF_KEY_MAIN_WINDOW_X, 50 ); 91 72 pref_int_set_default ( PREF_KEY_MAIN_WINDOW_Y, 50 ); 92 93 pref_string_set_default ( PREF_KEY_PROXY_SERVER, "" ); 94 pref_int_set_default ( PREF_KEY_PROXY_PORT, TR_DEFAULT_PROXY_PORT ); 95 pref_int_set_default ( PREF_KEY_PROXY_TYPE, TR_DEFAULT_PROXY_TYPE ); 96 pref_flag_set_default ( PREF_KEY_PROXY_SERVER_ENABLED, 97 TR_DEFAULT_PROXY_ENABLED ); 98 pref_flag_set_default ( PREF_KEY_PROXY_AUTH_ENABLED, 99 TR_DEFAULT_PROXY_AUTH_ENABLED ); 100 pref_string_set_default ( PREF_KEY_PROXY_USERNAME, "" ); 101 pref_string_set_default ( PREF_KEY_PROXY_PASSWORD, "" ); 73 pref_string_set_default ( PREF_KEY_MAIN_WINDOW_LAYOUT_ORDER, "menu,toolbar,filter,list,statusbar" ); 102 74 103 75 str = NULL; … … 106 78 #endif 107 79 if( !str ) str = g_get_home_dir( ); 108 pref_string_set_default ( PREF_KEY_DOWNLOAD_DIR, str ); 109 110 pref_int_set_default ( PREF_KEY_PORT, TR_DEFAULT_PORT ); 111 112 pref_flag_set_default ( PREF_KEY_PORT_FORWARDING, TRUE ); 113 pref_flag_set_default ( PREF_KEY_PEX, TR_DEFAULT_PEX_ENABLED ); 80 pref_string_set_default ( TR_PREFS_KEY_DOWNLOAD_DIR, str ); 81 114 82 pref_flag_set_default ( PREF_KEY_ASKQUIT, TRUE ); 115 pref_flag_set_default ( PREF_KEY_ENCRYPTION, TR_DEFAULT_ENCRYPTION );116 pref_flag_set_default ( PREF_KEY_LAZY_BITFIELD,117 TR_DEFAULT_LAZY_BITFIELD_ENABLED );118 119 pref_int_set_default ( PREF_KEY_MSGLEVEL, TR_MSG_INF );120 83 121 84 pref_string_set_default ( PREF_KEY_SORT_MODE, "sort-by-name" ); … … 125 88 pref_flag_set_default ( PREF_KEY_START, TRUE ); 126 89 pref_flag_set_default ( PREF_KEY_TRASH_ORIGINAL, FALSE ); 127 128 pref_flag_set_default ( PREF_KEY_RPC_ENABLED, TR_DEFAULT_RPC_ENABLED );129 pref_int_set_default ( PREF_KEY_RPC_PORT, TR_DEFAULT_RPC_PORT );130 pref_string_set_default ( PREF_KEY_RPC_WHITELIST, TR_DEFAULT_RPC_WHITELIST );131 pref_flag_set_default ( PREF_KEY_RPC_WHITELIST_ENABLED,132 TR_DEFAULT_RPC_WHITELIST_ENABLED );133 134 rand = g_rand_new ( );135 for( i = 0; i < 16; ++i )136 pw[i] = pool[g_rand_int_range ( rand, 0, strlen( pool ) )];137 g_rand_free ( rand );138 139 pw[16] = '\0';140 pref_string_set_default( PREF_KEY_RPC_USERNAME, "transmission" );141 pref_string_set_default( PREF_KEY_RPC_PASSWORD, pw );142 pref_flag_set_default ( PREF_KEY_RPC_AUTH_ENABLED, FALSE );143 144 pref_save( );145 90 } 146 91 … … 376 321 hig_workarea_add_wide_control( t, &row, w ); 377 322 378 w = new_path_chooser_button( PREF_KEY_DOWNLOAD_DIR, core );323 w = new_path_chooser_button( TR_PREFS_KEY_DOWNLOAD_DIR, core ); 379 324 hig_workarea_add_row( t, &row, _( "_Destination folder:" ), w, NULL ); 380 325 … … 511 456 : TR_ENCRYPTION_PREFERRED; 512 457 513 tr_core_set_pref_int( TR_CORE( core ), PREF_KEY_ENCRYPTION, val );458 tr_core_set_pref_int( TR_CORE( core ), TR_PREFS_KEY_ENCRYPTION, val ); 514 459 } 515 460 … … 531 476 hig_workarea_add_section_title( t, &row, _( "Blocklist" ) ); 532 477 533 w = new_check_button( "", PREF_KEY_BLOCKLIST_ENABLED, core );478 w = new_check_button( "", TR_PREFS_KEY_BLOCKLIST_ENABLED, core ); 534 479 updateBlocklistText( w, TR_CORE( core ) ); 535 480 h = gtk_hbox_new( FALSE, GUI_PAD_BIG ); … … 554 499 hig_workarea_add_section_title( t, &row, _( "Limits" ) ); 555 500 556 w = new_spin_button( PREF_KEY_MAX_PEERS_GLOBAL, core, 1, 3000, 5 );501 w = new_spin_button( TR_PREFS_KEY_PEER_LIMIT_GLOBAL, core, 1, 3000, 5 ); 557 502 hig_workarea_add_row( t, &row, _( "Maximum peers _overall:" ), w, NULL ); 558 w = new_spin_button( PREF_KEY_MAX_PEERS_PER_TORRENT, core, 1, 300, 5 ); 559 hig_workarea_add_row( t, &row, _( 560 "Maximum peers per _torrent:" ), w, NULL ); 503 w = new_spin_button( TR_PREFS_KEY_PEER_LIMIT_TORRENT, core, 1, 300, 5 ); 504 hig_workarea_add_row( t, &row, _( "Maximum peers per _torrent:" ), w, NULL ); 561 505 562 506 hig_workarea_add_section_divider( t, &row ); … … 566 510 w = gtk_check_button_new_with_mnemonic( s ); 567 511 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), 568 pref_int_get( 569 PREF_KEY_ENCRYPTION ) == 512 pref_int_get( TR_PREFS_KEY_ENCRYPTION ) == 570 513 TR_ENCRYPTION_REQUIRED ); 571 514 g_signal_connect( w, "toggled", G_CALLBACK( onEncryptionToggled ), core ); … … 573 516 574 517 s = _( "Use peer e_xchange" ); 575 w = new_check_button( s, PREF_KEY_PEX, core );518 w = new_check_button( s, TR_PREFS_KEY_PEX_ENABLED, core ); 576 519 hig_workarea_add_wide_control( t, &row, w ); 577 520 … … 649 592 g_string_truncate( gstr, gstr->len - 1 ); /* remove the trailing comma */ 650 593 651 tr_core_set_pref( page->core, PREF_KEY_RPC_WHITELIST, gstr->str );594 tr_core_set_pref( page->core, TR_PREFS_KEY_RPC_WHITELIST, gstr->str ); 652 595 653 596 g_string_free( gstr, TRUE ); … … 758 701 gpointer data UNUSED ) 759 702 { 760 int port = pref_int_get( PREF_KEY_RPC_PORT );703 int port = pref_int_get( TR_PREFS_KEY_RPC_PORT ); 761 704 char * url = g_strdup_printf( "http://localhost:%d/transmission/web", 762 705 port ); … … 785 728 /* "enabled" checkbutton */ 786 729 s = _( "_Enable web interface" ); 787 w = new_check_button( s, PREF_KEY_RPC_ENABLED, core );730 w = new_check_button( s, TR_PREFS_KEY_RPC_ENABLED, core ); 788 731 page->rpc_tb = GTK_TOGGLE_BUTTON( w ); 789 732 g_signal_connect( w, "clicked", G_CALLBACK( onRPCToggled ), page ); … … 797 740 798 741 /* port */ 799 w = new_spin_button( PREF_KEY_RPC_PORT, core, 0, 65535, 1 );742 w = new_spin_button( TR_PREFS_KEY_RPC_PORT, core, 0, 65535, 1 ); 800 743 page->widgets = g_slist_append( page->widgets, w ); 801 744 w = hig_workarea_add_row( t, &row, _( "Listening _port:" ), w, NULL ); … … 804 747 /* require authentication */ 805 748 s = _( "_Require username" ); 806 w = new_check_button( s, PREF_KEY_RPC_AUTH_ENABLED, core );749 w = new_check_button( s, TR_PREFS_KEY_RPC_AUTH_REQUIRED, core ); 807 750 hig_workarea_add_wide_control( t, &row, w ); 808 751 page->auth_tb = GTK_TOGGLE_BUTTON( w ); … … 812 755 /* username */ 813 756 s = _( "_Username:" ); 814 w = new_entry( PREF_KEY_RPC_USERNAME, core );757 w = new_entry( TR_PREFS_KEY_RPC_USERNAME, core ); 815 758 page->auth_widgets = g_slist_append( page->auth_widgets, w ); 816 759 w = hig_workarea_add_row( t, &row, s, w, NULL ); … … 819 762 /* password */ 820 763 s = _( "Pass_word:" ); 821 w = new_entry( PREF_KEY_RPC_PASSWORD, core );764 w = new_entry( TR_PREFS_KEY_RPC_PASSWORD, core ); 822 765 gtk_entry_set_visibility( GTK_ENTRY( w ), FALSE ); 823 766 page->auth_widgets = g_slist_append( page->auth_widgets, w ); … … 827 770 /* require authentication */ 828 771 s = _( "Only allow the following IP _addresses to connect:" ); 829 w = new_check_button( s, PREF_KEY_RPC_WHITELIST_ENABLED, core );772 w = new_check_button( s, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, core ); 830 773 hig_workarea_add_wide_control( t, &row, w ); 831 774 page->whitelist_tb = GTK_TOGGLE_BUTTON( w ); … … 835 778 /* access control list */ 836 779 { 837 const char * val = pref_string_get( PREF_KEY_RPC_WHITELIST );780 const char * val = pref_string_get( TR_PREFS_KEY_RPC_WHITELIST ); 838 781 GtkTreeModel * m = whitelist_tree_model_new( val ); 839 782 GtkTreeViewColumn * c; … … 920 863 { 921 864 GSList * l; 922 const gboolean proxy_enabled = pref_flag_get( 923 PREF_KEY_PROXY_SERVER_ENABLED ); 924 const gboolean proxy_auth_enabled = pref_flag_get( 925 PREF_KEY_PROXY_AUTH_ENABLED ); 865 const gboolean proxy_enabled = pref_flag_get( TR_PREFS_KEY_PROXY_ENABLED ); 866 const gboolean proxy_auth_enabled = pref_flag_get( TR_PREFS_KEY_PROXY_AUTH_ENABLED ); 926 867 927 868 for( l = p->proxy_widgets; l != NULL; l = l->next ) … … 974 915 { 975 916 struct ProxyPage * page = gpage; 976 int type = TR_PROXY_HTTP; 977 gtk_tree_model_get( gtk_combo_box_get_model( 978 w ), &iter, 1, &type, -1 ); 979 tr_core_set_pref_int( TR_CORE( 980 page->core ), PREF_KEY_PROXY_TYPE, type ); 917 int type = TR_PROXY_HTTP; 918 gtk_tree_model_get( gtk_combo_box_get_model( w ), &iter, 1, &type, -1 ); 919 tr_core_set_pref_int( TR_CORE( page->core ), TR_PREFS_KEY_PROXY_TYPE, type ); 981 920 } 982 921 } … … 999 938 1000 939 s = _( "Connect to tracker via a pro_xy" ); 1001 w = new_check_button( s, PREF_KEY_PROXY_SERVER_ENABLED, core );940 w = new_check_button( s, TR_PREFS_KEY_PROXY_ENABLED, core ); 1002 941 g_signal_connect( w, "toggled", G_CALLBACK( onProxyToggled ), page ); 1003 942 hig_workarea_add_wide_control( t, &row, w ); 1004 943 1005 944 s = _( "Proxy _server:" ); 1006 w = new_entry( PREF_KEY_PROXY_SERVER, core );945 w = new_entry( TR_PREFS_KEY_PROXY, core ); 1007 946 page->proxy_widgets = g_slist_append( page->proxy_widgets, w ); 1008 947 w = hig_workarea_add_row( t, &row, s, w, NULL ); 1009 948 page->proxy_widgets = g_slist_append( page->proxy_widgets, w ); 1010 949 1011 w = new_spin_button( PREF_KEY_PROXY_PORT, core, 0, 65535, 1 );950 w = new_spin_button( TR_PREFS_KEY_PROXY_PORT, core, 0, 65535, 1 ); 1012 951 page->proxy_widgets = g_slist_append( page->proxy_widgets, w ); 1013 952 w = hig_workarea_add_row( t, &row, _( "Proxy _port:" ), w, NULL ); … … 1019 958 r = gtk_cell_renderer_text_new( ); 1020 959 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( w ), r, TRUE ); 1021 gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( 1022 w ), r, "text", 0, NULL ); 1023 gtk_combo_box_set_active( GTK_COMBO_BOX( w ), 1024 pref_int_get( PREF_KEY_PROXY_TYPE ) ); 960 gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( w ), r, "text", 0, NULL ); 961 gtk_combo_box_set_active( GTK_COMBO_BOX( w ), pref_int_get( TR_PREFS_KEY_PROXY_TYPE ) ); 1025 962 g_signal_connect( w, "changed", G_CALLBACK( onProxyTypeChanged ), page ); 1026 963 g_object_unref( G_OBJECT( m ) ); … … 1030 967 1031 968 s = _( "_Authentication is required" ); 1032 w = new_check_button( s, PREF_KEY_PROXY_AUTH_ENABLED, core );969 w = new_check_button( s, TR_PREFS_KEY_PROXY_AUTH_ENABLED, core ); 1033 970 g_signal_connect( w, "toggled", G_CALLBACK( onProxyToggled ), page ); 1034 971 hig_workarea_add_wide_control( t, &row, w ); … … 1036 973 1037 974 s = _( "_Username:" ); 1038 w = new_entry( PREF_KEY_PROXY_USERNAME, core );975 w = new_entry( TR_PREFS_KEY_PROXY_USERNAME, core ); 1039 976 page->proxy_auth_widgets = g_slist_append( page->proxy_auth_widgets, w ); 1040 977 w = hig_workarea_add_row( t, &row, s, w, NULL ); … … 1042 979 1043 980 s = _( "Pass_word:" ); 1044 w = new_entry( PREF_KEY_PROXY_PASSWORD, core );981 w = new_entry( TR_PREFS_KEY_RPC_PASSWORD, core ); 1045 982 gtk_entry_set_visibility( GTK_ENTRY( w ), FALSE ); 1046 983 page->proxy_auth_widgets = g_slist_append( page->proxy_auth_widgets, w ); … … 1166 1103 1167 1104 s = _( "Limit _download speed (KB/s):" ); 1168 w = new_check_button( s, PREF_KEY_DL_LIMIT_ENABLED, core ); 1169 w2 = new_spin_button( PREF_KEY_DL_LIMIT, core, 0, INT_MAX, 5 ); 1170 gtk_widget_set_sensitive( GTK_WIDGET( w2 ), 1171 pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ) ); 1105 w = new_check_button( s, TR_PREFS_KEY_DSPEED_ENABLED, core ); 1106 w2 = new_spin_button( TR_PREFS_KEY_DSPEED, core, 0, INT_MAX, 5 ); 1107 gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED ) ); 1172 1108 g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); 1173 1109 hig_workarea_add_row_w( t, &row, w, w2, NULL ); 1174 1110 1175 1111 s = _( "Limit _upload speed (KB/s):" ); 1176 w = new_check_button( s, PREF_KEY_UL_LIMIT_ENABLED, core ); 1177 w2 = new_spin_button( PREF_KEY_UL_LIMIT, core, 0, INT_MAX, 5 ); 1178 gtk_widget_set_sensitive( GTK_WIDGET( w2 ), 1179 pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ) ); 1112 w = new_check_button( s, TR_PREFS_KEY_USPEED_ENABLED, core ); 1113 w2 = new_spin_button( TR_PREFS_KEY_USPEED, core, 0, INT_MAX, 5 ); 1114 gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED ) ); 1180 1115 g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); 1181 1116 hig_workarea_add_row_w( t, &row, w, w2, NULL ); … … 1202 1137 w = new_spin_button( PREF_KEY_SCHED_DL_LIMIT, core, 0, INT_MAX, 5 ); 1203 1138 page->sched_widgets = g_slist_append( page->sched_widgets, w ); 1204 l = hig_workarea_add_row( t, &row, _( 1205 "Limit d_ownload speed (KB/s):" ), w, 1206 NULL ); 1139 l = hig_workarea_add_row( t, &row, _( "Limit d_ownload speed (KB/s):" ), w, NULL ); 1207 1140 page->sched_widgets = g_slist_append( page->sched_widgets, l ); 1208 1141 1209 1142 w = new_spin_button( PREF_KEY_SCHED_UL_LIMIT, core, 0, INT_MAX, 5 ); 1210 1143 page->sched_widgets = g_slist_append( page->sched_widgets, w ); 1211 l = hig_workarea_add_row( t, &row, _( 1212 "Limit u_pload speed (KB/s):" ), w, NULL ); 1144 l = hig_workarea_add_row( t, &row, _( "Limit u_pload speed (KB/s):" ), w, NULL ); 1213 1145 page->sched_widgets = g_slist_append( page->sched_widgets, l ); 1214 1146 … … 1300 1232 gpointer gdata ) 1301 1233 { 1302 if( !strcmp( key, PREF_KEY_PORT ) )1234 if( !strcmp( key, TR_PREFS_KEY_PEER_PORT ) ) 1303 1235 { 1304 1236 struct network_page_data * ndata = gdata; … … 1355 1287 1356 1288 h = gtk_hbox_new( FALSE, GUI_PAD_BIG ); 1357 w2 = new_spin_button( PREF_KEY_PORT, core, 1, 65535, 1 );1289 w2 = new_spin_button( TR_PREFS_KEY_PEER_PORT, core, 1, 65535, 1 ); 1358 1290 gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 ); 1359 1291 data->label = l = gtk_label_new( NULL ); … … 1365 1297 g_object_set_data( G_OBJECT( l ), "session", 1366 1298 tr_core_session( TR_CORE( core ) ) ); 1367 data->id = g_signal_connect( TR_CORE( 1368 core ), "prefs-changed", 1299 data->id = g_signal_connect( TR_CORE( core ), "prefs-changed", 1369 1300 G_CALLBACK( onCorePrefsChanged ), data ); 1370 onCorePrefsChanged( NULL, PREF_KEY_PORT, data );1301 onCorePrefsChanged( NULL, TR_PREFS_KEY_PEER_PORT, data ); 1371 1302 1372 1303 s = _( "Use UPnP or NAT-PMP port _forwarding from my router" ); 1373 w = new_check_button( s, PREF_KEY_PORT_FORWARDING, core );1304 w = new_check_button( s, TR_PREFS_KEY_PORT_FORWARDING, core ); 1374 1305 hig_workarea_add_wide_control( t, &row, w ); 1375 1306 -
branches/1.5x/gtk/tr-prefs.h
r6870 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the … … 22 22 * default in tr_prefs_init_global( void ) */ 23 23 24 #define PREF_KEY_DL_LIMIT_ENABLED "download-limit-enabled" 25 #define PREF_KEY_DL_LIMIT "download-limit" 26 #define PREF_KEY_UL_LIMIT_ENABLED "upload-limit-enabled" 27 #define PREF_KEY_UL_LIMIT "upload-limit" 28 #define PREF_KEY_SCHED_LIMIT_ENABLED "sched-limit-enabled" 29 #define PREF_KEY_SCHED_BEGIN "sched-begin" 30 #define PREF_KEY_SCHED_END "sched-end" 31 #define PREF_KEY_SCHED_DL_LIMIT "sched-download-limit" 32 #define PREF_KEY_SCHED_UL_LIMIT "sched-upload-limit" 33 #define PREF_KEY_OPTIONS_PROMPT "show-options-window" 34 #define PREF_KEY_DOWNLOAD_DIR "download-dir" 35 #define PREF_KEY_OPEN_DIALOG_FOLDER "open-dialog-dir" 36 #define PREF_KEY_INHIBIT_HIBERNATION "inhibit-desktop-hibernation" 37 #define PREF_KEY_DIR_WATCH "watch-dir" 38 #define PREF_KEY_DIR_WATCH_ENABLED "watch-dir-enabled" 39 #define PREF_KEY_SHOW_TRAY_ICON "show-notification-area-icon" 40 #define PREF_KEY_START "start-added-torrents" 41 #define PREF_KEY_TRASH_ORIGINAL "trash-original-torrent-files" 42 #define PREF_KEY_PEER_SOCKET_TOS "peer-socket-tos" 43 #define PREF_KEY_PORT "peer-port" 44 #define PREF_KEY_PORT_FORWARDING "port-forwarding-enabled" 45 #define PREF_KEY_PEX "pex-enabled" 46 #define PREF_KEY_ASKQUIT "prompt-before-exit" 47 #define PREF_KEY_ENCRYPTION "encryption" 48 #define PREF_KEY_MSGLEVEL "debug-message-level" 49 #define PREF_KEY_LAZY_BITFIELD "lazy-bitfield-enabled" 50 #define PREF_KEY_SORT_MODE "sort-mode" 51 #define PREF_KEY_SORT_REVERSED "sort-reversed" 52 #define PREF_KEY_MINIMAL_VIEW "minimal-view" 53 #define PREF_KEY_FILTERBAR "show-filterbar" 54 #define PREF_KEY_STATUSBAR "show-statusbar" 55 #define PREF_KEY_STATUSBAR_STATS "statusbar-stats" 56 #define PREF_KEY_TOOLBAR "show-toolbar" 57 #define PREF_KEY_MAX_PEERS_GLOBAL "max-peers-global" 58 #define PREF_KEY_MAX_PEERS_PER_TORRENT "max-peers-per-torrent" 59 #define PREF_KEY_BLOCKLIST_ENABLED "blocklist-enabled" 24 #define PREF_KEY_SCHED_LIMIT_ENABLED "sched-limit-enabled" 25 #define PREF_KEY_SCHED_BEGIN "sched-begin" 26 #define PREF_KEY_SCHED_END "sched-end" 27 #define PREF_KEY_SCHED_DL_LIMIT "sched-download-limit" 28 #define PREF_KEY_SCHED_UL_LIMIT "sched-upload-limit" 29 #define PREF_KEY_OPTIONS_PROMPT "show-options-window" 30 #define PREF_KEY_OPEN_DIALOG_FOLDER "open-dialog-dir" 31 #define PREF_KEY_INHIBIT_HIBERNATION "inhibit-desktop-hibernation" 32 #define PREF_KEY_DIR_WATCH "watch-dir" 33 #define PREF_KEY_DIR_WATCH_ENABLED "watch-dir-enabled" 34 #define PREF_KEY_SHOW_TRAY_ICON "show-notification-area-icon" 35 #define PREF_KEY_START "start-added-torrents" 36 #define PREF_KEY_TRASH_ORIGINAL "trash-original-torrent-files" 37 #define PREF_KEY_ASKQUIT "prompt-before-exit" 38 #define PREF_KEY_SORT_MODE "sort-mode" 39 #define PREF_KEY_SORT_REVERSED "sort-reversed" 40 #define PREF_KEY_MINIMAL_VIEW "minimal-view" 41 #define PREF_KEY_FILTERBAR "show-filterbar" 42 #define PREF_KEY_STATUSBAR "show-statusbar" 43 #define PREF_KEY_STATUSBAR_STATS "statusbar-stats" 44 #define PREF_KEY_TOOLBAR "show-toolbar" 60 45 #define PREF_KEY_BLOCKLIST_UPDATES_ENABLED "blocklist-updates-enabled" 61 #define PREF_KEY_MAIN_WINDOW_HEIGHT "main-window-height" 62 #define PREF_KEY_MAIN_WINDOW_WIDTH "main-window-width" 63 #define PREF_KEY_MAIN_WINDOW_X "main-window-x" 64 #define PREF_KEY_MAIN_WINDOW_Y "main-window-y" 65 #define PREF_KEY_RPC_PORT "rpc-port" 66 #define PREF_KEY_RPC_ENABLED "rpc-enabled" 67 #define PREF_KEY_RPC_WHITELIST "rpc-whitelist" 68 #define PREF_KEY_RPC_WHITELIST_ENABLED "rpc-whitelist-enabled" 69 #define PREF_KEY_RPC_AUTH_ENABLED "rpc-authentication-required" 70 #define PREF_KEY_RPC_PASSWORD "rpc-password" 71 #define PREF_KEY_RPC_USERNAME "rpc-username" 72 #define PREF_KEY_PROXY_SERVER "proxy-server" 73 #define PREF_KEY_PROXY_PORT "proxy-port" 74 #define PREF_KEY_PROXY_SERVER_ENABLED "proxy-server-enabled" 75 #define PREF_KEY_PROXY_TYPE "proxy-type" 76 #define PREF_KEY_PROXY_AUTH_ENABLED "proxy-authentication-required" 77 #define PREF_KEY_PROXY_USERNAME "proxy-username" 78 #define PREF_KEY_PROXY_PASSWORD "proxy-authentication" 79 46 #define PREF_KEY_MAIN_WINDOW_LAYOUT_ORDER "main-window-layout-order" 47 #define PREF_KEY_MAIN_WINDOW_HEIGHT "main-window-height" 48 #define PREF_KEY_MAIN_WINDOW_WIDTH "main-window-width" 49 #define PREF_KEY_MAIN_WINDOW_X "main-window-x" 50 #define PREF_KEY_MAIN_WINDOW_Y "main-window-y" 80 51 81 52 void tr_prefs_init_global( void ); -
branches/1.5x/gtk/tr-torrent.c
r6978 r7664 167 167 void * user_data ) 168 168 { 169 if( completeness == TR_CP_COMPLETE)169 if( completeness != TR_LEECH ) 170 170 g_idle_add( notifyInMainThread, user_data ); 171 171 } … … 319 319 tr_torrent_delete_files( TrTorrent * gtor ) 320 320 { 321 tr_file_index_t i; 322 const tr_info * info = tr_torrent_info( gtor ); 323 const char * stop = 324 tr_torrentGetDownloadDir( tr_torrent_handle( gtor ) ); 325 326 for( i = 0; info && i < info->fileCount; ++i ) 327 { 328 char * file = g_build_filename( stop, info->files[i].name, NULL ); 329 while( strcmp( stop, file ) && strlen( stop ) < strlen( file ) ) 330 { 331 char * swap = g_path_get_dirname( file ); 332 tr_file_trash_or_unlink( file ); 333 g_free( file ); 334 file = swap; 335 } 336 337 g_free( file ); 338 } 321 tr_torrentDeleteLocalData( tr_torrent_handle( gtor ), tr_file_trash_or_unlink ); 339 322 } 340 323 -
branches/1.5x/gtk/tr-window.c
r7260 r7664 129 129 gpointer user_data UNUSED ) 130 130 { 131 action_activate( "show-torrent- details" );131 action_activate( "show-torrent-properties" ); 132 132 } 133 133 … … 499 499 500 500 GtkWidget * 501 tr_window_new( GtkUIManager * ui_manager, 502 TrCore * core ) 501 tr_window_new( GtkUIManager * ui_mgr, TrCore * core ) 503 502 { 504 503 int i, n; 505 504 const char * pch; 506 505 PrivateData * p; 506 GtkWidget *mainmenu, *toolbar, *filter, *list, *status; 507 507 GtkWidget * vbox, *w, *self, *h, *c, *s, *image, *menu; 508 508 GtkWindow * win; 509 509 GSList * l; 510 510 GSList * toggles; 511 511 512 const char * filter_names[FILTER_MODE_QTY] = { 512 513 /* show all torrents */ … … 538 539 gtk_window_set_role( win, "tr-main" ); 539 540 gtk_window_set_default_size( win, 540 pref_int_get( PREF_KEY_MAIN_WINDOW_WIDTH ),541 pref_int_get( PREF_KEY_MAIN_WINDOW_HEIGHT ) );541 pref_int_get( PREF_KEY_MAIN_WINDOW_WIDTH ), 542 pref_int_get( PREF_KEY_MAIN_WINDOW_HEIGHT ) ); 542 543 gtk_window_move( win, pref_int_get( PREF_KEY_MAIN_WINDOW_X ), 543 pref_int_get( PREF_KEY_MAIN_WINDOW_Y ) ); 544 gtk_window_add_accel_group( win, 545 gtk_ui_manager_get_accel_group( ui_manager ) ); 544 pref_int_get( PREF_KEY_MAIN_WINDOW_Y ) ); 545 gtk_window_add_accel_group( win, gtk_ui_manager_get_accel_group( ui_mgr ) ); 546 546 547 547 /* window's main container */ … … 550 550 551 551 /* main menu */ 552 w = action_get_widget( "/main-window-menu" ); 553 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); 552 w = mainmenu = action_get_widget( "/main-window-menu" ); 554 553 w = action_get_widget( "/main-window-menu/torrent-menu/update-tracker" ); 555 554 #if GTK_CHECK_VERSION( 2, 12, 0 ) … … 559 558 560 559 /* toolbar */ 561 w = p->toolbar = action_get_widget( "/main-window-toolbar" ); 562 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 ); 560 w = toolbar = p->toolbar = action_get_widget( "/main-window-toolbar" ); 563 561 564 562 /* filter */ 565 563 toggles = NULL; 566 h = p->filter = gtk_hbox_new( FALSE, 0 );564 h = filter = p->filter = gtk_hbox_new( FALSE, 0 ); 567 565 gtk_container_set_border_width( GTK_CONTAINER( h ), GUI_PAD_SMALL ); 568 566 for( i = 0; i < FILTER_MODE_QTY; ++i ) … … 591 589 TRUE ); 592 590 gtk_box_pack_end( GTK_BOX( h ), s, FALSE, FALSE, 0 ); 593 gtk_box_pack_start( GTK_BOX( vbox ), h, FALSE, FALSE, 0 );594 591 g_signal_connect( s, "changed", G_CALLBACK( filter_entry_changed ), p ); 595 596 w = gtk_hseparator_new( );597 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );598 592 599 593 /* status menu */ … … 618 612 619 613 /* status */ 620 h = p->status = gtk_hbox_new( FALSE, GUI_PAD );614 h = status = p->status = gtk_hbox_new( FALSE, GUI_PAD ); 621 615 gtk_container_set_border_width( GTK_CONTAINER( h ), GUI_PAD ); 622 616 w = p->gutter_lb = gtk_label_new( "N Torrents" ); … … 645 639 g_signal_connect( w, "button-release-event", 646 640 G_CALLBACK( onYinYangReleased ), p ); 647 gtk_box_pack_start( GTK_BOX( vbox ), h, FALSE, FALSE, 0 );648 641 649 642 menu = gtk_menu_new( ); … … 654 647 GtkWidget * w = gtk_radio_menu_item_new_with_label ( l, name ); 655 648 l = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM( w ) ); 656 g_object_set_data( G_OBJECT( 657 w ), FILTER_TEXT_MODE_KEY,GINT_TO_POINTER( i ) );658 g_signal_connect( w, "toggled", G_CALLBACK(659 649 g_object_set_data( G_OBJECT( w ), FILTER_TEXT_MODE_KEY, 650 GINT_TO_POINTER( i ) ); 651 g_signal_connect( w, "toggled", 652 G_CALLBACK( filter_text_toggled_cb ), p ); 660 653 gtk_menu_shell_append( GTK_MENU_SHELL( menu ), w ); 661 654 gtk_widget_show( w ); 662 655 } 663 g_signal_connect( s, "icon-released", G_CALLBACK(664 656 g_signal_connect( s, "icon-released", 657 G_CALLBACK( entry_icon_released ), menu ); 665 658 666 659 /* workarea */ 667 660 p->view = makeview( p, core ); 668 w = p->scroll = gtk_scrolled_window_new( NULL, NULL ); 669 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( 670 w ), GTK_POLICY_NEVER, 671 GTK_POLICY_AUTOMATIC ); 672 gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( 673 w ), GTK_SHADOW_IN ); 661 w = list = p->scroll = gtk_scrolled_window_new( NULL, NULL ); 662 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( w ), 663 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); 664 gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( w ), 665 GTK_SHADOW_IN ); 674 666 gtk_container_add( GTK_CONTAINER( w ), p->view ); 675 gtk_box_pack_start( GTK_BOX( vbox ), w, TRUE, TRUE, 0 ); 676 gtk_container_set_focus_child( GTK_CONTAINER( vbox ), w ); 667 668 /* layout the widgets */ 669 { 670 const char * str = pref_string_get( PREF_KEY_MAIN_WINDOW_LAYOUT_ORDER ); 671 char ** tokens = g_strsplit( str, ",", -1 ); 672 for( i=0; tokens && tokens[i]; ++i ) 673 { 674 const char * key = tokens[i]; 675 676 if( !strcmp( key, "menu" ) ) 677 gtk_box_pack_start( GTK_BOX( vbox ), mainmenu, FALSE, FALSE, 0 ); 678 else if( !strcmp( key, "toolbar" ) ) 679 gtk_box_pack_start( GTK_BOX( vbox ), toolbar, FALSE, FALSE, 0 ); 680 else if( !strcmp( key, "filter" ) ) 681 gtk_box_pack_start( GTK_BOX( vbox ), filter, FALSE, FALSE, 0 ); 682 else if( !strcmp( key, "list" ) ) 683 gtk_box_pack_start( GTK_BOX( vbox ), list, TRUE, TRUE, 0 ); 684 else if( !strcmp( key, "statusbar" ) ) 685 gtk_box_pack_start( GTK_BOX( vbox ), status, FALSE, FALSE, 0 ); 686 } 687 g_strfreev( tokens ); 688 } 677 689 678 690 /* show all but the window */ … … 740 752 tr_strlsize( up, stats.uploadedBytes, sizeof( up ) ); 741 753 tr_strlsize( down, stats.downloadedBytes, sizeof( down ) ); 742 /* Translators: do not translate the "size|" disambiguation prefix.754 /* Translators: "size|" is here for disambiguation. Please remove it from your translation. 743 755 %1$s is the size of the data we've downloaded 744 756 %2$s is the size of the data we've uploaded */ … … 751 763 tr_strlsize( up, stats.uploadedBytes, sizeof( up ) ); 752 764 tr_strlsize( down, stats.downloadedBytes, sizeof( down ) ); 753 /* Translators: do not translate the "size|" disambiguation prefix.765 /* Translators: "size|" is here for disambiguation. Please remove it from your translation. 754 766 %1$s is the size of the data we've downloaded 755 767 %2$s is the size of the data we've uploaded */ -
branches/1.5x/gtk/tracker-list.c
r7463 r7664 1 1 /* 2 * This file Copyright (C) 2007-200 8 Charles Kerr <charles@rebelbase.com>2 * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com> 3 3 * 4 4 * This file is licensed by the GPL version 2. Works owned by the -
branches/1.5x/gtk/ui.h
r6870 r7664 6 6 " <menuitem action='new-torrent'/>\n" 7 7 " <separator/>\n" 8 " <menuitem action='show-torrent- details'/>\n"8 " <menuitem action='show-torrent-properties'/>\n" 9 9 " <menuitem action='open-torrent-folder'/>\n" 10 10 " <separator/>\n" … … 56 56 " <toolitem action='remove-torrent'/>\n" 57 57 " <separator/>\n" 58 " <toolitem action='show-torrent- details'/>\n"58 " <toolitem action='show-torrent-properties'/>\n" 59 59 " </toolbar>\n" 60 60 "\n" 61 61 " <popup name='main-window-popup'>\n" 62 " <menuitem action='show-torrent- details'/>\n"62 " <menuitem action='show-torrent-properties'/>\n" 63 63 " <menuitem action='open-torrent-folder'/>\n" 64 64 " <separator/>\n" … … 79 79 " <menuitem action='show-about-dialog'/>\n" 80 80 " <separator/>\n" 81 " <menuitem action='pause-all-torrents'/>\n" 82 " <separator/>\n" 81 83 " <menuitem action='quit'/>\n" 82 84 " </popup>\n" -
branches/1.5x/gtk/util.c
r7463 r7664 515 515 } 516 516 517 void 517 int 518 518 tr_file_trash_or_unlink( const char * filename ) 519 519 { … … 522 522 gboolean trashed = FALSE; 523 523 #ifdef HAVE_GIO 524 GError * err = NULL;525 524 GFile * file = g_file_new_for_path( filename ); 526 trashed = g_file_trash( file, NULL, &err);525 trashed = g_file_trash( file, NULL, NULL ); 527 526 g_object_unref( G_OBJECT( file ) ); 528 527 #endif … … 530 529 g_unlink( filename ); 531 530 } 531 532 return 0; 532 533 } 533 534 -
branches/1.5x/gtk/util.h
r7463 r7664 133 133 gpointer tr_object_ref_sink( gpointer object ); 134 134 135 voidtr_file_trash_or_unlink( const char * filename );135 int tr_file_trash_or_unlink( const char * filename ); 136 136 137 137 #endif /* GTK_MAJOR_VERSION */ -
branches/1.5x/libtransmission/ConvertUTF.c
r6795 r7664 1 1 /* 2 2 * Copyright 2001-2004 Unicode, Inc. 3 * 3 * 4 4 * Disclaimer 5 * 5 * 6 6 * This source code is provided as is by Unicode, Inc. No claims are 7 7 * made as to fitness for any particular purpose. No warranties of any … … 11 11 * sole remedy for any claim will be exchange of defective media 12 12 * within 90 days of receipt. 13 * 13 * 14 14 * Limitations on Rights to Redistribute This Code 15 * 15 * 16 16 * Unicode, Inc. hereby grants the right to freely use the information 17 17 * supplied in this file in the creation of products supporting the … … 27 27 Rev History: Rick McGowan, fixes & updates May 2001. 28 28 Sept 2001: fixed const & error conditions per 29 29 mods suggested by S. Parent & A. Lillich. 30 30 June 2002: Tim Dodd added detection and handling of incomplete 31 32 31 source sequences, enhanced error detection, added casts 32 to eliminate compiler warnings. 33 33 July 2003: slight mods to back out aggressive FFFE detection. 34 34 Jan 2004: updated switches in from-UTF8 conversions. 35 35 Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. 36 May 2006: updated isLegalUTF8Sequence. 36 37 37 38 See the header file "ConvertUTF.h" for complete documentation. 38 39 39 ------------------------------------------------------------------------ */ 40 41 42 #include "ConvertUTF.h" 40 ------------------------------------------------------------------------ */ 41 43 42 #ifdef CVTUTF_DEBUG 44 43 #include <stdio.h> 45 44 #endif 46 47 static const int halfShift = 10; /* used for shifting by 10 bits */ 45 #include <string.h> /* strlen() */ 46 #include <unistd.h> /* ssize_t */ 47 #include "ConvertUTF.h" 48 49 static const int halfShift = 10; /* used for shifting by 10 bits */ 48 50 49 51 static const UTF32 halfBase = 0x0010000UL; … … 54 56 #define UNI_SUR_LOW_START (UTF32)0xDC00 55 57 #define UNI_SUR_LOW_END (UTF32)0xDFFF 56 #define false 0 57 #define true 1 58 59 /* --------------------------------------------------------------------- */ 60 61 ConversionResult 62 ConvertUTF32toUTF16( const UTF32** sourceStart, 63 const UTF32* sourceEnd, 64 UTF16** targetStart, 65 UTF16* targetEnd, 66 ConversionFlags flags ) 67 { 58 #define false 0 59 #define true 1 60 61 /* --------------------------------------------------------------------- */ 62 63 ConversionResult ConvertUTF32toUTF16 ( 64 const UTF32** sourceStart, const UTF32* sourceEnd, 65 UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { 68 66 ConversionResult result = conversionOK; 69 const UTF32* source = *sourceStart; 70 UTF16* target = *targetStart; 71 72 while( source < sourceEnd ) 73 { 74 UTF32 ch; 75 if( target >= targetEnd ) 76 { 77 result = targetExhausted; break; 78 } 79 ch = *source++; 80 if( ch <= UNI_MAX_BMP ) /* Target is a character <= 0xFFFF */ 81 { /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are 82 both reserved values */ 83 if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END ) 84 { 85 if( flags == strictConversion ) 86 { 87 --source; /* return to the illegal value itself */ 88 result = sourceIllegal; 89 break; 90 } 91 else 92 { 93 *target++ = UNI_REPLACEMENT_CHAR; 94 } 95 } 96 else 97 { 98 *target++ = (UTF16)ch; /* normal case */ 99 } 100 } 101 else if( ch > UNI_MAX_LEGAL_UTF32 ) 102 { 103 if( flags == strictConversion ) 104 { 105 result = sourceIllegal; 106 } 107 else 108 { 109 *target++ = UNI_REPLACEMENT_CHAR; 110 } 111 } 112 else 113 { 114 /* target is a character in range 0xFFFF - 0x10FFFF. */ 115 if( target + 1 >= targetEnd ) 116 { 117 --source; /* Back up source pointer! */ 118 result = targetExhausted; break; 119 } 120 ch -= halfBase; 121 *target++ = (UTF16)( ( ch >> halfShift ) + UNI_SUR_HIGH_START ); 122 *target++ = (UTF16)( ( ch & halfMask ) + UNI_SUR_LOW_START ); 123 } 124 } 125 67 const UTF32* source = *sourceStart; 68 UTF16* target = *targetStart; 69 while (source < sourceEnd) { 70 UTF32 ch; 71 if (target >= targetEnd) { 72 result = targetExhausted; break; 73 } 74 ch = *source++; 75 if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ 76 /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ 77 if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { 78 if (flags == strictConversion) { 79 --source; /* return to the illegal value itself */ 80 result = sourceIllegal; 81 break; 82 } else { 83 *target++ = UNI_REPLACEMENT_CHAR; 84 } 85 } else { 86 *target++ = (UTF16)ch; /* normal case */ 87 } 88 } else if (ch > UNI_MAX_LEGAL_UTF32) { 89 if (flags == strictConversion) { 90 result = sourceIllegal; 91 } else { 92 *target++ = UNI_REPLACEMENT_CHAR; 93 } 94 } else { 95 /* target is a character in range 0xFFFF - 0x10FFFF. */ 96 if (target + 1 >= targetEnd) { 97 --source; /* Back up source pointer! */ 98 result = targetExhausted; break; 99 } 100 ch -= halfBase; 101 *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); 102 *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); 103 } 104 } 126 105 *sourceStart = source; 127 106 *targetStart = target; … … 131 110 /* --------------------------------------------------------------------- */ 132 111 133 ConversionResult 134 ConvertUTF16toUTF32( const UTF16** sourceStart, 135 const UTF16* sourceEnd, 136 UTF32** targetStart, 137 UTF32* targetEnd, 138 ConversionFlags flags ) 139 { 112 ConversionResult ConvertUTF16toUTF32 ( 113 const UTF16** sourceStart, const UTF16* sourceEnd, 114 UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { 140 115 ConversionResult result = conversionOK; 141 const UTF16* source = *sourceStart; 142 UTF32* target = *targetStart; 143 UTF32 ch, ch2; 144 145 while( source < sourceEnd ) 146 { 147 const UTF16* oldSource = source; /* In case we have to back up because 148 of target overflow. */ 149 ch = *source++; 150 /* If we have a surrogate pair, convert to UTF32 first. */ 151 if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END ) 152 { 153 /* If the 16 bits following the high surrogate are in the source 154 buffer... */ 155 if( source < sourceEnd ) 156 { 157 ch2 = *source; 158 /* If it's a low surrogate, convert to UTF32. */ 159 if( ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END ) 160 { 161 ch = ( ( ch - UNI_SUR_HIGH_START ) << halfShift ) 162 + ( ch2 - UNI_SUR_LOW_START ) + halfBase; 163 ++source; 164 } 165 else if( flags == strictConversion ) /* it's an unpaired high 166 surrogate */ 167 { 168 --source; /* return to the illegal value itself */ 169 result = sourceIllegal; 170 break; 171 } 172 } 173 else /* We don't have the 16 bits following the high surrogate. */ 174 { 175 --source; /* return to the high surrogate */ 176 result = sourceExhausted; 177 break; 178 } 179 } 180 else if( flags == strictConversion ) 181 { 182 /* UTF-16 surrogate values are illegal in UTF-32 */ 183 if( ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END ) 184 { 185 --source; /* return to the illegal value itself */ 186 result = sourceIllegal; 187 break; 188 } 189 } 190 if( target >= targetEnd ) 191 { 192 source = oldSource; /* Back up source pointer! */ 193 result = targetExhausted; break; 194 } 195 *target++ = ch; 196 } 197 116 const UTF16* source = *sourceStart; 117 UTF32* target = *targetStart; 118 UTF32 ch, ch2; 119 while (source < sourceEnd) { 120 const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ 121 ch = *source++; 122 /* If we have a surrogate pair, convert to UTF32 first. */ 123 if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { 124 /* If the 16 bits following the high surrogate are in the source buffer... */ 125 if (source < sourceEnd) { 126 ch2 = *source; 127 /* If it's a low surrogate, convert to UTF32. */ 128 if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { 129 ch = ((ch - UNI_SUR_HIGH_START) << halfShift) 130 + (ch2 - UNI_SUR_LOW_START) + halfBase; 131 ++source; 132 } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ 133 --source; /* return to the illegal value itself */ 134 result = sourceIllegal; 135 break; 136 } 137 } else { /* We don't have the 16 bits following the high surrogate. */ 138 --source; /* return to the high surrogate */ 139 result = sourceExhausted; 140 break; 141 } 142 } else if (flags == strictConversion) { 143 /* UTF-16 surrogate values are illegal in UTF-32 */ 144 if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { 145 --source; /* return to the illegal value itself */ 146 result = sourceIllegal; 147 break; 148 } 149 } 150 if (target >= targetEnd) { 151 source = oldSource; /* Back up source pointer! */ 152 result = targetExhausted; break; 153 } 154 *target++ = ch; 155 } 198 156 *sourceStart = source; 199 157 *targetStart = target; 200 158 #ifdef CVTUTF_DEBUG 201 if( result == sourceIllegal ) 202 { 203 fprintf( stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", 204 ch, 205 ch2 ); 206 fflush( stderr ); 207 } 159 if (result == sourceIllegal) { 160 fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); 161 fflush(stderr); 162 } 208 163 #endif 209 164 return result; … … 219 174 * allowed in earlier algorithms. 220 175 */ 221 static const char trailingBytesForUTF8[256] = { 222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223 0, 0, 0, 0, 0, 0, 0, 0, 224 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225 0, 0, 0, 0, 0, 0, 0, 0, 226 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 227 0, 0, 0, 0, 0, 0, 0, 0, 228 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229 0, 0, 0, 0, 0, 0, 0, 0, 230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231 0, 0, 0, 0, 0, 0, 0, 0, 232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233 0, 0, 0, 0, 0, 0, 0, 0, 234 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 235 1, 1, 1, 1, 1, 1, 1, 1, 236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 237 4, 4, 4, 4, 5, 5, 5, 5 176 static const char trailingBytesForUTF8[256] = { 177 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 178 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 179 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 180 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 181 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 182 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 183 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 184 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 238 185 }; 239 186 … … 243 190 * in a UTF-8 sequence. 244 191 */ 245 static const UTF32 offsetsFromUTF8[6] = 246 { 0x00000000UL, 0x00003080UL, 247 0x000E2080UL, 248 0x03C82080UL, 0xFA082080UL, 249 0x82082080UL }; 192 static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 193 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; 250 194 251 195 /* … … 256 200 * for *legal* UTF-8 will be 4 or fewer bytes total. 257 201 */ 258 static const UTF8 firstByteMark[7] = 259 { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; 202 static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; 260 203 261 204 /* --------------------------------------------------------------------- */ … … 271 214 /* --------------------------------------------------------------------- */ 272 215 273 ConversionResult 274 ConvertUTF16toUTF8( const UTF16** sourceStart, 275 const UTF16* sourceEnd, 276 UTF8** targetStart, 277 UTF8* targetEnd, 278 ConversionFlags flags ) 279 { 216 ConversionResult ConvertUTF16toUTF8 ( 217 const UTF16** sourceStart, const UTF16* sourceEnd, 218 UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { 280 219 ConversionResult result = conversionOK; 281 const UTF16* source = *sourceStart; 282 UTF8* target = *targetStart; 283 284 while( source < sourceEnd ) 285 { 286 UTF32 ch; 287 unsigned short bytesToWrite = 0; 288 const UTF32 byteMask = 0xBF; 289 const UTF32 byteMark = 0x80; 290 const UTF16* oldSource = source; /* In case we have to back up because 291 of target overflow. */ 292 ch = *source++; 293 /* If we have a surrogate pair, convert to UTF32 first. */ 294 if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END ) 295 { 296 /* If the 16 bits following the high surrogate are in the source 297 buffer... */ 298 if( source < sourceEnd ) 299 { 300 UTF32 ch2 = *source; 301 /* If it's a low surrogate, convert to UTF32. */ 302 if( ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END ) 303 { 304 ch = ( ( ch - UNI_SUR_HIGH_START ) << halfShift ) 305 + ( ch2 - UNI_SUR_LOW_START ) + halfBase; 306 ++source; 307 } 308 else if( flags == strictConversion ) /* it's an unpaired high 309 surrogate */ 310 { 311 --source; /* return to the illegal value itself */ 312 result = sourceIllegal; 313 break; 314 } 315 } 316 else /* We don't have the 16 bits following the high surrogate. */ 317 { 318 --source; /* return to the high surrogate */ 319 result = sourceExhausted; 320 break; 321 } 322 } 323 else if( flags == strictConversion ) 324 { 325 /* UTF-16 surrogate values are illegal in UTF-32 */ 326 if( ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END ) 327 { 328 --source; /* return to the illegal value itself */ 329 result = sourceIllegal; 330 break; 331 } 332 } 333 /* Figure out how many bytes the result will require */ 334 if( ch < (UTF32)0x80 ) 335 { 336 bytesToWrite = 1; 337 } 338 else if( ch < (UTF32)0x800 ) 339 { 340 bytesToWrite = 2; 341 } 342 else if( ch < (UTF32)0x10000 ) 343 { 344 bytesToWrite = 3; 345 } 346 else if( ch < (UTF32)0x110000 ) 347 { 348 bytesToWrite = 4; 349 } 350 else 351 { 352 bytesToWrite = 3; 353 ch = UNI_REPLACEMENT_CHAR; 354 } 355 356 target += bytesToWrite; 357 if( target > targetEnd ) 358 { 359 source = oldSource; /* Back up source pointer! */ 360 target -= bytesToWrite; result = targetExhausted; break; 361 } 362 switch( bytesToWrite ) /* note: everything falls through. */ 363 { 364 case 4: 365 *--target = 366 (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6; 367 368 case 3: 369 *--target = 370 (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6; 371 372 case 2: 373 *--target = 374 (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6; 375 376 case 1: 377 *--target = (UTF8)( ch | firstByteMark[bytesToWrite] ); 378 } 379 target += bytesToWrite; 380 } 381 220 const UTF16* source = *sourceStart; 221 UTF8* target = *targetStart; 222 while (source < sourceEnd) { 223 UTF32 ch; 224 unsigned short bytesToWrite = 0; 225 const UTF32 byteMask = 0xBF; 226 const UTF32 byteMark = 0x80; 227 const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ 228 ch = *source++; 229 /* If we have a surrogate pair, convert to UTF32 first. */ 230 if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { 231 /* If the 16 bits following the high surrogate are in the source buffer... */ 232 if (source < sourceEnd) { 233 UTF32 ch2 = *source; 234 /* If it's a low surrogate, convert to UTF32. */ 235 if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { 236 ch = ((ch - UNI_SUR_HIGH_START) << halfShift) 237 + (ch2 - UNI_SUR_LOW_START) + halfBase; 238 ++source; 239 } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ 240 --source; /* return to the illegal value itself */ 241 result = sourceIllegal; 242 break; 243 } 244 } else { /* We don't have the 16 bits following the high surrogate. */ 245 --source; /* return to the high surrogate */ 246 result = sourceExhausted; 247 break; 248 } 249 } else if (flags == strictConversion) { 250 /* UTF-16 surrogate values are illegal in UTF-32 */ 251 if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { 252 --source; /* return to the illegal value itself */ 253 result = sourceIllegal; 254 break; 255 } 256 } 257 /* Figure out how many bytes the result will require */ 258 if (ch < (UTF32)0x80) { bytesToWrite = 1; 259 } else if (ch < (UTF32)0x800) { bytesToWrite = 2; 260 } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; 261 } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; 262 } else { bytesToWrite = 3; 263 ch = UNI_REPLACEMENT_CHAR; 264 } 265 266 target += bytesToWrite; 267 if (target > targetEnd) { 268 source = oldSource; /* Back up source pointer! */ 269 target -= bytesToWrite; result = targetExhausted; break; 270 } 271 switch (bytesToWrite) { /* note: everything falls through. */ 272 case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; 273 case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; 274 case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; 275 case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); 276 } 277 target += bytesToWrite; 278 } 382 279 *sourceStart = source; 383 280 *targetStart = target; … … 398 295 */ 399 296 400 static Boolean 401 isLegalUTF8( const UTF8 *source, 402 int length ) 403 { 404 UTF8 a; 405 const UTF8 *srcptr = source + length; 406 407 switch( length ) 408 { 409 default: 410 return false; 411 412 /* Everything else falls through when "true"... */ 413 case 4: 414 if( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return false; 415 416 case 3: 417 if( ( a = ( *--srcptr ) ) < 0x80 || a > 0xBF ) return false; 418 419 case 2: 420 if( ( a = ( *--srcptr ) ) > 0xBF ) return false; 421 422 switch( *source ) 423 { 424 /* no fall-through in this inner switch */ 425 case 0xE0: 426 if( a < 0xA0 ) return false;break; 427 428 case 0xED: 429 if( a > 0x9F ) return false;break; 430 431 case 0xF0: 432 if( a < 0x90 ) return false;break; 433 434 case 0xF4: 435 if( a > 0x8F ) return false;break; 436 437 default: 438 if( a < 0x80 ) return false; 439 } 440 441 case 1: 442 if( *source >= 0x80 && *source < 0xC2 ) return false; 443 } 444 if( *source > 0xF4 ) return false; 297 static Boolean isLegalUTF8(const UTF8 *source, int length) { 298 UTF8 a; 299 const UTF8 *srcptr = source+length; 300 switch (length) { 301 default: return false; 302 /* Everything else falls through when "true"... */ 303 case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; 304 case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; 305 case 2: if ((a = (*--srcptr)) > 0xBF) return false; 306 307 switch (*source) { 308 /* no fall-through in this inner switch */ 309 case 0xE0: if (a < 0xA0) return false; break; 310 case 0xED: if ((a < 0x80) || (a > 0x9F)) return false; break; 311 case 0xF0: if (a < 0x90) return false; break; 312 case 0xF4: if (a > 0x8F) return false; break; 313 default: if (a < 0x80) return false; 314 } 315 316 case 1: if (*source >= 0x80 && *source < 0xC2) return false; 317 } 318 if (*source > 0xF4) return false; 445 319 return true; 446 320 } … … 452 326 * This is not used here; it's just exported. 453 327 */ 328 329 Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { 330 int length; 331 if (source == sourceEnd) { 332 return true; 333 } 334 while (true) { 335 length = trailingBytesForUTF8[*source]+1; 336 if (source+length > sourceEnd) { 337 return false; 338 } 339 if (!isLegalUTF8(source, length)) { 340 return false; 341 } 342 source += length; 343 if (source >= sourceEnd) { 344 return true; 345 } 346 } 347 } 348 349 /** 350 * This is a variation of isLegalUTF8Sequence() that behaves like g_utf8_validate(). 351 * In addition to knowing if the sequence is legal, it also tells you the last good character. 352 */ 454 353 Boolean 455 isLegalUTF8Sequence( const UTF8 *source, 456 const UTF8 *sourceEnd ) 354 tr_utf8_validate( const char * str, ssize_t max_len, const char ** end ) 457 355 { 458 int length = trailingBytesForUTF8[*source] + 1; 459 460 if( source + length > sourceEnd ) 356 const UTF8* source = (const UTF8*) str; 357 const UTF8* sourceEnd = source; 358 359 if( max_len == 0 ) 360 return true; 361 362 if( str == NULL ) 363 return false; 364 365 sourceEnd = source + ((max_len < 0) ? strlen(str) : (size_t)max_len); 366 367 if( source == sourceEnd ) 461 368 { 462 return false; 463 } 464 return isLegalUTF8( source, length ); 465 } 466 467 /* --------------------------------------------------------------------- */ 468 469 ConversionResult 470 ConvertUTF8toUTF16( const UTF8** sourceStart, 471 const UTF8* sourceEnd, 472 UTF16** targetStart, 473 UTF16* targetEnd, 474 ConversionFlags flags ) 475 { 369 if( end != NULL ) 370 *end = (const char*) source; 371 return true; 372 } 373 374 for( ;; ) 375 { 376 const int length = trailingBytesForUTF8[*source] + 1; 377 if (source + length > sourceEnd) { 378 if( end != NULL ) 379 *end = (const char*) source; 380 return false; 381 } 382 if (!isLegalUTF8(source, length)) { 383 if( end != NULL ) 384 *end = (const char*) source; 385 return false; 386 } 387 source += length; 388 if (source >= sourceEnd) { 389 if( end != NULL ) 390 *end = (const char*) source; 391 return true; 392 } 393 } 394 395 396 } 397 398 399 /* --------------------------------------------------------------------- */ 400 401 ConversionResult ConvertUTF8toUTF16 ( 402 const UTF8** sourceStart, const UTF8* sourceEnd, 403 UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { 476 404 ConversionResult result = conversionOK; 477 const UTF8* source = *sourceStart; 478 UTF16* target = *targetStart; 479 480 while( source < sourceEnd ) 481 { 482 UTF32 ch = 0; 483 unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; 484 if( source + extraBytesToRead >= sourceEnd ) 485 { 486 result = sourceExhausted; break; 487 } 488 /* Do this check whether lenient or strict */ 489 if( !isLegalUTF8( source, extraBytesToRead + 1 ) ) 490 { 491 result = sourceIllegal; 492 break; 493 } 494 /* 495 * The cases all fall through. See "Note A" below. 496 */ 497 switch( extraBytesToRead ) 498 { 499 case 5: 500 ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ 501 502 case 4: 503 ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ 504 505 case 3: 506 ch += *source++; ch <<= 6; 507 508 case 2: 509 ch += *source++; ch <<= 6; 510 511 case 1: 512 ch += *source++; ch <<= 6; 513 514 case 0: 515 ch += *source++; 516 } 517 ch -= offsetsFromUTF8[extraBytesToRead]; 518 519 if( target >= targetEnd ) 520 { 521 source -= ( extraBytesToRead + 1 ); /* Back up source pointer! */ 522 result = targetExhausted; break; 523 } 524 if( ch <= UNI_MAX_BMP ) /* Target is a character <= 0xFFFF */ 525 { /* UTF-16 surrogate values are illegal in UTF-32 */ 526 if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END ) 527 { 528 if( flags == strictConversion ) 529 { 530 source -= ( extraBytesToRead + 1 ); /* return to the illegal 531 value itself */ 532 result = sourceIllegal; 533 break; 534 } 535 else 536 { 537 *target++ = UNI_REPLACEMENT_CHAR; 538 } 539 } 540 else 541 { 542 *target++ = (UTF16)ch; /* normal case */ 543 } 544 } 545 else if( ch > UNI_MAX_UTF16 ) 546 { 547 if( flags == strictConversion ) 548 { 549 result = sourceIllegal; 550 source -= ( extraBytesToRead + 1 ); /* return to the start */ 551 break; /* Bail out; shouldn't continue */ 552 } 553 else 554 { 555 *target++ = UNI_REPLACEMENT_CHAR; 556 } 557 } 558 else 559 { 560 /* target is a character in range 0xFFFF - 0x10FFFF. */ 561 if( target + 1 >= targetEnd ) 562 { 563 source -= ( extraBytesToRead + 1 ); /* Back up source pointer! 564 */ 565 result = targetExhausted; break; 566 } 567 ch -= halfBase; 568 *target++ = (UTF16)( ( ch >> halfShift ) + UNI_SUR_HIGH_START ); 569 *target++ = (UTF16)( ( ch & halfMask ) + UNI_SUR_LOW_START ); 570 } 571 } 572 405 const UTF8* source = *sourceStart; 406 UTF16* target = *targetStart; 407 while (source < sourceEnd) { 408 UTF32 ch = 0; 409 unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; 410 if (source + extraBytesToRead >= sourceEnd) { 411 result = sourceExhausted; break; 412 } 413 /* Do this check whether lenient or strict */ 414 if (! isLegalUTF8(source, extraBytesToRead+1)) { 415 result = sourceIllegal; 416 break; 417 } 418 /* 419 * The cases all fall through. See "Note A" below. 420 */ 421 switch (extraBytesToRead) { 422 case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ 423 case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ 424 case 3: ch += *source++; ch <<= 6; 425 case 2: ch += *source++; ch <<= 6; 426 case 1: ch += *source++; ch <<= 6; 427 case 0: ch += *source++; 428 } 429 ch -= offsetsFromUTF8[extraBytesToRead]; 430 431 if (target >= targetEnd) { 432 source -= (extraBytesToRead+1); /* Back up source pointer! */ 433 result = targetExhausted; break; 434 } 435 if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ 436 /* UTF-16 surrogate values are illegal in UTF-32 */ 437 if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { 438 if (flags == strictConversion) { 439 source -= (extraBytesToRead+1); /* return to the illegal value itself */ 440 result = sourceIllegal; 441 break; 442 } else { 443 *target++ = UNI_REPLACEMENT_CHAR; 444 } 445 } else { 446 *target++ = (UTF16)ch; /* normal case */ 447 } 448 } else if (ch > UNI_MAX_UTF16) { 449 if (flags == strictConversion) { 450 result = sourceIllegal; 451 source -= (extraBytesToRead+1); /* return to the start */ 452 break; /* Bail out; shouldn't continue */ 453 } else { 454 *target++ = UNI_REPLACEMENT_CHAR; 455 } 456 } else { 457 /* target is a character in range 0xFFFF - 0x10FFFF. */ 458 if (target + 1 >= targetEnd) { 459 source -= (extraBytesToRead+1); /* Back up source pointer! */ 460 result = targetExhausted; break; 461 } 462 ch -= halfBase; 463 *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); 464 *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); 465 } 466 } 573 467 *sourceStart = source; 574 468 *targetStart = target; … … 578 472 /* --------------------------------------------------------------------- */ 579 473 580 ConversionResult 581 ConvertUTF32toUTF8( const UTF32** sourceStart, 582 const UTF32* sourceEnd, 583 UTF8** targetStart, 584 UTF8* targetEnd, 585 ConversionFlags flags ) 586 { 474 ConversionResult ConvertUTF32toUTF8 ( 475 const UTF32** sourceStart, const UTF32* sourceEnd, 476 UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { 587 477 ConversionResult result = conversionOK; 588 const UTF32* source = *sourceStart; 589 UTF8* target = *targetStart; 590 591 while( source < sourceEnd ) 592 { 593 UTF32 ch; 594 unsigned short bytesToWrite = 0; 595 const UTF32 byteMask = 0xBF; 596 const UTF32 byteMark = 0x80; 597 ch = *source++; 598 if( flags == strictConversion ) 599 { 600 /* UTF-16 surrogate values are illegal in UTF-32 */ 601 if( ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END ) 602 { 603 --source; /* return to the illegal value itself */ 604 result = sourceIllegal; 605 break; 606 } 607 } 608 /* 609 * Figure out how many bytes the result will require. Turn any 610 * illegally large UTF32 things (> Plane 17) into replacement chars. 611 */ 612 if( ch < (UTF32)0x80 ) 613 { 614 bytesToWrite = 1; 615 } 616 else if( ch < (UTF32)0x800 ) 617 { 618 bytesToWrite = 2; 619 } 620 else if( ch < (UTF32)0x10000 ) 621 { 622 bytesToWrite = 3; 623 } 624 else if( ch <= UNI_MAX_LEGAL_UTF32 ) 625 { 626 bytesToWrite = 4; 627 } 628 else 629 { 630 bytesToWrite = 3; 631 ch = UNI_REPLACEMENT_CHAR; 632 result = sourceIllegal; 633 } 634 635 target += bytesToWrite; 636 if( target > targetEnd ) 637 { 638 --source; /* Back up source pointer! */ 639 target -= bytesToWrite; result = targetExhausted; break; 640 } 641 switch( bytesToWrite ) /* note: everything falls through. */ 642 { 643 case 4: 644 *--target = 645 (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6; 646 647 case 3: 648 *--target = 649 (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6; 650 651 case 2: 652 *--target = 653 (UTF8)( ( ch | byteMark ) & byteMask ); ch >>= 6; 654 655 case 1: 656 *--target = (UTF8) ( ch | firstByteMark[bytesToWrite] ); 657 } 658 target += bytesToWrite; 659 } 660 478 const UTF32* source = *sourceStart; 479 UTF8* target = *targetStart; 480 while (source < sourceEnd) { 481 UTF32 ch; 482 unsigned short bytesToWrite = 0; 483 const UTF32 byteMask = 0xBF; 484 const UTF32 byteMark = 0x80; 485 ch = *source++; 486 if (flags == strictConversion ) { 487 /* UTF-16 surrogate values are illegal in UTF-32 */ 488 if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { 489 --source; /* return to the illegal value itself */ 490 result = sourceIllegal; 491 break; 492 } 493 } 494 /* 495 * Figure out how many bytes the result will require. Turn any 496 * illegally large UTF32 things (> Plane 17) into replacement chars. 497 */ 498 if (ch < (UTF32)0x80) { bytesToWrite = 1; 499 } else if (ch < (UTF32)0x800) { bytesToWrite = 2; 500 } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; 501 } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; 502 } else { bytesToWrite = 3; 503 ch = UNI_REPLACEMENT_CHAR; 504 result = sourceIllegal; 505 } 506 507 target += bytesToWrite; 508 if (target > targetEnd) { 509 --source; /* Back up source pointer! */ 510 target -= bytesToWrite; result = targetExhausted; break; 511 } 512 switch (bytesToWrite) { /* note: everything falls through. */ 513 case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; 514 case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; 515 case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; 516 case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); 517 } 518 target += bytesToWrite; 519 } 661 520 *sourceStart = source; 662 521 *targetStart = target; … … 666 525 /* --------------------------------------------------------------------- */ 667 526 668 ConversionResult 669 ConvertUTF8toUTF32( const UTF8** sourceStart, 670 const UTF8* sourceEnd, 671 UTF32** targetStart, 672 UTF32* targetEnd, 673 ConversionFlags flags ) 674 { 527 ConversionResult ConvertUTF8toUTF32 ( 528 const UTF8** sourceStart, const UTF8* sourceEnd, 529 UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { 675 530 ConversionResult result = conversionOK; 676 const UTF8* source = *sourceStart; 677 UTF32* target = *targetStart; 678 679 while( source < sourceEnd ) 680 { 681 UTF32 ch = 0; 682 unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; 683 if( source + extraBytesToRead >= sourceEnd ) 684 { 685 result = sourceExhausted; break; 686 } 687 /* Do this check whether lenient or strict */ 688 if( !isLegalUTF8( source, extraBytesToRead + 1 ) ) 689 { 690 result = sourceIllegal; 691 break; 692 } 693 /* 694 * The cases all fall through. See "Note A" below. 695 */ 696 switch( extraBytesToRead ) 697 { 698 case 5: 699 ch += *source++; ch <<= 6; 700 701 case 4: 702 ch += *source++; ch <<= 6; 703 704 case 3: 705 ch += *source++; ch <<= 6; 706 707 case 2: 708 ch += *source++; ch <<= 6; 709 710 case 1: 711 ch += *source++; ch <<= 6; 712 713 case 0: 714