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

Last change on this file since 6154 was 6154, checked in by charles, 13 years ago

tr_ctorSetDownloadDir(): handle NULL download dirs more gracefully.

  • Property svn:keywords set to Date Rev Author Id
File size: 6.8 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: torrent-ctor.c 6154 2008-06-11 23:40:27Z charles $
11 */
12
13#include <libgen.h> /* basename */
14#include "transmission.h"
15#include "bencode.h"
16#include "platform.h"
17#include "session.h" /* tr_sessionFindTorrentFile */
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_downloadDir : 1;
27
28    unsigned int isPaused : 1;
29    uint16_t peerLimit;
30    char downloadDir[MAX_PATH_LENGTH];
31};
32
33/** Opaque class used when instantiating torrents.
34  * @ingroup tr_ctor */
35struct tr_ctor
36{
37    const tr_handle * handle;
38    unsigned int saveInOurTorrentsDir : 1;
39    unsigned int doDelete : 1;
40
41    unsigned int isSet_metainfo : 1;
42    unsigned int isSet_delete : 1;
43    tr_benc metainfo;
44    char * sourceFile;
45
46    struct optional_args optionalArgs[2];
47};
48
49/***
50****
51***/
52
53static void
54setSourceFile( tr_ctor * ctor, const char * sourceFile )
55{
56    tr_free( ctor->sourceFile );
57    ctor->sourceFile = tr_strdup( sourceFile );
58}
59
60static void
61clearMetainfo( tr_ctor * ctor )
62{
63    if( ctor->isSet_metainfo ) {
64        ctor->isSet_metainfo = 0;
65        tr_bencFree( &ctor->metainfo );
66    }
67
68    setSourceFile( ctor, NULL );
69}
70
71int
72tr_ctorSetMetainfo( tr_ctor        * ctor,
73                    const uint8_t  * metainfo,
74                    size_t           len )
75{
76    int err;
77    clearMetainfo( ctor );
78    err = tr_bencLoad( metainfo, len, &ctor->metainfo, NULL );
79    ctor->isSet_metainfo = !err;
80    return err;
81}
82
83const char*
84tr_ctorGetSourceFile( const tr_ctor * ctor )
85{
86    return ctor->sourceFile;
87}
88
89int
90tr_ctorSetMetainfoFromFile( tr_ctor        * ctor,
91                            const char     * filename )
92{
93    uint8_t * metainfo;
94    size_t len;
95    int err;
96
97    metainfo = tr_loadFile( filename, &len );
98    if( metainfo && len )
99        err = tr_ctorSetMetainfo( ctor, metainfo, len );
100    else {
101        clearMetainfo( ctor );
102        err = 1;
103    }
104
105    setSourceFile( ctor, filename );
106
107    /* if no `name' field was set, then set it from the filename */
108    if( ctor->isSet_metainfo ) {
109        tr_benc * info = tr_bencDictFindType( &ctor->metainfo, "info", TYPE_DICT );
110        if( info != NULL ) {
111            tr_benc * name = tr_bencDictFindFirst( info, "name.utf-8", "name", NULL );
112            if( name == NULL )
113                name = tr_bencDictAdd( info, "name" );
114            if( name->type!=TYPE_STR || !name->val.s.s || !*name->val.s.s ) {
115                char * tmp = tr_strdup( filename );
116                tr_bencInitStrDup( name, basename( tmp ) );
117                tr_free( tmp );
118            }
119        }
120    }
121
122    tr_free( metainfo );
123    return err;
124}
125
126int
127tr_ctorSetMetainfoFromHash( tr_ctor        * ctor,
128                            const char     * hashString )
129{
130    int err;
131    const char * filename;
132
133    if(( filename = tr_sessionFindTorrentFile( ctor->handle, hashString )))
134        err = tr_ctorSetMetainfoFromFile( ctor, filename ); 
135    else
136        err = TR_ERROR;
137
138    return err;
139}
140
141/***
142****
143***/
144
145void
146tr_ctorSetDeleteSource( tr_ctor  * ctor,
147                        uint8_t    deleteSource )
148{
149    ctor->doDelete = deleteSource ? 1 : 0;
150    ctor->isSet_delete = 1;
151}
152
153int
154tr_ctorGetDeleteSource( const tr_ctor  * ctor,
155                        uint8_t        * setme )
156{
157    int err = 0;
158
159    if( !ctor->isSet_delete )
160        err = 1;
161    else if( setme )
162        *setme = ctor->doDelete ? 1 : 0;
163
164    return err;
165}
166
167/***
168****
169***/
170
171void
172tr_ctorSetSave( tr_ctor  * ctor,
173                int        saveInOurTorrentsDir )
174{
175    ctor->saveInOurTorrentsDir = saveInOurTorrentsDir ? 1 : 0;
176}
177
178int
179tr_ctorGetSave( const tr_ctor * ctor )
180{
181    return ctor && ctor->saveInOurTorrentsDir;
182}
183
184void
185tr_ctorSetPaused( tr_ctor        * ctor,
186                  tr_ctorMode      mode,
187                  uint8_t          isPaused )
188{
189    struct optional_args * args = &ctor->optionalArgs[mode];
190    args->isSet_paused = 1;
191    args->isPaused = isPaused ? 1 : 0;
192}
193
194void
195tr_ctorSetPeerLimit( tr_ctor        * ctor,
196                     tr_ctorMode      mode,
197                     uint16_t         peerLimit )
198{
199    struct optional_args * args = &ctor->optionalArgs[mode];
200    args->isSet_connected = 1;
201    args->peerLimit = peerLimit;
202}
203
204void
205tr_ctorSetDownloadDir( tr_ctor        * ctor,
206                       tr_ctorMode      mode,
207                       const char     * directory )
208{
209    struct optional_args * args = &ctor->optionalArgs[mode];
210    if( directory ) {
211        args->isSet_downloadDir = 1;
212        tr_strlcpy( args->downloadDir, directory, sizeof( args->downloadDir ) );
213    } else {
214        args->isSet_downloadDir = 0;
215        *args->downloadDir = '\0';
216    }
217}
218
219int
220tr_ctorGetPeerLimit( 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->peerLimit;
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_ctorGetDownloadDir( const tr_ctor  * ctor,
253                       tr_ctorMode      mode,
254                       const char    ** setmeDownloadDir )
255{
256    int err = 0;
257    const struct optional_args * args = &ctor->optionalArgs[mode];
258
259    if( !args->isSet_downloadDir )
260        err = 1;
261    else if( setmeDownloadDir )
262        *setmeDownloadDir = args->downloadDir;
263
264    return err;
265}
266
267int
268tr_ctorGetMetainfo( const tr_ctor    * ctor,
269                    const tr_benc   ** 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_ctorSetPeerLimit( ctor, TR_FALLBACK, DEFAULT_MAX_CONNECTED_PEERS );
291    tr_ctorSetPaused( ctor, TR_FALLBACK, FALSE );
292    tr_ctorSetDownloadDir( ctor, TR_FALLBACK, handle->downloadDir );
293    tr_ctorSetSave( ctor, TRUE );
294    return ctor;
295}
296
297void
298tr_ctorFree( tr_ctor * ctor )
299{
300    clearMetainfo( ctor );
301    tr_free( ctor );
302}
Note: See TracBrowser for help on using the repository browser.