Changeset 1356 for trunk/libtransmission/inout.c
- Timestamp:
- Jan 14, 2007, 12:00:21 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/inout.c
r1074 r1356 47 47 * Local prototypes 48 48 **********************************************************************/ 49 static int createFiles( tr_io_t * );50 49 static int checkFiles( tr_io_t * ); 51 50 static void closeFiles( tr_io_t * ); … … 96 95 io->tor = tor; 97 96 98 if( c reateFiles( io ) || checkFiles( io ) )97 if( checkFiles( io ) ) 99 98 { 100 99 free( io ); … … 107 106 /*********************************************************************** 108 107 * tr_ioRead 109 ***********************************************************************110 *111 108 **********************************************************************/ 112 109 int tr_ioRead( tr_io_t * io, int index, int begin, int length, 113 110 uint8_t * buf ) 114 111 { 112 tr_info_t * inf = &io->tor->info; 115 113 uint64_t offset; 116 tr_info_t * inf = &io->tor->info;117 114 118 115 offset = (uint64_t) io->pieceSlot[index] * … … 124 121 /*********************************************************************** 125 122 * tr_ioWrite 126 ***********************************************************************127 *128 123 **********************************************************************/ 129 124 int tr_ioWrite( tr_io_t * io, int index, int begin, int length, 130 125 uint8_t * buf ) 131 126 { 132 tr_torrent_t * tor = io->tor;133 127 tr_info_t * inf = &io->tor->info; 134 128 uint64_t offset; 135 int i, hashFailed;136 uint8_t hash[SHA_DIGEST_LENGTH];137 uint8_t * pieceBuf;138 int pieceSize;139 int startBlock, endBlock;140 129 141 130 if( io->pieceSlot[index] < 0 ) … … 149 138 (uint64_t) inf->pieceSize + (uint64_t) begin; 150 139 151 if( writeBytes( io, offset, length, buf ) ) 152 { 153 return 1; 154 } 155 156 startBlock = tr_pieceStartBlock( index ); 157 endBlock = startBlock + tr_pieceCountBlocks( index ); 158 for( i = startBlock; i < endBlock; i++ ) 159 { 160 if( !tr_cpBlockIsComplete( tor->completion, i ) ) 161 { 162 /* The piece is not complete */ 163 return 0; 164 } 165 } 166 167 /* The piece is complete, check the hash */ 140 return writeBytes( io, offset, length, buf ); 141 } 142 143 /*********************************************************************** 144 * tr_ioHash 145 **********************************************************************/ 146 int tr_ioHash( tr_io_t * io, int index ) 147 { 148 tr_torrent_t * tor = io->tor; 149 tr_info_t * inf = &io->tor->info; 150 int pieceSize; 151 uint8_t * pieceBuf; 152 uint8_t hash[SHA_DIGEST_LENGTH]; 153 int hashFailed; 154 int ret; 155 int i; 156 157 if( !tr_cpPieceIsComplete( tor->completion, index ) ) 158 { 159 return TR_ERROR_ASSERT; 160 } 161 168 162 pieceSize = tr_pieceSize( index ); 169 163 pieceBuf = malloc( pieceSize ); 170 readBytes( io, (uint64_t) io->pieceSlot[index] * 171 (uint64_t) inf->pieceSize, pieceSize, pieceBuf ); 164 if( ( ret = readBytes( io, (uint64_t) io->pieceSlot[index] * 165 (uint64_t) inf->pieceSize, pieceSize, pieceBuf ) ) ) 166 { 167 free( pieceBuf ); 168 return ret; 169 } 172 170 SHA1( pieceBuf, pieceSize, hash ); 173 171 free( pieceBuf ); … … 178 176 tr_inf( "Piece %d (slot %d): hash FAILED", index, 179 177 io->pieceSlot[index] ); 180 181 /* We will need to reload the whole piece */ 182 for( i = startBlock; i < endBlock; i++ ) 183 { 184 tr_cpBlockRem( tor->completion, i ); 185 } 178 tr_cpPieceRem( tor->completion, index ); 186 179 } 187 180 else … … 201 194 } 202 195 196 /*********************************************************************** 197 * tr_ioSync 198 **********************************************************************/ 199 void tr_ioSync( tr_io_t * io ) 200 { 201 closeFiles( io ); 202 fastResumeSave( io ); 203 } 204 205 /*********************************************************************** 206 * tr_ioClose 207 **********************************************************************/ 203 208 void tr_ioClose( tr_io_t * io ) 204 209 { 205 closeFiles( io ); 206 207 fastResumeSave( io ); 210 tr_ioSync( io ); 208 211 209 212 free( io->pieceSlot ); 210 213 free( io->slotPiece ); 211 214 free( io ); 212 }213 214 void tr_ioSaveResume( tr_io_t * io )215 {216 fastResumeSave( io );217 }218 219 /***********************************************************************220 * createFiles221 ***********************************************************************222 * Make sure the existing folders/files have correct types and223 * permissions, and create missing folders and files224 **********************************************************************/225 static int createFiles( tr_io_t * io )226 {227 tr_torrent_t * tor = io->tor;228 tr_info_t * inf = &tor->info;229 230 int i;231 char * path, * p;232 struct stat sb;233 int file;234 235 tr_dbg( "Creating files..." );236 237 for( i = 0; i < inf->fileCount; i++ )238 {239 asprintf( &path, "%s/%s", tor->destination, inf->files[i].name );240 241 /* Create folders */242 if( NULL != ( p = strrchr( path, '/' ) ) )243 {244 *p = '\0';245 if( tr_mkdir( path ) )246 {247 free( path );248 return 1;249 }250 *p = '/';251 }252 253 /* Empty folders use a dummy "" file, skip those */254 if( p == &path[strlen( path ) - 1] )255 {256 free( path );257 continue;258 }259 260 if( stat( path, &sb ) )261 {262 /* File doesn't exist yet */263 if( ( file = open( path, O_WRONLY|O_CREAT|O_TRUNC, 0666 ) ) < 0 )264 {265 tr_err( "Could not create `%s' (%s)", path,266 strerror( errno ) );267 free( path );268 return 1;269 }270 close( file );271 }272 else if( ( sb.st_mode & S_IFMT ) != S_IFREG )273 {274 /* Node exists but isn't a file */275 /* XXX this should be reported to the frontend somehow */276 tr_err( "Remove %s, it's in the way.", path );277 free( path );278 return 1;279 }280 281 free( path );282 }283 284 return 0;285 215 } 286 216 … … 370 300 371 301 int i; 372 char * path;373 302 374 303 for( i = 0; i < inf->fileCount; i++ ) 375 304 { 376 asprintf( &path, "%s/%s", tor->destination, inf->files[i].name ); 377 tr_fdFileClose( tor->fdlimit, path ); 378 free( path ); 305 tr_fdFileClose( tor->fdlimit, tor->destination, 306 inf->files[i].name ); 379 307 } 380 308 } … … 396 324 int i; 397 325 size_t cur; 398 char * path;399 326 int file; 400 327 iofunc readOrWrite = isWrite ? (iofunc) write : (iofunc) read; 328 int ret = 0; 401 329 402 330 /* Release the torrent lock so the UI can still update itself if … … 408 336 { 409 337 tr_err( "readOrWriteBytes: trying to write more than a piece" ); 410 goto fail; 338 ret = TR_ERROR_ASSERT; 339 goto cleanup; 411 340 } 412 341 … … 426 355 tr_err( "readOrWriteBytes: offset out of range (%"PRIu64", %d, %d)", 427 356 offset, size, isWrite ); 428 goto fail; 357 ret = TR_ERROR_ASSERT; 358 goto cleanup; 429 359 } 430 360 … … 443 373 if( cur > 0 ) 444 374 { 445 /* Now let's get a streamon the file... */446 asprintf( &path, "%s/%s", tor->destination, inf->files[i].name );447 file = tr_fdFileOpen( tor->fdlimit, path);375 /* Now let's get a descriptor on the file... */ 376 file = tr_fdFileOpen( tor->fdlimit, tor->destination, 377 inf->files[i].name, isWrite ); 448 378 if( file < 0 ) 449 379 { 450 tr_err( "readOrWriteBytes: could not open file '%s'", path ); 451 free( path ); 452 goto fail; 453 } 454 free( path ); 380 ret = file; 381 goto cleanup; 382 } 455 383 456 384 /* seek to the right offset... */ 457 385 if( lseek( file, offset, SEEK_SET ) < 0 ) 458 386 { 459 goto fail; 387 tr_fdFileRelease( tor->fdlimit, file ); 388 ret = TR_ERROR_IO_OTHER; 389 goto cleanup; 460 390 } 461 391 … … 463 393 if( readOrWrite( file, buf, cur ) != cur ) 464 394 { 465 goto fail; 466 } 467 468 /* and close the stream. */ 395 tr_fdFileRelease( tor->fdlimit, file ); 396 ret = TR_ERROR_IO_OTHER; 397 goto cleanup; 398 } 399 400 /* and release the descriptor. */ 469 401 tr_fdFileRelease( tor->fdlimit, file ); 470 402 } … … 477 409 } 478 410 411 cleanup: 479 412 tr_lockLock( &tor->lock ); 480 return 0; 481 482 fail: 483 tr_lockLock( &tor->lock ); 484 return 1; 413 return ret; 485 414 } 486 415
Note: See TracChangeset
for help on using the changeset viewer.