transmission/libtransmission/torrent-ctor.c

296 lines
6.5 KiB
C
Raw Normal View History

/*
2008-01-01 17:20:20 +00:00
* This file Copyright (C) 2007-2008 Charles Kerr <charles@rebelbase.com>
*
* This file is licensed by the GPL version 2. Works owned by the
* Transmission project are granted a special exemption to clause 2(b)
* so that the bulk of its code can remain under the MIT license.
* This exemption does not extend to derived works not owned by
* the Transmission project.
*
* $Id$
*/
#include <libgen.h> /* basename */
#include "transmission.h"
#include "bencode.h"
#include "platform.h"
#include "session.h" /* tr_sessionFindTorrentFile */
#include "trcompat.h" /* strlcpy */
#include "utils.h"
2007-12-21 22:18:40 +00:00
#define DEFAULT_MAX_CONNECTED_PEERS 50
struct optional_args
{
unsigned int isSet_paused : 1;
unsigned int isSet_connected : 1;
unsigned int isSet_destination : 1;
unsigned int isPaused : 1;
uint16_t peerLimit;
char destination[MAX_PATH_LENGTH];
};
struct tr_ctor
{
2007-12-21 22:18:40 +00:00
const tr_handle * handle;
unsigned int saveInOurTorrentsDir : 1;
2008-02-13 02:24:12 +00:00
unsigned int doDelete : 1;
2007-12-21 22:18:40 +00:00
unsigned int isSet_metainfo : 1;
2008-02-13 02:24:12 +00:00
unsigned int isSet_delete : 1;
tr_benc metainfo;
2008-02-13 02:24:12 +00:00
char * sourceFile;
struct optional_args optionalArgs[2];
};
2007-12-21 22:18:40 +00:00
/***
****
***/
2008-02-13 02:24:12 +00:00
static void
setSourceFile( tr_ctor * ctor, const char * sourceFile )
{
tr_free( ctor->sourceFile );
ctor->sourceFile = tr_strdup( sourceFile );
}
static void
2007-12-21 22:18:40 +00:00
clearMetainfo( tr_ctor * ctor )
{
2007-12-21 22:18:40 +00:00
if( ctor->isSet_metainfo ) {
ctor->isSet_metainfo = 0;
tr_bencFree( &ctor->metainfo );
}
2008-02-13 02:24:12 +00:00
setSourceFile( ctor, NULL );
}
int
2007-12-21 22:18:40 +00:00
tr_ctorSetMetainfo( tr_ctor * ctor,
const uint8_t * metainfo,
size_t len )
{
int err;
2007-12-21 22:18:40 +00:00
clearMetainfo( ctor );
err = tr_bencLoad( metainfo, len, &ctor->metainfo, NULL );
ctor->isSet_metainfo = !err;
return err;
}
2008-02-13 02:24:12 +00:00
const char*
tr_ctorGetSourceFile( const tr_ctor * ctor )
{
return ctor->sourceFile;
}
int
2007-12-21 22:18:40 +00:00
tr_ctorSetMetainfoFromFile( tr_ctor * ctor,
const char * filename )
{
2007-12-21 22:18:40 +00:00
uint8_t * metainfo;
size_t len;
int err;
2007-12-21 22:18:40 +00:00
metainfo = tr_loadFile( filename, &len );
if( metainfo && len )
err = tr_ctorSetMetainfo( ctor, metainfo, len );
else {
2007-12-21 22:18:40 +00:00
clearMetainfo( ctor );
err = 1;
}
2008-02-13 02:24:12 +00:00
setSourceFile( ctor, filename );
/* if no `name' field was set, then set it from the filename */
if( ctor->isSet_metainfo ) {
tr_benc * info = tr_bencDictFindType( &ctor->metainfo, "info", TYPE_DICT );
if( info != NULL ) {
tr_benc * name = tr_bencDictFindFirst( info, "name.utf-8", "name", NULL );
if( name == NULL )
name = tr_bencDictAdd( info, "name" );
if( name->type!=TYPE_STR || !name->val.s.s || !*name->val.s.s ) {
char * tmp = tr_strdup( filename );
tr_bencInitStrDup( name, basename( tmp ) );
tr_free( tmp );
}
}
}
2007-12-21 22:18:40 +00:00
tr_free( metainfo );
return err;
}
int
2007-12-21 22:18:40 +00:00
tr_ctorSetMetainfoFromHash( tr_ctor * ctor,
const char * hashString )
{
int err;
const char * filename;
if(( filename = tr_sessionFindTorrentFile( ctor->handle, hashString )))
err = tr_ctorSetMetainfoFromFile( ctor, filename );
else
err = TR_ERROR;
return err;
}
/***
****
***/
2008-02-13 02:24:12 +00:00
void
tr_ctorSetDeleteSource( tr_ctor * ctor,
uint8_t deleteSource )
{
ctor->doDelete = deleteSource ? 1 : 0;
ctor->isSet_delete = 1;
}
int
tr_ctorGetDeleteSource( const tr_ctor * ctor,
uint8_t * setme )
{
int err = 0;
if( !ctor->isSet_delete )
err = 1;
else if( setme )
*setme = ctor->doDelete ? 1 : 0;
return err;
}
/***
****
***/
void
tr_ctorSetSave( tr_ctor * ctor,
int saveInOurTorrentsDir )
{
ctor->saveInOurTorrentsDir = saveInOurTorrentsDir ? 1 : 0;
}
int
tr_ctorGetSave( const tr_ctor * ctor )
{
return ctor && ctor->saveInOurTorrentsDir;
}
void
tr_ctorSetPaused( tr_ctor * ctor,
tr_ctorMode mode,
2007-12-21 22:18:40 +00:00
uint8_t isPaused )
{
struct optional_args * args = &ctor->optionalArgs[mode];
args->isSet_paused = 1;
2007-12-21 22:18:40 +00:00
args->isPaused = isPaused ? 1 : 0;
}
void
tr_ctorSetPeerLimit( tr_ctor * ctor,
tr_ctorMode mode,
uint16_t peerLimit )
{
struct optional_args * args = &ctor->optionalArgs[mode];
args->isSet_connected = 1;
args->peerLimit = peerLimit;
}
void
tr_ctorSetDestination( tr_ctor * ctor,
tr_ctorMode mode,
const char * directory )
{
struct optional_args * args = &ctor->optionalArgs[mode];
args->isSet_destination = 1;
strlcpy( args->destination, directory, sizeof( args->destination ) );
}
int
tr_ctorGetPeerLimit( const tr_ctor * ctor,
tr_ctorMode mode,
uint16_t * setmeCount )
{
2007-12-21 22:18:40 +00:00
int err = 0;
const struct optional_args * args = &ctor->optionalArgs[mode];
2007-12-21 22:18:40 +00:00
2008-02-13 02:24:12 +00:00
if( !args->isSet_connected )
2007-12-21 22:18:40 +00:00
err = 1;
2008-02-13 02:24:12 +00:00
else if( setmeCount )
*setmeCount = args->peerLimit;
2007-12-21 22:18:40 +00:00
return err;
}
int
2008-02-13 02:24:12 +00:00
tr_ctorGetPaused( const tr_ctor * ctor,
tr_ctorMode mode,
uint8_t * setmeIsPaused )
{
2007-12-21 22:18:40 +00:00
int err = 0;
const struct optional_args * args = &ctor->optionalArgs[mode];
2007-12-21 22:18:40 +00:00
2008-02-13 02:24:12 +00:00
if( !args->isSet_paused )
2007-12-21 22:18:40 +00:00
err = 1;
2008-02-13 02:24:12 +00:00
else if( setmeIsPaused )
*setmeIsPaused = args->isPaused ? 1 : 0;
2007-12-21 22:18:40 +00:00
return err;
}
int
tr_ctorGetDestination( const tr_ctor * ctor,
tr_ctorMode mode,
const char ** setmeDestination )
{
2007-12-21 22:18:40 +00:00
int err = 0;
const struct optional_args * args = &ctor->optionalArgs[mode];
2007-12-21 22:18:40 +00:00
2008-02-13 02:24:12 +00:00
if( !args->isSet_destination )
2007-12-21 22:18:40 +00:00
err = 1;
2008-02-13 02:24:12 +00:00
else if( setmeDestination )
*setmeDestination = args->destination;
2007-12-21 22:18:40 +00:00
return err;
}
int
tr_ctorGetMetainfo( const tr_ctor * ctor,
const tr_benc ** setme )
{
2007-12-21 22:18:40 +00:00
int err = 0;
2008-02-13 02:24:12 +00:00
if( !ctor->isSet_metainfo )
2007-12-21 22:18:40 +00:00
err = 1;
2008-02-13 02:24:12 +00:00
else if( setme )
*setme = &ctor->metainfo;
2007-12-21 22:18:40 +00:00
return err;
}
/***
****
***/
tr_ctor*
tr_ctorNew( const tr_handle * handle )
{
tr_ctor * ctor = tr_new0( struct tr_ctor, 1 );
ctor->handle = handle;
tr_ctorSetPeerLimit( ctor, TR_FALLBACK, DEFAULT_MAX_CONNECTED_PEERS );
2007-12-21 22:18:40 +00:00
tr_ctorSetPaused( ctor, TR_FALLBACK, FALSE );
tr_ctorSetSave( ctor, TRUE );
2007-12-21 22:18:40 +00:00
return ctor;
}
void
tr_ctorFree( tr_ctor * ctor )
{
clearMetainfo( ctor );
tr_free( ctor );
}