/* * DownloadUnarchiveFile: Unarchive archive zip_name to given * directory. Return True on success. */ Bool DownloadUnarchiveFile(char *zip_name, char *dir) { Bool retval = True; // Does file exist? struct stat s; if (stat(zip_name, &s) != 0) { ClientError(hInst, hDownloadDialog, IDS_MISSINGARCHIVE, zip_name); return False; } while (1) { extraction_error = 0; TransferMessage(GetString(hInst, IDS_DECOMPRESSING)); ExtractArchive(zip_name, dir); if (extraction_error == 0) // This means the user hit the abort button break; if (!AreYouSure(hInst, hDownloadDialog, YES_BUTTON, IDS_CANTUNCOMPRESS, zip_name, GetString(hInst, extraction_error))) { retval = False; break; } } return retval; }
void CmdExtract::DoExtract(CommandData *Cmd) { PasswordCancelled=false; DataIO.SetCurrentCommand(*Cmd->Command); struct FindData FD; while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName))) if (FindFile::FastFind(ArcName,ArcNameW,&FD)) DataIO.TotalArcSize+=FD.Size; Cmd->ArcNames->Rewind(); while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName))) { while (true) { char PrevCmdPassword[MAXPASSWORD]; strcpy(PrevCmdPassword,Cmd->Password); EXTRACT_ARC_CODE Code=ExtractArchive(Cmd); /* restore Cmd->Password which could be changed in IsArchive() call for next header encrypted archive */ strcpy(Cmd->Password,PrevCmdPassword); if (Code!=EXTRACT_ARC_REPEAT) break; } if (FindFile::FastFind(ArcName,ArcNameW,&FD)) DataIO.ProcessedArcSize+=FD.Size; } if (TotalFileCount==0 && *Cmd->Command!='I') { if (!PasswordCancelled) { mprintf(St(MExtrNoFiles)); } ErrHandler.SetErrorCode(WARNING); } #ifndef GUI else if (!Cmd->DisableDone) { if (*Cmd->Command=='I') mprintf(St(MDone)); else if (ErrHandler.GetErrorCount()==0) mprintf(St(MExtrAllOk)); else mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount()); } #endif }
void CmdExtract::DoExtract() { #if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT) Fat32=NotFat32=false; #endif PasswordCancelled=false; DataIO.SetCurrentCommand(Cmd->Command[0]); FindData FD; while (Cmd->GetArcName(ArcName,ASIZE(ArcName))) if (FindFile::FastFind(ArcName,&FD)) DataIO.TotalArcSize+=FD.Size; Cmd->ArcNames.Rewind(); while (Cmd->GetArcName(ArcName,ASIZE(ArcName))) { if (Cmd->ManualPassword) Cmd->Password.Clean(); // Clean user entered password before processing next archive. while (true) { EXTRACT_ARC_CODE Code=ExtractArchive(); if (Code!=EXTRACT_ARC_REPEAT) break; } if (FindFile::FastFind(ArcName,&FD)) DataIO.ProcessedArcSize+=FD.Size; } // Clean user entered password. Not really required, just for extra safety. if (Cmd->ManualPassword) Cmd->Password.Clean(); if (TotalFileCount==0 && Cmd->Command[0]!='I' && ErrHandler.GetErrorCode()!=RARX_BADPWD) // Not in case of wrong archive password. { if (!PasswordCancelled) uiMsg(UIERROR_NOFILESTOEXTRACT,ArcName); ErrHandler.SetErrorCode(RARX_NOFILES); } #ifndef GUI else if (!Cmd->DisableDone) { if (Cmd->Command[0]=='I') mprintf(St(MDone)); else if (ErrHandler.GetErrorCount()==0) mprintf(St(MExtrAllOk)); else mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount()); } #endif }
void CmdExtract::DoExtract(CommandData *Cmd) { PasswordCancelled=false; DataIO.SetCurrentCommand(Cmd->Command[0]); FindData FD; while (Cmd->GetArcName(ArcName,ASIZE(ArcName))) if (FindFile::FastFind(ArcName,&FD)) DataIO.TotalArcSize+=FD.Size; Cmd->ArcNames.Rewind(); while (Cmd->GetArcName(ArcName,ASIZE(ArcName))) { while (true) { SecPassword PrevCmdPassword; PrevCmdPassword=Cmd->Password; EXTRACT_ARC_CODE Code=ExtractArchive(Cmd); // Restore Cmd->Password, which could be changed in IsArchive() call // for next header encrypted archive. Cmd->Password=PrevCmdPassword; if (Code!=EXTRACT_ARC_REPEAT) break; } if (FindFile::FastFind(ArcName,&FD)) DataIO.ProcessedArcSize+=FD.Size; } if (TotalFileCount==0 && Cmd->Command[0]!='I' && ErrHandler.GetErrorCode()!=RARX_BADPWD) // Not in case of wrong archive password. { if (!PasswordCancelled) { mprintf(St(MExtrNoFiles)); } ErrHandler.SetErrorCode(RARX_NOFILES); } #ifndef GUI else if (!Cmd->DisableDone) if (Cmd->Command[0]=='I') mprintf(St(MDone)); else if (ErrHandler.GetErrorCount()==0) mprintf(St(MExtrAllOk)); else mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount()); #endif }
int ZipRec_Main(int argc, _TCHAR* argv[]) { if (argc >= 3) { FileEx archive(argv[1]); if(archive.Open()) return ExtractArchive(&archive, argv[2]); } else _tprintf(_T("Usage: <archive> <out directory>\n")); return 0; }
bool EndlessISO::UnpackSquashFS(const CString & image, const CString & destination, UnpackProgressCallback callback, HANDLE cancelEvent) { FUNCTION_ENTER; // TODO: assumes the squashfs contains exactly one file with the correct name const CString destinationDir = CSTRING_GET_PATH(destination, L'\\'); auto extractor = SevenZip::SevenZipExtractor(pImpl->sevenZip, image.GetString()); extractor.SetCompressionFormat(SevenZip::CompressionFormat::SquashFS); auto cb = ProgressCallback(callback, cancelEvent); auto ret = extractor.ExtractArchive(destinationDir.GetString(), &cb); IFFALSE_RETURN_VALUE(ret, "ExtractArchive returned false", false); return true; }
void Dearchive(const char *dest_path, const char *zip_name) { char msg[500]; SetDlgItemText(hwndMain,IDC_STATUS,GetString(hInst, IDS_UNARCHIVING)); // Make sure archive is legal // Does file exist? struct stat s; if (stat(zip_name, &s) != 0) { SetDlgItemText(hwndMain,IDC_STATUS, GetString(hInst, IDS_MISSINGFILE)); return; } while (1) { extraction_error = 0; ExtractArchive(zip_name, dest_path); if (extraction_error == 0) { success = True; break; } sprintf(msg, GetString(hInst, IDS_CANTUNPACK), GetString(hInst, extraction_error)); if (MessageBox(hwndMain, msg, GetString(hInst, IDS_APPNAME), MB_YESNO) == IDNO) { SetDlgItemText(hwndMain,IDC_STATUS,GetString(hInst, IDS_DEARCHIVEERROR)); break; } } unlink(zip_name); if (success) { Status(GetString(hInst, IDS_RESTARTING)); PostMessage(hwndMain,WM_CLOSE,0,0); } }
void CmdExtract::DoExtract(CommandData *Cmd) { PasswordCancelled=false; DataIO.SetCurrentCommand(*Cmd->Command); struct FindData FD; while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName))) if (FindFile::FastFind(ArcName,ArcNameW,&FD)) DataIO.TotalArcSize+=FD.Size; Cmd->ArcNames->Rewind(); while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName))) { while (ExtractArchive(Cmd)==EXTRACT_ARC_REPEAT) ; if (FindFile::FastFind(ArcName,ArcNameW,&FD)) DataIO.ProcessedArcSize+=FD.Size; } if (TotalFileCount==0 && *Cmd->Command!='I') { if (!PasswordCancelled) { mprintf(St(MExtrNoFiles)); } ErrHandler.SetErrorCode(WARNING); } #ifndef GUI else if (!Cmd->DisableDone) if (*Cmd->Command=='I') mprintf(St(MDone)); else if (ErrHandler.GetErrorCount()==0) mprintf(St(MExtrAllOk)); else mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount()); #endif }
bool InstallFiles() { ButtonBar.Clear(); ButtonBar.AddButton("C", "Cancel"); ButtonBar.Draw(); char *msg; char *dbuttons[2] = { GetTranslation("Continue"), GetTranslation("Exit program") }; if ((InstallInfo.dest_dir_type == DEST_SELECT) || (InstallInfo.dest_dir_type == DEST_DEFAULT)) { msg = CreateText(GetTranslation("This will install %s to the following directory:\n%s\nContinue?"), InstallInfo.program_name.c_str(), MakeCString(InstallInfo.dest_dir)); } else { msg = CreateText(GetTranslation("This will install %s\nContinue?"), InstallInfo.program_name.c_str()); } CCDKDialog Diag(CDKScreen, CENTER, CENTER, msg, dbuttons, 2); Diag.SetBgColor(26); int sel = Diag.Activate(); Diag.Destroy(); refreshCDKScreen(CDKScreen); if (sel == 1) return false; CCDKSWindow InstallOutput(CDKScreen, 0, 6, GetDefaultHeight()-5, -1, CreateText("<C></29/B>%s", GetTranslation("Install output")), 2000); InstallOutput.SetBgColor(5); nodelay(WindowOf(InstallOutput.GetSWin()), true); // Make sure input doesn't block const int maxx = getmaxx(InstallOutput.GetSWin()->win); CCDKSWindow ProggWindow(CDKScreen, 0, 2, 5, maxx, NULL, 4); ProggWindow.SetBgColor(5); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (1/%d)", GetTranslation("Extracting files"), InstallInfo.command_entries.size()+1), true, BOTTOM, 24); CCDKHistogram ProgressBar(CDKScreen, 25, 3, 1, maxx-29, HORIZONTAL, CreateText("<C></29/B>%s", GetTranslation("Progress")), false); ProgressBar.SetBgColor(5); ProgressBar.SetHistogram(vPERCENT, TOP, 0, 100, 0, COLOR_PAIR (24) | A_REVERSE | ' ', A_BOLD); setCDKSwindowLLChar(ProggWindow.GetSWin(), ACS_LTEE); setCDKSwindowLRChar(ProggWindow.GetSWin(), ACS_RTEE); InstallOutput.Draw(); ProggWindow.Draw(); // Check if we need root access char *passwd = NULL; LIBSU::CLibSU SuHandler; SuHandler.SetUser("root"); SuHandler.SetTerminalOutput(false); bool askpass = false; for (std::list<command_entry_s *>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++) { if ((*it)->need_root != NO_ROOT) { // Command may need root permission, check if it is so if ((*it)->need_root == DEPENDED_ROOT) { param_entry_s *p = GetParamByVar((*it)->dep_param); if (p && !WriteAccess(p->value)) { (*it)->need_root = NEED_ROOT; if (!askpass) askpass = true; } } else if (!askpass) askpass = true; } } if (!askpass) askpass = !WriteAccess(InstallInfo.dest_dir); // Ask root password if one of the command entries need root access and root isn't passwordless if (askpass && SuHandler.NeedPassword()) { CCDKEntry entry(CDKScreen, CENTER, CENTER, GetTranslation("This installation requires root(administrator) privileges in order to continue\n" "Please enter the password of the root user"), "", 60, 0, 256, vHMIXED); entry.SetHiddenChar('*'); entry.SetBgColor(26); while(1) { char *sz = entry.Activate(); if ((entry.ExitType() != vNORMAL) || !sz || !sz[0]) { if (YesNoBox(GetTranslation("Root access is required to continue\nAbort installation?"))) EndProg(); refreshCDKScreen(CDKScreen); } else { if (SuHandler.TestSU(sz)) { passwd = strdup(sz); for (short s=0;s<strlen(sz);s++) sz[s] = 0; break; } for (short s=0;s<strlen(sz);s++) sz[s] = 0; entry.Clean(); // Some error appeared if (SuHandler.GetError() == LIBSU::CLibSU::SU_ERROR_INCORRECTPASS) { WarningBox(GetTranslation("Incorrect password given for root user\nPlease retype")); } else { throwerror(true, GetTranslation("Could not use su to gain root access\n" "Make sure you can use su(adding the current user to the wheel group may help)")); } } } // Restore screen entry.Destroy(); refreshCDKScreen(CDKScreen); } short percent = 0; bool alwaysroot = false; if (!WriteAccess(InstallInfo.dest_dir)) { CExtractAsRootFunctor Extracter; Extracter.SetUpdateProgFunc(SUUpdateProgress, &ProgressBar); Extracter.SetUpdateTextFunc(SUUpdateText, &InstallOutput); if (!Extracter(passwd)) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Error during extracting files"); } InstallOutput.AddText("Done!\n"); alwaysroot = true; // Install commands need root now too } else { while(percent<100) { std::string curfile; percent = ExtractArchive(curfile); InstallOutput.AddText("Extracting file: " + curfile, false); if (percent==100) InstallOutput.AddText("Done!", false); else if (percent==-1) throwerror(true, "Error during extracting files"); ProgressBar.SetValue(0, 100, percent/(1+InstallInfo.command_entries.size())); ProgressBar.Draw(); chtype input = getch(); if (input == 'c') { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } } SuHandler.SetThinkFunc(InstThinkFunc, passwd); SuHandler.SetOutputFunc(PrintInstOutput, &InstallOutput); percent = 100/(1+InstallInfo.command_entries.size()); // Convert to overall progress short step = 2; // Not 1, because extracting files is also a step for (std::list<command_entry_s*>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++, step++) { if ((*it)->command.empty()) continue; ProggWindow.Clear(); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (%d/%d)", GetTranslation((*it)->description.c_str()), step, InstallInfo.command_entries.size()+1), true, BOTTOM, 24); ProgressBar.Draw(); std::string command = (*it)->command + " " + GetParameters(*it); InstallOutput.AddText(""); InstallOutput.AddText(CreateText("Execute: %s", command.c_str())); InstallOutput.AddText(""); InstallOutput.AddText(""); if (((*it)->need_root == NEED_ROOT) || alwaysroot) { SuHandler.SetPath((*it)->path.c_str()); SuHandler.SetCommand(command); if (!SuHandler.ExecuteCommand(passwd)) { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "%s\n('%s')", GetTranslation("Failed to execute install command"), SuHandler.GetErrorMsgC()); } } } else { // Redirect stderr to stdout, so that errors will be displayed too command += " 2>&1"; setenv("PATH", (*it)->path.c_str(), 1); FILE *pipe = popen(command.c_str(), "r"); char term[1024]; if (pipe) { while (fgets(term, sizeof(term), pipe)) { InstallOutput.AddText(term); chtype input = getch(); if (input == 'c') /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } // Check if command exitted normally and close pipe int state = pclose(pipe); if (!WIFEXITED(state) || (WEXITSTATUS(state) == 127)) // SH returns 127 if command execution failes { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Failed to execute install command"); } } } else { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Could not execute installation commands (could not open pipe)"); } #if 0 // Need to find a good way to safely suspend a process...this code doesn't always work :( int pipefd[2]; pipe(pipefd); pid_t pid = fork(); if (pid == -1) throwerror(true, "Error during command execution: Could not fork process"); else if (pid) // Parent process { close(pipefd[1]); // We're not going to write here std::string out; char c; int compid = -1; // PID of the executed command while(read(pipefd[0], &c, sizeof(c)) > 0) { out += c; if (c == '\n') { if (compid == -1) { compid = atoi(out.c_str()); InstallOutput.AddText(CreateText("pid: %d compid: %d", pid, compid), false); } else InstallOutput.AddText(out, false); out.clear(); } chtype input = getch(); if (input != ERR) /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (kill(compid, SIGTSTP) < 0) // Pause command execution WarningBox("PID Error: %s\n", strerror(errno)); char *buttons[2] = { GetTranslation("Yes"), GetTranslation("No") }; CCharListHelper msg; msg.AddItem(GetTranslation("This will abort the installation")); msg.AddItem(GetTranslation("Are you sure?")); CCDKDialog dialog(CDKScreen, CENTER, CENTER, msg, msg.Count(), buttons, 2); dialog.SetBgColor(26); int ret = dialog.Activate(); bool cont = ((ret == 1) || (dialog.ExitType() != vNORMAL)); dialog.Destroy(); refreshCDKScreen(CDKScreen); if (!cont) { kill(pid, SIGTERM); EndProg(); } kill(compid, SIGCONT); // Continue command execution } } close (pipefd[0]); int status; //waitpid(pid, &status, 0); } else // Child process { // Redirect stdout to pipe close(STDOUT_FILENO); dup (pipefd[1]); close (pipefd[0]); // No need to read here // Make sure no errors are printed and write pid of new command command += " 2> /dev/null & echo $!"; execl("/bin/sh", "sh", "-c", command.c_str(), NULL); system(CreateText("echo %s", strerror(errno))); _exit(1); } #endif } percent += (1.0f/((float)InstallInfo.command_entries.size()+1.0f))*100.0f; ProgressBar.SetValue(0, 100, percent); } ProgressBar.SetValue(0, 100, 100); ProgressBar.Draw(); CleanPasswdString(passwd); passwd = NULL; ButtonBar.Clear(); ButtonBar.AddButton("Arrows", "Scroll install output"); ButtonBar.AddButton("Enter", (FileExists(InstallInfo.own_dir + "/config/finish")) ? "Continue" : "Finish"); // HACK ButtonBar.Draw(); WarningBox("Installation of %s complete!", InstallInfo.program_name.c_str()); InstallOutput.Activate(); return (InstallOutput.ExitType() == vNORMAL); }