Ejemplo n.º 1
0
int main(int argc, char* argv[]) {

    for (int i = 0; i < RSN_ENTRIES; i++) {
        rsnEntries[i] = NULL;
        rsnSize[i] = 0;
    }
    rsnInfo = NULL;

    resetRsnEntries();
    printf("\nUnrar Into Memory Learn 1.0\n\n");

    rarFileData.ArcName = "test.rar";
    rarFileData.OpenMode = RAR_OM_EXTRACT;
    rarHandle = RAROpenArchive(&rarFileData);

    printf("Opening test.rar: %d\n", rarFileData.OpenResult);

    if (rarFileData.OpenResult == ERAR_SUCCESS) {
        printf("-->Success\n");

        int res = RARReadHeader(rarHandle, &rarFileHeader);
        while(res == ERAR_SUCCESS) {
            printf("Header '%s' -> %d -> %d Bytes\n", rarFileHeader.FileName, res, rarFileHeader.UnpSize);
            if (strfind(rarFileHeader.FileName, ".spc") != NULL && rsnCount < RSN_ENTRIES && rarFileHeader.UnpSize > 66000 && rarFileHeader.UnpSize < 67000) {
                printf("--> SPC File, going to extract\n");
                rsnEntries[rsnCount] = (char*)malloc(rarFileHeader.UnpSize);
                if (rsnEntries[rsnCount] != NULL) {
                    printf("--> Pointer to memory: %p\n", rsnEntries[rsnCount]);
                    RARSetCallback(rarHandle, rarExtractSpcBytes, (long)rsnEntries[rsnCount]);
                    RARProcessFile(rarHandle, RAR_EXTRACT, NULL, NULL);
                    rsnSize[rsnCount] = rarFileHeader.UnpSize;
                    rsnCount++;
                }
            } else if (strfind(rarFileHeader.FileName, ".txt") != NULL && rsnInfo == NULL && rarFileHeader.UnpSize < 10000) {
                printf("--> TXT File, going to extract\n");
                rsnInfo = (char*)calloc(rarFileHeader.UnpSize + 1, 1);
                if (rsnInfo != NULL) {
                    RARSetCallback(rarHandle, rarExtractInfoBytes, (long)rsnInfo);
                    RARProcessFile(rarHandle, RAR_EXTRACT, NULL, NULL);
                }
            } else {
                printf("--> Skip\n");
                RARProcessFile(rarHandle, RAR_SKIP, NULL, NULL);
            }
            res = RARReadHeader(rarHandle, &rarFileHeader);
        }
        printf("Result: %d\n", res);
    }
    RARCloseArchive(rarHandle);

    printf("Tracks: %d\n", rsnCount);
    printf("Info: %d\n\n%s\n", rsnInfo == NULL ? 0 : strlen(rsnInfo), rsnInfo == NULL ? "<?>" : rsnInfo);

    return 0;
}
Ejemplo n.º 2
0
jint Java_de_illogical_modo_SpcDecoder_spcLoadRSN(JNIEnv* env, jclass clazz, jstring path)
{
	char cpath[1024];
	memset(cpath, 0, 1024);

	int clen = (*env)->GetStringLength(env, path);
	(*env)->GetStringUTFRegion(env, path, 0, clen, cpath);
	
	rarFileData.ArcName = cpath;
	rarFileData.OpenMode = RAR_OM_EXTRACT;
	rarHandle = RAROpenArchive(&rarFileData);

	if (rarFileData.OpenResult == ERAR_SUCCESS)
	{
		int res = RARReadHeader(rarHandle, &rarFileHeader);
		while(res == ERAR_SUCCESS)
		{
			if (strfind(rarFileHeader.FileName, ".spc") != NULL && rsnCount < RSN_ENTRIES && rarFileHeader.UnpSize > 66000 && rarFileHeader.UnpSize < 67000)
			{
				rsnEntries[rsnCount] = (char*)malloc(rarFileHeader.UnpSize);
				if (rsnEntries[rsnCount] != NULL) {
					rarExtractSpcBytes(0xFFFF, 0, 0, 0);
					RARSetCallback(rarHandle, rarExtractSpcBytes, (long)rsnEntries[rsnCount]);
					RARProcessFile(rarHandle, RAR_EXTRACT, NULL, NULL);
					rsnSize[rsnCount] = rarFileHeader.UnpSize;
					rsnCount++;
				} 
			} else if (strfind(rarFileHeader.FileName, ".txt") != NULL && rsnInfo == NULL && rarFileHeader.UnpSize < 10000)
			{
				rsnInfo = (char*)calloc(rarFileHeader.UnpSize + 1, 1);
				if (rsnInfo != NULL) {
					rarExtractInfoBytes(0xFFFF, 0, 0, 0);
					RARSetCallback(rarHandle, rarExtractInfoBytes, (long)rsnInfo);
					RARProcessFile(rarHandle, RAR_EXTRACT, NULL, NULL);
				}
			} else
			{
				RARProcessFile(rarHandle, RAR_SKIP, NULL, NULL);
			}
			res = RARReadHeader(rarHandle, &rarFileHeader);
		}
	}
	RARCloseArchive(rarHandle);

	return rsnCount;	
}
Ejemplo n.º 3
0
bool ComicBookRAR::TestPassword()
{
	HANDLE rarFile;
	int RHCode = 0, PFCode = 0;
	struct RARHeaderDataEx header;
	struct RAROpenArchiveDataEx flags;
	bool passwordCorrect = true;
	
	if (Pages.size() == 0)
		// nothing in the archive to open
		return true;

	wxString page = Pages.at(0)->Filename; // test using the first page
	
	rarFile = openRar(&flags, &header, RAR_OM_EXTRACT);

	if (password)
		RARSetPassword(rarFile, password);

	while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) {
		if (page.Cmp(header.FileNameW) == 0) {
			break;
		} else {
			if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) {
				closeRar(rarFile, &flags);
				throw ArchiveException(filename, ProcessFileError(PFCode, page));
			}
		}
	}
	
	if (RHCode != 0) {
		closeRar(rarFile, &flags);
		throw new ArchiveException(filename, OpenArchiveError(RHCode));
	}

	RARSetCallback(rarFile, TestPasswordCallbackProc, (long) &passwordCorrect);
	PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL);

	closeRar(rarFile, &flags);

	// If the password is wrong, RARProcessFile will return ERAR_BAD_DATA.  Of
	// course, it will also return ERAR_BAD_DATA when the first file in the archive
	// is corrupted.  How does one tell the difference?
	if (PFCode == ERAR_BAD_DATA)
		return false;

	return passwordCorrect;
}
Ejemplo n.º 4
0
Archivo: utils.c Proyecto: azuwis/cview
/* XXX a return value indicate the status */
static void extract_rar_file_into_loader(GdkPixbufLoader * loader,
        const char *archname,
        const char *archpath)
{
    struct RAROpenArchiveData arcdata;
    int code = 0;
    int ret;
    HANDLE hrar;

    arcdata.ArcName = (char *)archname;
    arcdata.OpenMode = RAR_OM_EXTRACT;
    arcdata.CmtBuf = NULL;
    arcdata.CmtBufSize = 0;
    hrar = RAROpenArchive(&arcdata);

    if (hrar == NULL && loader == NULL)
        return;
    RARSetCallback(hrar, rarcbpixbuf, (LONG) loader);
    do {
        struct RARHeaderData header;

        if ((ret = RARReadHeader(hrar, &header)) != 0) {
            if (ret != ERAR_UNKNOWN && ret != ERAR_BAD_DATA)
                break;
            RARCloseArchive(hrar);
            //test_rar_file_password(buf, archname, archpath);
            return;
        }
        if (strcasecmp(header.FileName, archpath) == 0) {
            code = RARProcessFile(hrar, RAR_TEST, NULL, NULL);
            break;
        }
    } while (RARProcessFile(hrar, RAR_SKIP, NULL, NULL) == 0);
    RARCloseArchive(hrar);

    if (code == 22) {
        //test_rar_file_password(buf, archname, archpath);
        return;
    }
    if (code != 0) {
        g_object_unref(loader);
    }
}
void UnPackIntoSubdirActionTask::process(const volatile Flags &aborted, QString &error)
{
    QByteArray fileName;
    IFileContainer::Holder destination;
    Tryier tryier(this, &UnPackIntoSubdirActionTask::askForSkipIfNotCopy, aborted);

    int res;
    void *archive;
    struct RARHeaderDataEx fileInfo;
    struct RAROpenArchiveDataEx archiveData;

    m_aborted = &aborted;

    for (AsyncAction::FilesList::size_type i = 0, size = files().size(); i < size && !aborted; ++i)
        if (tryier.tryTo(CreateDestination(m_container, m_file = files().at(i).second, destination)))
        {
            fileName = m_container->location(m_file);

            memset(&archiveData, 0, sizeof(struct RAROpenArchiveDataEx));

            archiveData.ArcName = fileName.data();
            archiveData.OpenMode = RAR_OM_EXTRACT;

            if (archive = RAROpenArchiveEx(&archiveData))
            {
                RARSetCallback(archive, callbackProc, (long)this);

                while ((res = RARReadHeaderEx(archive, &fileInfo)) == 0 && !aborted)
                {
                    if ((res = RARProcessFile(archive, RAR_EXTRACT, const_cast<char *>(destination->location().as<QByteArray>().data()), NULL)) != 0)
                        break;
                }

                if (!aborted && res != ERAR_END_ARCHIVE)
                    error = Scanner::errorDescription(res);

                RARCloseArchive(archive);
            }
        }
}
Ejemplo n.º 6
0
Archivo: unrar.c Proyecto: layus/Os
int
unrar_test_password(const char * file, const char * pwd) 
{
        void                      * unrar;
        struct RARHeaderData        headerdata;
        struct RAROpenArchiveData   archivedata;
        int                         password_incorrect;

        password_incorrect = 0;
        memset(&headerdata, 0, sizeof(headerdata));
        memset(&archivedata, 0, sizeof(archivedata));
        archivedata.ArcName  = (char *) file;
        archivedata.OpenMode = RAR_OM_EXTRACT;

        unrar = RAROpenArchive(&archivedata);
        if (!unrar || archivedata.OpenResult)
                return -2;

        RARSetPassword(unrar, (char *) pwd);

        RARSetCallback(unrar, _unrar_test_password_callback, (long) &password_incorrect);

        if (RARReadHeader(unrar, &headerdata) != 0)
                goto error;

        if (RARProcessFile(unrar, RAR_TEST, NULL, NULL) != 0)
                goto error;

        if (password_incorrect)
                goto error;

        RARCloseArchive(unrar);
        return 0;

error:
        RARCloseArchive(unrar);
        return -1;
}
JNIEXPORT jbyteArray JNICALL Java_net_kervala_comicsreader_RarFile_nativeGetData(JNIEnv *env, jclass, jstring jFilename, jstring jEntry)
{
	jbyteArray ret = NULL;

	const char *filename = env->GetStringUTFChars(jFilename, NULL);
	const char *entry = env->GetStringUTFChars(jEntry, NULL);

	RAROpenArchiveData data;
	memset(&data, 0, sizeof(RAROpenArchiveData));

	data.ArcName = (char*)filename;
	data.OpenMode = RAR_OM_EXTRACT;

	HANDLE handle = RAROpenArchive(&data);

	if (handle && !data.OpenResult)
	{
		RARHeaderData header;
		memset(&header, 0, sizeof(RARHeaderData));

		// process each entry
		while (RARReadHeader(handle, &header) == 0)
		{
			// check if we must process this entry
			if (strcmp(header.FileName, entry) == 0)
			{
				// set buffer related variables
				Buffer buffer(header.UnpSize);

				RARSetCallback(handle, callbackData, (LPARAM)&buffer);

				// don't use RAR_EXTRACT because files will be extracted in current directory
				int result = RARProcessFile(handle, RAR_TEST, NULL, NULL);

				if (result)
				{
					LOGE("Unable to process %s, error: %d", header.FileName, result);
				}
				else
				{
					// allocates a new Java buffer
					ret = env->NewByteArray(buffer.getSize());

					// copy C++ buffer data to Java buffer
					env->SetByteArrayRegion(ret, 0, buffer.getSize(), (jbyte *)buffer.getAddress());

					// exit if file was correctly extracted
					break;
				}
			}
			else
			{
				// skip this entry
				int result = RARProcessFile(handle, RAR_SKIP, NULL, NULL);

				if (result)
				{
					LOGE("Unable to skip %s, error: %d", header.FileName, result);
				}
			}
		}

		RARCloseArchive(handle);
	}
	else
	{
		displayError(data.OpenResult, filename);
	}

	// release UTF-8 strings
	env->ReleaseStringUTFChars(jEntry, entry);
	env->ReleaseStringUTFChars(jFilename, filename);

	return ret;
}
Ejemplo n.º 8
0
JNIEXPORT jint JNICALL Java_com_aroma_unrartool_Unrar_RarOpenArchive
  (JNIEnv *env, jobject obj, jstring param2, jstring param3)
{
	//const char *filename = env->GetStringUTFChars(param2, NULL);
	char outbuf[255],extrPath[255];
	jstring jstr;
	int retresult=0;
	jclass cls = env->GetObjectClass(obj);
	jmethodID mid = env->GetMethodID(cls, "relayMessage", "(ILjava/lang/String;)V");
	if(mid == NULL)
		LOGE("Error retrieving methodID for %s \n", "relayMessage()");
	int len = env->GetStringLength( param2);
	env->GetStringUTFRegion( param2, 0, len, outbuf);
	len = env->GetStringLength( param3);
	env->GetStringUTFRegion( param3, 0, len, extrPath);
	LOGI("openning Archive: %s \n", outbuf);
	LOGI("==========================\n");
	LOGI("Extracting to :%s\n",extrPath);
	LOGI("==========================\n");
	RAROpenArchiveDataEx data;
    memset(&data, 0, sizeof(RAROpenArchiveDataEx));
	 memset(&environment, 0, sizeof(Environment));

    data.ArcName = (char*)outbuf;//filename;
    data.OpenMode = RAR_OM_EXTRACT;
	HANDLE handle = RAROpenArchiveEx(&data);
	if (handle && !data.OpenResult)
	{
		environment.env=env;
		environment.obj=obj;
		RARSetCallback(handle,UnRarCallBack,(LPARAM)&environment);
		
		bool firstcheck=true;
		RARHeaderDataEx header;
		memset(&header, 0, sizeof(RARHeaderDataEx));
        int headererror=0 ;     
		while ((headererror=RARReadHeaderEx(handle, &header)) == 0)
		{  
			if(mid != NULL)
			{
				jstr = env->NewStringUTF(header.FileName);
				if (jstr != NULL) {
						
					env->CallVoidMethod(obj, mid,0,jstr);
					env->DeleteLocalRef(jstr);
				}
				else
					LOGE("Unable to Create JString ,outofmemory error");/* out of memory */				   
			}
			int result = RARProcessFile(handle, RAR_EXTRACT, extrPath/*"/mnt/sdcard/unrartestfile"*/, NULL);
			if(firstcheck && (data.Flags & MHD_VOLUME))
			{
				LOGI("Archive is a Volume");
				if(header.UnpVer >=29 && (data.Flags & MHD_FIRSTVOLUME)==0)
				{
					LOGE("unrar from the wrong Volume");
					if(archivefirstVolume)
						env->SetBooleanField(obj, archivefirstVolume , false);
				}
				firstcheck=false;
			}

			if (result)
			{
				LOGE("Unable to process %s, error: %d", header.FileName, result);
				retresult=result;
				if(mid != NULL)
				{
					jstr = env->NewStringUTF(header.FileName);
					if (jstr != NULL) {
						
						env->CallVoidMethod(obj, mid,result,jstr);
						env->DeleteLocalRef(jstr);
					}
					else
	 					LOGE("Unable to Create JString ,outofmemory error");/* out of memory */				   
				}
				switch(result)
				{
					case ERAR_BAD_DATA :						
						break;
					case ERAR_BAD_ARCHIVE:						
						break;	
					case ERAR_UNKNOWN_FORMAT:						
						break;
					case ERAR_EOPEN:						
						break;
					case ERAR_ECREATE:						
						break;
					case ERAR_ECLOSE:						
						break;
					case ERAR_EREAD:						
						break;
					case ERAR_EWRITE:						
						break;
				}
			}
			else
			{
				//LOGI("Processing file: %s \n", header.FileName);
				/*if(mid != NULL)
				{
					jstr = env->NewStringUTF(header.FileName);
					if (jstr != NULL) {
						
						env->CallVoidMethod(obj, mid,0,jstr);
						env->DeleteLocalRef(jstr);
					}
					else
						LOGE("Unable to Create JString ,outofmemory error");			   
				}*/
			}
		}
        if(headererror==ERAR_BAD_DATA)	
		{
             LOGI("RARReadHeaderEx returned ERAR_BAD_DATA");
			 retresult= headererror;
		}
		if(headererror==ERAR_END_ARCHIVE)
			LOGI("RARReadHeaderEx returned ERAR_END_ARCHIVE");
		LOGI("RARReadHeaderEx returned %d",headererror);
		RARCloseArchive(handle);
	}
	else
	{
		printf("Error Code:%d \n",data.OpenResult);
		return displayError(data.OpenResult, outbuf);
		//return -1;
	}
	 //env->ReleaseStringUTFChars(param2, filename);

  LOGI("end of RarOpenArchive()");
  return retresult;
}
Ejemplo n.º 9
0
wxInputStream * ComicBookRAR::ExtractStream(wxUint32 pageindex)
{
	HANDLE rarFile;
	int RHCode = 0, PFCode = 0;
	struct RARHeaderDataEx header;
	struct RAROpenArchiveDataEx flags;
	
	wxString page = Filenames->Item(pageindex);
	size_t length = 0;
	
	rarFile = openRar(&flags, &header, RAR_OM_EXTRACT);

	if (password)
		RARSetPassword(rarFile, password);

	while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) {
#ifdef wxUSE_UNICODE
		if (page.IsSameAs(wxString(header.FileNameW))) {
#else // ASCII
		if (page.IsSameAs(header.FileName)) {
#endif
			length = header.UnpSize;
			break;	
		} else {
			if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) {
				closeRar(rarFile, &flags);
				throw ArchiveException(filename, ProcessFileError(PFCode, page));
			}
		}
	}
	
	if (length == 0) { // archived file not found
		closeRar(rarFile, &flags);
		throw new ArchiveException(filename, page + wxT(" not found in this archive."));
	}
	if (RHCode) {
		closeRar(rarFile, &flags);
		throw new ArchiveException(filename, OpenArchiveError(PFCode));
	}

	wxUint8 *buffer = new wxUint8[length];
	wxUint8 *callBackBuffer = buffer;

	RARSetCallback(rarFile, CallbackProc, (long) &callBackBuffer);

	PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL);

	closeRar(rarFile, &flags);
	
	if (PFCode != 0)
		throw new ArchiveException(filename, ProcessFileError(PFCode, page));

	return new wxMemoryInputStream(buffer, length);
}

bool ComicBookRAR::TestPassword()
{
	HANDLE rarFile;
	int RHCode = 0, PFCode = 0;
	struct RARHeaderDataEx header;
	struct RAROpenArchiveDataEx flags;
	bool passwordCorrect = true;
	
	wxString page = Filenames->Item(0); // test using the first page
	
	rarFile = openRar(&flags, &header, RAR_OM_EXTRACT);

	if (password)
		RARSetPassword(rarFile, password);

	while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) {
#ifdef wxUSE_UNICODE
		if (page.IsSameAs(wxString(header.FileNameW))) {
#else // ASCII
		if (page.IsSameAs(header.FileName)) {
#endif
			break;	
		} else {
			if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) {
				closeRar(rarFile, &flags);
				throw ArchiveException(filename, ProcessFileError(PFCode, page));
			}
		}
	}
	
	if (RHCode != 0) {
		closeRar(rarFile, &flags);
		throw new ArchiveException(filename, OpenArchiveError(RHCode));
	}

	RARSetCallback(rarFile, TestPasswordCallbackProc, (long) &passwordCorrect);
	PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL);

	closeRar(rarFile, &flags);

	// If the password is wrong, RARProcessFile will return ERAR_BAD_DATA.  Of
	// course, it will also return ERAR_BAD_DATA when the first file in the archive
	// is corrupted.  How does one tell the difference?
	if (PFCode == ERAR_BAD_DATA)
		return false;

	return passwordCorrect;
}

wxString ComicBookRAR::OpenArchiveError(int Error)
{
	wxString prefix = wxT("Could not open ") + filename;
	switch(Error) {
		case ERAR_NO_MEMORY:
			return wxString(prefix + wxT(": out of memory"));
		case ERAR_EOPEN:
			return prefix;
		case ERAR_BAD_ARCHIVE:
			return wxString(prefix + wxT(": it is not a valid RAR archive"));
		case ERAR_BAD_DATA:
			return wxString(prefix + wxT(": archive header broken"));
		case ERAR_UNKNOWN:
			return wxString(prefix + wxT(": unknown error"));
		default:
			return prefix;
	}
}
Ejemplo n.º 10
0
//Img *ImgBookRAR::ExtractStream(int pageindex, int aWidth, int aHeight)
GrPixbuf *ImgBookRAR::ExtractStream(int pageindex, int aWidth, int aHeight)
{
	HANDLE rarFile;
	int RHCode = 0, PFCode = 0;
	struct RARHeaderDataEx header;
	struct RAROpenArchiveDataEx flags;

	imagenes->setPos(pageindex);
	string page = imagenes->get();

	size_t length = 0;
	
	rarFile = openRar(filename, &flags, &header, RAR_OM_EXTRACT);

	while ((RHCode = RARReadHeaderEx(rarFile, &header)) == 0) 
	{
		if (page.compare(header.FileName) == 0) 
		{
			length = header.UnpSize;
			break;	
		} 
		else 
		{
			if ((PFCode = RARProcessFile(rarFile, RAR_SKIP, NULL, NULL)) != 0) 
			{
				closeRar(rarFile, &flags);
				string msg = ProcessFileError(PFCode, page);
				return NULL;
			}
		}
	}
	
	if (length == 0) 
	{ // archived file not found
		closeRar(rarFile, &flags);
		return NULL;
	}
	
	if (RHCode) 
	{
		closeRar(rarFile, &flags);
		return NULL;
	}

	unsigned char *buffer;
	unsigned char *callBackBuffer;
	buffer = new unsigned char[length];
	callBackBuffer = buffer;
	
	RARSetCallback(rarFile, CallbackProc, (long) &callBackBuffer);

	PFCode = RARProcessFile(rarFile, RAR_TEST, NULL, NULL);

	closeRar(rarFile, &flags);
	
	if (PFCode != 0)
	{
		return NULL;
	}	
	
//	Img *pageImg = getPixbuf((const guchar*)buffer, length, page);
	GrPixbuf *pageImg = getPixbuf((const guchar*)buffer, length, page, aWidth, aHeight); 

	delete[] buffer;
Ejemplo n.º 11
0
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);
}