transmission 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+