/** * (Re)-initialize RHash context, to calculate hash sums. * * @param info the file data */ static void re_init_rhash_context(struct file_info *info) { if(rhash_data.rctx != 0) { if(opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) { /* a set of hash sums can change from file to file */ rhash_free(rhash_data.rctx); rhash_data.rctx = 0; } else { info->rctx = rhash_data.rctx; if(!opt.bt_batch_file) { rhash_reset(rhash_data.rctx); } else { /* add another file to the torrent batch */ rhash_transmit(RMSG_BT_ADD_FILE, rhash_data.rctx, RHASH_STR2UPTR((char*)file_info_get_utf8_print_path(info)), (rhash_uptr_t)&info->size); return; } } } if(rhash_data.rctx == 0) { info->rctx = rhash_data.rctx = rhash_init(info->sums_flags); } /* re-initialize BitTorrent data */ if(info->sums_flags & RHASH_BTIH) { init_btih_data(info); } }
/** * 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); }
/** * Initialize BTIH hash function. Unlike other algorithms BTIH * requires more data for correct computation. * * @param info the file data */ static void init_btih_data(struct file_info *info) { assert((info->rctx->hash_id & RHASH_BTIH) != 0); rhash_transmit(RMSG_BT_ADD_FILE, info->rctx, RHASH_STR2UPTR((char*)file_info_get_utf8_print_path(info)), (rhash_uptr_t)&info->size); rhash_transmit(RMSG_BT_SET_PROGRAM_NAME, info->rctx, RHASH_STR2UPTR(PROGRAM_NAME "/" VERSION), 0); if(opt.flags & OPT_BT_PRIVATE) { rhash_transmit(RMSG_BT_SET_OPTIONS, info->rctx, RHASH_BT_OPT_PRIVATE, 0); } if(opt.bt_announce) { rhash_transmit(RMSG_BT_SET_ANNOUNCE, info->rctx, RHASH_STR2UPTR(opt.bt_announce), 0); } if(opt.bt_piece_length) { rhash_transmit(RMSG_BT_SET_PIECE_LENGTH, info->rctx, RHASH_STR2UPTR(opt.bt_piece_length), 0); } else if(opt.bt_batch_file && rhash_data.batch_size) { rhash_transmit(RMSG_BT_SET_BATCH_SIZE, info->rctx, RHASH_STR2UPTR(&rhash_data.batch_size), 0); } }
/** * Print formated file information to given output stream. * * @param out the stream to print information to * @param list the format according to which information shall be printed * @param info the file information */ void print_line(FILE* out, print_item* list, struct file_info *info) { const char* basename = get_basename(info->print_path), *tmp; char *url = NULL, *ed2k_url = NULL; char buffer[130]; for(; list; list = list->next) { int print_type = list->flags & ~(PRINT_FLAGS_ALL); size_t len; /* output a hash function digest */ if(list->hash_id && print_type != PRINT_ED2K_LINK) { unsigned hash_id = list->hash_id; int print_flags = (list->flags & PRINT_FLAG_UPPERCASE ? RHPR_UPPERCASE : 0) | (list->flags & PRINT_FLAG_RAW ? RHPR_RAW : 0) | (list->flags & PRINT_FLAG_BASE32 ? RHPR_BASE32 : 0) | (list->flags & PRINT_FLAG_BASE64 ? RHPR_BASE64 : 0) | (list->flags & PRINT_FLAG_HEX ? RHPR_HEX : 0); if((hash_id == RHASH_GOST || hash_id == RHASH_GOST_CRYPTOPRO) && (opt.flags & OPT_GOST_REVERSE)) print_flags |= RHPR_REVERSE; len = rhash_print(buffer, info->rctx, hash_id, print_flags); assert(len < sizeof(buffer)); /* output the hash, exit on fail */ if(fwrite(buffer, 1, len, out) != len) break; continue; } /* output other special items: filepath, URL-encoded filename etc. */ switch(print_type) { case PRINT_STR: fprintf(out, "%s", list->data); break; case PRINT_ZERO: /* the '\0' character */ fprintf(out, "%c", 0); break; case PRINT_FILEPATH: fprintf(out, "%s", info->print_path); break; case PRINT_BASENAME: /* the filename without directory */ fprintf(out, "%s", basename); break; case PRINT_URLNAME: /* URL-encoded filename */ if(!url) { tmp = get_basename(file_info_get_utf8_print_path(info)); url = (char*)rsh_malloc(urlencode(NULL, tmp) + 1); urlencode(url, tmp); } fprintf(out, "%s", url); break; case PRINT_MTIME: /* the last-modified tine of the filename */ print_time(out, info->stat_buf.st_mtime); break; case PRINT_SIZE: /* file size */ fprintI64(out, info->size, list->width, (list->flags & PRINT_FLAG_PAD_WITH_ZERO)); break; case PRINT_ED2K_LINK: fprint_ed2k_url(out, info, list->flags); break; } } free(url); free(ed2k_url); }