コード例 #1
0
ファイル: torrentfile.cpp プロジェクト: Shevchik-CS/dinosaur
bool TorrentFile::check_all_pieces()
{
	for(uint32_t i = 0; i < m_pieces_count; i++)
	{
		if (!check_piece_hash(i))
			return false;
	}
	return true;
}
コード例 #2
0
ファイル: torrentfile.cpp プロジェクト: Shevchik-CS/dinosaur
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);
	}
}
コード例 #3
0
ファイル: job.c プロジェクト: darnir/mget
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;
}