Пример #1
0
static bool add_file(CTar32CmdInfo &cmdinfo, CTar32 *pTarfile, const char *fname,std::vector<char> &buffer)
{
	CTar32FileStatus &stat = pTarfile->m_currentfile_status;
	std::string fname2 = fname;

	EXTRACTINGINFOEX extractinfo;
	EXTRACTINGINFOEX64 exinfo64;
	MakeExtractingInfo(pTarfile,fname2.c_str(),extractinfo,exinfo64);
	{
		int ret = SendArcMessage(cmdinfo, ARCEXTRACT_BEGIN, &extractinfo,&exinfo64);
		if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);}
		// fname2 = extractinfo.exinfo.szDestFileName;
	}

	size64 filesize = pTarfile->m_currentfile_status.original_size;
	if(filesize == 0){return true;}
	CTar32InternalFile file; file.open(pTarfile, /*write*/true);


	//std::ifstream fs_r;
	fast_fstream fs_r;
	fs_r.open(fname2.c_str(), std::ios::in|std::ios::binary);
	if(fs_r.fail()){throw CTar32Exception("can't read file", ERROR_CANNOT_READ);return false;}

	size64 readsize = 0;
	size64 n;
	while(fs_r.read(&buffer[0],buffer.size()),(n=fs_r.gcount())>0){
		size64 m = file.write(&buffer[0], n);
		if(m>0){readsize += m;}
		if(n!=m){
			throw CTar32Exception("can't write to arcfile", ERROR_CANNOT_WRITE);
		}
//		if(cmdinfo.hTar32StatusDialog){
			extractinfo.exinfo.dwWriteSize = (DWORD)readsize;
			exinfo64.exinfo.dwWriteSize = (DWORD)readsize;
			exinfo64.llWriteSize = readsize;
			int ret = SendArcMessage(cmdinfo, ARCEXTRACT_INPROCESS, &extractinfo,&exinfo64);
			if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);}
//		}
	}
	bool bret = file.close();
	if(!bret){throw CTar32Exception("can't write to arcfile", ERROR_CANNOT_WRITE);}
//	if(cmdinfo.hTar32StatusDialog){
		extractinfo.exinfo.dwWriteSize = (DWORD)readsize;
		exinfo64.exinfo.dwWriteSize = (DWORD)readsize;
		exinfo64.llWriteSize = readsize;
		int ret = SendArcMessage(cmdinfo, 6, &extractinfo,&exinfo64);
		if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);}
//	}
	return true;
}
Пример #2
0
bool CTar32::extract(const char *fname_extract_to)
{
	std::string fname;
	if(fname_extract_to){
		fname = fname_extract_to;
	}else{
		fname = m_currentfile_status.filename;
	}
	size64 filesize = m_currentfile_status.original_size;
	const int buf_size = 4096;
	char buf[buf_size];

	CTar32InternalFile file;
	file.open(this);

	//string dirname = get_dirname(fname.c_str());
	//mkdir_recursive(dirname.c_str());
	mkdir_recursive(get_dirname(fname.c_str()).c_str());

	//std::ofstream fs_w;
	fast_fstream fs_w;
	fs_w.open(fname.c_str(), std::ios::out|std::ios::binary);
	if(fs_w.fail()){return false;}
	//FILE *fp_w = fopen(fname.c_str(), "wb");
	//if(fp_w == NULL){
	//	return false;
	//}
	size64 readsize = 0;
	while(filesize==-1 || readsize<filesize){
		size64 nextreadsize = (filesize==-1) ? buf_size : min(filesize-readsize,buf_size);
		size64 n = file.read(buf,nextreadsize);
		fs_w.write(buf,nextreadsize);
		if(fs_w.fail()){
			if(filesize==-1){
				return true;
			}else{
				return false;
			}
		}
		//fwrite(buf,1,ret,fp_w);
		readsize += n;
		if(n != nextreadsize){/*fclose(fp_w);*/return false;}
	}
	//fclose(fp_w);
	return true;
}
Пример #3
0
bool CTar32::readskip()
{
	CTar32InternalFile file;
	if(! file.open(this)){
		return false;
	}
	if(! file.close()){
		return false;
	}
#if 0
	int size;
	int ret;

	if(m_currentfile_status.size == 0){return true;}

	size = (((m_currentfile_status.size-1)/512)+1)*512;
	ret = m_pfile->seek(size, SEEK_CUR);
	if(ret == -1){return false;}
#endif
	return true;
}
Пример #4
0
bool extract_file(CTar32CmdInfo &cmdinfo, CTar32 *pTarfile, const char *fname,std::vector<char> &buffer)
{
	CTar32FileStatus &stat = pTarfile->m_currentfile_status;
	std::string fname2 = fname;

	EXTRACTINGINFOEX extractinfo;
	EXTRACTINGINFOEX64 exinfo64;
	MakeExtractingInfo(pTarfile,fname2.c_str(),extractinfo,exinfo64);
	{
		int ret = SendArcMessage(cmdinfo, ARCEXTRACT_BEGIN, &extractinfo,&exinfo64);
		if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);}
		fname2 = extractinfo.exinfo.szDestFileName;
	}

	//上書き確認
	if(cmdinfo.b_confirm_overwrite){
		switch(ConfirmOverwrite(cmdinfo, exinfo64)){
		case -1://cancel(abort)
			throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);
			break;
		case 1:	//yes to all
			cmdinfo.b_confirm_overwrite=false;
			break;
		}
	}

	size64 filesize = pTarfile->m_currentfile_status.original_size;

	CTar32InternalFile file; file.open(pTarfile);


	//std::ofstream fs_w;
	fast_fstream fs_w;
	if(!cmdinfo.b_print){
		mkdir_recursive(get_dirname(fname2.c_str()).c_str());
		fs_w.open(fname2.c_str(), std::ios::out|std::ios::binary);
		if(fs_w.fail()){return false;}
	}

	size64 readsize = 0;
	//static std::vector<char> buf;
	//const int bufsize=512*1024;
	//buf.resize(bufsize);
	const size_t bufsize=buffer.size();
	while(filesize ==-1 || readsize<filesize){
		size64 nextreadsize;
		if(filesize == -1){ // case ".gz",".Z",".bz2"
			//nextreadsize = sizeof(buf);
			nextreadsize=bufsize;
		}else{
			size64 nextreadsize64 = filesize-readsize;
			if(nextreadsize64 > bufsize){nextreadsize64 = bufsize;}
			nextreadsize = nextreadsize64;
			if(nextreadsize==0){
				Sleep(0);
			}
			// nextreadsize = (int)min(filesize-readsize, sizeof(buf));
		}
		if(nextreadsize==0){
			Sleep(0);
		}
		size64 n = file.read(&buffer[0],nextreadsize);
		readsize += n;
		if(cmdinfo.b_print){
			cmdinfo.output.write(&buffer[0],(size_t)n);	//TODO:size lost
		}else{
			fs_w.write(&buffer[0],n);
			if(fs_w.fail()){return false;}
		}
		if(n != nextreadsize){
			if(filesize == -1){ // case .gz/.Z/.bz2"
				break;
			}else{
				return false;
			}
		}
//		if(cmdinfo.hTar32StatusDialog){
			extractinfo.exinfo.dwWriteSize = (DWORD)readsize;
			exinfo64.exinfo.dwWriteSize = (DWORD)readsize;
			exinfo64.llWriteSize = readsize;
			int ret = SendArcMessage(cmdinfo, ARCEXTRACT_INPROCESS, &extractinfo,&exinfo64);
			if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);}
//		}
	}
	if(!cmdinfo.b_print){
		fs_w.close();
		struct _utimbuf ut;
		ut.actime = (stat.atime ? stat.atime : time(NULL));
		ut.modtime = (stat.mtime ? stat.mtime : time(NULL));
		int ret;
		ret = _utime(fname2.c_str(), &ut);
		ret = _chmod(fname2.c_str(), stat.mode);
	}
//	if(cmdinfo.hTar32StatusDialog){
		extractinfo.exinfo.dwWriteSize = (DWORD)readsize;
		exinfo64.exinfo.dwWriteSize = (DWORD)readsize;
		exinfo64.llWriteSize = readsize;
		int ret = SendArcMessage(cmdinfo, 6, &extractinfo,&exinfo64);
		if(ret){throw CTar32Exception("Cancel button was pushed.",ERROR_USER_CANCEL);}
//	}
	return true;
}
Пример #5
0
bool CTar32::readdir_AR(CTar32FileStatus &stat)
{
	if(m_filecount == 0){
		char magic[8];
		/*size64 ret = */m_pfile->read(magic,8);	/* skip "!<arch>\012" */
	}
	ar_hdr header;
	{
		size64 ret = m_pfile->read(&header,sizeof(header));
		if(ret == 0){return false;}
		if(ret != sizeof(header)){
			throw CTar32Exception("can't read tar header",ERROR_HEADER_BROKEN);
		}
		if(! header.magic_check()){
			throw CTar32Exception("tar header checksum error.",ERROR_HEADER_CRC);
		}
	}
	char *p = strchr(header.name,' '); *p = '\0';			// cut from ' '
	if(strcmp(header.name,"//")!=0 && p-1 > header.name && strrchr(header.name,'/') == p-1){ *(p-1) = '\0';}	// cut last '/'
	stat.filename = header.name;
	stat.mtime = strtol(header.date,NULL,10);
	stat.uid = strtol(header.uid,NULL,10);
	stat.gid = strtol(header.gid,NULL,10);
	stat.mode = strtol(header.mode,NULL,8);
	//TODO:ここは10進数解釈?
	stat.original_size = strtol(header.size,NULL,10);
	stat.blocksize		= 2;

	if(stat.filename == "/"){
		char buf[1000];
		sprintf(buf,"root%d",m_filecount);
		stat.filename = buf;
	}
	if(stat.filename == "//"){
		/* long file name support */
		CTar32InternalFile file;
		m_currentfile_status = stat;
		if(!file.open(this)){throw CTar32Exception("can't read tar header",ERROR_HEADER_BROKEN);}
		//longfilenames_buf = new char[stat.original_size]; // (char*)malloc(stat.original_size);
		longfilenames_buf.resize((unsigned int)stat.original_size+1);	//TODO:size lost
		size64 n = file.read(&longfilenames_buf[0],stat.original_size);
		if(n!=stat.original_size){throw CTar32Exception("can't read tar header",ERROR_HEADER_BROKEN);}
		file.close();

		longfilenames_buf[(unsigned int)stat.original_size]='\0';
		CTar32FileStatus nextstat;
		bool bRet = readdir(&nextstat); m_filecount --;
		stat = nextstat;
		//if(!bRet || stat.filename != "/0"){
		//	throw CTar32Exception("can't read tar header",ERROR_HEADER_BROKEN);
		//}
		//stat.filename = longfilename;
	}
	{
		/* if use longfilename, substitute "/\d+" to filename */
		int bytes; int num;
		int n = sscanf(stat.filename.c_str(), "/%d%n", &bytes, &num);
		int len = stat.filename.length();
		if(n == 1 && num == len && !longfilenames_buf.empty()){
			stat.filename = &longfilenames_buf[0]+bytes;
		}
	}
	return true;
}