示例#1
0
/*
 * 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
}
示例#3
0
文件: extract.cpp 项目: KastB/OpenCPN
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
}
示例#4
0
文件: extract.cpp 项目: ikvm/mpc-hc
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
}
示例#5
0
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;
}
示例#6
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;
}
示例#7
0
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);
   }
}
示例#8
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
}
示例#9
0
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);
}