Beispiel #1
0
/**
 * Print verbose error on hash sums mismatch.
 *
 * @param info file information with path and its hash sums.
 */
static void print_verbose_error(struct file_info *info)
{
	char actual[130], expected[130];
	assert(HC_FAILED(info->hc.flags));

	rsh_fprintf(rhash_data.out, _("ERROR"));

	if (HC_WRONG_FILESIZE & info->hc.flags) {
		sprintI64(actual, info->rctx->msg_size, 0);
		sprintI64(expected, info->hc.file_size, 0);
		rsh_fprintf(rhash_data.out, _(", size is %s should be %s"), actual, expected);
	}

	if (HC_WRONG_EMBCRC32 & info->hc.flags) {
		rhash_print(expected, info->rctx, RHASH_CRC32, RHPR_UPPERCASE);
		rsh_fprintf(rhash_data.out, _(", embedded CRC32 should be %s"), expected);
	}

	if (HC_WRONG_HASHES & info->hc.flags) {
		int i;
		unsigned reported = 0;
		for (i = 0; i < info->hc.hashes_num; i++) {
			hash_value *hv = &info->hc.hashes[i];
			char *expected_hash = info->hc.data + hv->offset;
			unsigned hid = hv->hash_id;
			int pflags;
			if ((info->hc.wrong_hashes & (1 << i)) == 0) continue;

			assert(hid != 0);

			/* if can't detect precise hash */
			if ((hid & (hid - 1)) != 0) {
				/* guess the hash id */
				if (hid & opt.sum_flags) hid &= opt.sum_flags;
				if (hid & ~info->hc.found_hash_ids) hid &= ~info->hc.found_hash_ids;
				if (hid & ~reported) hid &= ~reported; /* avoiding repeating */
				if (hid & REPORT_FIRST_MASK) hid &= REPORT_FIRST_MASK;
				hid &= -(int)hid; /* take the lowest bit */
			}
			assert(hid != 0 && (hid & (hid - 1)) == 0); /* single bit only */
			reported |= hid;

			pflags = (hv->length == (rhash_get_digest_size(hid) * 2) ?
				(RHPR_HEX | RHPR_UPPERCASE) : (RHPR_BASE32 | RHPR_UPPERCASE));
			rhash_print(actual, info->rctx, hid, pflags);
			rsh_fprintf(rhash_data.out, _(", %s is %s should be %s"),
				rhash_get_name(hid), actual, expected_hash);
		}
	}

	rsh_fprintf(rhash_data.out, "\n");
}
Beispiel #2
0
/**
 * Print EDonkey 2000 url for given file to a stream.
 *
 * @param out the stream where to print url to
 * @param filename the file name
 * @param filesize the file size
 * @param sums the file hash sums
 */
static void fprint_ed2k_url(FILE* out, struct file_info *info, int print_type)
{
	const char *filename = get_basename(file_info_get_utf8_print_path(info));
	int upper_case = (print_type & PRINT_FLAG_UPPERCASE ? RHPR_UPPERCASE : 0);
	int len = urlencode(NULL, filename) + int_len(info->size) + (info->sums_flags & RHASH_AICH ? 84 : 49);
	char* buf = (char*)rsh_malloc( len + 1 );
	char* dst = buf;

	assert(info->sums_flags & (RHASH_ED2K|RHASH_AICH));
	assert(info->rctx);

	strcpy(dst, "ed2k://|file|");
	dst += 13;
	dst += urlencode(dst, filename);
	*dst++ = '|';
	sprintI64(dst, info->size, 0);
	dst += strlen(dst);
	*dst++ = '|';
	rhash_print(dst, info->rctx, RHASH_ED2K, upper_case);
	dst += 32;
	if((info->sums_flags & RHASH_AICH) != 0) {
		strcpy(dst, "|h=");
		rhash_print(dst += 3, info->rctx, RHASH_AICH, RHPR_BASE32 | upper_case);
		dst += 32;
	}
	strcpy(dst, "|/");
	fprintf(out, "%s", buf);
	free(buf);
}
Beispiel #3
0
/**
 * Output aligned uint64_t number to specified output stream.
 *
 * @param out the stream to output to
 * @param filesize the 64-bit integer to output, usually a file size
 * @param width minimal width of integer to output
 * @param flag =1 if the integer shall be prepent by zeros
 */
static void fprintI64(FILE* out, uint64_t filesize, int width, int zero_pad)
{
	char *buf = (char*)rsh_malloc(width > 40 ? width + 1 : 41);
	int len = int_len(filesize);
	sprintI64(buf, filesize, width);
	if(len < width && zero_pad) {
		memset(buf, '0', width-len);
	}
	fprintf(out, "%s", buf);
	free(buf);
}
Beispiel #4
0
/**
 * B-encode given integer.
 *
 * @param out the string buffer to output encoded integer to
 * @param number the integer to output
 */
static void bt_bencode_int(strbuf_t *out, uint64_t number)
{
  char* p;
  /* add up to 20 digits and 2 letters */
  str_ensure_size(out, out->len + 22);
  p = out->str + out->len;
  *(p++) = 'i';
  p += sprintI64(p, number);
  *(p++) = 'e';
  *p = '\0'; /* terminate string with \0 */

  out->len = (p - out->str);
}
Beispiel #5
0
/**
 * B-encode a string.
 *
 * @param out the string buffer to put encoded string into
 * @param str the string to encode
 */
static void bt_bencode_str(strbuf_t *out, const char* str)
{
  size_t len = strlen(str);
  int num_len;
  char* p;
  str_ensure_size(out, out->len + len + 21);

  p = out->str + out->len;
  p += (num_len = sprintI64(p, len));
  out->len += len + num_len + 1;

  *(p++) = ':';
  memcpy(p, str, len + 1); /* copy with trailing '\0' */
}
Beispiel #6
0
/**
 * B-encode array of SHA1 hashes of file pieces.
 *
 * @param out the string buffer to put encoded array into
 * @param ctx pointer to the torrent structure containing hashes
 */
static void bt_bencode_pieces(strbuf_t *out, torrent_ctx* ctx)
{
  int pieces_length = ctx->blocks_hashes.size * BT_HASH_SIZE;
  int num_len;
  int size, i;
  char* p;

  str_ensure_size(out, out->len + pieces_length + 21);
  p = out->str + out->len;
  p += (num_len = sprintI64(p, pieces_length));
  out->len += pieces_length + num_len + 1;

  *(p++) = ':';
  p[pieces_length] = '\0'; /* terminate with \0 just in case */

  for(size = ctx->blocks_hashes.size, i = 0; size > 0; size -= BT_BLOCK_SIZE, i++) {
    memcpy(p, ctx->blocks_hashes.blocks.array[i], (size < BT_BLOCK_SIZE ? size : BT_BLOCK_SIZE) * BT_HASH_SIZE);
    p += BT_BLOCK_SIZE * BT_HASH_SIZE;
  }
}
/**
 * Print a file info line in SFV header format.
 *
 * @param out a stream to print info to
 * @param file the file info to print
 * @return 0 on success, -1 on fail with error code stored in errno
 */
int print_sfv_header_line(FILE* out, file_t* file, const char* printpath)
{
	char buf[24];

	if(!printpath) printpath = file->path;
	if(printpath[0] == '.' && IS_PATH_SEPARATOR(printpath[1])) printpath += 2;

#ifdef _WIN32
	/* skip file if it can't be opened with exclusive sharing rights */
	if(!can_open_exclusive(file->path)) {
		return 0;
	}
#endif

	sprintI64(buf, file->size, 12);
	fprintf(out, "; %s  ", buf);
	print_time64(out, file->mtime);
	fprintf(out, " %s\n", printpath);
	return 0;
}