transmission 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,44 @@
1
+ /******************************************************************************
2
+ * $Id: metainfo.h 310 2006-06-09 19:53:35Z joshe $
3
+ *
4
+ * Copyright (c) 2005 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
+ #ifndef TR_METAINFO_H
26
+ #define TR_METAINFO_H 1
27
+
28
+ #define TR_PARSE_FILE 10
29
+ #define TR_PARSE_STAT 20
30
+ #define TR_PARSE_FILE_TYPE 30
31
+ #define TR_PARSE_TOO_BIG 40
32
+ #define TR_PARSE_READ 50
33
+ #define TR_PARSE_WRITE 60
34
+ #define TR_PARSE_BENCODE 70
35
+ #define TR_PARSE_INFO_DIR 80
36
+ #define TR_PARSE_ANN 90
37
+ #define TR_PARSE_ANN_URL 100
38
+ #define TR_PARSE_PIECE 110
39
+ #define TR_PARSE_HASH 120
40
+ int tr_metainfoParse( tr_info_t *, const char * path,
41
+ const char * savedHash, int saveCopy );
42
+
43
+ void tr_metainfoRemoveSaved( const char * hashString );
44
+ #endif
@@ -0,0 +1,405 @@
1
+ /******************************************************************************
2
+ * $Id: net.c 261 2006-05-29 21:27:31Z titer $
3
+ *
4
+ * Copyright (c) 2005-2006 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 "transmission.h"
26
+
27
+ /***********************************************************************
28
+ * DNS resolution
29
+ **********************************************************************/
30
+
31
+ /***********************************************************************
32
+ * tr_netResolve
33
+ ***********************************************************************
34
+ * Synchronous "resolution": only works with character strings
35
+ * representing numbers expressed in the Internet standard `.' notation.
36
+ * Returns a non-zero value if an error occurs.
37
+ **********************************************************************/
38
+ int tr_netResolve( char * address, struct in_addr * addr )
39
+ {
40
+ addr->s_addr = inet_addr( address );
41
+ return ( addr->s_addr == 0xFFFFFFFF );
42
+ }
43
+
44
+ /* TODO: Make this code reentrant */
45
+ static tr_thread_t resolveThread;
46
+ static tr_lock_t resolveLock;
47
+ static volatile int resolveDie;
48
+ static tr_resolve_t * resolveQueue;
49
+
50
+ static void resolveRelease ( tr_resolve_t * );
51
+ static void resolveFunc ( void * );
52
+
53
+ struct tr_resolve_s
54
+ {
55
+ int status;
56
+ char * address;
57
+ struct in_addr addr;
58
+
59
+ int refcount;
60
+ tr_resolve_t * next;
61
+ };
62
+
63
+ /***********************************************************************
64
+ * tr_netResolveThreadInit
65
+ ***********************************************************************
66
+ * Initializes the static variables used for resolution and launch the
67
+ * gethostbyname thread.
68
+ **********************************************************************/
69
+ void tr_netResolveThreadInit()
70
+ {
71
+ resolveDie = 0;
72
+ resolveQueue = NULL;
73
+ tr_lockInit( &resolveLock );
74
+ tr_threadCreate( &resolveThread, resolveFunc, NULL );
75
+ }
76
+
77
+ /***********************************************************************
78
+ * tr_netResolveThreadClose
79
+ ***********************************************************************
80
+ * Notices the gethostbyname thread that is should terminate. Doesn't
81
+ * wait until it does, in case it is stuck in a resolution: we let it
82
+ * die and clean itself up.
83
+ **********************************************************************/
84
+ void tr_netResolveThreadClose()
85
+ {
86
+ tr_lockLock( &resolveLock );
87
+ resolveDie = 1;
88
+ tr_lockUnlock( &resolveLock );
89
+ tr_wait( 200 );
90
+ }
91
+
92
+ /***********************************************************************
93
+ * tr_netResolveInit
94
+ ***********************************************************************
95
+ * Adds an address to the resolution queue.
96
+ **********************************************************************/
97
+ tr_resolve_t * tr_netResolveInit( char * address )
98
+ {
99
+ tr_resolve_t * r;
100
+
101
+ r = malloc( sizeof( tr_resolve_t ) );
102
+ r->status = TR_RESOLVE_WAIT;
103
+ r->address = strdup( address );
104
+ r->refcount = 2;
105
+ r->next = NULL;
106
+
107
+ tr_lockLock( &resolveLock );
108
+ if( !resolveQueue )
109
+ {
110
+ resolveQueue = r;
111
+ }
112
+ else
113
+ {
114
+ tr_resolve_t * iter;
115
+ for( iter = resolveQueue; iter->next; iter = iter->next );
116
+ iter->next = r;
117
+ }
118
+ tr_lockUnlock( &resolveLock );
119
+
120
+ return r;
121
+ }
122
+
123
+ /***********************************************************************
124
+ * tr_netResolvePulse
125
+ ***********************************************************************
126
+ * Checks the current status of a resolution.
127
+ **********************************************************************/
128
+ int tr_netResolvePulse( tr_resolve_t * r, struct in_addr * addr )
129
+ {
130
+ int ret;
131
+
132
+ tr_lockLock( &resolveLock );
133
+ ret = r->status;
134
+ if( ret == TR_RESOLVE_OK )
135
+ {
136
+ *addr = r->addr;
137
+ }
138
+ tr_lockUnlock( &resolveLock );
139
+
140
+ return ret;
141
+ }
142
+
143
+ /***********************************************************************
144
+ * tr_netResolveClose
145
+ ***********************************************************************
146
+ *
147
+ **********************************************************************/
148
+ void tr_netResolveClose( tr_resolve_t * r )
149
+ {
150
+ resolveRelease( r );
151
+ }
152
+
153
+ /***********************************************************************
154
+ * resolveRelease
155
+ ***********************************************************************
156
+ * The allocated tr_resolve_t structures should be freed when
157
+ * tr_netResolveClose was called *and* it was removed from the queue.
158
+ * This can happen in any order, so we use a refcount to know we can
159
+ * take it out.
160
+ **********************************************************************/
161
+ static void resolveRelease( tr_resolve_t * r )
162
+ {
163
+ if( --r->refcount < 1 )
164
+ {
165
+ free( r->address );
166
+ free( r );
167
+ }
168
+ }
169
+
170
+ /***********************************************************************
171
+ * resolveFunc
172
+ ***********************************************************************
173
+ * Keeps waiting for addresses to resolve, and removes them from the
174
+ * queue once resolution is done.
175
+ **********************************************************************/
176
+ static void resolveFunc( void * arg UNUSED )
177
+ {
178
+ tr_resolve_t * r;
179
+ struct hostent * host;
180
+
181
+ tr_dbg( "Resolve thread started" );
182
+
183
+ tr_lockLock( &resolveLock );
184
+
185
+ while( !resolveDie )
186
+ {
187
+ if( !( r = resolveQueue ) )
188
+ {
189
+ /* TODO: Use a condition wait */
190
+ tr_lockUnlock( &resolveLock );
191
+ tr_wait( 50 );
192
+ tr_lockLock( &resolveLock );
193
+ continue;
194
+ }
195
+
196
+ /* Blocking resolution */
197
+ tr_lockUnlock( &resolveLock );
198
+ host = gethostbyname( r->address );
199
+ tr_lockLock( &resolveLock );
200
+
201
+ if( host )
202
+ {
203
+ memcpy( &r->addr, host->h_addr, host->h_length );
204
+ r->status = TR_RESOLVE_OK;
205
+ }
206
+ else
207
+ {
208
+ r->status = TR_RESOLVE_ERROR;
209
+ }
210
+
211
+ resolveQueue = r->next;
212
+ resolveRelease( r );
213
+ }
214
+
215
+ /* Clean up */
216
+ tr_lockUnlock( &resolveLock );
217
+ tr_lockClose( &resolveLock );
218
+ while( ( r = resolveQueue ) )
219
+ {
220
+ resolveQueue = r->next;
221
+ resolveRelease( r );
222
+ }
223
+
224
+ tr_dbg( "Resolve thread exited" );
225
+ }
226
+
227
+
228
+ /***********************************************************************
229
+ * TCP sockets
230
+ **********************************************************************/
231
+
232
+ static int makeSocketNonBlocking( int s )
233
+ {
234
+ int flags;
235
+
236
+ #ifdef SYS_BEOS
237
+ flags = 1;
238
+ if( setsockopt( s, SOL_SOCKET, SO_NONBLOCK,
239
+ &flags, sizeof( int ) ) < 0 )
240
+ #else
241
+ if( ( flags = fcntl( s, F_GETFL, 0 ) ) < 0 ||
242
+ fcntl( s, F_SETFL, flags | O_NONBLOCK ) < 0 )
243
+ #endif
244
+ {
245
+ tr_err( "Could not set socket to non-blocking mode (%s)",
246
+ strerror( errno ) );
247
+ tr_netClose( s );
248
+ return -1;
249
+ }
250
+
251
+ return s;
252
+ }
253
+
254
+ static int createSocket()
255
+ {
256
+ int s;
257
+
258
+ s = socket( AF_INET, SOCK_STREAM, 0 );
259
+ if( s < 0 )
260
+ {
261
+ tr_err( "Could not create socket (%s)", strerror( errno ) );
262
+ return -1;
263
+ }
264
+
265
+ return makeSocketNonBlocking( s );
266
+ }
267
+
268
+ int tr_netOpen( struct in_addr addr, in_port_t port )
269
+ {
270
+ int s;
271
+ struct sockaddr_in sock;
272
+
273
+ s = createSocket();
274
+ if( s < 0 )
275
+ {
276
+ return -1;
277
+ }
278
+
279
+ memset( &sock, 0, sizeof( sock ) );
280
+ sock.sin_family = AF_INET;
281
+ sock.sin_addr.s_addr = addr.s_addr;
282
+ sock.sin_port = port;
283
+
284
+ if( connect( s, (struct sockaddr *) &sock,
285
+ sizeof( struct sockaddr_in ) ) < 0 &&
286
+ errno != EINPROGRESS )
287
+ {
288
+ tr_err( "Could not connect socket (%s)", strerror( errno ) );
289
+ tr_netClose( s );
290
+ return -1;
291
+ }
292
+
293
+ return s;
294
+ }
295
+
296
+ int tr_netBind( int port )
297
+ {
298
+ int s;
299
+ struct sockaddr_in sock;
300
+ #ifdef SO_REUSEADDR
301
+ int optval;
302
+ #endif
303
+
304
+ s = createSocket();
305
+ if( s < 0 )
306
+ {
307
+ return -1;
308
+ }
309
+
310
+ #ifdef SO_REUSEADDR
311
+ optval = 1;
312
+ setsockopt( s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof( optval ) );
313
+ #endif
314
+
315
+ memset( &sock, 0, sizeof( sock ) );
316
+ sock.sin_family = AF_INET;
317
+ sock.sin_addr.s_addr = INADDR_ANY;
318
+ sock.sin_port = htons( port );
319
+
320
+ if( bind( s, (struct sockaddr *) &sock,
321
+ sizeof( struct sockaddr_in ) ) )
322
+ {
323
+ tr_err( "Could not bind port %d", port );
324
+ tr_netClose( s );
325
+ return -1;
326
+ }
327
+
328
+ tr_inf( "Binded port %d", port );
329
+ listen( s, 5 );
330
+
331
+ return s;
332
+ }
333
+
334
+ int tr_netAccept( int s, struct in_addr * addr, in_port_t * port )
335
+ {
336
+ int t;
337
+ unsigned len;
338
+ struct sockaddr_in sock;
339
+
340
+ len = sizeof( sock );
341
+ t = accept( s, (struct sockaddr *) &sock, &len );
342
+
343
+ if( t < 0 )
344
+ {
345
+ return -1;
346
+ }
347
+
348
+ *addr = sock.sin_addr;
349
+ *port = sock.sin_port;
350
+
351
+ return makeSocketNonBlocking( t );
352
+ }
353
+
354
+ int tr_netSend( int s, uint8_t * buf, int size )
355
+ {
356
+ int ret;
357
+
358
+ ret = send( s, buf, size, 0 );
359
+ if( ret < 0 )
360
+ {
361
+ if( errno == ENOTCONN || errno == EAGAIN || errno == EWOULDBLOCK )
362
+ {
363
+ ret = TR_NET_BLOCK;
364
+ }
365
+ else
366
+ {
367
+ ret = TR_NET_CLOSE;
368
+ }
369
+ }
370
+
371
+ return ret;
372
+ }
373
+
374
+ int tr_netRecv( int s, uint8_t * buf, int size )
375
+ {
376
+ int ret;
377
+
378
+ ret = recv( s, buf, size, 0 );
379
+ if( ret < 0 )
380
+ {
381
+ if( errno == EAGAIN || errno == EWOULDBLOCK )
382
+ {
383
+ ret = TR_NET_BLOCK;
384
+ }
385
+ else
386
+ {
387
+ ret = TR_NET_CLOSE;
388
+ }
389
+ }
390
+ if( !ret )
391
+ {
392
+ ret = TR_NET_CLOSE;
393
+ }
394
+
395
+ return ret;
396
+ }
397
+
398
+ void tr_netClose( int s )
399
+ {
400
+ #ifdef BEOS_NETSERVER
401
+ closesocket( s );
402
+ #else
403
+ close( s );
404
+ #endif
405
+ }
@@ -0,0 +1,54 @@
1
+ /******************************************************************************
2
+ * $Id: net.h 261 2006-05-29 21:27:31Z titer $
3
+ *
4
+ * Copyright (c) 2005-2006 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
+
26
+ /***********************************************************************
27
+ * DNS resolution
28
+ **********************************************************************/
29
+ int tr_netResolve( char *, struct in_addr * );
30
+
31
+ #define TR_RESOLVE_WAIT 0
32
+ #define TR_RESOLVE_ERROR 1
33
+ #define TR_RESOLVE_OK 2
34
+ typedef struct tr_resolve_s tr_resolve_t;
35
+ void tr_netResolveThreadInit();
36
+ void tr_netResolveThreadClose();
37
+ tr_resolve_t * tr_netResolveInit( char * );
38
+ int tr_netResolvePulse( tr_resolve_t *, struct in_addr * );
39
+ void tr_netResolveClose( tr_resolve_t * );
40
+
41
+
42
+ /***********************************************************************
43
+ * TCP sockets
44
+ **********************************************************************/
45
+ int tr_netOpen ( struct in_addr addr, in_port_t port );
46
+ int tr_netBind ( int );
47
+ int tr_netAccept ( int s, struct in_addr *, in_port_t * );
48
+ void tr_netClose ( int s );
49
+
50
+ #define TR_NET_BLOCK 0x80000000
51
+ #define TR_NET_CLOSE 0x40000000
52
+ int tr_netSend ( int s, uint8_t * buf, int size );
53
+ int tr_netRecv ( int s, uint8_t * buf, int size );
54
+