source: trunk/libtransmission/torrent-ctor.c @ 5126

Last change on this file since 5126 was 5126, checked in by charles, 14 years ago

svn propset svn:keywords 'Date Rev Author Id' filename

  • Property svn:keywords set to Date Rev Author Id
File size: 6.9 KB
Line 
1/*
2 * This file Copyright (C) 2007-2008 Charles Kerr <charles@rebelbase.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id:$
11 */
12
13#include <libgen.h> /* basename */
14#include "transmission.h"
15#include "bencode.h"
16#include "platform.h"
17#include "trcompat.h" /* strlcpy */
18#include "utils.h"
19
20#define DEFAULT_MAX_CONNECTED_PEERS 50
21
22struct optional_args
23{
24    unsigned int isSet_paused : 1;
25    unsigned int isSet_connected : 1;
26    unsigned int isSet_destination : 1;
27
28    unsigned int isPaused : 1;
29    uint16_t maxConnectedPeers;
30    char destination[MAX_PATH_LENGTH];
31};
32
33struct tr_ctor
34{
35    const tr_handle * handle;
36    unsigned int saveInOurTorrentsDir : 1;
37    unsigned int doDelete : 1;
38
39    unsigned int isSet_metainfo : 1;
40    unsigned int isSet_delete : 1;
41    benc_val_t metainfo;
42    char * sourceFile;
43
44    struct optional_args optionalArgs[2];
45};
46
47/***
48****
49***/
50
51static void
52setSourceFile( tr_ctor * ctor, const char * sourceFile )
53{
54    tr_free( ctor->sourceFile );
55    ctor->sourceFile = tr_strdup( sourceFile );
56}
57
58static void
59clearMetainfo( tr_ctor * ctor )
60{
61    if( ctor->isSet_metainfo ) {
62        ctor->isSet_metainfo = 0;
63        tr_bencFree( &ctor->metainfo );
64    }
65
66    setSourceFile( ctor, NULL );
67}
68
69int
70tr_ctorSetMetainfo( tr_ctor        * ctor,
71                    const uint8_t  * metainfo,
72                    size_t           len )
73{
74    int err;
75    clearMetainfo( ctor );
76    err = tr_bencLoad( metainfo, len, &ctor->metainfo, NULL );
77    ctor->isSet_metainfo = !err;
78    return err;
79}
80
81const char*
82tr_ctorGetSourceFile( const tr_ctor * ctor )
83{
84    return ctor->sourceFile;
85}
86
87int
88tr_ctorSetMetainfoFromFile( tr_ctor        * ctor,
89                            const char     * filename )
90{
91    uint8_t * metainfo;
92    size_t len;
93    int err;
94
95    metainfo = tr_loadFile( filename, &len );
96    if( metainfo && len )
97        err = tr_ctorSetMetainfo( ctor, metainfo, len );
98    else {
99        clearMetainfo( ctor );
100        err = 1;
101    }
102
103    setSourceFile( ctor, filename );
104
105    /* if no `name' field was set, then set it from the filename */
106    if( ctor->isSet_metainfo ) {
107        benc_val_t * info = tr_bencDictFindType( &ctor->metainfo, "info", TYPE_DICT );
108        if( info != NULL ) {
109            benc_val_t * name = tr_bencDictFindFirst( info, "name.utf-8", "name", NULL );
110            if( name == NULL )
111                name = tr_bencDictAdd( info, "name" );
112            if( name->type!=TYPE_STR || !name->val.s.s || !*name->val.s.s ) {
113                char * tmp = tr_strdup( filename );
114                tr_bencInitStrDup( name, basename( tmp ) );
115                tr_free( tmp );
116            }
117        }
118    }
119
120    tr_free( metainfo );
121    return err;
122}
123
124int
125tr_ctorSetMetainfoFromHash( tr_ctor        * ctor,
126                            const char     * hashString )
127{
128    int err = -1;
129    char basename[2048];
130    char filename[MAX_PATH_LENGTH];
131
132    if( err && ( ctor->handle->tag != NULL ) ) {
133        snprintf( basename, sizeof(basename), "%s-%s", hashString, ctor->handle->tag );
134        tr_buildPath( filename, sizeof(filename), tr_getTorrentsDirectory(), basename, NULL );
135        err = tr_ctorSetMetainfoFromFile( ctor, filename );
136    }
137
138    if( err ) {
139        tr_buildPath( filename, sizeof(filename), tr_getTorrentsDirectory(), hashString, NULL );
140        err = tr_ctorSetMetainfoFromFile( ctor, filename );
141    }
142
143    return err;
144}
145
146/***
147****
148***/
149
150void
151tr_ctorSetDeleteSource( tr_ctor  * ctor,
152                        uint8_t    deleteSource )
153{
154    ctor->doDelete = deleteSource ? 1 : 0;
155    ctor->isSet_delete = 1;
156}
157
158int
159tr_ctorGetDeleteSource( const tr_ctor  * ctor,
160                        uint8_t        * setme )
161{
162    int err = 0;
163
164    if( !ctor->isSet_delete )
165        err = 1;
166    else if( setme )
167        *setme = ctor->doDelete ? 1 : 0;
168
169    return err;
170}
171
172/***
173****
174***/
175
176void
177tr_ctorSetSave( tr_ctor  * ctor,
178                int        saveInOurTorrentsDir )
179{
180    ctor->saveInOurTorrentsDir = saveInOurTorrentsDir ? 1 : 0;
181}
182
183int
184tr_ctorGetSave( const tr_ctor * ctor )
185{
186    return ctor && ctor->saveInOurTorrentsDir;
187}
188
189void
190tr_ctorSetPaused( tr_ctor        * ctor,
191                  tr_ctorMode      mode,
192                  uint8_t          isPaused )
193{
194    struct optional_args * args = &ctor->optionalArgs[mode];
195    args->isSet_paused = 1;
196    args->isPaused = isPaused ? 1 : 0;
197}
198
199void
200tr_ctorSetMaxConnectedPeers( tr_ctor        * ctor,
201                             tr_ctorMode      mode,
202                             uint16_t         maxConnectedPeers )
203{
204    struct optional_args * args = &ctor->optionalArgs[mode];
205    args->isSet_connected = 1;
206    args->maxConnectedPeers = maxConnectedPeers;
207}
208
209void
210tr_ctorSetDestination( tr_ctor        * ctor,
211                       tr_ctorMode      mode,
212                       const char     * directory )
213{
214    struct optional_args * args = &ctor->optionalArgs[mode];
215    args->isSet_destination = 1;
216    strlcpy( args->destination, directory, sizeof( args->destination ) );
217}
218
219int
220tr_ctorGetMaxConnectedPeers( const tr_ctor  * ctor,
221                             tr_ctorMode      mode,
222                             uint16_t       * setmeCount )
223{
224    int err = 0;
225    const struct optional_args * args = &ctor->optionalArgs[mode];
226
227    if( !args->isSet_connected )
228        err = 1;
229    else if( setmeCount )
230        *setmeCount = args->maxConnectedPeers;
231
232    return err;
233}
234
235int
236tr_ctorGetPaused( const tr_ctor  * ctor,
237                  tr_ctorMode      mode,
238                  uint8_t        * setmeIsPaused )
239{
240    int err = 0;
241    const struct optional_args * args = &ctor->optionalArgs[mode];
242
243    if( !args->isSet_paused )
244        err = 1;
245    else if( setmeIsPaused )
246        *setmeIsPaused = args->isPaused ? 1 : 0;
247
248    return err;
249}
250
251int
252tr_ctorGetDestination( const tr_ctor  * ctor,
253                       tr_ctorMode      mode,
254                       const char    ** setmeDestination )
255{
256    int err = 0;
257    const struct optional_args * args = &ctor->optionalArgs[mode];
258
259    if( !args->isSet_destination )
260        err = 1;
261    else if( setmeDestination )
262        *setmeDestination = args->destination;
263
264    return err;
265}
266
267int
268tr_ctorGetMetainfo( const tr_ctor              * ctor,
269                    const struct benc_val_s   ** setme )
270{
271    int err = 0;
272
273    if( !ctor->isSet_metainfo )
274        err = 1;
275    else if( setme )
276        *setme = &ctor->metainfo;
277
278    return err;
279}
280
281/***
282****
283***/
284
285tr_ctor*
286tr_ctorNew( const tr_handle * handle )
287{
288    tr_ctor * ctor = tr_new0( struct tr_ctor, 1 );
289    ctor->handle = handle;
290    tr_ctorSetMaxConnectedPeers( ctor, TR_FALLBACK, DEFAULT_MAX_CONNECTED_PEERS );
291    tr_ctorSetPaused( ctor, TR_FALLBACK, FALSE );
292    tr_ctorSetSave( ctor, TRUE );
293    return ctor;
294}
295
296void
297tr_ctorFree( tr_ctor * ctor )
298{
299    clearMetainfo( ctor );
300    tr_free( ctor );
301}
Note: See TracBrowser for help on using the repository browser.