~ubuntu-branches/ubuntu/jaunty/transmission/jaunty-security

« back to all changes in this revision

Viewing changes to gtk/tr-torrent.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2008-11-28 15:33:48 UTC
  • mfrom: (1.1.19 upstream)
  • Revision ID: james.westby@ubuntu.com-20081128153348-it70trfnxiroblmc
Tags: 1.40-0ubuntu1
* New upstream release (LP: #302672)
  - Tracker communication uses fewer resources
  - More accurate bandwidth limits
  - Reduce disk fragmentation by preallocating files (LP: #287726)
  - Stability, security and performance improvements to the RPC /
    Web UI server (closes LP: #290423)
  - Support compression when serving Web UI and RPC responses
  - Simplify the RPC whitelist
  - Fix bug that prevented handshakes with encrypted BitComet peers
  - Fix 1.3x bug that could re-download some data unnecessarily
    (LP: #295040)
  - Option to automatically update the blocklist weekly
  - Added off-hour bandwidth scheduling
  - Simplify file/priority selection in the details dialog
  - Fix a couple of crashes
  - New / updated translations
  - Don't inhibit hibernation by default (LP: #292929)
  - Use "close" animation when sending to notification area (LP: #130811)
  - Fix resize problems (LP: #269872)
  - Support "--version" option when launching from command line
    (LP: #292011)
  - Correctly parse announce URLs that have leading or trailing
    spaces (LP: #262411)
  - Display an error when "Open Torrent" fails (LP: #281463)
* Dropped 10_fix_crasher_from_upstream.dpatch: Fix is in this
  upstream release.
* debian/control: Don't just build-depend on libcurl-dev, which is
  a virtual package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: tr-torrent.c 6489 2008-08-11 19:05:00Z charles $
 
2
 * $Id: tr-torrent.c 6978 2008-10-28 19:49:33Z charles $
3
3
 *
4
4
 * Copyright (c) 2006-2008 Transmission authors and contributors
5
5
 *
38
38
 
39
39
struct TrTorrentPrivate
40
40
{
41
 
   tr_torrent * handle;
42
 
   gboolean do_remove;
 
41
    tr_torrent *  handle;
 
42
    gboolean      do_remove;
43
43
};
44
44
 
45
45
 
46
46
static void
47
 
tr_torrent_init(GTypeInstance *instance, gpointer g_class UNUSED )
 
47
tr_torrent_init( GTypeInstance *  instance,
 
48
                 gpointer g_class UNUSED )
48
49
{
49
 
    TrTorrent * self = TR_TORRENT( instance );
 
50
    TrTorrent *               self = TR_TORRENT( instance );
50
51
    struct TrTorrentPrivate * p;
51
52
 
52
53
    p = self->priv = G_TYPE_INSTANCE_GET_PRIVATE( self,
69
70
tr_torrent_dispose( GObject * o )
70
71
{
71
72
    GObjectClass * parent;
72
 
    TrTorrent * self = TR_TORRENT( o );
 
73
    TrTorrent *    self = TR_TORRENT( o );
73
74
 
74
75
    if( !isDisposed( self ) )
75
76
    {
84
85
        self->priv = NULL;
85
86
    }
86
87
 
87
 
    parent = g_type_class_peek(g_type_parent(TR_TORRENT_TYPE));
 
88
    parent = g_type_class_peek( g_type_parent( TR_TORRENT_TYPE ) );
88
89
    parent->dispose( o );
89
90
}
90
91
 
98
99
}
99
100
 
100
101
static void
101
 
tr_torrent_class_init( gpointer g_class, gpointer g_class_data UNUSED )
 
102
tr_torrent_class_init( gpointer              g_class,
 
103
                       gpointer g_class_data UNUSED )
102
104
{
103
 
    GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
 
105
    GObjectClass *gobject_class = G_OBJECT_CLASS( g_class );
 
106
 
104
107
    gobject_class->dispose = tr_torrent_dispose;
105
108
    g_type_class_add_private( g_class, sizeof( struct TrTorrentPrivate ) );
106
109
}
108
111
GType
109
112
tr_torrent_get_type( void )
110
113
{
111
 
  static GType type = 0;
 
114
    static GType type = 0;
112
115
 
113
 
  if( !type )
114
 
  {
115
 
    static const GTypeInfo info = {
116
 
      sizeof (TrTorrentClass),
117
 
      NULL,   /* base_init */
118
 
      NULL,   /* base_finalize */
119
 
      tr_torrent_class_init,   /* class_init */
120
 
      NULL,   /* class_finalize */
121
 
      NULL,   /* class_data */
122
 
      sizeof (TrTorrent),
123
 
      0,      /* n_preallocs */
124
 
      tr_torrent_init, /* instance_init */
125
 
      NULL,
126
 
    };
127
 
    type = g_type_register_static(G_TYPE_OBJECT, "TrTorrent", &info, 0);
128
 
  }
129
 
  return type;
 
116
    if( !type )
 
117
    {
 
118
        static const GTypeInfo info = {
 
119
            sizeof ( TrTorrentClass ),
 
120
            NULL,                     /* base_init */
 
121
            NULL,                     /* base_finalize */
 
122
            tr_torrent_class_init,    /* class_init */
 
123
            NULL,                     /* class_finalize */
 
124
            NULL,                     /* class_data */
 
125
            sizeof ( TrTorrent ),
 
126
            0,                        /* n_preallocs */
 
127
            tr_torrent_init,          /* instance_init */
 
128
            NULL,
 
129
        };
 
130
        type = g_type_register_static( G_TYPE_OBJECT, "TrTorrent", &info, 0 );
 
131
    }
 
132
    return type;
130
133
}
131
134
 
132
135
tr_torrent *
133
 
tr_torrent_handle(TrTorrent *tor)
 
136
tr_torrent_handle( TrTorrent *tor )
134
137
{
135
138
    return isDisposed( tor ) ? NULL : tor->priv->handle;
136
139
}
137
140
 
138
141
const tr_stat *
139
 
tr_torrent_stat(TrTorrent *tor)
 
142
tr_torrent_stat( TrTorrent *tor )
140
143
{
141
144
    tr_torrent * handle = tr_torrent_handle( tor );
 
145
 
142
146
    return handle ? tr_torrentStatCached( handle ) : NULL;
143
147
}
144
148
 
146
150
tr_torrent_info( TrTorrent * tor )
147
151
{
148
152
    tr_torrent * handle = tr_torrent_handle( tor );
 
153
 
149
154
    return handle ? tr_torrentInfo( handle ) : NULL;
150
155
}
151
156
 
155
160
    tr_notify_send( TR_TORRENT( user_data ) );
156
161
    return FALSE;
157
162
}
 
163
 
158
164
static void
159
 
statusChangedCallback( tr_torrent   * tor UNUSED,
160
 
                       cp_status_t    status,
161
 
                       void         * user_data )
 
165
completenessChangedCallback( tr_torrent       * tor UNUSED,
 
166
                             tr_completeness    completeness,
 
167
                             void *             user_data )
162
168
{
163
 
    if( status == TR_CP_COMPLETE )
 
169
    if( completeness == TR_CP_COMPLETE )
164
170
        g_idle_add( notifyInMainThread, user_data );
165
171
}
 
172
 
166
173
static TrTorrent *
167
 
maketorrent( tr_torrent * handle )
 
174
maketorrent( tr_torrent * tor )
168
175
{
169
 
    TrTorrent * tor = g_object_new( TR_TORRENT_TYPE, NULL );
170
 
    tor->priv->handle = handle;
171
 
    tr_torrentSetStatusCallback( handle, statusChangedCallback, tor );
172
 
    return tor;
 
176
    TrTorrent * gtor = g_object_new( TR_TORRENT_TYPE, NULL );
 
177
 
 
178
    gtor->priv->handle = tor;
 
179
    tr_torrentSetCompletenessCallback( tor, completenessChangedCallback, gtor );
 
180
    return gtor;
173
181
}
174
182
 
175
183
TrTorrent*
179
187
}
180
188
 
181
189
TrTorrent *
182
 
tr_torrent_new_ctor( tr_handle  * handle,
183
 
                     tr_ctor    * ctor,
184
 
                     char      ** err )
 
190
tr_torrent_new_ctor( tr_session   * session,
 
191
                     tr_ctor      * ctor,
 
192
                     char        ** err )
185
193
{
186
194
    tr_torrent * tor;
187
 
    int errcode;
188
 
    uint8_t doTrash = FALSE;
 
195
    int          errcode;
 
196
    uint8_t      doTrash = FALSE;
189
197
 
190
198
    errcode = -1;
191
199
    *err = NULL;
194
202
     * doesn't have any concept of the glib trash API */
195
203
    tr_ctorGetDeleteSource( ctor, &doTrash );
196
204
    tr_ctorSetDeleteSource( ctor, FALSE );
197
 
    tor = tr_torrentNew( handle, ctor, &errcode );
 
205
    tor = tr_torrentNew( session, ctor, &errcode );
198
206
 
199
207
    if( tor && doTrash )
200
 
        tr_file_trash_or_unlink( tr_ctorGetSourceFile( ctor ) );
201
 
  
 
208
    {
 
209
        const char * config = tr_sessionGetConfigDir( session );
 
210
        const char * source = tr_ctorGetSourceFile( ctor );
 
211
        const int is_internal = source && ( strstr( source, config ) == source );
 
212
 
 
213
        /* #1294: don't delete the source .torrent file if it's our internal copy */
 
214
        if( !is_internal )
 
215
            tr_file_trash_or_unlink( source );
 
216
    }
 
217
 
202
218
    if( !tor )
203
219
    {
204
220
        const char * filename = tr_ctorGetSourceFile( ctor );
208
224
        switch( errcode )
209
225
        {
210
226
            case TR_EINVALID:
211
 
                *err = g_strdup_printf( _( "File \"%s\" isn't a valid torrent" ), filename );
212
 
                 break;
 
227
                *err =
 
228
                    g_strdup_printf( _(
 
229
                                         "File \"%s\" isn't a valid torrent" ),
 
230
                                     filename );
 
231
                break;
 
232
 
213
233
            case TR_EDUPLICATE:
214
 
                *err = g_strdup_printf( _( "File \"%s\" is already open" ), filename );
 
234
                *err = g_strdup_printf( _(
 
235
                                            "File \"%s\" is already open" ),
 
236
                                        filename );
215
237
                break;
 
238
 
216
239
            default:
217
240
                *err = g_strdup( filename );
218
241
                break;
225
248
}
226
249
 
227
250
char *
228
 
tr_torrent_status_str ( TrTorrent * gtor )
 
251
tr_torrent_status_str( TrTorrent * gtor )
229
252
{
230
 
    char * top = NULL;
 
253
    char *          top = NULL;
231
254
 
232
255
    const tr_stat * st = tr_torrent_stat( gtor );
233
256
 
234
 
    const int tpeers = MAX (st->peersConnected, 0);
235
 
    const int upeers = MAX (st->peersGettingFromUs, 0);
236
 
    const int eta = st->eta;
237
 
    double prog = st->percentDone * 100.0; /* [0...100] */
 
257
    const int       tpeers = MAX ( st->peersConnected, 0 );
 
258
    const int       upeers = MAX ( st->peersGettingFromUs, 0 );
 
259
    const int       eta = st->eta;
238
260
 
239
 
    switch( st->status )
 
261
    switch( st->activity )
240
262
    {
241
263
        case TR_STATUS_CHECK_WAIT:
242
 
            prog = st->recheckProgress * 100.0; /* [0...100] */
243
 
            top = g_strdup_printf( _("Waiting to verify local data (%.1f%% tested)"), prog );
 
264
            top =
 
265
                g_strdup_printf( _(
 
266
                                     "Waiting to verify local data (%.1f%% tested)" ),
 
267
                                 st->recheckProgress * 100.0 );
244
268
            break;
245
269
 
246
270
        case TR_STATUS_CHECK:
247
 
            prog = st->recheckProgress * 100.0; /* [0...100] */
248
 
            top = g_strdup_printf( _("Verifying local data (%.1f%% tested)"), prog );
 
271
            top =
 
272
                g_strdup_printf( _(
 
273
                                     "Verifying local data (%.1f%% tested)" ),
 
274
                                 st->recheckProgress * 100.0 );
249
275
            break;
250
276
 
251
277
        case TR_STATUS_DOWNLOAD:
252
278
 
253
 
            if( eta == TR_ETA_NOT_AVAIL )
254
 
                top = g_strdup_printf( _("Data not fully available (%.1f%%)" ), prog );
255
 
            else if( eta == TR_ETA_UNKNOWN )
256
 
                top = g_strdup_printf( _( "Stalled (%.1f%%)" ), prog );
257
 
            else {
 
279
            if( eta < 0 )
 
280
                top = g_strdup_printf( _( "Remaining time unknown" ) );
 
281
            else
 
282
            {
258
283
                char timestr[128];
259
284
                tr_strltime( timestr, eta, sizeof( timestr ) );
260
 
                /* %1$s is # of minutes
261
 
                   %2$.1f is a percentage of how much of the torrent is done */
262
 
                top = g_strdup_printf( _("%1$s remaining (%2$.1f%%)"), timestr, prog );
 
285
                /* %s is # of minutes */
 
286
                top = g_strdup_printf( _( "%1$s remaining" ), timestr );
263
287
            }
264
288
            break;
265
289
 
266
290
        case TR_STATUS_SEED:
267
291
            top = g_strdup_printf(
268
292
                ngettext( "Seeding to %1$'d of %2$'d connected peer",
269
 
                          "Seeding to %1$'d of %2$'d connected peers", tpeers ),
270
 
                          upeers, tpeers );
 
293
                          "Seeding to %1$'d of %2$'d connected peers",
 
294
                          tpeers ),
 
295
                upeers, tpeers );
271
296
            break;
272
297
 
273
298
        case TR_STATUS_STOPPED:
274
 
            top = g_strdup_printf( _("Stopped (%.1f%%)"), prog );
 
299
            top = g_strdup( _( "Stopped" ) );
275
300
            break;
276
301
 
277
302
        default:
278
 
            top = g_strdup_printf( "???" );
 
303
            top = g_strdup( "???" );
279
304
            break;
280
 
 
281
305
    }
282
306
 
283
307
    return top;
284
308
}
285
309
 
286
310
void
287
 
tr_torrent_set_remove_flag( TrTorrent * gtor, gboolean do_remove )
 
311
tr_torrent_set_remove_flag( TrTorrent * gtor,
 
312
                            gboolean    do_remove )
288
313
{
289
314
    if( !isDisposed( gtor ) )
290
315
        gtor->priv->do_remove = do_remove;
295
320
{
296
321
    tr_file_index_t i;
297
322
    const tr_info * info = tr_torrent_info( gtor );
298
 
    const char * stop = tr_torrentGetDownloadDir( tr_torrent_handle( gtor ) );
 
323
    const char *    stop =
 
324
        tr_torrentGetDownloadDir( tr_torrent_handle( gtor ) );
299
325
 
300
 
    for( i=0; info && i<info->fileCount; ++i )
 
326
    for( i = 0; info && i < info->fileCount; ++i )
301
327
    {
302
328
        char * file = g_build_filename( stop, info->files[i].name, NULL );
303
 
        while( strcmp( stop, file ) && strlen(stop) < strlen(file) )
 
329
        while( strcmp( stop, file ) && strlen( stop ) < strlen( file ) )
304
330
        {
305
331
            char * swap = g_path_get_dirname( file );
306
332
            tr_file_trash_or_unlink( file );
307
333
            g_free( file );
308
334
            file = swap;
309
335
        }
 
336
 
310
337
        g_free( file );
311
338
    }
312
339
}
314
341
void
315
342
tr_torrent_open_folder( TrTorrent * gtor )
316
343
{
317
 
    tr_torrent * tor = tr_torrent_handle( gtor );
 
344
    tr_torrent *    tor = tr_torrent_handle( gtor );
318
345
    const tr_info * info = tr_torrent_info( gtor );
319
 
    char * path = info->fileCount == 1
320
 
        ? g_build_filename( tr_torrentGetDownloadDir(tor), NULL )
321
 
        : g_build_filename( tr_torrentGetDownloadDir(tor), info->name, NULL );
 
346
    char *          path = info->fileCount == 1
 
347
                           ? g_build_filename( tr_torrentGetDownloadDir(
 
348
                                                   tor ), NULL )
 
349
                           : g_build_filename( tr_torrentGetDownloadDir(
 
350
                                                   tor ), info->name, NULL );
 
351
 
322
352
    gtr_open_file( path );
323
353
    g_free( path );
324
354
}
 
355