Changeset 1524
- Timestamp:
- Mar 5, 2007, 12:07:48 AM (15 years ago)
- Location:
- trunk/libtransmission
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/bencode.c
r1444 r1524 215 215 } 216 216 217 benc_val_t * tr_bencDictFind( benc_val_t * val, c har * key )217 benc_val_t * tr_bencDictFind( benc_val_t * val, const char * key ) 218 218 { 219 219 int i; … … 232 232 233 233 return NULL; 234 } 235 236 benc_val_t * tr_bencDictFindFirst( benc_val_t * val, ... ) 237 { 238 const char * key; 239 benc_val_t * ret; 240 va_list ap; 241 242 va_start( ap, val ); 243 while( ( key = va_arg( ap, const char * ) ) ) 244 { 245 ret = tr_bencDictFind( val, key ); 246 if( NULL != ret ) 247 { 248 break; 249 } 250 } 251 va_end( ap ); 252 253 return ret; 234 254 } 235 255 -
trunk/libtransmission/bencode.h
r920 r1524 57 57 void tr_bencPrint( benc_val_t * val ); 58 58 void tr_bencFree( benc_val_t * val ); 59 benc_val_t * tr_bencDictFind( benc_val_t * val, char * key ); 59 benc_val_t * tr_bencDictFind( benc_val_t * val, const char * key ); 60 benc_val_t * tr_bencDictFindFirst( benc_val_t * val, ... ); 60 61 char * tr_bencSaveMalloc( benc_val_t * val, int * len ); 61 62 int tr_bencSave( benc_val_t * val, char ** buf, -
trunk/libtransmission/metainfo.c
r1517 r1524 30 30 * Local prototypes 31 31 **********************************************************************/ 32 static int getfile( char * buf, int size, 33 const char * prefix, const benc_val_t * name ); 32 34 static int getannounce( tr_info_t * inf, benc_val_t * meta ); 33 35 static char * announceToScrape( const char * announce ); 34 #define strcatUTF8( dst, src) _strcatUTF8( (dst), sizeof( dst ) - 1, (src) ) 35 static void _strcatUTF8( char *, int, char * ); 36 static void strcatUTF8( char *, int, const char *, int ); 36 37 37 38 /*********************************************************************** … … 103 104 104 105 /* Get info hash */ 105 if( !( beInfo = tr_bencDictFind( &meta, "info" ) ) ) 106 { 107 tr_err( "Could not find \"info\" dictionary" ); 106 beInfo = tr_bencDictFind( &meta, "info" ); 107 if( NULL == beInfo || TYPE_DICT != beInfo->type ) 108 { 109 tr_err( "%s \"info\" dictionary", ( beInfo ? "Invalid" : "Missing" ) ); 108 110 tr_bencFree( &meta ); 109 111 free( buf ); … … 151 153 152 154 /* Comment info */ 153 if( ( val = tr_bencDictFind( &meta, "comment.utf-8" ) ) || ( val = tr_bencDictFind( &meta, "comment" ) ) ) 154 { 155 strcatUTF8( inf->comment, val->val.s.s ); 155 val = tr_bencDictFindFirst( &meta, "comment.utf-8", "comment", NULL ); 156 if( NULL != val && TYPE_STR == val->type ) 157 { 158 strcatUTF8( inf->comment, sizeof( inf->comment ), val->val.s.s, 0 ); 156 159 } 157 160 158 161 /* Creator info */ 159 if( ( val = tr_bencDictFind( &meta, "created by.utf-8" ) ) || ( val = tr_bencDictFind( &meta, "created by" ) ) ) 160 { 161 strcatUTF8( inf->creator, val->val.s.s ); 162 tr_bencDictFindFirst( &meta, "created by.utf-8", "created by", NULL ); 163 if( NULL != val && TYPE_STR == val->type ) 164 { 165 strcatUTF8( inf->creator, sizeof( inf->creator ), val->val.s.s, 0 ); 162 166 } 163 167 164 168 /* Date created */ 165 if( ( val = tr_bencDictFind( &meta, "creation date" ) ) ) 169 inf->dateCreated = 0; 170 val = tr_bencDictFind( &meta, "creation date" ); 171 if( NULL != val && TYPE_INT == val->type ) 166 172 { 167 173 inf->dateCreated = val->val.i; 168 174 } 169 else170 {171 inf->dateCreated = 0;172 }173 175 174 176 /* Private torrent */ 175 if( ( NULL != ( val = tr_bencDictFind( beInfo, "private" ) ) && 176 TYPE_INT == val->type && val->val.i ) || 177 ( NULL != ( val = tr_bencDictFind( &meta, "private" ) ) && 178 TYPE_INT == val->type && val->val.i ) ) 177 if( tr_bencDictFind( beInfo, "private" ) || 178 tr_bencDictFind( &meta, "private" ) ) 179 179 { 180 180 inf->flags |= TR_FLAG_PRIVATE; … … 182 182 183 183 /* Piece length */ 184 if( !( val = tr_bencDictFind( beInfo, "piece length" ) ) )185 {186 tr_err( "No \"piece length\" entry" );187 tr_ bencFree( &meta);188 return 1;184 val = tr_bencDictFind( beInfo, "piece length" ); 185 if( NULL == val || TYPE_INT != val->type ) 186 { 187 tr_err( "%s \"piece length\" entry", ( val ? "Invalid" : "Missing" ) ); 188 goto fail; 189 189 } 190 190 inf->pieceSize = val->val.i; … … 192 192 /* Hashes */ 193 193 val = tr_bencDictFind( beInfo, "pieces" ); 194 if( NULL == val || TYPE_STR != val->type ) 195 { 196 tr_err( "%s \"pieces\" entry", ( val ? "Invalid" : "Missing" ) ); 197 goto fail; 198 } 194 199 if( val->val.s.i % SHA_DIGEST_LENGTH ) 195 200 { 196 201 tr_err( "Invalid \"piece\" string (size is %d)", val->val.s.i ); 197 tr_bencFree( &meta ); 198 return 1; 202 goto fail; 199 203 } 200 204 inf->pieceCount = val->val.s.i / SHA_DIGEST_LENGTH; … … 204 208 /* TODO add more tests so we don't crash on weird files */ 205 209 210 /* get file or top directory name */ 211 val = tr_bencDictFindFirst( beInfo, "name.utf-8", "name", NULL ); 212 if( NULL == val || TYPE_STR != val->type ) 213 { 214 tr_err( "%s \"name\" string", ( val ? "Invalid" : "Missing" ) ); 215 goto fail; 216 } 217 strcatUTF8( inf->name, sizeof( inf->name ), val->val.s.s, 1 ); 206 218 inf->totalSize = 0; 219 207 220 if( ( list = tr_bencDictFind( beInfo, "files" ) ) ) 208 221 { 209 222 /* Multi-file mode */ 210 int j;211 212 val = tr_bencDictFind( beInfo, "name.utf-8" );213 if( NULL == val )214 {215 val = tr_bencDictFind( beInfo, "name" );216 }217 strcatUTF8( inf->name, val->val.s.s );218 219 223 inf->multifile = 1; 220 224 inf->fileCount = list->val.l.count; … … 223 227 for( i = 0; i < list->val.l.count; i++ ) 224 228 { 225 val = tr_bencDictFind( &list->val.l.vals[i], "path.utf-8" ); 226 if( NULL == val ) 227 { 228 val = tr_bencDictFind( &list->val.l.vals[i], "path" ); 229 } 230 strcatUTF8( inf->files[i].name, inf->name ); 231 for( j = 0; j < val->val.l.count; j++ ) 232 { 233 strcatUTF8( inf->files[i].name, "/" ); 234 strcatUTF8( inf->files[i].name, 235 val->val.l.vals[j].val.s.s ); 229 val = tr_bencDictFindFirst( &list->val.l.vals[i], 230 "path.utf-8", "path", NULL ); 231 if( getfile( inf->files[i].name, sizeof( inf->files[i].name ), 232 inf->name, val ) ) 233 { 234 tr_err( "%s \"path\" entry", ( val ? "Invalid" : "Missing" ) ); 235 goto fail; 236 236 } 237 237 val = tr_bencDictFind( &list->val.l.vals[i], "length" ); … … 239 239 inf->totalSize += val->val.i; 240 240 } 241 242 241 } 243 242 else … … 248 247 inf->files = calloc( sizeof( tr_file_t ), 1 ); 249 248 250 val = tr_bencDictFind( beInfo, "name.utf-8" ); 251 if( NULL == val ) 252 { 253 val = tr_bencDictFind( beInfo, "name" ); 254 } 255 strcatUTF8( inf->files[0].name, val->val.s.s ); 256 strcatUTF8( inf->name, val->val.s.s ); 249 strcatUTF8( inf->files[0].name, sizeof( inf->files[0].name), 250 val->val.s.s, 1 ); 257 251 258 252 val = tr_bencDictFind( beInfo, "length" ); 253 if( NULL == val || TYPE_INT != val->type ) 254 { 255 tr_err( "%s \"length\" entry", ( val ? "Invalid" : "Missing" ) ); 256 goto fail; 257 } 259 258 inf->files[0].length = val->val.i; 260 259 inf->totalSize += val->val.i; … … 265 264 { 266 265 tr_err( "Size of hashes and files don't match" ); 267 tr_metainfoFree( inf ); 268 tr_bencFree( &meta ); 269 return 1; 266 goto fail; 270 267 } 271 268 … … 273 270 if( getannounce( inf, &meta ) ) 274 271 { 275 tr_metainfoFree( inf ); 276 tr_bencFree( &meta ); 277 return 1; 272 goto fail; 278 273 } 279 274 280 275 tr_bencFree( &meta ); 281 276 return 0; 277 278 fail: 279 tr_metainfoFree( inf ); 280 tr_bencFree( &meta ); 281 return 1; 282 282 } 283 283 … … 300 300 } 301 301 free( inf->trackerList ); 302 } 303 304 static int getfile( char * buf, int size, 305 const char * prefix, const benc_val_t * name ) 306 { 307 const benc_val_t * dir; 308 const char ** list; 309 int ii, jj; 310 311 if( TYPE_LIST != name->type ) 312 { 313 return 1; 314 } 315 316 list = calloc( name->val.l.count, sizeof( list[0] ) ); 317 if( NULL == list ) 318 { 319 return 1; 320 } 321 322 for( ii = jj = 0; name->val.l.count > ii; ii++ ) 323 { 324 if( TYPE_STR != name->val.l.vals[ii].type ) 325 { 326 continue; 327 } 328 dir = &name->val.l.vals[ii]; 329 if( 0 == strcmp( "..", dir->val.s.s ) ) 330 { 331 if( 0 < jj ) 332 { 333 jj--; 334 } 335 } 336 else if( 0 != strcmp( ".", dir->val.s.s ) ) 337 { 338 list[jj] = dir->val.s.s; 339 jj++; 340 } 341 } 342 343 if( 0 == jj ) 344 { 345 return 1; 346 } 347 348 strcatUTF8( buf, size, prefix, 0 ); 349 for( ii = 0; jj > ii; ii++ ) 350 { 351 strcatUTF8( buf, size, "/", 0 ); 352 strcatUTF8( buf, size, list[ii], 1 ); 353 } 354 free( list ); 355 356 return 0; 302 357 } 303 358 … … 475 530 #define WANTBYTES( want, got ) \ 476 531 if( (want) > (got) ) { return; } else { (got) -= (want); } 477 static void _strcatUTF8( char * s, int len, char * append)532 static void strcatUTF8( char * s, int len, const char * append, int deslash ) 478 533 { 479 char * p; 534 const char * p; 535 536 /* don't overwrite the nul at the end */ 537 len--; 480 538 481 539 /* Go to the end of the destination string */ … … 489 547 for( p = append; p[0]; ) 490 548 { 549 /* skip over / if requested */ 550 if( deslash && '/' == p[0] ) 551 { 552 p++; 553 continue; 554 } 555 491 556 if( !( p[0] & 0x80 ) ) 492 557 {
Note: See TracChangeset
for help on using the changeset viewer.