config file and dead code cleanup.
This commit is contained in:
parent
2e6ebae16e
commit
ddcd160449
359
gtk/conf.c
359
gtk/conf.c
|
@ -43,34 +43,34 @@
|
|||
#include "conf.h"
|
||||
#include "util.h"
|
||||
|
||||
#define CONF_SUBDIR "gtk"
|
||||
#define FILE_LOCK "lock"
|
||||
#define FILE_SOCKET "socket"
|
||||
#define FILE_STATE "state"
|
||||
#define FILE_STATE_TMP "state.tmp"
|
||||
#define OLD_FILE_LOCK "gtk_lock" /* remove this after next release */
|
||||
#define OLD_FILE_STATE "gtk_state"
|
||||
#define PREF_SEP_LINE '\n'
|
||||
|
||||
static int
|
||||
lockfile(const char *file, char **errstr);
|
||||
static void
|
||||
cf_removelocks(void);
|
||||
static char *
|
||||
cf_readfile(const char *file, const char *oldfile, gsize *len,
|
||||
gboolean *usedold, char **errstr);
|
||||
static void
|
||||
cf_benc_append(benc_val_t *val, char type, int incsize);
|
||||
static void
|
||||
cf_writebenc(const char *file, const char *tmp, benc_val_t *data,
|
||||
char **errstr);
|
||||
static char *
|
||||
getstateval(benc_val_t *state, char *line);
|
||||
#define CONF_SUBDIR "gtk"
|
||||
#define FILE_SOCKET "socket"
|
||||
|
||||
static char *gl_confdir = NULL;
|
||||
static char *gl_old_confdir = NULL;
|
||||
static char *gl_lockpath = NULL;
|
||||
static char *gl_old_lockpath = NULL;
|
||||
|
||||
|
||||
/* errstr may be NULL, this might be called before GTK is initialized */
|
||||
gboolean
|
||||
cf_init(const char *dir, char **errstr) {
|
||||
if(NULL != errstr)
|
||||
*errstr = NULL;
|
||||
gl_confdir = g_build_filename(dir, CONF_SUBDIR, NULL);
|
||||
|
||||
if(mkdir_p(gl_confdir, 0755 ))
|
||||
return TRUE;
|
||||
|
||||
if(NULL != errstr)
|
||||
*errstr = g_strdup_printf(_("Failed to create the directory %s:\n%s"),
|
||||
gl_confdir, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
**** Lockfile
|
||||
****
|
||||
***/
|
||||
|
||||
/* errstr may be NULL, this might be called before GTK is initialized */
|
||||
static int
|
||||
|
@ -113,44 +113,11 @@ lockfile(const char *file, char **errstr) {
|
|||
return fd;
|
||||
}
|
||||
|
||||
/* errstr may be NULL, this might be called before GTK is initialized */
|
||||
gboolean
|
||||
cf_init(const char *dir, char **errstr) {
|
||||
if(NULL != errstr)
|
||||
*errstr = NULL;
|
||||
gl_old_confdir = g_strdup(dir);
|
||||
gl_confdir = g_build_filename(dir, CONF_SUBDIR, NULL);
|
||||
|
||||
if(mkdir_p(gl_confdir, 0777))
|
||||
return TRUE;
|
||||
|
||||
if(NULL != errstr)
|
||||
*errstr = g_strdup_printf(_("Failed to create the directory %s:\n%s"),
|
||||
gl_confdir, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* errstr may be NULL, this might be called before GTK is initialized */
|
||||
gboolean
|
||||
cf_lock(char **errstr) {
|
||||
char *path = g_build_filename(gl_old_confdir, OLD_FILE_LOCK, NULL);
|
||||
int fd = lockfile(path, errstr);
|
||||
|
||||
if(0 > fd)
|
||||
g_free(path);
|
||||
else {
|
||||
gl_old_lockpath = path;
|
||||
path = g_build_filename(gl_confdir, FILE_LOCK, NULL);
|
||||
fd = lockfile(path, errstr);
|
||||
if(0 > fd)
|
||||
g_free(path);
|
||||
else
|
||||
gl_lockpath = path;
|
||||
}
|
||||
|
||||
g_atexit(cf_removelocks);
|
||||
|
||||
return 0 <= fd;
|
||||
static char*
|
||||
getLockFilename( void )
|
||||
{
|
||||
return g_build_filename( tr_getPrefsDirectory(),
|
||||
CONF_SUBDIR, "lock", NULL );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -158,64 +125,31 @@ cf_removelocks( void )
|
|||
{
|
||||
g_unlink( gl_lockpath );
|
||||
g_free( gl_lockpath );
|
||||
g_unlink( gl_old_lockpath );
|
||||
g_free( gl_old_lockpath );
|
||||
}
|
||||
|
||||
char *
|
||||
cf_sockname(void) {
|
||||
return g_build_filename(gl_confdir, FILE_SOCKET, NULL);
|
||||
/* errstr may be NULL, this might be called before GTK is initialized */
|
||||
gboolean
|
||||
cf_lock( char ** errstr )
|
||||
{
|
||||
const char * path = getLockFilename( );
|
||||
int fd = lockfile( path, errstr );
|
||||
if( fd >= 0 )
|
||||
gl_lockpath = g_strdup( path );
|
||||
g_atexit( cf_removelocks );
|
||||
return fd >= 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
cf_readfile(const char *file, const char *oldfile, gsize *len,
|
||||
gboolean *usedold, char **errstr) {
|
||||
char *path;
|
||||
GIOChannel *io;
|
||||
GError *err = NULL;
|
||||
char *ret;
|
||||
|
||||
*errstr = NULL;
|
||||
*usedold = FALSE;
|
||||
ret = NULL;
|
||||
err = NULL;
|
||||
*len = 0;
|
||||
|
||||
path = g_build_filename(gl_confdir, file, NULL);
|
||||
io = g_io_channel_new_file(path, "r", &err);
|
||||
if(NULL != err && g_error_matches(err, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
|
||||
g_error_free(err);
|
||||
err = NULL;
|
||||
g_free(path);
|
||||
path = g_build_filename(gl_old_confdir, oldfile, NULL);
|
||||
io = g_io_channel_new_file(path, "r", &err);
|
||||
*usedold = TRUE;
|
||||
}
|
||||
if(NULL != err) {
|
||||
if(!g_error_matches(err, G_FILE_ERROR, G_FILE_ERROR_NOENT))
|
||||
*errstr = g_strdup_printf(
|
||||
_("Failed to open the file %s for reading:\n%s"), path, err->message);
|
||||
goto done;
|
||||
}
|
||||
g_io_channel_set_encoding(io, NULL, NULL);
|
||||
|
||||
if(G_IO_STATUS_ERROR == g_io_channel_read_to_end(io, &ret, len, &err)) {
|
||||
*errstr = g_strdup_printf(
|
||||
_("Error while reading from the file %s:\n%s"), path, err->message);
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
g_free (path);
|
||||
g_clear_error( &err );
|
||||
if(NULL != io)
|
||||
g_io_channel_unref(io);
|
||||
return ret;
|
||||
char*
|
||||
cf_sockname( void )
|
||||
{
|
||||
return g_build_filename( gl_confdir, FILE_SOCKET, NULL );
|
||||
}
|
||||
|
||||
/**
|
||||
*** Prefs Files
|
||||
**/
|
||||
/***
|
||||
****
|
||||
**** Preferences
|
||||
****
|
||||
***/
|
||||
|
||||
#define GROUP "general"
|
||||
|
||||
|
@ -321,198 +255,3 @@ pref_save(char **errstr)
|
|||
g_free( path );
|
||||
g_free( filename );
|
||||
}
|
||||
|
||||
/**
|
||||
***
|
||||
**/
|
||||
|
||||
benc_val_t *
|
||||
cf_loadstate(char **errstr) {
|
||||
char *data, *line, *eol, *prog;
|
||||
gsize len;
|
||||
gboolean usedold;
|
||||
benc_val_t *state, *torstate;
|
||||
|
||||
*errstr = NULL;
|
||||
|
||||
data = cf_readfile(FILE_STATE, OLD_FILE_STATE, &len, &usedold, errstr);
|
||||
if(NULL != *errstr) {
|
||||
g_assert(NULL == data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(NULL == data)
|
||||
return NULL;
|
||||
|
||||
state = g_new0(benc_val_t, 1);
|
||||
if(usedold || tr_bencLoad(data, len, state, NULL)) {
|
||||
/* XXX all this evil compat code should go away at some point */
|
||||
memset(state, 0, sizeof(benc_val_t));
|
||||
state->type = TYPE_LIST;
|
||||
for(line = data; NULL != (eol = strchr(line, PREF_SEP_LINE));
|
||||
line = eol + 1) {
|
||||
*eol = '\0';
|
||||
if(g_utf8_validate(line, -1, NULL)) {
|
||||
cf_benc_append(state, TYPE_DICT, 10);
|
||||
torstate = state->val.l.vals + state->val.l.count - 1;
|
||||
prog = line;
|
||||
while(NULL != (prog = getstateval(torstate, prog)))
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free(data);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static void
|
||||
cf_benc_append(benc_val_t *val, char type, int incsize) {
|
||||
if(++val->val.l.count > val->val.l.alloc) {
|
||||
val->val.l.alloc += incsize;
|
||||
val->val.l.vals = g_renew(benc_val_t, val->val.l.vals, val->val.l.alloc);
|
||||
memset(val->val.l.vals + val->val.l.alloc - incsize, 0,
|
||||
incsize * sizeof(benc_val_t));
|
||||
}
|
||||
val->val.l.vals[val->val.l.count-1].type = type;
|
||||
}
|
||||
|
||||
static void
|
||||
cf_writebenc(const char *file, const char *tmp, benc_val_t *data,
|
||||
char **errstr) {
|
||||
char *path = g_build_filename(gl_confdir, file, NULL);
|
||||
char *pathtmp = g_build_filename(gl_confdir, tmp, NULL);
|
||||
GIOChannel *io = NULL;
|
||||
GError *err = NULL;
|
||||
char *datastr;
|
||||
int len;
|
||||
gsize written;
|
||||
|
||||
*errstr = NULL;
|
||||
err = NULL;
|
||||
datastr = NULL;
|
||||
|
||||
io = g_io_channel_new_file(pathtmp, "w", &err);
|
||||
if(NULL != err) {
|
||||
*errstr = g_strdup_printf(_("Failed to open the file %s for writing:\n%s"),
|
||||
pathtmp, err->message);
|
||||
goto done;
|
||||
}
|
||||
g_io_channel_set_encoding(io, NULL, NULL);
|
||||
|
||||
len = 0;
|
||||
datastr = tr_bencSaveMalloc(data, &len);
|
||||
|
||||
written = 0;
|
||||
g_io_channel_write_chars(io, datastr, len, &written, &err);
|
||||
if(NULL != err)
|
||||
g_io_channel_flush(io, &err);
|
||||
if(NULL != err) {
|
||||
*errstr = g_strdup_printf(_("Error while writing to the file %s:\n%s"),
|
||||
pathtmp, err->message);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(0 > rename(pathtmp, path)) {
|
||||
*errstr = g_strdup_printf(_("Failed to rename the file %s to %s:\n%s"),
|
||||
pathtmp, file, strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
g_free(path);
|
||||
g_free(pathtmp);
|
||||
if(NULL != io)
|
||||
g_io_channel_unref(io);
|
||||
if(NULL != datastr)
|
||||
free(datastr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
strbool( const char * str )
|
||||
{
|
||||
if( !str )
|
||||
return FALSE;
|
||||
|
||||
switch(str[0]) {
|
||||
case 'y': case 't': case 'Y': case '1': case 'j': case 'e':
|
||||
return TRUE;
|
||||
default:
|
||||
if(0 == g_ascii_strcasecmp("on", str))
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
getstateval(benc_val_t *state, char *line) {
|
||||
char *start, *end;
|
||||
|
||||
/* skip any leading whitespace */
|
||||
while(g_ascii_isspace(*line))
|
||||
line++;
|
||||
|
||||
/* walk over the key, which may be alphanumerics as well as - or _ */
|
||||
for(start = line; g_ascii_isalnum(*start)
|
||||
|| '_' == *start || '-' == *start; start++)
|
||||
;
|
||||
|
||||
/* they key must be immediately followed by an = */
|
||||
if('=' != *start)
|
||||
return NULL;
|
||||
*(start++) = '\0';
|
||||
|
||||
/* then the opening quote for the value */
|
||||
if('"' != *(start++))
|
||||
return NULL;
|
||||
|
||||
/* walk over the value */
|
||||
for(end = start; '\0' != *end && '"' != *end; end++)
|
||||
/* skip over escaped quotes */
|
||||
if('\\' == *end && '\0' != *(end + 1))
|
||||
end++;
|
||||
|
||||
/* make sure we didn't hit the end of the string */
|
||||
if('"' != *end)
|
||||
return NULL;
|
||||
*end = '\0';
|
||||
|
||||
/* if it's a key we recognize then save the data */
|
||||
if(0 == strcmp(line, "torrent") || 0 == strcmp(line, "dir") ||
|
||||
0 == strcmp(line, "paused")) {
|
||||
cf_benc_append(state, TYPE_STR, 6);
|
||||
state->val.l.vals[state->val.l.count-1].val.s.s = g_strdup(line);
|
||||
state->val.l.vals[state->val.l.count-1].val.s.i = strlen(line);
|
||||
if('p' == *line) {
|
||||
cf_benc_append(state, TYPE_INT, 6);
|
||||
state->val.l.vals[state->val.l.count-1].val.i = strbool(start);
|
||||
} else {
|
||||
cf_benc_append(state, TYPE_STR, 6);
|
||||
state->val.l.vals[state->val.l.count-1].val.s.s = g_strdup(start);
|
||||
state->val.l.vals[state->val.l.count-1].val.s.i = strlen(start);
|
||||
}
|
||||
}
|
||||
|
||||
/* return a pointer to just past the end of the value */
|
||||
return end + 1;
|
||||
}
|
||||
|
||||
void
|
||||
cf_savestate(benc_val_t *state, char **errstr) {
|
||||
*errstr = NULL;
|
||||
cf_writebenc(FILE_STATE, FILE_STATE_TMP, state, errstr);
|
||||
}
|
||||
|
||||
void
|
||||
cf_freestate( benc_val_t * state )
|
||||
{
|
||||
if( NULL != state )
|
||||
{
|
||||
tr_bencFree( state );
|
||||
g_free( state );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,13 +55,5 @@ gboolean
|
|||
cf_lock(char **errstr);
|
||||
char *
|
||||
cf_sockname(void);
|
||||
void
|
||||
cf_loadprefs(char **errstr);
|
||||
struct benc_val_s *
|
||||
cf_loadstate(char **errstr);
|
||||
void
|
||||
cf_savestate(struct benc_val_s *state, char **errstr);
|
||||
void
|
||||
cf_freestate(struct benc_val_s *state);
|
||||
|
||||
#endif /* TG_CONF_H */
|
||||
|
|
|
@ -924,7 +924,6 @@ smsg_tor( enum ipc_msg id, benc_val_t * val, int64_t tag, void * arg )
|
|||
}
|
||||
|
||||
tr_core_update( srv->core );
|
||||
tr_core_save( srv->core );
|
||||
|
||||
/* XXX this is a lie */
|
||||
simpleresp( con, tag, IPC_MSG_OK );
|
||||
|
@ -967,7 +966,6 @@ smsg_torall( enum ipc_msg id, benc_val_t * val SHUTUP, int64_t tag,
|
|||
}
|
||||
|
||||
tr_core_update( srv->core );
|
||||
tr_core_save( srv->core );
|
||||
|
||||
/* XXX this is a lie */
|
||||
simpleresp( con, tag, IPC_MSG_OK );
|
||||
|
|
26
gtk/main.c
26
gtk/main.c
|
@ -216,7 +216,10 @@ main( int argc, char ** argv )
|
|||
char * err;
|
||||
struct cbdata * cbdata = g_new (struct cbdata, 1);
|
||||
GList * argfiles;
|
||||
gboolean didinit, didlock, sendquit, startpaused;
|
||||
gboolean didinit = FALSE;
|
||||
gboolean didlock = FALSE;
|
||||
gboolean sendquit = FALSE;
|
||||
gboolean startpaused = FALSE;
|
||||
char * domain = "transmission";
|
||||
GOptionEntry entries[] = {
|
||||
{ "paused", 'p', 0, G_OPTION_ARG_NONE, &startpaused, _("Start with all torrents paused"), NULL },
|
||||
|
@ -251,24 +254,14 @@ main( int argc, char ** argv )
|
|||
if( ( didinit || cf_init( tr_getPrefsDirectory(), &err ) ) &&
|
||||
( didlock || cf_lock( &err ) ) )
|
||||
{
|
||||
GtkWindow * mainwind;
|
||||
benc_val_t * state;
|
||||
|
||||
/* create main window now to be a parent to any error dialogs */
|
||||
mainwind = GTK_WINDOW( tr_window_new( myUIManager ) );
|
||||
GtkWindow * mainwind = GTK_WINDOW( tr_window_new( myUIManager ) );
|
||||
|
||||
/* try to load prefs and saved state */
|
||||
tr_prefs_init_global( );
|
||||
state = cf_loadstate( &err );
|
||||
if( NULL != err )
|
||||
{
|
||||
errmsg( mainwind, "%s", err );
|
||||
g_free( err );
|
||||
}
|
||||
|
||||
msgwin_loadpref(); /* set message level here before tr_init() */
|
||||
/* set message level here before tr_init() */
|
||||
msgwin_loadpref( );
|
||||
appsetup( mainwind, argfiles, cbdata, startpaused );
|
||||
cf_freestate( state );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1016,11 +1009,8 @@ doAction ( const char * action_name, gpointer user_data )
|
|||
}
|
||||
else g_error ("Unhandled action: %s", action_name );
|
||||
|
||||
if(changed)
|
||||
{
|
||||
if( changed )
|
||||
updatemodel( data );
|
||||
tr_core_save( data->core );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <libtransmission/bencode.h>
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/utils.h>
|
||||
|
||||
|
@ -219,8 +218,8 @@ tr_core_init( GTypeInstance * instance, gpointer g_class SHUTUP )
|
|||
G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
|
||||
/* leechers, completedFromTracker, downloaded, uploaded */
|
||||
G_TYPE_INT, G_TYPE_INT, G_TYPE_UINT64, G_TYPE_UINT64,
|
||||
/* left, tracker, TrTorrent object, ID for IPC */
|
||||
G_TYPE_UINT64, TR_TRACKER_BOXED_TYPE, TR_TORRENT_TYPE, G_TYPE_INT,
|
||||
/* left, TrTorrent object, ID for IPC */
|
||||
G_TYPE_UINT64, TR_TORRENT_TYPE, G_TYPE_INT,
|
||||
};
|
||||
|
||||
#ifdef REFDBG
|
||||
|
@ -345,64 +344,6 @@ tr_core_quiescent( TrCore * self )
|
|||
return TR_NAT_TRAVERSAL_DISABLED == hstat->natTraversalStatus;
|
||||
}
|
||||
|
||||
void
|
||||
tr_core_save( TrCore * self )
|
||||
{
|
||||
benc_val_t state;
|
||||
int count;
|
||||
GtkTreeIter iter;
|
||||
TrTorrent * tor;
|
||||
char * errstr;
|
||||
GList * saved, * ii;
|
||||
|
||||
TR_IS_CORE( self );
|
||||
|
||||
count = gtk_tree_model_iter_n_children( self->model, NULL );
|
||||
|
||||
tr_bencInit( &state, TYPE_LIST );
|
||||
if( tr_bencListReserve( &state, count ) )
|
||||
{
|
||||
tr_core_errsig( self, TR_CORE_ERR_SAVE_STATE, "malloc failure" );
|
||||
return;
|
||||
}
|
||||
|
||||
saved = NULL;
|
||||
if( gtk_tree_model_get_iter_first( self->model, &iter) ) do
|
||||
{
|
||||
benc_val_t * item = tr_bencListAdd( &state );
|
||||
gtk_tree_model_get( self->model, &iter, MC_TORRENT, &tor, -1 );
|
||||
if( tr_torrent_get_state( tor, item ) )
|
||||
{
|
||||
saved = g_list_append( saved, tor );
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_bencFree( item );
|
||||
tr_bencInitStr( item, NULL, 0, 1 );
|
||||
}
|
||||
g_object_unref( tor );
|
||||
}
|
||||
while( gtk_tree_model_iter_next( self->model, &iter ) );
|
||||
|
||||
errstr = NULL;
|
||||
cf_savestate( &state, &errstr );
|
||||
tr_bencFree( &state );
|
||||
if( NULL != errstr )
|
||||
{
|
||||
tr_core_errsig( self, TR_CORE_ERR_SAVE_STATE, errstr );
|
||||
g_free( errstr );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( ii = saved; NULL != ii; ii = ii->next )
|
||||
{
|
||||
tr_torrent_state_saved( ii->data );
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free( saved );
|
||||
}
|
||||
|
||||
int
|
||||
tr_core_load( TrCore * self, gboolean forcepaused )
|
||||
{
|
||||
|
@ -545,7 +486,6 @@ tr_core_torrents_added( TrCore * self )
|
|||
TR_IS_CORE( self );
|
||||
|
||||
tr_core_update( self );
|
||||
tr_core_save( self );
|
||||
tr_core_errsig( self, TR_CORE_ERR_NO_MORE_TORRENTS, NULL );
|
||||
}
|
||||
|
||||
|
@ -614,7 +554,6 @@ tr_core_update( TrCore * self )
|
|||
MC_SEED, st->seeders,
|
||||
MC_LEECH, st->leechers,
|
||||
MC_DONE, st->completedFromTracker,
|
||||
MC_TRACKER, st->tracker,
|
||||
MC_DOWN, st->downloadedEver,
|
||||
MC_UP, st->uploadedEver,
|
||||
MC_LEFT, st->leftUntilDone,
|
||||
|
|
|
@ -117,10 +117,6 @@ tr_core_shutdown( TrCore * self );
|
|||
gboolean
|
||||
tr_core_quiescent( TrCore * self );
|
||||
|
||||
/* Save state. May trigger "error" signal with TR_CORE_ERR_SAVE_STATE */
|
||||
void
|
||||
tr_core_save( TrCore * self );
|
||||
|
||||
/* Load saved state, return number of torrents added. May trigger one
|
||||
or more "error" signals with TR_CORE_ERR_ADD_TORRENT */
|
||||
int
|
||||
|
@ -190,7 +186,7 @@ enum {
|
|||
MC_NAME, MC_SIZE, MC_HASH, MC_STAT, MC_ERR, MC_TERR,
|
||||
MC_PROG_C, MC_PROG_D, MC_DRATE, MC_URATE, MC_ETA, MC_PEERS,
|
||||
MC_UPEERS, MC_DPEERS, MC_SEED, MC_LEECH, MC_DONE,
|
||||
MC_DOWN, MC_UP, MC_LEFT, MC_TRACKER, MC_TORRENT, MC_ID,
|
||||
MC_DOWN, MC_UP, MC_LEFT, MC_TORRENT, MC_ID,
|
||||
MC_ROW_COUNT
|
||||
};
|
||||
|
||||
|
|
337
gtk/tr_torrent.c
337
gtk/tr_torrent.c
|
@ -29,61 +29,61 @@
|
|||
#include <glib/gi18n.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/bencode.h>
|
||||
|
||||
#include "tr_prefs.h"
|
||||
#include "tr_torrent.h"
|
||||
#include "conf.h"
|
||||
#include "util.h"
|
||||
|
||||
enum {
|
||||
TR_TORRENT_HANDLE = 1,
|
||||
TR_TORRENT_DIR,
|
||||
};
|
||||
|
||||
static void
|
||||
tr_torrent_init(GTypeInstance *instance, gpointer g_class);
|
||||
static void
|
||||
tr_torrent_set_property(GObject *object, guint property_id,
|
||||
const GValue *value, GParamSpec *pspec);
|
||||
static void
|
||||
tr_torrent_get_property(GObject *object, guint property_id,
|
||||
GValue *value, GParamSpec *pspec);
|
||||
static void
|
||||
tr_torrent_class_init(gpointer g_class, gpointer g_class_data);
|
||||
static void
|
||||
tr_torrent_dispose(GObject *obj);
|
||||
static void
|
||||
tr_torrent_set_folder(TrTorrent *tor);
|
||||
|
||||
static gpointer
|
||||
tracker_boxed_fake_copy( gpointer boxed )
|
||||
tr_torrent_init(GTypeInstance *instance, gpointer g_class UNUSED )
|
||||
{
|
||||
return boxed;
|
||||
TrTorrent *self = (TrTorrent *)instance;
|
||||
|
||||
#ifdef REFDBG
|
||||
fprintf( stderr, "torrent %p init\n", self );
|
||||
#endif
|
||||
|
||||
self->handle = NULL;
|
||||
self->lastStatTime = 0;
|
||||
self->delfile = NULL;
|
||||
self->severed = FALSE;
|
||||
self->disposed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
tracker_boxed_fake_free( gpointer boxed SHUTUP )
|
||||
tr_torrent_dispose(GObject *obj)
|
||||
{
|
||||
GObjectClass *parent = g_type_class_peek(g_type_parent(TR_TORRENT_TYPE));
|
||||
TrTorrent *self = (TrTorrent*)obj;
|
||||
|
||||
if(self->disposed)
|
||||
return;
|
||||
self->disposed = TRUE;
|
||||
|
||||
#ifdef REFDBG
|
||||
fprintf( stderr, "torrent %p dispose\n", self );
|
||||
#endif
|
||||
|
||||
if( !self->severed )
|
||||
tr_torrent_sever( self );
|
||||
|
||||
g_free (self->delfile);
|
||||
|
||||
/* Chain up to the parent class */
|
||||
parent->dispose(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
tr_torrent_class_init(gpointer g_class, gpointer g_class_data UNUSED )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
|
||||
gobject_class->dispose = tr_torrent_dispose;
|
||||
}
|
||||
|
||||
GType
|
||||
tr_tracker_boxed_get_type( void )
|
||||
tr_torrent_get_type(void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if( 0 == type )
|
||||
{
|
||||
type = g_boxed_type_register_static( "TrTrackerBoxed",
|
||||
tracker_boxed_fake_copy,
|
||||
tracker_boxed_fake_free );
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
GType
|
||||
tr_torrent_get_type(void) {
|
||||
static GType type = 0;
|
||||
|
||||
if(0 == type) {
|
||||
|
@ -104,114 +104,6 @@ tr_torrent_get_type(void) {
|
|||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
tr_torrent_class_init(gpointer g_class, gpointer g_class_data SHUTUP) {
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = tr_torrent_set_property;
|
||||
gobject_class->get_property = tr_torrent_get_property;
|
||||
gobject_class->dispose = tr_torrent_dispose;
|
||||
|
||||
pspec = g_param_spec_pointer("torrent-handle", "Torrent handle",
|
||||
"Torrent handle from libtransmission",
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||
g_object_class_install_property(gobject_class, TR_TORRENT_HANDLE, pspec);
|
||||
|
||||
pspec = g_param_spec_string("download-directory", "Download directory",
|
||||
"Directory to download files to", NULL,
|
||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||
g_object_class_install_property(gobject_class, TR_TORRENT_DIR, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
tr_torrent_init(GTypeInstance *instance, gpointer g_class SHUTUP) {
|
||||
TrTorrent *self = (TrTorrent *)instance;
|
||||
|
||||
#ifdef REFDBG
|
||||
fprintf( stderr, "torrent %p init\n", self );
|
||||
#endif
|
||||
|
||||
self->handle = NULL;
|
||||
self->lastStatTime = 0;
|
||||
self->dir = NULL;
|
||||
self->delfile = NULL;
|
||||
self->severed = FALSE;
|
||||
self->disposed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
tr_torrent_set_property(GObject *object, guint property_id,
|
||||
const GValue *value, GParamSpec *pspec) {
|
||||
TrTorrent *self = (TrTorrent*)object;
|
||||
|
||||
if(self->severed)
|
||||
return;
|
||||
|
||||
switch(property_id) {
|
||||
case TR_TORRENT_HANDLE:
|
||||
g_assert(NULL == self->handle);
|
||||
self->handle = g_value_get_pointer(value);
|
||||
if(NULL != self->handle && NULL != self->dir)
|
||||
tr_torrent_set_folder(self);
|
||||
break;
|
||||
case TR_TORRENT_DIR:
|
||||
g_assert(NULL == self->dir);
|
||||
self->dir = g_value_dup_string(value);
|
||||
if(NULL != self->handle && NULL != self->dir)
|
||||
tr_torrent_set_folder(self);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tr_torrent_get_property(GObject *object, guint property_id,
|
||||
GValue *value, GParamSpec *pspec) {
|
||||
TrTorrent *self = (TrTorrent*)object;
|
||||
|
||||
if(self->severed)
|
||||
return;
|
||||
|
||||
switch(property_id) {
|
||||
case TR_TORRENT_HANDLE:
|
||||
g_value_set_pointer(value, self->handle);
|
||||
break;
|
||||
case TR_TORRENT_DIR:
|
||||
g_value_set_string(value, (NULL != self->dir ? self->dir :
|
||||
tr_torrentGetFolder(self->handle)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tr_torrent_dispose(GObject *obj) {
|
||||
GObjectClass *parent = g_type_class_peek(g_type_parent(TR_TORRENT_TYPE));
|
||||
TrTorrent *self = (TrTorrent*)obj;
|
||||
|
||||
if(self->disposed)
|
||||
return;
|
||||
self->disposed = TRUE;
|
||||
|
||||
#ifdef REFDBG
|
||||
fprintf( stderr, "torrent %p dispose\n", self );
|
||||
#endif
|
||||
|
||||
if( !self->severed )
|
||||
tr_torrent_sever( self );
|
||||
|
||||
g_free (self->delfile);
|
||||
g_free (self->dir);
|
||||
|
||||
/* Chain up to the parent class */
|
||||
parent->dispose(obj);
|
||||
}
|
||||
|
||||
void
|
||||
tr_torrent_sever( TrTorrent * self )
|
||||
{
|
||||
|
@ -285,10 +177,9 @@ static TrTorrent *
|
|||
maketorrent( tr_torrent * handle )
|
||||
{
|
||||
tr_torrentDisablePex( handle, !pref_flag_get( PREF_KEY_PEX ) );
|
||||
|
||||
return g_object_new( TR_TORRENT_TYPE,
|
||||
"torrent-handle", handle,
|
||||
NULL);
|
||||
TrTorrent * tor = g_object_new( TR_TORRENT_TYPE, NULL );
|
||||
tor->handle = handle;
|
||||
return tor;
|
||||
}
|
||||
|
||||
TrTorrent*
|
||||
|
@ -316,6 +207,7 @@ tr_torrent_new( tr_handle * back, const char *torrent, const char *dir,
|
|||
if( paused )
|
||||
flags |= TR_FLAG_PAUSED;
|
||||
|
||||
g_message( "dir is [%s]", dir ? dir : "(null)" );
|
||||
handle = tr_torrentInit( back, torrent, dir, flags, &errcode );
|
||||
|
||||
if(NULL == handle) {
|
||||
|
@ -380,149 +272,6 @@ tr_torrent_new_with_data( tr_handle * back, uint8_t * data, size_t size,
|
|||
return maketorrent( handle );
|
||||
}
|
||||
|
||||
TrTorrent *
|
||||
tr_torrent_new_with_state( tr_handle * back, benc_val_t * state,
|
||||
gboolean forcedpause, char ** err )
|
||||
{
|
||||
TrTorrent * ret;
|
||||
tr_torrent * handle;
|
||||
int ii, errcode;
|
||||
int flags;
|
||||
benc_val_t *name, *data;
|
||||
char *torrent, *hash, *dir;
|
||||
gboolean paused = FALSE;
|
||||
gboolean seeding_cap_enabled = FALSE;
|
||||
gdouble seeding_cap = 0.0;
|
||||
|
||||
*err = NULL;
|
||||
|
||||
if(TYPE_DICT != state->type)
|
||||
return NULL;
|
||||
|
||||
torrent = hash = dir = NULL;
|
||||
|
||||
for(ii = 0; ii + 1 < state->val.l.count; ii += 2) {
|
||||
name = state->val.l.vals + ii;
|
||||
data = state->val.l.vals + ii + 1;
|
||||
if(TYPE_STR == name->type &&
|
||||
(TYPE_STR == data->type || TYPE_INT == data->type)) {
|
||||
char * key = name->val.s.s;
|
||||
char * val = data->val.s.s;
|
||||
if (!strcmp (key, "torrent")) torrent = val;
|
||||
else if (!strcmp (key, "hash")) hash = val;
|
||||
else if (!strcmp (key, "dir")) dir = val;
|
||||
else if (!strcmp (key, "paused")) paused = !!data->val.i;
|
||||
else if (!strcmp (key, "seeding-cap-ratio")) seeding_cap = (data->val.i / 100.0);
|
||||
else if (!strcmp (key, "seeding-cap-enabled")) seeding_cap_enabled = !!data->val.i;
|
||||
}
|
||||
}
|
||||
|
||||
if((NULL != torrent && NULL != hash) ||
|
||||
(NULL == torrent && NULL == hash) || NULL == dir)
|
||||
return NULL;
|
||||
|
||||
flags = 0;
|
||||
if( paused || forcedpause )
|
||||
flags |= TR_FLAG_PAUSED;
|
||||
|
||||
if( NULL != hash )
|
||||
handle = tr_torrentInitSaved(back, hash, dir, flags, &errcode);
|
||||
else
|
||||
handle = tr_torrentInit(back, torrent, dir, flags, &errcode);
|
||||
|
||||
if(NULL == handle) {
|
||||
torrent = ( NULL == hash ? torrent : hash );
|
||||
switch(errcode) {
|
||||
case TR_EINVALID:
|
||||
*err = g_strdup_printf(_("%s: not a valid torrent file"), torrent);
|
||||
break;
|
||||
case TR_EDUPLICATE:
|
||||
*err = g_strdup_printf(_("%s: torrent is already open"), torrent);
|
||||
break;
|
||||
default:
|
||||
*err = g_strdup(torrent);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = maketorrent( handle );
|
||||
ret->seeding_cap = seeding_cap;
|
||||
ret->seeding_cap_enabled = seeding_cap_enabled;
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
tr_torrent_get_state( TrTorrent * tor, benc_val_t * state )
|
||||
{
|
||||
const tr_info * inf;
|
||||
|
||||
TR_IS_TORRENT( tor );
|
||||
|
||||
if( tor->severed )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
inf = tr_torrentInfo( tor->handle );
|
||||
|
||||
tr_bencInit( state, TYPE_DICT );
|
||||
if( tr_bencDictReserve( state, 3 ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( TR_FLAG_SAVE & inf->flags )
|
||||
{
|
||||
tr_bencInitStr( tr_bencDictAdd( state, "hash" ),
|
||||
inf->hashString, -1, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_bencInitStr( tr_bencDictAdd( state, "torrent" ),
|
||||
inf->torrent, -1, 1 );
|
||||
}
|
||||
tr_bencInitStr( tr_bencDictAdd( state, "dir" ),
|
||||
tr_torrentGetFolder( tor->handle ), -1, 1 );
|
||||
tr_bencInitInt( tr_bencDictAdd( state, "paused" ),
|
||||
(refreshStat(tor)->status & TR_STATUS_INACTIVE) ? 1 : 0);
|
||||
tr_bencInitInt( tr_bencDictAdd( state, "seeding-cap-ratio" ),
|
||||
(int)(tor->seeding_cap * 100.0)); /* two decimal places */
|
||||
tr_bencInitInt( tr_bencDictAdd( state, "seeding-cap-enabled" ),
|
||||
tor->seeding_cap_enabled ? 1 : 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* XXX this should probably be done with a signal */
|
||||
void
|
||||
tr_torrent_state_saved(TrTorrent *tor) {
|
||||
TR_IS_TORRENT(tor);
|
||||
|
||||
if(tor->severed)
|
||||
return;
|
||||
|
||||
if(NULL != tor->delfile) {
|
||||
unlink(tor->delfile);
|
||||
g_free(tor->delfile);
|
||||
tor->delfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tr_torrent_set_folder(TrTorrent *tor) {
|
||||
char *wd;
|
||||
|
||||
if(NULL != tor->dir)
|
||||
tr_torrentSetFolder(tor->handle, tor->dir);
|
||||
else {
|
||||
wd = g_new(char, MAX_PATH_LENGTH + 1);
|
||||
tr_torrentSetFolder(tor->handle,
|
||||
(NULL == getcwd(wd, MAX_PATH_LENGTH + 1) ? "." : wd));
|
||||
g_free(wd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tr_torrent_check_seeding_cap ( TrTorrent *gtor)
|
||||
{
|
||||
|
|
|
@ -30,11 +30,6 @@
|
|||
#include <libtransmission/bencode.h>
|
||||
#include "util.h"
|
||||
|
||||
/* boxed type for tr_tracker_info */
|
||||
#define TR_TRACKER_BOXED_TYPE (tr_tracker_boxed_get_type ())
|
||||
GType
|
||||
tr_tracker_boxed_get_type( void );
|
||||
|
||||
#define TR_TORRENT_TYPE (tr_torrent_get_type ())
|
||||
#define TR_TORRENT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), TR_TORRENT_TYPE, TrTorrent))
|
||||
|
@ -54,7 +49,6 @@ typedef struct _TrTorrentClass TrTorrentClass;
|
|||
struct _TrTorrent {
|
||||
GObject parent;
|
||||
tr_torrent *handle;
|
||||
char *dir;
|
||||
char *delfile;
|
||||
tr_stat stat;
|
||||
time_t lastStatTime;
|
||||
|
@ -109,16 +103,6 @@ TrTorrent *
|
|||
tr_torrent_new_with_data( tr_handle * handle, uint8_t * data, size_t size,
|
||||
const char * dir, gboolean paused, char ** err );
|
||||
|
||||
TrTorrent *
|
||||
tr_torrent_new_with_state( tr_handle * handle, benc_val_t * state,
|
||||
gboolean forcepaused, char ** err );
|
||||
|
||||
gboolean
|
||||
tr_torrent_get_state( TrTorrent * tor, benc_val_t * state );
|
||||
|
||||
void
|
||||
tr_torrent_state_saved(TrTorrent *tor);
|
||||
|
||||
void
|
||||
tr_torrent_sever( TrTorrent * tor );
|
||||
|
||||
|
|
Loading…
Reference in New Issue