gtk/cli/daemon/remote/proxy: add command-line argument --config-dir / -g to override the default config dir
This commit is contained in:
parent
b483b30889
commit
1ae1607025
|
@ -56,6 +56,8 @@ scripting capabilities.
|
|||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl g, Fl -config-dir Ar directory
|
||||
Where to look for configuration files.
|
||||
.It Fl c, Fl -create-from Ar source-file
|
||||
Create torrent from the specified source file.
|
||||
.It Fl a, Fl -announce Ar announce-url
|
||||
|
|
|
@ -43,23 +43,24 @@
|
|||
#endif
|
||||
|
||||
const char * USAGE =
|
||||
"Usage: %s [-car[-m]] [-dfinpsuv] [-h] file.torrent [output-dir]\n\n"
|
||||
"Usage: %s [-car[-m]] [-dfginpsuv] [-h] file.torrent [output-dir]\n\n"
|
||||
"Options:\n"
|
||||
" -h, --help Print this help and exit\n"
|
||||
" -i, --info Print metainfo and exit\n"
|
||||
" -s, --scrape Print counts of seeders/leechers and exit\n"
|
||||
" -V, --version Print the version number and exit\n"
|
||||
" -c, --create-from <file> Create torrent from the specified source file.\n"
|
||||
" -a, --announce <url> Used in conjunction with -c.\n"
|
||||
" -r, --private Used in conjunction with -c.\n"
|
||||
" -m, --comment <text> Adds an optional comment when creating a torrent.\n"
|
||||
" -d, --download <int> Maximum download rate (-1 = no limit, default = -1)\n"
|
||||
" -f, --finish <shell script> Command you wish to run on completion\n"
|
||||
" -h, --help Print this help and exit\n"
|
||||
" -i, --info Print metainfo and exit\n"
|
||||
" -n --nat-traversal Attempt NAT traversal using NAT-PMP or UPnP IGD\n"
|
||||
" -p, --port <int> Port we should listen on (default = %d)\n"
|
||||
" -s, --scrape Print counts of seeders/leechers and exit\n"
|
||||
" -u, --upload <int> Maximum upload rate (-1 = no limit, default = 20)\n"
|
||||
" -v, --verbose <int> Verbose level (0 to 2, default = 0)\n"
|
||||
" -V, --version Print the version number and exit\n"
|
||||
" -y, --recheck Force a recheck of the torrent data\n";
|
||||
" -a, --announce <url> Used in conjunction with -c.\n"
|
||||
" -g, --config-dir <path> Where to look for configuration files\n"
|
||||
" -r, --private Used in conjunction with -c.\n"
|
||||
" -m, --comment <text> Adds an optional comment when creating a torrent.\n"
|
||||
" -d, --download <int> Max download rate (-1 = no limit, default = -1)\n"
|
||||
" -f, --finish <script> Command you wish to run on completion\n"
|
||||
" -n --nat-traversal Attempt NAT traversal using NAT-PMP or UPnP IGD\n"
|
||||
" -p, --port <int> Port we should listen on (default = %d)\n"
|
||||
" -u, --upload <int> Maximum upload rate (-1 = no limit, default = 20)\n"
|
||||
" -v, --verbose <int> Verbose level (0 to 2, default = 0)\n"
|
||||
" -y, --recheck Force a recheck of the torrent data\n";
|
||||
|
||||
static int showHelp = 0;
|
||||
static int showInfo = 0;
|
||||
|
@ -79,6 +80,7 @@ static sig_atomic_t manualUpdate = 0;
|
|||
|
||||
static char * finishCall = NULL;
|
||||
static char * announce = NULL;
|
||||
static char * configdir = NULL;
|
||||
static char * sourceFile = NULL;
|
||||
static char * comment = NULL;
|
||||
|
||||
|
@ -144,8 +146,11 @@ main( int argc, char ** argv )
|
|||
if( showInfo || showScrape || ( sourceFile != NULL ) )
|
||||
bindPort = -1;
|
||||
|
||||
if( configdir == NULL )
|
||||
configdir = strdup( tr_getDefaultConfigDir( ) );
|
||||
|
||||
/* Initialize libtransmission */
|
||||
h = tr_initFull( TR_DEFAULT_CONFIG_DIR,
|
||||
h = tr_initFull( configdir,
|
||||
"cli", /* tag */
|
||||
1, /* pex enabled */
|
||||
natTraversal, /* nat enabled */
|
||||
|
@ -377,83 +382,53 @@ parseCommandLine( int argc, char ** argv )
|
|||
{
|
||||
for( ;; )
|
||||
{
|
||||
static struct option long_options[] =
|
||||
{ { "help", no_argument, NULL, 'h' },
|
||||
{ "info", no_argument, NULL, 'i' },
|
||||
{ "scrape", no_argument, NULL, 's' },
|
||||
{ "private", no_argument, NULL, 'r' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "verbose", required_argument, NULL, 'v' },
|
||||
{ "port", required_argument, NULL, 'p' },
|
||||
{ "upload", required_argument, NULL, 'u' },
|
||||
{ "download", required_argument, NULL, 'd' },
|
||||
{ "finish", required_argument, NULL, 'f' },
|
||||
{ "create-from", required_argument, NULL, 'c' },
|
||||
{ "comment", required_argument, NULL, 'm' },
|
||||
{ "announce", required_argument, NULL, 'a' },
|
||||
{ "nat-traversal", no_argument, NULL, 'n' },
|
||||
{ "recheck", no_argument, NULL, 'y' },
|
||||
{ "output-dir", required_argument, NULL, 'o' },
|
||||
static const struct option long_options[] = {
|
||||
{ "announce", required_argument, NULL, 'a' },
|
||||
{ "create-from", required_argument, NULL, 'c' },
|
||||
{ "download", required_argument, NULL, 'd' },
|
||||
{ "finish", required_argument, NULL, 'f' },
|
||||
{ "config-dir", required_argument, NULL, 'g' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "info", no_argument, NULL, 'i' },
|
||||
{ "comment", required_argument, NULL, 'm' },
|
||||
{ "nat-traversal", no_argument, NULL, 'n' },
|
||||
{ "output-dir", required_argument, NULL, 'o' },
|
||||
{ "port", required_argument, NULL, 'p' },
|
||||
{ "private", no_argument, NULL, 'r' },
|
||||
{ "scrape", no_argument, NULL, 's' },
|
||||
{ "upload", required_argument, NULL, 'u' },
|
||||
{ "verbose", required_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "recheck", no_argument, NULL, 'y' },
|
||||
{ 0, 0, 0, 0} };
|
||||
|
||||
int c, optind = 0;
|
||||
c = getopt_long( argc, argv, "hisrVv:p:u:d:f:c:m:a:no:y",
|
||||
long_options, &optind );
|
||||
int optind = 0;
|
||||
int c = getopt_long( argc, argv,
|
||||
"a:c:d:f:g:him:no:p:rsu:v:Vy",
|
||||
long_options, &optind );
|
||||
if( c < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
switch( c )
|
||||
{
|
||||
case 'h':
|
||||
showHelp = 1;
|
||||
break;
|
||||
case 'i':
|
||||
showInfo = 1;
|
||||
break;
|
||||
case 's':
|
||||
showScrape = 1;
|
||||
break;
|
||||
case 'r':
|
||||
isPrivate = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verboseLevel = atoi( optarg );
|
||||
break;
|
||||
case 'V':
|
||||
showVersion = 1;
|
||||
break;
|
||||
case 'p':
|
||||
bindPort = atoi( optarg );
|
||||
break;
|
||||
case 'u':
|
||||
uploadLimit = atoi( optarg );
|
||||
break;
|
||||
case 'd':
|
||||
downloadLimit = atoi( optarg );
|
||||
break;
|
||||
case 'f':
|
||||
finishCall = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
sourceFile = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
comment = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
announce = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
natTraversal = 1;
|
||||
break;
|
||||
case 'y':
|
||||
recheckData = 1;
|
||||
break;
|
||||
case 'o':
|
||||
savePath = optarg;
|
||||
default:
|
||||
return 1;
|
||||
case 'a': announce = optarg; break;
|
||||
case 'c': sourceFile = optarg; break;
|
||||
case 'd': downloadLimit = atoi( optarg ); break;
|
||||
case 'f': finishCall = optarg; break;
|
||||
case 'g': configdir = strdup( optarg ); break;
|
||||
case 'h': showHelp = 1; break;
|
||||
case 'i': showInfo = 1; break;
|
||||
case 'm': comment = optarg; break;
|
||||
case 'n': natTraversal = 1; break;
|
||||
case 'o': savePath = optarg;
|
||||
case 'p': bindPort = atoi( optarg ); break;
|
||||
case 'r': isPrivate = 1; break;
|
||||
case 's': showScrape = 1; break;
|
||||
case 'u': uploadLimit = atoi( optarg ); break;
|
||||
case 'v': verboseLevel = atoi( optarg ); break;
|
||||
case 'V': showVersion = 1; break;
|
||||
case 'y': recheckData = 1; break;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,9 +136,9 @@ client_new_sock( const char * path )
|
|||
int fd;
|
||||
struct con * con;
|
||||
|
||||
assert( NULL != gl_base );
|
||||
assert( gl_base );
|
||||
assert( path );
|
||||
assert( 0 > gl_proxy );
|
||||
assert( NULL != path );
|
||||
|
||||
gl_proxy = 0;
|
||||
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
#include "torrents.h"
|
||||
|
||||
static void usage ( const char *, ... );
|
||||
static void readargs ( int, char **, int *, int *, char **, char ** );
|
||||
static int trylocksock ( const char * );
|
||||
static void readargs ( int, char **, int *, int *, char **, char **, char ** );
|
||||
static int trylocksock ( const char * configdir, const char * sockpath );
|
||||
static int getsock ( const char * );
|
||||
static void exitcleanup ( void );
|
||||
static void setupsigs ( struct event_base * );
|
||||
|
@ -68,23 +68,24 @@ main( int argc, char ** argv )
|
|||
{
|
||||
struct event_base * evbase;
|
||||
int nofork, debug, sockfd;
|
||||
char * sockpath, * pidfile;
|
||||
char * configdir, * sockpath, * pidfile;
|
||||
|
||||
setmyname( argv[0] );
|
||||
readargs( argc, argv, &nofork, &debug, &sockpath, &pidfile );
|
||||
readargs( argc, argv, &nofork, &debug, &configdir, &sockpath, &pidfile );
|
||||
|
||||
if( !nofork )
|
||||
{
|
||||
if( 0 > daemon( 1, 0 ) )
|
||||
{
|
||||
if( !nofork ) {
|
||||
if( 0 > daemon( 1, 0 ) ) {
|
||||
errnomsg( "failed to daemonize" );
|
||||
exit( 1 );
|
||||
}
|
||||
errsyslog( 1 );
|
||||
}
|
||||
|
||||
if( configdir == NULL )
|
||||
configdir = (char*) tr_getDefaultConfigDir( );
|
||||
|
||||
atexit( exitcleanup );
|
||||
sockfd = trylocksock( sockpath );
|
||||
sockfd = trylocksock( configdir, sockpath );
|
||||
if( 0 > sockfd )
|
||||
{
|
||||
exit( 1 );
|
||||
|
@ -96,7 +97,7 @@ main( int argc, char ** argv )
|
|||
|
||||
evbase = event_init();
|
||||
setupsigs( evbase );
|
||||
torrent_init( evbase );
|
||||
torrent_init( configdir, evbase );
|
||||
server_init( evbase );
|
||||
server_debug( debug );
|
||||
server_listen( sockfd );
|
||||
|
@ -128,6 +129,7 @@ usage( const char * msg, ... )
|
|||
"\n"
|
||||
" -d --debug Print data send and received, implies -f\n"
|
||||
" -f --foreground Run in the foreground and log to stderr\n"
|
||||
" -g --config-dir <path> Where to look for configuration files\n"
|
||||
" -h --help Display this message and exit\n"
|
||||
" -p --pidfile <path> Save the process id in a file at <path>\n"
|
||||
" -s --socket <path> Place the socket file at <path>\n"
|
||||
|
@ -138,14 +140,15 @@ usage( const char * msg, ... )
|
|||
}
|
||||
|
||||
void
|
||||
readargs( int argc, char ** argv, int * nofork, int * debug, char ** sock,
|
||||
char ** pidfile )
|
||||
readargs( int argc, char ** argv, int * nofork, int * debug,
|
||||
char ** configdir, char ** sock, char ** pidfile )
|
||||
{
|
||||
char optstr[] = "dfhp:s:";
|
||||
char optstr[] = "dfg:hp:s:";
|
||||
struct option longopts[] =
|
||||
{
|
||||
{ "debug", no_argument, NULL, 'd' },
|
||||
{ "foreground", no_argument, NULL, 'f' },
|
||||
{ "config-dir", required_argument, NULL, 'g' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "pidfile", required_argument, NULL, 'p' },
|
||||
{ "socket", required_argument, NULL, 's' },
|
||||
|
@ -157,26 +160,16 @@ readargs( int argc, char ** argv, int * nofork, int * debug, char ** sock,
|
|||
*debug = 0;
|
||||
*sock = NULL;
|
||||
*pidfile = NULL;
|
||||
*configdir = NULL;
|
||||
|
||||
while( 0 <= ( opt = getopt_long( argc, argv, optstr, longopts, NULL ) ) )
|
||||
{
|
||||
switch( opt )
|
||||
{
|
||||
case 'd':
|
||||
*debug = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 'f':
|
||||
*nofork = 1;
|
||||
break;
|
||||
case 'p':
|
||||
*pidfile = optarg;
|
||||
break;
|
||||
case 's':
|
||||
*sock = optarg;
|
||||
break;
|
||||
default:
|
||||
usage( NULL );
|
||||
break;
|
||||
while( 0 <= ( opt = getopt_long( argc, argv, optstr, longopts, NULL ) ) ) {
|
||||
switch( opt ) {
|
||||
case 'd': *debug = 1; /* FALLTHROUGH */
|
||||
case 'f': *nofork = 1; break;
|
||||
case 'g': *configdir = strdup( optarg ); break;
|
||||
case 'p': *pidfile = optarg; break;
|
||||
case 's': *sock = optarg; break;
|
||||
default: usage( NULL ); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -204,26 +197,26 @@ getlock( const char * filename )
|
|||
|
||||
|
||||
int
|
||||
trylocksock( const char * sockpath )
|
||||
trylocksock( const char * configdir, const char * sockpath )
|
||||
{
|
||||
char path[MAXPATHLEN];
|
||||
int fd;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
confpath( path, sizeof path, NULL, CONF_PATH_TYPE_DAEMON );
|
||||
confpath( path, sizeof path, configdir, NULL, CONF_PATH_TYPE_DAEMON );
|
||||
if( 0 > mkdir( path, 0777 ) && EEXIST != errno )
|
||||
{
|
||||
errnomsg( "failed to create directory: %s", path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
confpath( path, sizeof path, CONF_FILE_LOCK, 0 );
|
||||
confpath( path, sizeof path, configdir, CONF_FILE_LOCK, 0 );
|
||||
if( !getlock( path ) )
|
||||
return -1;
|
||||
strlcpy( gl_lockpath, path, sizeof gl_lockpath );
|
||||
|
||||
if( NULL == sockpath )
|
||||
if( !sockpath )
|
||||
{
|
||||
confpath( path, sizeof path, CONF_FILE_SOCKET, 0 );
|
||||
confpath( path, sizeof path, configdir, CONF_FILE_SOCKET, 0 );
|
||||
sockpath = path;
|
||||
}
|
||||
fd = getsock( sockpath );
|
||||
|
|
|
@ -77,9 +77,13 @@ pushdir( char * path, const char * file, size_t size )
|
|||
}
|
||||
|
||||
void
|
||||
confpath( char * buf, size_t len, const char * file, enum confpathtype type )
|
||||
confpath( char * buf,
|
||||
size_t len,
|
||||
const char * configDir,
|
||||
const char * file,
|
||||
enum confpathtype type )
|
||||
{
|
||||
strlcpy( buf, tr_getDefaultConfigDir(), len );
|
||||
strlcpy( buf, configDir, len );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
|
|
|
@ -136,7 +136,7 @@ SLIST_HEAD( strlist, stritem );
|
|||
|
||||
void setmyname ( const char * );
|
||||
const char * getmyname ( void );
|
||||
void confpath ( char *, size_t, const char *, enum confpathtype );
|
||||
void confpath ( char *, size_t, const char *, const char *, enum confpathtype );
|
||||
void absolutify( char *, size_t, const char * );
|
||||
int writefile ( const char *, uint8_t *, ssize_t );
|
||||
uint8_t * readfile ( const char *, size_t * );
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
#include "misc.h"
|
||||
|
||||
static void usage ( const char *, ... );
|
||||
static enum confpathtype readargs ( int, char **, char ** );
|
||||
static int makesock ( enum confpathtype, const char * );
|
||||
static enum confpathtype readargs ( int, char **, char **, char ** );
|
||||
static int makesock ( enum confpathtype, const char *, const char * );
|
||||
static void inread ( struct bufferevent *, void * );
|
||||
static void noop ( struct bufferevent *, void * );
|
||||
static void inerr ( struct bufferevent *, short, void * );
|
||||
|
@ -62,14 +62,18 @@ main( int argc, char ** argv )
|
|||
{
|
||||
struct event_base * base;
|
||||
enum confpathtype type;
|
||||
char * configdir;
|
||||
char * sockpath;
|
||||
int sockfd;
|
||||
|
||||
setmyname( argv[0] );
|
||||
type = readargs( argc, argv, &sockpath );
|
||||
type = readargs( argc, argv, &configdir, &sockpath );
|
||||
if( configdir == NULL )
|
||||
configdir = strdup( tr_getDefaultConfigDir( ) );
|
||||
|
||||
base = event_init();
|
||||
|
||||
sockfd = makesock( type, sockpath );
|
||||
sockfd = makesock( type, configdir, sockpath );
|
||||
if( 0 > sockfd )
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
|
@ -132,6 +136,7 @@ usage( const char * msg, ... )
|
|||
"A fast and easy BitTorrent client\n"
|
||||
"\n"
|
||||
" -h --help Display this message and exit\n"
|
||||
" -g --config-dir <path> Where to look for configuration files\n"
|
||||
" -t --type daemon Use the daemon frontend, transmission-daemon\n"
|
||||
" -t --type gtk Use the GTK+ frontend, transmission\n"
|
||||
" -t --type mac Use the Mac OS X frontend\n",
|
||||
|
@ -140,11 +145,12 @@ usage( const char * msg, ... )
|
|||
}
|
||||
|
||||
enum confpathtype
|
||||
readargs( int argc, char ** argv, char ** sockpath )
|
||||
readargs( int argc, char ** argv, char ** configdir, char ** sockpath )
|
||||
{
|
||||
char optstr[] = "ht:";
|
||||
char optstr[] = "g:ht:";
|
||||
struct option longopts[] =
|
||||
{
|
||||
{ "config-dir", required_argument, NULL, 'g' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "type", required_argument, NULL, 't' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
|
@ -152,13 +158,18 @@ readargs( int argc, char ** argv, char ** sockpath )
|
|||
enum confpathtype type;
|
||||
int opt;
|
||||
|
||||
type = CONF_PATH_TYPE_DAEMON;
|
||||
*sockpath = NULL;
|
||||
type = CONF_PATH_TYPE_DAEMON;
|
||||
*configdir = NULL;
|
||||
*sockpath = NULL;
|
||||
|
||||
while( 0 <= ( opt = getopt_long( argc, argv, optstr, longopts, NULL ) ) )
|
||||
{
|
||||
switch( opt )
|
||||
{
|
||||
case 'g':
|
||||
*configdir = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if( 0 == strcasecmp( "daemon", optarg ) )
|
||||
{
|
||||
|
@ -193,20 +204,22 @@ readargs( int argc, char ** argv, char ** sockpath )
|
|||
}
|
||||
|
||||
int
|
||||
makesock( enum confpathtype type, const char * path )
|
||||
makesock( enum confpathtype type,
|
||||
const char * configdir,
|
||||
const char * sockpath )
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int fd;
|
||||
|
||||
memset( &sa, 0, sizeof sa );
|
||||
sa.sun_family = AF_LOCAL;
|
||||
if( NULL == path )
|
||||
if( !sockpath )
|
||||
{
|
||||
confpath( sa.sun_path, sizeof sa.sun_path, CONF_FILE_SOCKET, type );
|
||||
confpath( sa.sun_path, sizeof sa.sun_path, configdir, CONF_FILE_SOCKET, type );
|
||||
}
|
||||
else
|
||||
{
|
||||
strlcpy( sa.sun_path, path, sizeof sa.sun_path );
|
||||
strlcpy( sa.sun_path, sockpath, sizeof sa.sun_path );
|
||||
}
|
||||
|
||||
fd = socket( AF_UNIX, SOCK_STREAM, 0 );
|
||||
|
|
|
@ -74,6 +74,7 @@ struct opts
|
|||
char dir[MAXPATHLEN];
|
||||
int pex;
|
||||
const char * crypto;
|
||||
const char * configdir;
|
||||
};
|
||||
|
||||
struct torinfo
|
||||
|
@ -144,13 +145,14 @@ main( int argc, char ** argv )
|
|||
{
|
||||
struct event_base * evbase;
|
||||
struct opts o;
|
||||
char sockpath[MAXPATHLEN];
|
||||
|
||||
setmyname( argv[0] );
|
||||
|
||||
if( 0 > readargs( argc, argv, &o ) )
|
||||
{
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if( o.configdir == NULL )
|
||||
o.configdir = strdup( tr_getDefaultConfigDir( ) );
|
||||
|
||||
signal( SIGPIPE, SIG_IGN );
|
||||
|
||||
|
@ -163,14 +165,12 @@ main( int argc, char ** argv )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( NULL == o.sock )
|
||||
{
|
||||
confpath( sockpath, sizeof sockpath, CONF_FILE_SOCKET, o.type );
|
||||
client_new_sock( sockpath );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( o.sock )
|
||||
client_new_sock( o.sock );
|
||||
else {
|
||||
char sockpath[MAXPATHLEN];
|
||||
confpath( sockpath, sizeof sockpath, o.configdir, CONF_FILE_SOCKET, o.type );
|
||||
client_new_sock( sockpath );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,7 @@ usage( const char * msg, ... )
|
|||
" -e --enable-pex Enable peer exchange\n"
|
||||
" -E --disable-pex Disable peer exchange\n"
|
||||
" -f --folder <path> Folder to set for new torrents\n"
|
||||
" -g --config-dir <path> Where to look for configuration files\n"
|
||||
" -h --help Display this message and exit\n"
|
||||
" -i --info List all torrents with info hashes\n"
|
||||
" -l --list List all torrents with status\n"
|
||||
|
@ -271,7 +272,7 @@ usage( const char * msg, ... )
|
|||
int
|
||||
readargs( int argc, char ** argv, struct opts * opts )
|
||||
{
|
||||
char optstr[] = "a:c:d:DeEf:hilmMp:qr:s:S:t:u:Uxv:";
|
||||
char optstr[] = "a:c:d:DeEf:g:hilmMp:qr:s:S:t:u:Uxv:";
|
||||
struct option longopts[] =
|
||||
{
|
||||
{ "add", required_argument, NULL, 'a' },
|
||||
|
@ -281,6 +282,7 @@ readargs( int argc, char ** argv, struct opts * opts )
|
|||
{ "enable-pex", no_argument, NULL, 'e' },
|
||||
{ "disable-pex", no_argument, NULL, 'E' },
|
||||
{ "folder", required_argument, NULL, 'f' },
|
||||
{ "config-dir", required_argument, NULL, 'g' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "info", no_argument, NULL, 'i' },
|
||||
{ "list", no_argument, NULL, 'l' },
|
||||
|
@ -306,6 +308,7 @@ readargs( int argc, char ** argv, struct opts * opts )
|
|||
SLIST_INIT( &opts->files );
|
||||
opts->map = -1;
|
||||
opts->pex = -1;
|
||||
opts->configdir = NULL;
|
||||
SLIST_INIT( &opts->start );
|
||||
SLIST_INIT( &opts->stop );
|
||||
SLIST_INIT( &opts->remove );
|
||||
|
@ -347,6 +350,9 @@ readargs( int argc, char ** argv, struct opts * opts )
|
|||
case 'f':
|
||||
absolutify( opts->dir, sizeof opts->dir, optarg );
|
||||
break;
|
||||
case 'g':
|
||||
opts->configdir = strdup( optarg );
|
||||
break;
|
||||
case 'i':
|
||||
opts->listquick = 1;
|
||||
break;
|
||||
|
|
|
@ -104,14 +104,14 @@ INTCMP_FUNC( toridcmp, tor, id )
|
|||
RB_GENERATE_STATIC( tortree, tor, idlinks, toridcmp )
|
||||
|
||||
void
|
||||
torrent_init( struct event_base * base )
|
||||
torrent_init( const char * configdir, struct event_base * base )
|
||||
{
|
||||
assert( NULL == gl_handle && NULL == gl_base );
|
||||
|
||||
gl_base = base;
|
||||
gl_handle = tr_init( tr_getDefaultConfigDir(), "daemon" );
|
||||
gl_handle = tr_init( configdir, "daemon" );
|
||||
|
||||
confpath( gl_state, sizeof gl_state, CONF_FILE_STATE, 0 );
|
||||
confpath( gl_state, sizeof gl_state, configdir, CONF_FILE_STATE, 0 );
|
||||
strlcpy( gl_newstate, gl_state, sizeof gl_state );
|
||||
strlcat( gl_newstate, ".new", sizeof gl_state );
|
||||
absolutify( gl_dir, sizeof gl_dir, "." );
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
struct event_base;
|
||||
|
||||
void torrent_init ( struct event_base * );
|
||||
void torrent_init ( const char * configDir, struct event_base * );
|
||||
int torrent_add_file ( const char *, const char *, int );
|
||||
int torrent_add_data ( uint8_t *, size_t, const char *, int );
|
||||
void torrent_start ( int );
|
||||
|
|
|
@ -55,6 +55,8 @@ Print command-line option descriptions.
|
|||
.It Fl p Fl -pidfile Ar pid-file
|
||||
Save the daemon's process ID in
|
||||
.Ar pid-file .
|
||||
.It Fl g, Fl -config-dir Ar directory
|
||||
Where to look for configuration files.
|
||||
.It Fl s Fl -socket Ar socket-file
|
||||
Create the unix-domain socket file at
|
||||
.Ar socket-file
|
||||
|
|
|
@ -41,6 +41,8 @@ Connect to either
|
|||
.Xr transmission-daemon 1
|
||||
or
|
||||
.Xr transmission 1 .
|
||||
.It Fl g, Fl -config-dir Ar directory
|
||||
Where to look for configuration files.
|
||||
.It Fl h Fl -help
|
||||
Print command-line option descriptions.
|
||||
.El
|
||||
|
|
|
@ -116,6 +116,8 @@ Disable peer exchange.
|
|||
Use
|
||||
.Ar directory
|
||||
as the default location for newly added torrents to download files to.
|
||||
.It Fl g, Fl -config-dir Ar directory
|
||||
Where to look for configuration files.
|
||||
.It Fl h Fl -help
|
||||
Print command-line option descriptions.
|
||||
.It Fl i Fl -info
|
||||
|
|
25
gtk/main.c
25
gtk/main.c
|
@ -275,7 +275,7 @@ main( int argc, char ** argv )
|
|||
gboolean startpaused = FALSE;
|
||||
gboolean startminimized = FALSE;
|
||||
char * domain = "transmission";
|
||||
const char * configDir = tr_getDefaultConfigDir( );
|
||||
char * configDir = NULL;
|
||||
|
||||
GOptionEntry entries[] = {
|
||||
{ "paused", 'p', 0, G_OPTION_ARG_NONE, &startpaused,
|
||||
|
@ -286,6 +286,8 @@ main( int argc, char ** argv )
|
|||
{ "minimized", 'm', 0, G_OPTION_ARG_NONE, &startminimized,
|
||||
_( "Start minimized in system tray"), NULL },
|
||||
#endif
|
||||
{ "config-dir", 'g', 0, G_OPTION_ARG_FILENAME, &configDir,
|
||||
_( "Where to look for configuration files" ), NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -307,6 +309,8 @@ main( int argc, char ** argv )
|
|||
g_clear_error( &gerr );
|
||||
return 0;
|
||||
}
|
||||
if( !configDir )
|
||||
configDir = (char*) tr_getDefaultConfigDir( );
|
||||
|
||||
tr_notify_init( );
|
||||
|
||||
|
@ -325,7 +329,24 @@ main( int argc, char ** argv )
|
|||
if( ( didinit || cf_init( configDir, &err ) ) &&
|
||||
( didlock || cf_lock( &err ) ) )
|
||||
{
|
||||
cbdata->core = tr_core_new( );
|
||||
tr_handle * h = tr_initFull( configDir,
|
||||
"gtk",
|
||||
pref_flag_get( PREF_KEY_PEX ),
|
||||
pref_flag_get( PREF_KEY_NAT ),
|
||||
pref_int_get( PREF_KEY_PORT ),
|
||||
pref_flag_get( PREF_KEY_ENCRYPTED_ONLY )
|
||||
? TR_ENCRYPTION_REQUIRED
|
||||
: TR_ENCRYPTION_PREFERRED,
|
||||
pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ),
|
||||
pref_int_get( PREF_KEY_UL_LIMIT ),
|
||||
pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ),
|
||||
pref_int_get( PREF_KEY_DL_LIMIT ),
|
||||
pref_int_get( PREF_KEY_MAX_PEERS_GLOBAL ),
|
||||
pref_int_get( PREF_KEY_MSGLEVEL ),
|
||||
TRUE, /* message queueing */
|
||||
pref_flag_get( PREF_KEY_BLOCKLIST_ENABLED ),
|
||||
pref_int_get( PREF_KEY_PEER_SOCKET_TOS ) );
|
||||
cbdata->core = tr_core_new( h );
|
||||
|
||||
/* create main window now to be a parent to any error dialogs */
|
||||
GtkWindow * mainwind = GTK_WINDOW( tr_window_new( myUIManager, cbdata->core ) );
|
||||
|
|
|
@ -457,7 +457,6 @@ prefsChanged( TrCore * core, const char * key, gpointer data UNUSED )
|
|||
static void
|
||||
tr_core_init( GTypeInstance * instance, gpointer g_class UNUSED )
|
||||
{
|
||||
tr_handle * h;
|
||||
TrCore * self = (TrCore *) instance;
|
||||
GtkListStore * store;
|
||||
struct TrCorePrivate * p;
|
||||
|
@ -478,31 +477,11 @@ tr_core_init( GTypeInstance * instance, gpointer g_class UNUSED )
|
|||
TR_CORE_TYPE,
|
||||
struct TrCorePrivate );
|
||||
|
||||
|
||||
h = tr_initFull( tr_getDefaultConfigDir( ),
|
||||
"gtk",
|
||||
pref_flag_get( PREF_KEY_PEX ),
|
||||
pref_flag_get( PREF_KEY_NAT ),
|
||||
pref_int_get( PREF_KEY_PORT ),
|
||||
pref_flag_get( PREF_KEY_ENCRYPTED_ONLY )
|
||||
? TR_ENCRYPTION_REQUIRED
|
||||
: TR_ENCRYPTION_PREFERRED,
|
||||
pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ),
|
||||
pref_int_get( PREF_KEY_UL_LIMIT ),
|
||||
pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ),
|
||||
pref_int_get( PREF_KEY_DL_LIMIT ),
|
||||
pref_int_get( PREF_KEY_MAX_PEERS_GLOBAL ),
|
||||
pref_int_get( PREF_KEY_MSGLEVEL ),
|
||||
TRUE, /* message queueing */
|
||||
pref_flag_get( PREF_KEY_BLOCKLIST_ENABLED ),
|
||||
pref_int_get( PREF_KEY_PEER_SOCKET_TOS ) );
|
||||
|
||||
/* create the model used to store torrent data */
|
||||
g_assert( ALEN( types ) == MC_ROW_COUNT );
|
||||
store = gtk_list_store_newv( MC_ROW_COUNT, types );
|
||||
|
||||
p->model = GTK_TREE_MODEL( store );
|
||||
p->handle = h;
|
||||
p->nextid = 1;
|
||||
}
|
||||
|
||||
|
@ -537,9 +516,10 @@ tr_core_get_type( void )
|
|||
**/
|
||||
|
||||
TrCore *
|
||||
tr_core_new( void )
|
||||
tr_core_new( tr_handle * h )
|
||||
{
|
||||
TrCore * core = TR_CORE( g_object_new( TR_CORE_TYPE, NULL ) );
|
||||
core->priv->handle = h;
|
||||
|
||||
/* init from prefs & listen to pref changes */
|
||||
prefsChanged( core, PREF_KEY_SORT_MODE, NULL );
|
||||
|
|
|
@ -89,7 +89,7 @@ enum tr_core_err
|
|||
|
||||
GType tr_core_get_type( void );
|
||||
|
||||
TrCore * tr_core_new( void );
|
||||
TrCore * tr_core_new( tr_handle * );
|
||||
|
||||
void tr_core_close( TrCore* );
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@ Ask the running
|
|||
instance to quit
|
||||
.It Fl m Fl -minimized
|
||||
Start minimized in system tray
|
||||
.It Fl g, Fl -config-dir Ar directory
|
||||
Where to look for configuration files
|
||||
.El
|
||||
.Pp
|
||||
Only one instance of
|
||||
|
|
Loading…
Reference in New Issue