/** * Print file path and result of its verification by hash. * Also if error occurred, print error message. * * @param info pointer to the file-info structure * @param print_name set to non-zero to print file path * @param print_result set to non-zero to print hash verification result */ static void print_check_result(struct file_info *info, int print_name, int print_result) { if (print_name) { rsh_fprintf(rhash_data.out, "%-51s ", info->print_path); } if (print_result) { if (info->error == -1) { /* print error to stdout */ rsh_fprintf(rhash_data.out, "%s\n", strerror(errno)); } else if (!HC_FAILED(info->hc.flags) || !(opt.flags & OPT_VERBOSE)) { /* TRANSLATORS: use at least 3 characters to overwrite "99%" */ rsh_fprintf(rhash_data.out, (!HC_FAILED(info->hc.flags) ? _("OK \n") : /* TRANSLATORS: ERR is short for 'error' */ _("ERR\n")) ); } else { print_verbose_error(info); } } fflush(rhash_data.out); }
/** * Prepare or print result of file processing. * * @param info pointer to the file-info structure * @param init non-zero on initialization before hash calculation, * and zero after hash calculation finished. */ static void print_results_on_check(struct file_info *info, int init) { if (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) { int print_name = (opt.flags & (OPT_PERCENTS | OPT_SKIP_OK) ? !init : init); if (!init && (opt.flags & OPT_SKIP_OK) && errno == 0 && !HC_FAILED(info->hc.flags)) { return; /* skip OK message */ } print_check_result(info, print_name, !init); } }
/** * 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"); }
/** * Finish one-line percent mode. If in hash verification mode, * then print the results of file check. * * @param info pointer to the file-info structure * @param process_res non-zero if error occurred while hashing/checking */ static void p_finish_percents(struct file_info *info, int process_res) { int need_check_result; need_check_result = (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) && !((opt.flags & OPT_SKIP_OK) && errno == 0 && !HC_FAILED(info->hc.flags)); info->error = process_res; if (percents.same_output && need_check_result) { print_check_result(info, 0, 1); } else { rsh_fprintf(rhash_data.log, "100%%\n"); fflush(rhash_data.log); if (need_check_result) print_check_result(info, 1, 1); } }
/** * Finish one-line percent mode. If in hash verification mode, * then print the results of file check. * * @param info pointer to the file-info structure * @param process_res non-zero if error occurred while hashing/checking */ static void p_finish_percents(struct file_info *info, int process_res) { int need_check_result; #ifdef WIN32_USE_CURSOR if(percents.use_cursor && percents.hOut == NULL) return; #endif need_check_result = (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) && !((opt.flags & OPT_SKIP_OK) && errno == 0 && !HC_FAILED(info->hc.flags)); info->error = process_res; if(percents.same_output && need_check_result) { print_check_result(info, 0, 1); } else { fprintf(rhash_data.log, "100%%\n"); fflush(rhash_data.log); if(need_check_result) print_check_result(info, 1, 1); } }