bool TorrentFile::check_all_pieces() { for(uint32_t i = 0; i < m_pieces_count; i++) { if (!check_piece_hash(i)) return false; } return true; }
int TorrentFile::event_file_write(fs::write_event * eo) { if (eo->writted >= 0) { uint32_t block_index = get_block_from_id(eo->id);//(eo->id & (uint32_t)4294967295); uint32_t piece = get_piece_from_id(eo->id);//(eo->id - block_index)>>32; //printf("WRITE %u %u\n", piece, block_index); if (block_done(piece, block_index) == 0) m_piece_info[piece].remain -= eo->writted; if (m_piece_info[piece].remain == 0) { printf("piece done %u, checking hash\n", piece); check_piece_hash(piece); } return ERR_NO_ERROR; } else { //printf("write error\n"); uint32_t block_index = get_block_from_id(eo->id);//(eo->id & (uint32_t)4294967295); uint32_t piece = get_piece_from_id(eo->id);//(eo->id - block_index)>>32; return unmark_block(piece, block_index); } }
int job_validate_file(JOB *job) { PART part; mget_metalink_t *metalink; off_t fsize; int fd, rc = -1, it; struct stat st; if (!job || !(metalink = job->metalink)) return 0; memset(&part, 0, sizeof(PART)); // create space to hold enough parts if (!job->parts) job->parts = mget_vector_create(mget_vector_size(metalink->pieces), 4, NULL); else mget_vector_clear(job->parts); fsize = metalink->size; if (mget_vector_size(metalink->hashes) == 0) { // multipart non-metalink download: do not clobber if file has expected size if (stat(metalink->name, &st) == 0 && st.st_size == fsize) { return 1; // we are done } } // truncate file if needed if (stat(metalink->name, &st) == 0 && st.st_size > fsize) { if (truncate(metalink->name, fsize) == -1) error_printf(_("Failed to truncate %s\n from %llu to %llu bytes\n"), metalink->name, (unsigned long long)st.st_size, (unsigned long long)fsize); } if ((fd = open(metalink->name, O_RDONLY)) != -1) { // file exists, check which piece is invalid and requeue it for (it = 0; errno != EINTR && it < mget_vector_size(metalink->hashes); it++) { mget_metalink_hash_t *hash = mget_vector_get(metalink->hashes, it); if ((rc = check_file_fd(hash, fd)) == -1) continue; // hash type not available, try next break; } if (rc == 1) { info_printf(_("Checksum OK for '%s'\n"), metalink->name); return 1; // we are done } else if (rc == -1) { // failed to check file, continue as if file is ok info_printf(_("Failed to build checksum, assuming file to be OK\n")); return 1; // we are done } else info_printf(_("Bad checksum for '%s'\n"), metalink->name); // if (vec_size(metalink->pieces) < 1) // return; for (it = 0; errno != EINTR && it < mget_vector_size(metalink->pieces); it++) { mget_metalink_piece_t *piece = mget_vector_get(metalink->pieces, it); mget_metalink_hash_t *hash = &piece->hash; if (fsize >= piece->length) { part.length = piece->length; } else { part.length = (size_t)fsize; } part.id = it + 1; if ((rc = check_piece_hash(hash, fd, part.position, part.length)) != 1) { info_printf(_("Piece %d/%d not OK - requeuing\n"), it + 1, mget_vector_size(metalink->pieces)); mget_vector_add(job->parts, &part, sizeof(PART)); debug_printf(" need to download %llu bytes from pos=%llu\n", (unsigned long long)part.length, (unsigned long long)part.position); } part.position += part.length; fsize -= piece->length; } close(fd); } else { for (it = 0; it < mget_vector_size(metalink->pieces); it++) { mget_metalink_piece_t *piece = mget_vector_get(metalink->pieces, it); if (fsize >= piece->length) { part.length = piece->length; } else { part.length = fsize; } part.id = it + 1; mget_vector_add(job->parts, &part, sizeof(PART)); part.position += part.length; fsize -= piece->length; } } return 0; }