config file and dead code cleanup.

This commit is contained in:
Charles Kerr 2007-10-12 20:50:03 +00:00
parent 2e6ebae16e
commit ddcd160449
8 changed files with 103 additions and 716 deletions

View File

@ -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 );
}
}

View File

@ -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 */

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -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,

View File

@ -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
};

View File

@ -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)
{

View File

@ -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 );