void extract(const std::string & archive_name, const std::string & dest_dir, const std::string & password) { bool already_extracted; #ifdef WINDOWS already_extracted = contains(extracted_files, archive_name, false); #else already_extracted = contains(extracted_files, archive_name, true); #endif if (already_extracted) return; fprintf(stdout, "Extracting %s to %s\n", archive_name.c_str(), dest_dir.c_str()); HANDLE archive; struct RAROpenArchiveData data; struct RARHeaderData header; if (!fileExists(archive_name)) return; if (!createDir(dest_dir)) return; data.ArcName = (char *)archive_name.c_str(); data.OpenMode = RAR_OM_EXTRACT; data.CmtBuf = NULL; data.CmtBufSize = 0; //fprintf(stdout, "Opening %s\n", argv[1]); archive = RAROpenArchive(&data); if (!archive || data.OpenResult != 0) { fprintf(stderr, "Couldn't open %s\n", archive_name.c_str()); return; } header.CmtBuf = NULL; //fprintf(stdout, "Clearing password\n"); RARSetPassword(archive, (char*)password.c_str()); MultipartInfo info; //fprintf(stdout, "Setting callback\n"); RARSetCallback(archive, &missing_file, (ssize_t)&info); //fprintf(stdout, "Starting to process file\n"); // the complete path to the file to be extracted std::string dest_path; start_timer(); while (!RARReadHeader(archive, &header)) { dest_path = dest_dir + PATH_SEP + header.FileName; if (pathExists(dest_path)) { fprintf(stderr, "Skpping %s\n", header.FileName); continue; } if (RARProcessFile(archive, RAR_EXTRACT, (char *)dest_dir.c_str(), NULL)) { /*if (!pathExists(dest_path)) { fprintf(stderr, "Couldn't create %s\n", dest_path.c_str()); break; }*/ if (elapsed(five_seconds)) { info.bytes_processed = 0; start_timer(); } } else { break; } // (bytes / (1024 * 1024) = MBytes // ms / 1000 = s // (bytes / (1024 * 1024) / (ms / 1000) = 0.00095367431640625 * bytes/ms //fprintf(stdout, "%d MB/s", (int)(0.00095367431640625 * (info.bytes_processed / calc_elapsed()))); } //fprintf(stdout, "Closing file\n"); RARCloseArchive(archive); extracted_files.push_back(archive_name); }
extern u32 fs_rar_to_menu(const char *rarfile, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor) { int fid; struct RAROpenArchiveData arcdata; struct RARHeaderDataEx header; int ret; HANDLE hrar; t_fs_filetype ft; t_win_menuitem item; if (menu_renew(&g_menu) == NULL) { return 0; } fid = freq_enter_hotzone(); arcdata.ArcName = (char *) rarfile; arcdata.OpenMode = RAR_OM_LIST; arcdata.CmtBuf = NULL; arcdata.CmtBufSize = 0; hrar = RAROpenArchive(&arcdata); if (hrar == 0) { freq_leave(fid); return 0; } add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor); do { char t[20]; if ((ret = RARReadHeaderEx(hrar, &header)) != 0) { if (ret != ERAR_UNKNOWN) break; RARCloseArchive(hrar); if ((hrar = reopen_rar_with_passwords(&arcdata)) == 0) break; if (RARReadHeaderEx(hrar, &header) != 0) break; } if (header.UnpSize == 0) continue; ft = fs_file_get_type(header.FileName); if (ft == fs_filetype_chm || ft == fs_filetype_zip || ft == fs_filetype_rar) continue; win_menuitem_new(&item); item.data = (void *) ft; if (header.Flags & 0x200) { char str[1024]; const u8 *uni; memset(str, 0, 1024); uni = (u8 *) header.FileNameW; charsets_utf32_conv(uni, sizeof(header.FileNameW), (u8 *) str, sizeof(str)); buffer_copy_string_len(item.compname, header.FileName, 256); filename_to_itemname(&item, str); } else { buffer_copy_string_len(item.compname, header.FileName, 256); filename_to_itemname(&item, header.FileName); } SPRINTF_S(t, "%u", (unsigned int) header.UnpSize); buffer_copy_string(item.shortname, t); item.selected = false; item.icolor = icolor; item.selicolor = selicolor; item.selrcolor = selrcolor; item.selbcolor = selbcolor; item.data3 = header.UnpSize; win_menu_add(g_menu, &item); } while (RARProcessFile(hrar, RAR_SKIP, NULL, NULL) == 0); RARCloseArchive(hrar); freq_leave(fid); return g_menu->size; }