Changeset 5860
- Timestamp:
- May 20, 2008, 5:33:54 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/daemon/remote.c
r5857 r5860 101 101 } 102 102 103 static char* 104 getEncodedMetainfo( const char * filename ) 105 { 106 size_t len; 107 uint8_t * buf = tr_loadFile( filename, &len ); 108 char * b64 = tr_base64_encode( buf, len, NULL ); 109 tr_free( buf ); 110 return b64; 111 } 112 103 113 static void 104 114 readargs( int argc, char ** argv ) … … 133 143 while((( opt = getopt_long( argc, argv, optstr, longopts, NULL ))) != -1 ) 134 144 { 145 char * tmp; 135 146 char buf[MAX_PATH_LENGTH]; 136 147 tr_benc top, *args; 137 148 tr_bencInitDict( &top, 3 ); 138 args = tr_bencDictAddDict( &top, "arg s", 0 );149 args = tr_bencDictAddDict( &top, "arguments", 0 ); 139 150 140 151 switch( opt ) … … 143 154 case 'h': showUsage( ); break; 144 155 case 'a': tr_bencDictAddStr( &top, "method", "torrent-add" ); 145 tr_bencDictAddStr( args, "filename", optarg ); 156 tr_bencDictAddStr( args, "metainfo", ((tmp=getEncodedMetainfo(optarg))) ); 157 tr_free( tmp ); 146 158 break; 147 159 case 'c': tr_bencDictAddStr( &top, "method", "session-set" ); -
trunk/doc/rpc-spec.txt
r5843 r5860 159 159 "download-dir" | string path to download the torrent to 160 160 "filename" | string location of the .torrent file 161 "metainfo" | string base64-encoded .torrent content 161 162 "paused" | boolean if true, don't start the torrent 162 163 "peer-limit" | int maximum number of peers 163 164 164 The "filename" argument is required; all others are optional. 165 Either "filename" OR "metainfo" must be included. 166 All other arguments are optional. 165 167 166 168 Response arguments: on success, a "torrent-added" object in the -
trunk/libtransmission/JSON_checker.c
r5810 r5860 386 386 if (jc->parse_buffer == &jc->static_parse_buffer[0]) { 387 387 jc->parse_buffer = (char*)malloc(jc->parse_buffer_capacity * sizeof(jc->parse_buffer[0])); 388 memcpy( jc->parse_buffer, jc->static_parse_buffer, jc->parse_buffer_count ); 388 389 } else { 389 390 jc->parse_buffer = (char*)realloc(jc->parse_buffer, jc->parse_buffer_capacity * sizeof(jc->parse_buffer[0])); -
trunk/libtransmission/Makefile.am
r5843 r5860 5 5 6 6 libtransmission_a_SOURCES = \ 7 ConvertUTF.c \8 JSON_checker.c \9 7 bencode.c \ 10 8 blocklist.c \ 11 9 clients.c \ 12 10 completion.c \ 11 ConvertUTF.c \ 13 12 crypto.c \ 14 13 fastresume.c \ … … 18 17 inout.c \ 19 18 json.c \ 19 JSON_checker.c \ 20 20 list.c \ 21 21 makemeta.c \ … … 46 46 47 47 noinst_HEADERS = \ 48 ConvertUTF.h \49 JSON_checker.h \50 48 bencode.h \ 51 49 blocklist.h \ 52 50 clients.h \ 51 ConvertUTF.h \ 53 52 crypto.h \ 54 53 completion.h \ … … 59 58 inout.h \ 60 59 json.h \ 60 JSON_checker.h \ 61 61 list.h \ 62 62 makemeta.h \ … … 93 93 json-test \ 94 94 test-fastset \ 95 test-peer-id 95 test-peer-id \ 96 utils-test 96 97 97 98 noinst_PROGRAMS = $(TESTS) … … 121 122 test_peer_id_SOURCES = test-peer-id.c 122 123 test_peer_id_LDADD = $(APPS_LDADD) 124 utils_test_SOURCES = utils-test.c 125 utils_test_LDADD = $(APPS_LDADD) 123 126 124 127 -
trunk/libtransmission/bencode-test.c
r5843 r5860 273 273 274 274 static int 275 testRISONSnippet( const char * rison_str, const char * expected )276 {277 char * serialized = tr_rison2json( rison_str, -1 );278 #if 0279 fprintf( stderr, " expected: [%s]\n", expected );280 fprintf( stderr, " got: [%s]\n", serialized );281 #endif282 check( !strcmp( serialized, expected ) );283 tr_free( serialized );284 return 0;285 }286 287 static int288 testRISON( void )289 {290 int val;291 const char * rison;292 const char * expected;293 294 rison = "(a:0,b:foo,c:'23skidoo')";295 expected = "{ \"a\": 0, \"b\": \"foo\", \"c\": \"23skidoo\" }";296 if(( val = testRISONSnippet( rison, expected )))297 return val;298 299 rison = "(method:torrent-info)";300 expected = "{ \"method\": \"torrent-info\" }";301 if(( val = testRISONSnippet( rison, expected )))302 return val;303 304 return 0;305 }306 307 static int308 275 testJSONSnippet( const char * benc_str, const char * expected ) 309 276 { … … 406 373 return i; 407 374 408 if(( i = testRISON( )))409 return i;410 411 375 if(( i = testStackSmash( ))) 412 376 return i; -
trunk/libtransmission/bencode.h
r5843 r5860 91 91 int tr_bencInitStrDup( tr_benc * val, const char * str ); 92 92 void tr_bencInitRaw( tr_benc * val, const void * src, size_t byteCount ); 93 int tr_bencInitStrDupLen( tr_benc * val, const char * str, int len );94 93 void tr_bencInitInt( tr_benc * val, int64_t num ); 95 94 int tr_bencInitDict( tr_benc * val, int reserveCount ); -
trunk/libtransmission/json.c
r5843 r5860 148 148 return err; 149 149 } 150 151 /***152 **** RISON-to-JSON converter153 ***/154 155 enum { ESCAPE,156 STRING_BEGIN,157 STRING, ESCAPE_STRING,158 UNQUOTED_STRING, ESCAPE_UNQUOTED_STRING,159 VAL_BEGIN,160 OTHER };161 162 char*163 tr_rison2json( const char * str, int rison_len )164 {165 struct evbuffer * out = evbuffer_new( );166 int stack[1000], *parents=stack;167 int mode = OTHER;168 char * ret;169 const char * end;170 171 if( rison_len < 0 )172 end = str + strlen( str );173 else174 end = str + rison_len;175 176 #define IN_OBJECT ((parents!=stack) && (parents[-1]=='}'))177 178 for( ; str!=end; ++str )179 {180 if( mode == ESCAPE )181 {182 switch( *str )183 {184 case '(': evbuffer_add_printf( out, "[ " ); *parents++ = ']'; break;185 case 't': evbuffer_add_printf( out, " true" ); break;186 case 'f': evbuffer_add_printf( out, " false" ); break;187 case 'n': evbuffer_add_printf( out, " null" ); break;188 default: fprintf( stderr, "invalid escape sequence!\n" ); break;189 }190 mode = OTHER;191 }192 else if( mode == STRING_BEGIN )193 {194 switch( *str )195 {196 case '\'': evbuffer_add_printf( out, "\"" ); mode = STRING; break;197 case ')': evbuffer_add_printf( out, " %c", *--parents ); mode = OTHER; break;198 default: evbuffer_add_printf( out, "\"%c", *str ); mode = UNQUOTED_STRING; break;199 }200 }201 else if( mode == UNQUOTED_STRING )202 {203 switch( *str )204 {205 case '\'': evbuffer_add_printf( out, "\"" ); mode = OTHER; break;206 case ':': evbuffer_add_printf( out, "\": "); mode = VAL_BEGIN; break;207 case '!': mode = ESCAPE_UNQUOTED_STRING; break;208 case ')': if( IN_OBJECT ) { evbuffer_add_printf( out, "\" }"); mode = OTHER; break; }209 case ',': if( IN_OBJECT ) { evbuffer_add_printf( out, "\", "); mode = STRING_BEGIN; break; }210 /* fallthrough */211 default: evbuffer_add_printf( out, "%c", *str ); break;212 }213 }214 else if( mode == VAL_BEGIN )215 {216 if( *str == '\'' ) { evbuffer_add_printf( out, "\"" ); mode = STRING; }217 else if( isdigit( *str ) ) { evbuffer_add_printf( out, "%c", *str ); mode = OTHER; }218 else { evbuffer_add_printf( out, "\"%c", *str ); mode = UNQUOTED_STRING; }219 }220 else if( mode == STRING )221 {222 switch( *str )223 {224 case '\'': evbuffer_add_printf( out, "\"" ); mode = OTHER; break;225 case '!': mode = ESCAPE_STRING; break;226 default: evbuffer_add_printf( out, "%c", *str ); break;227 }228 }229 else if( mode == ESCAPE_STRING || mode == ESCAPE_UNQUOTED_STRING )230 {231 switch( *str )232 {233 case '!': evbuffer_add_printf( out, "!" ); break;234 case '\'': evbuffer_add_printf( out, "'" ); break;235 default: fprintf( stderr, "invalid string escape sequence\n" ); break;236 }237 if( mode == ESCAPE_UNQUOTED_STRING ) mode = UNQUOTED_STRING;238 if( mode == ESCAPE_STRING ) mode = STRING;239 }240 else241 {242 switch( *str )243 {244 case '(': evbuffer_add_printf( out, "{ " ); mode=STRING_BEGIN; *parents++ = '}'; break;245 case '!': mode = ESCAPE; break;246 case ')': evbuffer_add_printf( out, " %c", *--parents ); break;247 case '\'': evbuffer_add_printf( out, "\"" ); mode = STRING; break;248 case ':': if( IN_OBJECT ) {249 evbuffer_add_printf( out, ": " ); mode = VAL_BEGIN;250 } else {251 evbuffer_add_printf( out, "%c", *str );252 }253 break;254 case ',': if( IN_OBJECT ) {255 evbuffer_add_printf( out, ", " ); mode = STRING_BEGIN;256 } else {257 evbuffer_add_printf( out, "%c", *str );258 }259 break;260 default: evbuffer_add_printf( out, "%c", *str ); break;261 }262 }263 }264 265 ret = tr_strdup( (char*) EVBUFFER_DATA( out ) );266 evbuffer_free( out );267 return ret;268 } -
trunk/libtransmission/json.h
r5843 r5860 18 18 const uint8_t ** setme_end ); 19 19 20 char* tr_rison2json( const char * rison,21 int rison_len );22 23 20 #endif -
trunk/libtransmission/rpc-server.c
r5855 r5860 67 67 68 68 evbuffer_add_printf( s->out, "HTTP/1.1 200 OK\r\n" 69 "Content-Type: text/x-json\r\n"69 "Content-Type: application/json\r\n" 70 70 "Content-Length: %d\r\n" 71 71 "\r\n" -
trunk/libtransmission/rpc.c
r5843 r5860 528 528 torrentAdd( tr_handle * h, tr_benc * args_in, tr_benc * args_out ) 529 529 { 530 const char * filename; 531 if( !tr_bencDictFindStr( args_in, "filename", &filename ) ) 532 return "no filename specified"; 530 const char * filename = NULL; 531 const char * metainfo_base64 = NULL; 532 tr_bencDictFindStr( args_in, "filename", &filename ); 533 tr_bencDictFindStr( args_in, "metainfo", &metainfo_base64 ); 534 if( !filename && !metainfo_base64 ) 535 return "no filename or metainfo specified"; 533 536 else 534 537 { … … 540 543 541 544 ctor = tr_ctorNew( h ); 542 tr_ctorSetMetainfoFromFile( ctor, filename ); 545 546 /* set the metainfo */ 547 if( filename ) 548 tr_ctorSetMetainfoFromFile( ctor, filename ); 549 else { 550 int len; 551 char * metainfo = tr_base64_decode( metainfo_base64, -1, &len ); 552 tr_ctorSetMetainfo( ctor, (uint8_t*)metainfo, len ); 553 tr_free( metainfo ); 554 } 555 556 /* set the optional arguments */ 543 557 if( tr_bencDictFindStr( args_in, "download-dir", &str ) ) 544 558 tr_ctorSetDownloadDir( ctor, TR_FORCE, str ); … … 547 561 if( tr_bencDictFindInt( args_in, "peer-limit", &i ) ) 548 562 tr_ctorSetPeerLimit( ctor, TR_FORCE, i ); 563 549 564 tor = tr_torrentNew( h, ctor, &err ); 550 565 tr_ctorFree( ctor ); -
trunk/libtransmission/utils.c
r5843 r5860 602 602 out[len] = '\0'; 603 603 } 604 604 605 return out; 605 606 } … … 1015 1016 return err; 1016 1017 } 1018 1019 #include <string.h> 1020 #include <openssl/sha.h> 1021 #include <openssl/hmac.h> 1022 #include <openssl/evp.h> 1023 #include <openssl/bio.h> 1024 #include <openssl/buffer.h> 1025 1026 char * 1027 tr_base64_encode( const void * input, int length, int * setme_len ) 1028 { 1029 char * ret; 1030 BIO * b64; 1031 BIO * bmem; 1032 BUF_MEM * bptr; 1033 1034 if( length < 1 ) 1035 length = strlen( input ); 1036 1037 bmem = BIO_new( BIO_s_mem( ) ); 1038 b64 = BIO_new( BIO_f_base64( ) ); 1039 b64 = BIO_push( b64, bmem ); 1040 BIO_write( b64, input, length ); 1041 (void) BIO_flush( b64 ); 1042 BIO_get_mem_ptr( b64, &bptr ); 1043 ret = tr_strndup( bptr->data, bptr->length ); 1044 if( setme_len ) 1045 *setme_len = bptr->length; 1046 1047 BIO_free_all( b64 ); 1048 return ret; 1049 } 1050 1051 char * 1052 tr_base64_decode( const void * input, int length, int * setme_len ) 1053 { 1054 char * ret; 1055 BIO * b64; 1056 BIO * bmem; 1057 int retlen; 1058 1059 if( length < 1 ) 1060 length = strlen( input ); 1061 1062 ret = tr_new0( char, length ); 1063 b64 = BIO_new( BIO_f_base64( ) ); 1064 bmem = BIO_new_mem_buf( (unsigned char*)input, length ); 1065 bmem = BIO_push( b64, bmem ); 1066 retlen = BIO_read( bmem, ret, length ); 1067 if( setme_len ) 1068 *setme_len = retlen; 1069 1070 BIO_free_all( bmem ); 1071 return ret; 1072 } -
trunk/libtransmission/utils.h
r5855 r5860 192 192 char* tr_strndup( const char * str, int len ) TR_GNUC_MALLOC; 193 193 char* tr_strdup_printf( const char * fmt, ... ) TR_GNUC_PRINTF( 1, 2 ) TR_GNUC_MALLOC; 194 char* tr_base64_encode( const void * input, int inlen, int *outlen ) TR_GNUC_MALLOC; 195 char* tr_base64_decode( const void * input, int inlen, int *outlen ) TR_GNUC_MALLOC; 196 194 197 size_t tr_strlcpy( char * dst, const char * src, size_t siz ); 195 198
Note: See TracChangeset
for help on using the changeset viewer.