source: trunk/libtransmission/transmission.c @ 2526

Last change on this file since 2526 was 2526, checked in by charles, 15 years ago

get both build systems (hand-written configure, and autoconf) to generate equivalent version.h headers

  • Property svn:keywords set to Date Rev Author Id
File size: 7.8 KB
Line 
1/******************************************************************************
2 * $Id: transmission.c 2526 2007-07-28 04:10:09Z charles $
3 *
4 * Copyright (c) 2005-2007 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#include <signal.h>
26#include <sys/types.h> /* stat */
27#include <sys/stat.h> /* stat */
28#include <unistd.h> /* stat */
29#include <dirent.h> /* opendir */
30#include "transmission.h"
31#include "fdlimit.h"
32#include "list.h"
33#include "net.h"
34#include "shared.h"
35
36/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric
37   characters, where x is the major version number, y is the
38   minor version number, z is the maintenance number, and b
39   designates beta (Azureus-style) */
40void
41tr_peerIdNew ( char * buf, int buflen )
42{
43    int i;
44    assert( buflen == TR_ID_LEN + 1 );
45
46    snprintf( buf, TR_ID_LEN, "%s", PEERID_PREFIX );
47    assert( strlen(buf) == 8 );
48    for( i=8; i<TR_ID_LEN; ++i ) {
49        const int r = tr_rand( 36 );
50        buf[i] = ( r < 26 ) ? ( 'a' + r ) : ( '0' + r - 26 ) ;
51    }
52    buf[TR_ID_LEN] = '\0';
53}
54
55
56/***********************************************************************
57 * tr_init
58 ***********************************************************************
59 * Allocates a tr_handle_t structure and initializes a few things
60 **********************************************************************/
61tr_handle_t * tr_init( const char * tag )
62{
63    tr_handle_t * h;
64    int           i;
65
66    tr_msgInit();
67    tr_netResolveThreadInit();
68
69    h = calloc( 1, sizeof( tr_handle_t ) );
70    if( NULL == h )
71    {
72        return NULL;
73    }
74
75    h->tag = strdup( tag );
76    if( NULL == h->tag )
77    {
78        free( h );
79        return NULL;
80    }
81
82    /* Random key */
83    for( i=0; i < TR_KEY_LEN; ++i )
84    {
85        const int r = tr_rand( 36 );
86        h->key[i] = ( r < 26 ) ? ( 'a' + r ) : ( '0' + r - 26 ) ;
87    }
88
89    /* Azureus identity */
90    for( i=0; i < TR_AZ_ID_LEN; ++i )
91    {
92        h->azId[i] = tr_rand( 0xff );
93    }
94
95    /* Don't exit when writing on a broken socket */
96    signal( SIGPIPE, SIG_IGN );
97
98    /* Initialize rate and file descripts controls */
99    h->upload   = tr_rcInit();
100    h->download = tr_rcInit();
101
102    tr_fdInit();
103    h->shared = tr_sharedInit( h );
104
105    tr_inf( TR_NAME " " LONG_VERSION_STRING " started" );
106
107    return h;
108}
109
110/***********************************************************************
111 * tr_setBindPort
112 ***********************************************************************
113 *
114 **********************************************************************/
115void tr_setBindPort( tr_handle_t * h, int port )
116{
117    h->isPortSet = 1;
118    tr_sharedSetPort( h->shared, port );
119}
120
121void tr_natTraversalEnable( tr_handle_t * h, int enable )
122{
123    tr_sharedLock( h->shared );
124    tr_sharedTraversalEnable( h->shared, enable );
125    tr_sharedUnlock( h->shared );
126}
127
128tr_handle_status_t * tr_handleStatus( tr_handle_t * h )
129{
130    tr_handle_status_t * s;
131
132    h->statCur = ( h->statCur + 1 ) % 2;
133    s = &h->stats[h->statCur];
134
135    tr_sharedLock( h->shared );
136
137    s->natTraversalStatus = tr_sharedTraversalStatus( h->shared );
138    s->publicPort = tr_sharedGetPublicPort( h->shared );
139
140    tr_sharedUnlock( h->shared );
141
142    return s;
143}
144
145/***
146****
147***/
148
149void
150tr_setUseGlobalSpeedLimit( tr_handle_t  * h,
151                           int            up_or_down,
152                           int            use_flag )
153{
154    char * ch = up_or_down==TR_UP ? &h->useUploadLimit
155                                  : &h->useDownloadLimit;
156    *ch = use_flag;
157}
158
159void
160tr_setGlobalSpeedLimit( tr_handle_t  * h,
161                        int            up_or_down,
162                        int            KiB_sec )
163{
164    if( up_or_down == TR_DOWN )
165        tr_rcSetLimit( h->download, KiB_sec );
166    else {
167        tr_rcSetLimit( h->upload, KiB_sec );
168        tr_sharedSetLimit( h->shared, KiB_sec );
169    }
170}
171
172void
173tr_getGlobalSpeedLimit( tr_handle_t  * h,
174                        int            up_or_down,
175                        int          * setme_enabled,
176                        int          * setme_KiBsec )
177{
178    if( setme_enabled != NULL )
179       *setme_enabled = up_or_down==TR_UP ? h->useUploadLimit
180                                          : h->useDownloadLimit;
181    if( setme_KiBsec != NULL )
182       *setme_KiBsec = tr_rcGetLimit( up_or_down==TR_UP ? h->upload
183                                                        : h->download );
184}
185
186
187void tr_torrentRates( tr_handle_t * h, float * dl, float * ul )
188{
189    tr_torrent_t * tor;
190
191    *dl = 0.0;
192    *ul = 0.0;
193    tr_sharedLock( h->shared );
194    for( tor = h->torrentList; tor; tor = tor->next )
195    {
196        tr_torrentReaderLock( tor );
197        if( tor->cpStatus == TR_CP_INCOMPLETE )
198            *dl += tr_rcRate( tor->download );
199        *ul += tr_rcRate( tor->upload );
200        tr_torrentReaderUnlock( tor );
201    }
202    tr_sharedUnlock( h->shared );
203}
204
205int tr_torrentCount( tr_handle_t * h )
206{
207    return h->torrentCount;
208}
209
210void tr_torrentIterate( tr_handle_t * h, tr_callback_t func, void * d )
211{
212    tr_torrent_t * tor, * next;
213
214    for( tor = h->torrentList; tor; tor = next )
215    {
216        next = tor->next;
217        func( tor, d );
218    }
219}
220
221void tr_close( tr_handle_t * h )
222{
223    tr_rcClose( h->upload );
224    tr_rcClose( h->download );
225   
226    tr_sharedClose( h->shared );
227    tr_fdClose();
228    free( h->tag );
229    free( h );
230
231    tr_netResolveThreadClose();
232}
233
234tr_torrent_t **
235tr_loadTorrents ( tr_handle_t   * h,
236                  const char    * destination,
237                  int             flags,
238                  int          * setmeCount )
239{
240    int i, n = 0;
241    struct stat sb;
242    DIR * odir = NULL;
243    const char * torrentDir = tr_getTorrentsDirectory( );
244    tr_torrent_t ** torrents;
245    tr_list_t *l=NULL, *list=NULL;
246
247    if( !stat( torrentDir, &sb )
248        && S_ISDIR( sb.st_mode )
249        && (( odir = opendir ( torrentDir ) )) )
250    {
251        struct dirent *d;
252        for (d = readdir( odir ); d!=NULL; d=readdir( odir ) )
253        {
254            if( d->d_name && d->d_name[0]!='.' ) /* skip dotfiles, ., and .. */
255            {
256                tr_torrent_t * tor;
257                char path[MAX_PATH_LENGTH];
258                tr_buildPath( path, sizeof(path), torrentDir, d->d_name, NULL );
259                tor = tr_torrentInit( h, path, destination, flags, NULL );
260                if( tor != NULL ) {
261                    list = tr_list_append( list, tor );
262                    //fprintf (stderr, "#%d - %s\n", n, tor->info.name );
263                    n++;
264                }
265            }
266        }
267        closedir( odir );
268    }
269
270    torrents = tr_new( tr_torrent_t*, n );
271    for( i=0, l=list; l!=NULL; l=l->next )
272        torrents[i++] = (tr_torrent_t*) l->data;
273    assert( i==n );
274
275    tr_list_free( list );
276
277    *setmeCount = n;
278    tr_inf( "Loaded %d torrents from disk", *setmeCount );
279    return torrents;
280}
Note: See TracBrowser for help on using the repository browser.