Changeset 1635 for branches/daemon
- Timestamp:
- Apr 2, 2007, 8:37:07 PM (15 years ago)
- Location:
- branches/daemon/daemon
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/daemon/daemon/client.c
r1631 r1635 65 65 size_t listlen; 66 66 int64_t * numlist; 67 uint8_t * buf; 67 68 int types; 68 69 SLIST_ENTRY( req ) next; … … 108 109 static struct resptree gl_resps = RB_INITIALIZER( &gl_resps ); 109 110 static int64_t gl_tag = 0; 111 static int gl_proxy = -1; 110 112 111 113 int … … 139 141 140 142 assert( NULL != gl_base ); 143 assert( 0 > gl_proxy ); 141 144 assert( NULL != path ); 145 146 gl_proxy = 0; 142 147 143 148 bzero( &sun, sizeof sun ); … … 196 201 197 202 assert( NULL != gl_base ); 203 assert( 0 > gl_proxy ); 198 204 assert( NULL != cmd && NULL != cmd[0] ); 205 206 gl_proxy = 1; 199 207 200 208 if( 0 > pipe( tocmd ) ) … … 329 337 client_addfiles( struct strlist * list ) 330 338 { 339 struct stritem * ii; 340 uint8_t * buf; 341 size_t size; 342 struct req * req; 343 344 if( gl_proxy ) 345 { 346 SLIST_FOREACH( ii, list, next ) 347 { 348 buf = readfile( ii->str, &size ); 349 req = addreq( IPC_MSG_ADDONEFILE, -1, NULL ); 350 if( NULL == req ) 351 { 352 free( buf ); 353 return -1; 354 } 355 req->buf = buf; 356 req->listlen = size; 357 } 358 } 359 else 360 { 361 req = addreq( IPC_MSG_ADDMANYFILES, -1, NULL ); 362 if( NULL == req ) 363 { 364 return -1; 365 } 366 367 /* XXX need to move arg parsing back here or something */ 368 req->strs = list; 369 } 370 371 return 0; 372 } 373 374 int 375 client_automap( int automap ) 376 { 331 377 struct req * req; 332 378 333 req = addreq( IPC_MSG_ADDMANYFILES, -1, NULL ); 334 if( NULL == req ) 335 { 336 return -1; 337 } 338 339 /* XXX need to move arg parsing back here or something */ 340 req->strs = list; 341 342 return 0; 343 } 344 345 int 346 client_automap( int automap ) 379 req = addreq( IPC_MSG_AUTOMAP, -1, NULL ); 380 if( NULL == req ) 381 { 382 return -1; 383 } 384 385 req->num = ( automap ? 1 : 0 ); 386 387 return 0; 388 } 389 390 int 391 client_pex( int pex ) 347 392 { 348 393 struct req * req; 349 394 350 req = addreq( IPC_MSG_ AUTOMAP, -1, NULL );351 if( NULL == req ) 352 { 353 return -1; 354 } 355 356 req->num = ( automap? 1 : 0 );395 req = addreq( IPC_MSG_PEX, -1, NULL ); 396 if( NULL == req ) 397 { 398 return -1; 399 } 400 401 req->num = ( pex ? 1 : 0 ); 357 402 358 403 return 0; … … 670 715 flushreqs( struct con * con ) 671 716 { 672 struct req * req; 673 uint8_t * buf; 674 size_t buflen; 717 struct req * req; 718 uint8_t * buf; 719 size_t buflen, ii; 720 benc_val_t pk, * val; 721 struct stritem * jj; 675 722 676 723 if( !HASVERS( &con->ipc ) ) … … 688 735 req = SLIST_FIRST( &gl_reqs ); 689 736 SLIST_REMOVE_HEAD( &gl_reqs, next ); 737 buf = NULL; 690 738 switch( req->id ) 691 739 { … … 697 745 break; 698 746 case IPC_MSG_ADDMANYFILES: 699 buf = ipc_mkstrlist( &con->ipc, &buflen, req->id, -1, 700 req->strs ); 747 ii = 0; 748 SLIST_FOREACH( jj, req->strs, next ) 749 { 750 ii++; 751 } 752 val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_LIST ); 753 if( NULL != val && !tr_bencListReserve( val, ii ) ) 754 { 755 SLIST_FOREACH( jj, req->strs, next ) 756 { 757 tr_bencInitStr( tr_bencListAdd( val ), 758 jj->str, -1, 1 ); 759 } 760 buf = ipc_mkval( &pk, &buflen ); 761 SAFEBENCFREE( &pk ); 762 } 701 763 SAFEFREESTRLIST( req->strs ); 764 break; 765 case IPC_MSG_ADDONEFILE: 766 val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_DICT ); 767 if( NULL != val && !tr_bencDictReserve( val, 1 ) ) 768 { 769 tr_bencInitStr( tr_bencDictAdd( val, "data" ), 770 req->buf, req->listlen, 1 ); 771 buf = ipc_mkval( &pk, &buflen ); 772 SAFEBENCFREE( &pk ); 773 } 774 SAFEFREE( req->buf ); 702 775 break; 703 776 case IPC_MSG_AUTOMAP: … … 714 787 case IPC_MSG_STOP: 715 788 case IPC_MSG_REMOVE: 716 buf = ipc_mkints( &con->ipc, &buflen, req->id, req->tag, 717 req->listlen, req->numlist ); 789 val = ipc_initval( &con->ipc, req->id, -1, &pk, TYPE_LIST ); 790 if( NULL != val && !tr_bencListReserve( val, req->listlen ) ) 791 { 792 for( ii = 0; ii < req->listlen; ii++ ) 793 { 794 tr_bencInitInt( tr_bencListAdd( val ), 795 req->numlist[ii] ); 796 } 797 buf = ipc_mkval( &pk, &buflen ); 798 SAFEBENCFREE( &pk ); 799 } 718 800 SAFEFREE( req->numlist ); 719 801 break; -
branches/daemon/daemon/client.h
r1626 r1635 42 42 int client_port ( int ); 43 43 int client_automap ( int ); 44 int client_pex ( int ); 44 45 int client_downlimit( int ); 45 46 int client_uplimit ( int ); -
branches/daemon/daemon/ipc.c
r1631 r1635 101 101 { "noop", 2, IPC_MSG_NOOP, RB_ENTRY_INITIALIZER() }, 102 102 { "not-supported", 2, IPC_MSG_NOTSUP, RB_ENTRY_INITIALIZER() }, 103 { "pex", 2, IPC_MSG_P ORT,RB_ENTRY_INITIALIZER() },103 { "pex", 2, IPC_MSG_PEX, RB_ENTRY_INITIALIZER() }, 104 104 { "port", 2, IPC_MSG_PORT, RB_ENTRY_INITIALIZER() }, 105 105 { "quit", 1, IPC_MSG_QUIT, RB_ENTRY_INITIALIZER() }, … … 157 157 }; 158 158 159 static int pkinit ( struct ipc_info *, benc_val_t *, enum ipc_msg,160 benc_val_t **, int64_t );161 static uint8_t * pkgenerate ( benc_val_t *, size_t * );162 159 static int handlevers ( struct ipc_info *, benc_val_t * ); 163 160 static int handlemsgs ( struct ipc_info *, benc_val_t *, void * ); … … 245 242 } 246 243 247 int 248 pkinit( struct ipc_info * info, benc_val_t * pk, enum ipc_msg id, 249 benc_val_t ** val, int64_t tag ) 250 { 244 benc_val_t * 245 ipc_initval( struct ipc_info * info, enum ipc_msg id, int64_t tag, 246 benc_val_t * pk, int type ) 247 { 248 benc_val_t * ret; 249 251 250 assert( MSGVALID( id ) ); 252 251 … … 254 253 { 255 254 errno = EPERM; 256 return -1;255 return NULL; 257 256 } 258 257 … … 262 261 if( tr_bencDictReserve( pk, 1 ) ) 263 262 { 264 return -1;265 } 266 *val= tr_bencDictAdd( pk, MSGNAME( id ) );263 return NULL; 264 } 265 ret = tr_bencDictAdd( pk, MSGNAME( id ) ); 267 266 } 268 267 else … … 271 270 if( tr_bencListReserve( pk, ( 0 < tag ? 3 : 2 ) ) ) 272 271 { 273 return -1;272 return NULL; 274 273 } 275 274 tr_bencInitStr( tr_bencListAdd( pk ), MSGNAME( id ), -1, 1 ); 276 *val= tr_bencListAdd( pk );275 ret = tr_bencListAdd( pk ); 277 276 if( 0 < tag ) 278 277 { … … 281 280 } 282 281 283 return 0; 282 tr_bencInit( ret, type ); 283 284 return ret; 284 285 } 285 286 286 287 uint8_t * 287 pkgenerate( benc_val_t * pk, size_t * len )288 ipc_mkval( benc_val_t * pk, size_t * len ) 288 289 { 289 290 char * buf, hex[IPC_MIN_MSG_LEN+1]; … … 322 323 323 324 uint8_t * 324 ipc_mkstr( struct ipc_info * info, size_t * len, enum ipc_msg id, int64_t tag,325 const char * str )326 {327 benc_val_t pk, * strval;328 uint8_t * ret;329 330 if( 0 > pkinit( info, &pk, id, &strval, tag ) )331 {332 return NULL;333 }334 335 tr_bencInitStr( strval, str, -1, 1 );336 337 ret = pkgenerate( &pk, len );338 SAFEBENCFREE( &pk );339 340 return ret;341 }342 343 uint8_t *344 ipc_mkstrlist( struct ipc_info * info, size_t * len, enum ipc_msg id,345 int64_t tag, struct strlist * strs )346 {347 benc_val_t pk, * list;348 struct stritem * ii;349 uint8_t * ret;350 int count;351 352 if( 0 > pkinit( info, &pk, id, &list, tag ) )353 {354 return NULL;355 }356 357 count = 0;358 SLIST_FOREACH( ii, strs, next )359 {360 count++;361 }362 363 tr_bencInit( list, TYPE_LIST );364 if( tr_bencListReserve( list, count ) )365 {366 SAFEBENCFREE( &pk );367 return NULL;368 }369 370 SLIST_FOREACH( ii, strs, next )371 {372 if( tr_bencInitStrDup( tr_bencListAdd( list ), ii->str ) )373 {374 SAFEBENCFREE( &pk );375 return NULL;376 }377 }378 379 ret = pkgenerate( &pk, len );380 SAFEBENCFREE( &pk );381 382 return ret;383 }384 385 uint8_t *386 325 ipc_mkempty( struct ipc_info * info, size_t * len, enum ipc_msg id, 387 326 int64_t tag ) 388 327 { 389 benc_val_t pk , * empty;328 benc_val_t pk; 390 329 uint8_t * ret; 391 330 392 if( 0 > pkinit( info, &pk, id, &empty, tag) )331 if( NULL == ipc_initval( info, id, tag, &pk, TYPE_STR ) ) 393 332 { 394 333 return NULL; 395 334 } 396 335 397 tr_bencInitStr( empty, NULL, 0, 1 ); 398 ret = pkgenerate( &pk, len ); 336 ret = ipc_mkval( &pk, len ); 399 337 SAFEBENCFREE( &pk ); 400 338 … … 409 347 uint8_t * ret; 410 348 411 if( 0 > pkinit( info, &pk, id, &val, tag ) ) 349 val = ipc_initval( info, id, tag, &pk, TYPE_INT ); 350 if( NULL == val ) 412 351 { 413 352 return NULL; 414 353 } 415 354 416 tr_bencInitInt( val, num );417 ret = pkgenerate( &pk, len );355 val->val.i = num; 356 ret = ipc_mkval( &pk, len ); 418 357 SAFEBENCFREE( &pk ); 419 358 … … 422 361 423 362 uint8_t * 424 ipc_mkints( struct ipc_info * info, size_t * len, enum ipc_msg id, int64_t tag, 425 size_t count, const int64_t * nums ) 426 { 427 benc_val_t pk, * list; 428 size_t ii; 363 ipc_mkstr( struct ipc_info * info, size_t * len, enum ipc_msg id, int64_t tag, 364 const char * str ) 365 { 366 benc_val_t pk, * val; 429 367 uint8_t * ret; 430 368 431 if( 0 > pkinit( info, &pk, id, &list, tag ) ) 369 val = ipc_initval( info, id, tag, &pk, TYPE_STR ); 370 if( NULL == val ) 432 371 { 433 372 return NULL; 434 373 } 435 374 436 tr_bencInit( list, TYPE_LIST ); 437 if( tr_bencListReserve( list, count ) ) 438 { 439 SAFEBENCFREE( &pk ); 440 return NULL; 441 } 442 443 for( ii = 0; count > ii; ii++ ) 444 { 445 tr_bencInitInt( tr_bencListAdd( list ), nums[ii] ); 446 } 447 448 ret = pkgenerate( &pk, len ); 375 tr_bencInitStr( val, str, -1, 1 ); 376 ret = ipc_mkval( &pk, len ); 449 377 SAFEBENCFREE( &pk ); 450 378 … … 474 402 tr_bencInitInt( tr_bencDictAdd( dict, "max" ), PROTO_VERS_MAX ); 475 403 476 ret = pkgenerate( &pk, len );404 ret = ipc_mkval( &pk, len ); 477 405 SAFEBENCFREE( &pk ); 478 406 … … 489 417 uint8_t * ret; 490 418 491 if( 0 > pkinit( info, &pk, id, &top, tag ) )492 {493 return NULL;494 }495 496 419 /* no ID list, send an -all message */ 497 420 if( NULL == ids ) 498 421 { 499 typelist = top; 422 typelist = ipc_initval( info, id, tag, &pk, TYPE_LIST ); 423 if( NULL == typelist ) 424 { 425 return NULL; 426 } 500 427 } 501 428 else 502 429 { 430 top = ipc_initval( info, id, tag, &pk, TYPE_DICT ); 431 if( NULL == top ) 432 { 433 return NULL; 434 } 503 435 /* add the requested IDs */ 504 tr_bencInit( top, TYPE_DICT );505 436 if( tr_bencDictReserve( top, 2 ) ) 506 437 { … … 511 442 typelist = tr_bencDictAdd( top, "type" ); 512 443 tr_bencInit( idlist, TYPE_LIST ); 444 tr_bencInit( typelist, TYPE_LIST ); 513 445 for( ii = 0; TORRENT_ID_VALID( ids[ii] ); ii++ ) 514 446 { … … 544 476 545 477 /* add the type names */ 546 tr_bencInit( typelist, TYPE_LIST );547 478 for( ii = used = 0; typecount > ii; ii++ ) 548 479 { … … 569 500 570 501 /* generate packet */ 571 ret = pkgenerate( &pk, len );502 ret = ipc_mkval( &pk, len ); 572 503 SAFEBENCFREE( &pk ); 573 504 574 505 return ret; 575 }576 577 int578 ipc_initinfo( struct ipc_info * info, enum ipc_msg id, int64_t tag,579 benc_val_t * pk, benc_val_t ** val )580 {581 assert( IPC_MSG_INFO == id || IPC_MSG_STAT == id );582 583 if( 0 > pkinit( info, pk, id, val, tag ) )584 {585 return -1;586 }587 588 tr_bencInit( *val, TYPE_LIST );589 590 return 0;591 506 } 592 507 … … 918 833 } 919 834 920 uint8_t *921 ipc_mkinfo( benc_val_t * pk, size_t * len )922 {923 return pkgenerate( pk, len );924 }925 926 835 ssize_t 927 836 ipc_parse( struct ipc_info * info, uint8_t * buf, ssize_t total, void * arg ) -
branches/daemon/daemon/ipc.h
r1631 r1635 140 140 /* message creation */ 141 141 /* sets errno to EPERM if requested message not supported by protocol vers */ 142 benc_val_t * ipc_initval ( struct ipc_info *, enum ipc_msg, int64_t, 143 benc_val_t *, int ); 144 uint8_t * ipc_mkval ( benc_val_t *, size_t * ); 145 uint8_t * ipc_mkempty ( struct ipc_info *, size_t *, enum ipc_msg, 146 int64_t ); 147 uint8_t * ipc_mkint ( struct ipc_info *, size_t *, enum ipc_msg, int64_t, 148 int64_t ); 142 149 uint8_t * ipc_mkstr ( struct ipc_info *, size_t *, enum ipc_msg, int64_t, 143 150 const char * ); 144 uint8_t * ipc_mkstrlist( struct ipc_info *, size_t *, enum ipc_msg, int64_t,145 struct strlist * );146 uint8_t * ipc_mkempty ( struct ipc_info *, size_t *, enum ipc_msg,147 int64_t );148 uint8_t * ipc_mkint ( struct ipc_info *, size_t *, enum ipc_msg,149 int64_t, int64_t );150 uint8_t * ipc_mkints ( struct ipc_info *, size_t *, enum ipc_msg, int64_t,151 size_t, const int64_t * );152 151 uint8_t * ipc_mkvers ( size_t * ); 153 152 uint8_t * ipc_mkgetinfo( struct ipc_info *, size_t *, enum ipc_msg, int64_t, 154 153 int, const int * ); 155 int ipc_initinfo ( struct ipc_info *, enum ipc_msg, int64_t,156 benc_val_t *, benc_val_t ** );157 154 int ipc_addinfo ( benc_val_t *, int, tr_info_t *, int ); 158 155 int ipc_addstat ( benc_val_t *, int, tr_info_t *, tr_stat_t *, int ); 159 uint8_t * ipc_mkinfo ( benc_val_t *, size_t * );160 156 161 157 /* sets errno to EINVAL on parse error or -
branches/daemon/daemon/misc.c
r1617 r1635 24 24 25 25 #include <sys/types.h> 26 #include <sys/stat.h> 26 27 #include <assert.h> 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <stdlib.h> 27 31 #include <string.h> 28 32 #include <unistd.h> … … 116 120 strlcat( buf, path, len ); 117 121 } 122 123 int 124 writefile( const char * name, uint8_t * buf, ssize_t len ) 125 { 126 int fd; 127 ssize_t res; 128 129 fd = open( name, O_WRONLY | O_CREAT | O_TRUNC, 0666 ); 130 if( 0 > fd ) 131 { 132 errnomsg( "failed to open %s for writing", name ); 133 return -1; 134 } 135 136 res = write( fd, buf, len ); 137 if( 0 > res ) 138 { 139 errnomsg( "failed to write to %s", name ); 140 return -1; 141 } 142 if( len > res ) 143 { 144 errmsg( "failed to write all data to %s", name ); 145 return -1; 146 } 147 148 close( fd ); 149 150 return 0; 151 } 152 153 uint8_t * 154 readfile( const char * name, size_t * len ) 155 { 156 struct stat sb; 157 int fd; 158 uint8_t * buf; 159 ssize_t res; 160 161 fd = open( name, O_RDONLY ); 162 if( 0 > fd ) 163 { 164 if( ENOENT != errno ) 165 { 166 errnomsg( "failed to open %s for reading", name ); 167 } 168 return NULL; 169 } 170 171 if( 0 > fstat( fd, &sb ) ) 172 { 173 errnomsg( "failed to stat %s", name ); 174 return NULL; 175 } 176 177 buf = malloc( sb.st_size ); 178 if( NULL == buf ) 179 { 180 mallocmsg( sb.st_size ); 181 return NULL; 182 } 183 184 res = read( fd, buf, sb.st_size ); 185 if( 0 > res ) 186 { 187 errnomsg( "failed to read from %s", name ); 188 free( buf ); 189 return NULL; 190 } 191 if( res < sb.st_size ) 192 { 193 errmsg( "failed to read all data from %s", name ); 194 free( buf ); 195 return NULL; 196 } 197 198 close( fd ); 199 *len = res; 200 201 return buf; 202 } -
branches/daemon/daemon/misc.h
r1621 r1635 136 136 void confpath ( char *, size_t, const char *, enum confpathtype ); 137 137 void absolutify( char *, size_t, const char * ); 138 int writefile ( const char *, uint8_t *, ssize_t ); 139 uint8_t * readfile ( const char *, size_t * ); 138 140 139 141 #endif /* TR_DAEMON_MISC_H */ -
branches/daemon/daemon/proxy.c
r1630 r1635 40 40 #include "transmission.h" 41 41 42 #define TIMEOUT ( 60 ) 43 44 static void usage ( const char *, ... ); 45 static enum confpathtype readargs ( int, char ** ); 46 static int makesock ( enum confpathtype ); 47 static struct bufferevent * setupev ( struct event_base *, int, 48 void ( * )( struct bufferevent *, short, 49 void * ), void * ); 50 static void noop ( struct bufferevent *, void * ); 51 static void relay ( struct bufferevent *, void * ); 52 static void outerr ( struct bufferevent *, short, void * ); 53 static void inerr ( struct bufferevent *, short, void * ); 54 static void sockerr ( struct bufferevent *, short, void * ); 42 static void usage ( const char *, ... ); 43 static enum confpathtype readargs ( int, char ** ); 44 static int makesock ( enum confpathtype ); 45 static void inread ( struct bufferevent *, void * ); 46 static void noop ( struct bufferevent *, void * ); 47 static void inerr ( struct bufferevent *, short, void * ); 48 static void wtf ( struct bufferevent *, void * ); 49 static void outerr ( struct bufferevent *, short, void * ); 50 static void sockread ( struct bufferevent *, void * ); 51 static void sockwrite( struct bufferevent *, void * ); 52 static void sockerr ( struct bufferevent *, short, void * ); 53 54 static struct bufferevent * gl_in = NULL; 55 static struct bufferevent * gl_out = NULL; 56 static struct bufferevent * gl_sock = NULL; 55 57 56 58 int … … 60 62 enum confpathtype type; 61 63 int sockfd; 62 struct bufferevent * outev, * inev, * sockev;63 64 64 65 setmyname( argv[0] ); … … 72 73 } 73 74 74 outev = setupev( base, STDOUT_FILENO, outerr, NULL ); 75 sockev = setupev( base, sockfd, sockerr, outev ); 76 inev = setupev( base, STDIN_FILENO, inerr, sockev ); 77 78 if( NULL == outev || NULL == inev || NULL == sockev ) 79 { 75 gl_in = bufferevent_new( STDIN_FILENO, inread, noop, inerr, NULL ); 76 if( NULL == gl_in ) 77 { 78 errnomsg( "failed to set up event buffer for stdin" ); 80 79 return EXIT_FAILURE; 81 80 } 82 83 bufferevent_disable( outev, EV_READ ); 84 bufferevent_enable( outev, EV_WRITE ); 85 bufferevent_enable( inev, EV_READ ); 86 bufferevent_disable( inev, EV_WRITE ); 87 bufferevent_enable( sockev, EV_READ ); 88 bufferevent_enable( sockev, EV_WRITE ); 81 bufferevent_base_set( base, gl_in ); 82 bufferevent_enable( gl_in, EV_READ ); 83 bufferevent_disable( gl_in, EV_WRITE ); 84 85 gl_out = bufferevent_new( STDOUT_FILENO, wtf, noop, outerr, NULL ); 86 if( NULL == gl_in ) 87 { 88 errnomsg( "failed to set up event buffer for stdin" ); 89 return EXIT_FAILURE; 90 } 91 bufferevent_base_set( base, gl_out ); 92 bufferevent_disable( gl_out, EV_READ ); 93 bufferevent_enable( gl_out, EV_WRITE ); 94 95 gl_sock = bufferevent_new( sockfd, sockread, sockwrite, sockerr, NULL ); 96 if( NULL == gl_in ) 97 { 98 errnomsg( "failed to set up event buffer for stdin" ); 99 return EXIT_FAILURE; 100 } 101 bufferevent_base_set( base, gl_sock ); 102 bufferevent_enable( gl_sock, EV_READ ); 103 bufferevent_enable( gl_sock, EV_WRITE ); 89 104 90 105 event_base_dispatch( base ); … … 189 204 } 190 205 191 struct bufferevent * 192 setupev( struct event_base * base, int fd, 193 void ( * efunc )( struct bufferevent *, short, void * ), void * arg ) 194 { 195 struct bufferevent * ev; 196 197 ev = bufferevent_new( fd, relay, noop, efunc, arg ); 198 if( NULL == ev ) 199 { 200 mallocmsg( -1 ); 201 return NULL; 202 } 203 204 bufferevent_base_set( base, ev ); 205 bufferevent_settimeout( ev, TIMEOUT, TIMEOUT ); 206 207 return ev; 206 void 207 inread( struct bufferevent * ev UNUSED, void * arg UNUSED ) 208 { 209 bufferevent_write_buffer( gl_sock, EVBUFFER_INPUT( gl_in ) ); 208 210 } 209 211 … … 211 213 noop( struct bufferevent * ev UNUSED, void * arg UNUSED ) 212 214 { 213 /* libevent prior to 1.2 couldn't handle a NULL write callback */ 214 } 215 216 void 217 relay( struct bufferevent * in, void * arg ) 218 { 219 struct bufferevent * out = arg; 220 221 if( NULL == arg ) 222 { 223 /* this shouldn't happen, but let's drain the buffer anyway */ 224 evbuffer_drain( EVBUFFER_INPUT( in ), 225 EVBUFFER_LENGTH( EVBUFFER_INPUT( in ) ) ); 215 } 216 217 void 218 inerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED ) 219 { 220 if( EVBUFFER_EOF & what ) 221 { 222 bufferevent_free( gl_in ); 223 gl_in = NULL; 224 sockwrite( NULL, NULL ); 225 return; 226 } 227 228 if( EVBUFFER_TIMEOUT & what ) 229 { 230 errmsg( "timed out reading from stdin" ); 231 } 232 else if( EVBUFFER_READ & what ) 233 { 234 errmsg( "read error on stdin" ); 235 } 236 else if( EVBUFFER_ERROR & what ) 237 { 238 errmsg( "error on stdin" ); 226 239 } 227 240 else 228 241 { 229 bufferevent_write_buffer( out, EVBUFFER_INPUT( in ) ); 230 } 242 errmsg( "unknown error on stdin: 0x%x", what ); 243 } 244 245 exit( EXIT_FAILURE ); 246 } 247 248 void 249 wtf( struct bufferevent * ev, void * arg UNUSED ) 250 { 251 /* this shouldn't happen, but let's drain the buffer anyway */ 252 evbuffer_drain( EVBUFFER_INPUT( ev ), 253 EVBUFFER_LENGTH( EVBUFFER_INPUT( ev ) ) ); 231 254 } 232 255 … … 255 278 256 279 void 257 inerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED ) 280 sockread( struct bufferevent * ev UNUSED, void * arg UNUSED ) 281 { 282 bufferevent_write_buffer( gl_out, EVBUFFER_INPUT( gl_sock ) ); 283 } 284 285 void 286 sockwrite( struct bufferevent * ev UNUSED, void * arg UNUSED ) 287 { 288 if( NULL == gl_in && 0 == EVBUFFER_LENGTH( EVBUFFER_OUTPUT( gl_sock ) ) ) 289 { 290 exit( EXIT_SUCCESS ); 291 } 292 } 293 294 void 295 sockerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED ) 258 296 { 259 297 if( EVBUFFER_EOF & what ) 260 298 { 261 e xit( EXIT_SUCCESS);299 errmsg( "server closed connection" ); 262 300 } 263 301 else if( EVBUFFER_TIMEOUT & what ) 264 302 { 265 errmsg( " timed out reading from stdin" );303 errmsg( "server connection timed out" ); 266 304 } 267 305 else if( EVBUFFER_READ & what ) 268 306 { 269 errmsg( "read error on stdin" ); 307 errmsg( "read error on server connection" ); 308 } 309 else if( EVBUFFER_WRITE & what ) 310 { 311 errmsg( "write error on server connection" ); 270 312 } 271 313 else if( EVBUFFER_ERROR & what ) 272 314 { 273 errmsg( "error on s tdin" );315 errmsg( "error on server connection" ); 274 316 } 275 317 else 276 318 { 277 errmsg( "unknown error on s tdin: 0x%x", what );319 errmsg( "unknown error on server connection: 0x%x", what ); 278 320 } 279 321 280 322 exit( EXIT_FAILURE ); 281 323 } 282 283 void284 sockerr( struct bufferevent * ev UNUSED, short what, void * arg UNUSED )285 {286 if( EVBUFFER_EOF & what )287 {288 errmsg( "server closed connection" );289 }290 else if( EVBUFFER_TIMEOUT & what )291 {292 errmsg( "server connection timed out" );293 }294 else if( EVBUFFER_READ & what )295 {296 errmsg( "read error on server connection" );297 }298 else if( EVBUFFER_WRITE & what )299 {300 errmsg( "write error on server connection" );301 }302 else if( EVBUFFER_ERROR & what )303 {304 errmsg( "error on server connection" );305 }306 else307 {308 errmsg( "unknown error on server connection: 0x%x", what );309 }310 311 exit( EXIT_FAILURE );312 } -
branches/daemon/daemon/remote.c
r1631 r1635 162 162 ( o.port && 0 > client_port ( o.port ) ) || 163 163 ( 0 <= o.map && 0 > client_automap ( o.map ) ) || 164 ( 0 <= o.pex && 0 > client_pex ( o.pex ) ) || 164 165 ( o.uplimit && 0 > client_uplimit ( o.up ) ) || 165 166 ( o.downlimit && 0 > client_downlimit( o.down ) ) || … … 212 213 " -d --download-limit <int> Max download rate in KiB/s\n" 213 214 " -D --download-unlimited No download rate limit\n" 215 " -e --enable-pex Enable peer exchange\n" 216 " -E --disable-pex Disable peer exchange\n" 214 217 " -f --folder <path> Folder to set for new torrents\n" 215 218 " -h --help Display this message and exit\n" … … 238 241 readargs( int argc, char ** argv, struct opts * opts ) 239 242 { 240 char optstr[] = "a:d:D f:hilmMp:qr:s:S:t:u:Ux";243 char optstr[] = "a:d:DeEf:hilmMp:qr:s:S:t:u:Ux"; 241 244 struct option longopts[] = 242 245 { … … 244 247 { "download-limit", required_argument, NULL, 'd' }, 245 248 { "download-unlimited", no_argument, NULL, 'D' }, 249 { "enable-pex", no_argument, NULL, 'e' }, 250 { "disable-pex", no_argument, NULL, 'E' }, 246 251 { "folder", required_argument, NULL, 'f' }, 247 252 { "help", no_argument, NULL, 'h' }, … … 268 273 SLIST_INIT( &opts->files ); 269 274 opts->map = -1; 275 opts->pex = -1; 270 276 SLIST_INIT( &opts->start ); 271 277 SLIST_INIT( &opts->stop ); … … 289 295 opts->downlimit = 1; 290 296 opts->down = -1; 297 break; 298 case 'e': 299 opts->pex = 1; 300 break; 301 case 'E': 302 opts->pex = 0; 291 303 break; 292 304 case 'f': … … 876 888 downspeed = fmtsize( ii->down, &downunits ); 877 889 name = ( NULL == ii->name ? "???" : ii->name ); 878 progress = ( float )ii->done / ( float )ii->size ;890 progress = ( float )ii->done / ( float )ii->size * 100.0; 879 891 progress = MIN( 100.0, progress ); 880 892 progress = MAX( 0.0, progress ); -
branches/daemon/daemon/server.c
r1631 r1635 409 409 } 410 410 411 if( 0 > ipc_initinfo( &client->ipc, IPC_MSG_INFO, tag, &pk, &added ) ) 411 added = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST ); 412 if( NULL == added ) 412 413 { 413 414 errnomsg( "failed to build message" ); … … 424 425 } 425 426 /* XXX need to somehow inform client of skipped or failed files */ 426 tor = torrent_add ( file->val.s.s, NULL, -1 );427 tor = torrent_add_file( file->val.s.s, NULL, -1 ); 427 428 if( TORRENT_ID_VALID( tor ) ) 428 429 { … … 438 439 } 439 440 440 buf = ipc_mk info( &pk, &buflen );441 buf = ipc_mkval( &pk, &buflen ); 441 442 tr_bencFree( &pk ); 442 443 queuemsg( client, buf, buflen ); … … 469 470 if( NULL != val && TYPE_STR == val->type ) 470 471 { 471 /* XXX not quite yet */ 472 msgresp( client, tag, IPC_MSG_NOTSUP ); 473 return; 472 /* XXX detect duplicates and return a message indicating so */ 473 tor = torrent_add_data( val->val.s.s, val->val.s.i, dir, start ); 474 474 } 475 475 else … … 482 482 } 483 483 /* XXX detect duplicates and return a message indicating so */ 484 tor = torrent_add ( val->val.s.s, dir, start );484 tor = torrent_add_file( val->val.s.s, dir, start ); 485 485 } 486 486 487 487 if( TORRENT_ID_VALID( tor ) ) 488 488 { 489 if( 0 > ipc_initinfo( &client->ipc, IPC_MSG_INFO, tag, &pk, &val ) ) 489 val = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST ); 490 if( NULL == val ) 490 491 { 491 492 errnomsg( "failed to build message" ); … … 501 502 return; 502 503 } 503 buf = ipc_mk info( &pk, &buflen );504 buf = ipc_mkval( &pk, &buflen ); 504 505 tr_bencFree( &pk ); 505 506 queuemsg( client, buf, buflen ); … … 628 629 629 630 /* initialize packet */ 630 if( 0 > ipc_initinfo( &client->ipc, respid, tag, &pk, &pkinf ) ) 631 pkinf = ipc_initval( &client->ipc, respid, tag, &pk, TYPE_LIST ); 632 if( NULL == pkinf ) 631 633 { 632 634 errnomsg( "failed to build message" ); … … 650 652 if( 0 > addfunc( pkinf, tor, types ) ) 651 653 { 654 errnomsg( "failed to build message" ); 652 655 tr_bencFree( &pk ); 653 656 byebye( client->ev, EVBUFFER_EOF, NULL ); … … 685 688 if( 0 > addfunc( pkinf, idval->val.i, types ) ) 686 689 { 690 errnomsg( "failed to build message" ); 687 691 tr_bencFree( &pk ); 688 692 byebye( client->ev, EVBUFFER_EOF, NULL ); … … 693 697 694 698 /* generate packet data and send it */ 695 buf = ipc_mkinfo( &pk, &buflen ); 699 buf = ipc_mkval( &pk, &buflen ); 700 tr_bencFree( &pk ); 696 701 queuemsg( client, buf, buflen ); 697 702 free( buf ); 698 tr_bencFree( &pk );699 703 } 700 704 … … 813 817 } 814 818 815 if( 0 > ipc_initinfo( &client->ipc, IPC_MSG_INFO, tag, &pk, &pkinf ) ) 816 { 819 pkinf = ipc_initval( &client->ipc, IPC_MSG_INFO, tag, &pk, TYPE_LIST ); 820 if( NULL == pkinf ) 821 { 822 errnomsg( "failed to build message" ); 817 823 byebye( client->ev, EVBUFFER_EOF, NULL ); 818 824 return; … … 838 844 if( 0 > ipc_addinfo( pkinf, found, inf, IPC_INF_HASH ) ) 839 845 { 846 errnomsg( "failed to build message" ); 840 847 tr_bencFree( &pk ); 841 848 byebye( client->ev, EVBUFFER_EOF, NULL ); … … 844 851 } 845 852 846 buf = ipc_mk info( &pk, &buflen );853 buf = ipc_mkval( &pk, &buflen ); 847 854 tr_bencFree( &pk ); 848 855 queuemsg( client, buf, buflen ); … … 902 909 uint8_t * buf; 903 910 size_t buflen; 904 int ii, used; 905 benc_val_t * name; 906 struct stritem * strs; 907 struct strlist strlist; 911 int ii; 912 benc_val_t pk, *pkval, * name; 908 913 enum ipc_msg found; 909 914 … … 914 919 } 915 920 916 strs = calloc( val->val.l.count, sizeof *strs ); 917 if( NULL == strs ) 918 { 921 pkval = ipc_initval( &client->ipc, IPC_MSG_SUP, tag, &pk, TYPE_LIST ); 922 if( NULL == pkval ) 923 { 924 errnomsg( "failed to build message" ); 919 925 byebye( client->ev, EVBUFFER_EOF, NULL ); 920 926 return; 921 927 } 922 used = 0; 928 /* XXX look at other initval to make sure we free pk */ 929 if( tr_bencListReserve( pkval, val->val.l.count ) ) 930 { 931 errnomsg( "failed to build message" ); 932 tr_bencFree( &pk ); 933 byebye( client->ev, EVBUFFER_EOF, NULL ); 934 return; 935 } 923 936 924 937 for( ii = 0; val->val.l.count > ii; ii++ ) … … 927 940 if( NULL == name || TYPE_STR != name->type ) 928 941 { 929 free( strs);942 tr_bencFree( &pk ); 930 943 msgresp( client, tag, IPC_MSG_NOTSUP ); 931 944 return; … … 936 949 continue; 937 950 } 938 strs[used].str = name->val.s.s; 939 used++; 940 } 941 942 SLIST_INIT( &strlist ); 943 while( 0 < used ) 944 { 945 SLIST_INSERT_HEAD( &strlist, &strs[used-1], next ); 946 used--; 947 } 948 buf = ipc_mkstrlist( &client->ipc, &buflen, IPC_MSG_SUP, tag, &strlist ); 951 tr_bencInitStr( tr_bencListAdd( pkval ), 952 name->val.s.s, name->val.s.i, 1 ); 953 } 954 955 buf = ipc_mkval( &pk, &buflen ); 956 tr_bencFree( &pk ); 949 957 queuemsg( client, buf, buflen ); 950 free( strs);951 } 958 free( buf ); 959 } -
branches/daemon/daemon/torrents.c
r1631 r1635 66 66 RB_HEAD( hashtree, tor ); 67 67 68 static struct tor * opentorrent ( const char *, const char *, const char * ); 69 static void closetorrent( struct tor *, int ); 70 static void starttimer ( int ); 71 static void timerfunc ( int, short, void * ); 72 static int loadstate ( void ); 73 static int savestate ( void ); 74 static int toridcmp ( struct tor *, struct tor * ); 75 static int torhashcmp ( struct tor *, struct tor * ); 76 static int writefile ( const char *, uint8_t *, ssize_t ); 77 static uint8_t * readfile ( const char *, size_t * ); 78 static struct tor * idlookup ( int, int ); 79 static struct tor * hashlookup ( const uint8_t *, int ); 80 static struct tor * iterate ( struct tor * ); 68 static struct tor * opentor ( const char *, const char *, uint8_t *, size_t, 69 const char * ); 70 static void closetor ( struct tor *, int ); 71 static void starttimer ( int ); 72 static void timerfunc ( int, short, void * ); 73 static int loadstate ( void ); 74 static int savestate ( void ); 75 static int toridcmp ( struct tor *, struct tor * ); 76 static int torhashcmp ( struct tor *, struct tor * ); 77 static struct tor * idlookup ( int, int ); 78 static struct tor * hashlookup ( const uint8_t *, int ); 79 static struct tor * iterate ( struct tor * ); 81 80 82 81 static struct event_base * gl_base = NULL; … … 120 119 121 120 int 122 torrent_add( const char * path, const char * dir, int autostart ) 123 { 124 struct tor * tor; 125 126 assert( NULL != gl_handle ); 127 assert( !gl_exiting ); 128 129 tor = opentorrent( path, NULL, dir ); 121 torrent_add_file( const char * path, const char * dir, int autostart ) 122 { 123 struct tor * tor; 124 125 assert( NULL != gl_handle ); 126 assert( !gl_exiting ); 127 128 tor = opentor( path, NULL, NULL, 0, dir ); 129 if( NULL == tor ) 130 { 131 return -1; 132 } 133 134 if( 0 > autostart ) 135 { 136 autostart = gl_autostart; 137 } 138 if( autostart ) 139 { 140 tr_torrentStart( tor->tor ); 141 } 142 143 savestate(); 144 145 return tor->id; 146 } 147 148 int 149 torrent_add_data( uint8_t * data, size_t size, const char * dir, int autostart ) 150 { 151 struct tor * tor; 152 153 assert( NULL != gl_handle ); 154 assert( !gl_exiting ); 155 156 tor = opentor( NULL, NULL, data, size, dir ); 130 157 if( NULL == tor ) 131 158 { … … 207 234 } 208 235 209 closetor rent( tor, 1 );236 closetor( tor, 1 ); 210 237 savestate(); 211 238 } … … 306 333 RB_FOREACH( tor, tortree, &gl_tree ) 307 334 { 308 closetor rent( tor, 0 );335 closetor( tor, 0 ); 309 336 } 310 337 … … 444 471 445 472 struct tor * 446 opentorrent( const char * path, const char * hash, const char * dir ) 473 opentor( const char * path, const char * hash, uint8_t * data, size_t size, 474 const char * dir ) 447 475 { 448 476 struct tor * tor, * found; … … 450 478 tr_info_t * inf; 451 479 452 assert( NULL == path || NULL == hash ); 453 assert( NULL != path || NULL != hash ); 480 assert( ( NULL != path && NULL == hash && NULL == data ) || 481 ( NULL == path && NULL != hash && NULL == data ) || 482 ( NULL == path && NULL == hash && NULL != data ) ); 454 483 455 484 /* XXX should probably wrap around back to 1 and avoid duplicates */ … … 473 502 TR_FLAG_SAVE, &errcode ); 474 503 } 504 else if( NULL != hash ) 505 { 506 tor->tor = tr_torrentInitSaved( gl_handle, hash, 0, &errcode ); 507 } 475 508 else 476 509 { 477 tor->tor = tr_torrentInitSaved( gl_handle, hash, 0, &errcode ); 510 tor->tor = tr_torrentInitData( gl_handle, data, size, tor->hash, 511 TR_FLAG_SAVE, &errcode ); 478 512 } 479 513 … … 484 518 { 485 519 case TR_EINVALID: 486 errmsg( "invalid torrent file: %s", path ); 520 if( NULL == path ) 521 { 522 errmsg( "invalid torrent file" ); 523 } 524 else 525 { 526 errmsg( "invalid torrent file: %s", path ); 527 } 487 528 break; 488 529 case TR_EUNSUPPORTED: 489 errmsg( "unsupported torrent file: %s", path ); 530 if( NULL == path ) 531 { 532 errmsg( "unsupported torrent file" ); 533 } 534 else 535 { 536 errmsg( "unsupported torrent file: %s", path ); 537 } 490 538 break; 491 539 case TR_EDUPLICATE: … … 495 543 break; 496 544 default: 497 errmsg( "torrent file failed to load: %s", path ); 545 if( NULL == path ) 546 { 547 errmsg( "torrent file failed to load" ); 548 } 549 else 550 { 551 errmsg( "torrent file failed to load: %s", path ); 552 } 498 553 break; 499 554 } … … 530 585 531 586 void 532 closetor rent( struct tor * tor, int calltimer )587 closetor( struct tor * tor, int calltimer ) 533 588 { 534 589 tr_stat_t * st; … … 729 784 } 730 785 731 tor = opentor rent( NULL, str->val.s.s, dir );786 tor = opentor( NULL, str->val.s.s, NULL, 0, dir ); 732 787 if( NULL == tor ) 733 788 { … … 854 909 } 855 910 856 int857 writefile( const char * name, uint8_t * buf, ssize_t len )858 {859 int fd;860 ssize_t res;861 862 fd = open( name, O_WRONLY | O_CREAT | O_TRUNC, 0666 );863 if( 0 > fd )864 {865 errnomsg( "failed to open %s for writing", name );866 return -1;867 }868 869 res = write( fd, buf, len );870 if( 0 > res )871 {872 errnomsg( "failed to write to %s", name );873 return -1;874 }875 if( len > res )876 {877 errmsg( "failed to write all data to %s", name );878 return -1;879 }880 881 close( fd );882 883 return 0;884 }885 886 uint8_t *887 readfile( const char * name, size_t * len )888 {889 struct stat sb;890 int fd;891 uint8_t * buf;892 ssize_t res;893 894 fd = open( name, O_RDONLY );895 if( 0 > fd )896 {897 if( ENOENT != errno )898 {899 errnomsg( "failed to open %s for reading", name );900 }901 return NULL;902 }903 904 if( 0 > fstat( fd, &sb ) )905 {906 errnomsg( "failed to stat %s", name );907 return NULL;908 }909 910 buf = malloc( sb.st_size );911 if( NULL == buf )912 {913 mallocmsg( sb.st_size );914 return NULL;915 }916 917 res = read( fd, buf, sb.st_size );918 if( 0 > res )919 {920 errnomsg( "failed to read from %s", name );921 free( buf );922 return NULL;923 }924 if( res < sb.st_size )925 {926 errmsg( "failed to read all data from %s", name );927 free( buf );928 return NULL;929 }930 931 close( fd );932 *len = res;933 934 return buf;935 }936 937 911 struct tor * 938 912 idlookup( int id, int wantdel ) -
branches/daemon/daemon/torrents.h
r1631 r1635 34 34 35 35 void torrent_init ( struct event_base * ); 36 int torrent_add ( const char *, const char *, int ); 36 int torrent_add_file ( const char *, const char *, int ); 37 int torrent_add_data ( uint8_t *, size_t, const char *, int ); 37 38 void torrent_start ( int ); 38 39 void torrent_stop ( int ); -
branches/daemon/daemon/transmission-remote.1
r1629 r1635 41 41 .Op Fl d Ar download-rate 42 42 .Op Fl D 43 .Op Fl e 44 .Op Fl E 43 45 .Op Fl f Ar directory 44 46 .Op Fl i … … 65 67 .Op Fl d Ar download-rate 66 68 .Op Fl D 69 .Op Fl e 70 .Op Fl E 67 71 .Op Fl f Ar directory 68 72 .Op Fl i … … 103 107 .It Fl D Fl -download-unlimited 104 108 Remove the download limit. 109 .It Fl e 110 Enable peer exchange. 111 .It Fl E 112 Disable peer exchange. 105 113 .It Fl f Fl -folder Ar directory 106 114 Use
Note: See TracChangeset
for help on using the changeset viewer.