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; }
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; }
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; }
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; }
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; }