Logo Search packages:      
Sourcecode: dar version File versions

macro_tools.cpp

/*********************************************************************/
// dar - disk archive - a backup/restoration program
// Copyright (C) 2002-2052 Denis Corbin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// to contact the author : dar.linux@free.fr
/*********************************************************************/
// $Id: macro_tools.cpp,v 1.19.2.1 2005/02/05 09:34:13 edrusb Rel $
//
/*********************************************************************/

#include "../my_config.h"
#include "macro_tools.hpp"
#include "terminateur.hpp"
#include "user_interaction.hpp"
#include "zapette.hpp"
#include "sar.hpp"
#include "elastic.hpp"

using namespace std;

namespace libdar
{

    const dar_version macro_tools_supported_version = "04";
      // this is the archive version format generated by the application
      // this is also the highest version of format that can be read

    static void version_check(user_interaction & dialog, const header_version & ver);

    catalogue *macro_tools_get_catalogue_from(user_interaction & dialog, generic_file & f,
                                    const header_version & ver, compressor & zip,
                                    bool info_details, infinint &cat_size,
                                    generic_file *zip_base)
    {
        terminateur term;
        catalogue *ret;

        if(info_details)
            dialog.warning(gettext("Extracting contents of the archive..."));

      if(atoi(ver.edition) > 3)
          term.read_catalogue(*zip_base, (ver.flag & VERSION_FLAG_SCRAMBLED) != 0);
           // terminator is encrypted since format "04"
           // elastic buffer present when encryption is used
       else
           term.read_catalogue(f, false);
          // elastic buffer did not exist before format "04"

        if(zip.skip(term.get_catalogue_start()))
        {
            try
            {
                ret = new catalogue(dialog, zip, ver.edition, char2compression(ver.algo_zip), zip_base, &zip);
                contextual *ptr = dynamic_cast<contextual *>(&f);
                if(ptr != NULL)
                    ptr->set_info_status(CONTEXT_OP);
            }
            catch(Egeneric & e)
            {
                throw Erange("get_catalogue_from", string(gettext("Cannot open catalogue: ")) + e.get_message());
            }
            cat_size = zip.get_position() - term.get_catalogue_start();
        }
        else
            throw Erange("get_catalogue_from", gettext("Missing catalogue in file."));

        if(ret == NULL)
            throw Ememory("get_catalogue_from");

        return ret;
    }

    void macro_tools_open_archive(user_interaction & dialog,
                          const path &sauv_path,
                                  const string &basename,
                                  const string &extension,
                                  S_I options,
                          crypto_algo crypto,
                                  const string & pass,
                          U_32 crypto_size,
                                  generic_file *&ret1,
                                  generic_file *&scram,
                                  compressor *&ret2,
                                  header_version &ver,
                                  const string &input_pipe,
                                  const string &output_pipe,
                                  const string & execute)
    {
        generic_file *zip_base = NULL;
      string real_pass = pass;

        if(basename == "-")
        {
            tuyau *in = NULL;
            tuyau *out = NULL;

            try
            {
            tools_open_pipes(dialog, input_pipe, output_pipe, in, out);
                ret1 = new zapette(dialog, in, out);
                if(ret1 == NULL)
                {
                    delete in;
                    delete out;
                }
                else
                    in = out = NULL; // now managed by the zapette
            }
            catch(...)
            {
                if(in != NULL)
                    delete in;
                if(out != NULL)
                    delete out;
                throw;
            }
        }
        else
            ret1 = new sar(dialog, basename, extension, options, sauv_path, execute);

        if(ret1 == NULL)
            throw Ememory("open_archive");

        ver.read(*ret1);

      if(((ver.flag & VERSION_FLAG_SCRAMBLED) != 0) && crypto == crypto_none)
          throw Erange("macro_tools_open_archive", tools_printf(gettext("The archive %S is encrypted and no encryption cypher has been given, cannot open archive."), &basename));

      if(crypto != crypto_none && pass == "")
          real_pass = dialog.get_string(tools_printf(gettext("Archive %S requires a password: "), &basename), false);

      switch(crypto)
      {
      case crypto_scrambling:
            scram = new scrambler(dialog, real_pass, *ret1);
          break;
      case crypto_blowfish:
          scram = new blowfish(dialog, crypto_size, real_pass, *ret1);
          break;
        case crypto_none:
            scram = NULL;
            zip_base = ret1;
          break;
      default:
          throw Erange("macro_tools_open_archive", gettext("Unknown encryption algorithm"));
        }

      if(crypto != crypto_none)
      {
            if(scram == NULL)
                throw Ememory("open_archive");
            zip_base = scram;
      }

        version_check(dialog, ver);
        ret2 = new compressor(dialog, char2compression(ver.algo_zip), *zip_base);
        if((ver.flag & VERSION_FLAG_SCRAMBLED) != 0)
            dialog.warning(gettext("Warning, this archive has been encrypted. A wrong key is not possible to detect, it would cause DAR to report the archive as corrupted\n"));

        if(ret2 == NULL)
        {
            delete ret1;
            throw Ememory("open_archive");
        }
    }

    catalogue *macro_tools_get_catalogue_from(user_interaction & dialog,
                                    const string &basename,
                                    const string &extension,
                                    crypto_algo crypto,
                                    const string & pass,
                                    U_32 crypto_size)
    {
        generic_file *ret1 = NULL;
        generic_file *scram = NULL;
        compressor *ret2 = NULL;
        header_version ver;
        string input_pipe, output_pipe, execute;
        catalogue *ret = NULL;
        infinint size;
        string chemin, base;

        input_pipe = output_pipe = execute = "";
        tools_split_path_basename(basename, chemin, base);
        if(chemin == "")
            chemin = ".";
        try
        {
            path where = chemin;
            macro_tools_open_archive(dialog, where, base, extension, SAR_OPT_DONT_ERASE, crypto, pass, crypto_size,
                                     ret1, scram, ret2, ver, input_pipe, output_pipe, execute);

            ret = macro_tools_get_catalogue_from(dialog, *ret1, ver, *ret2, false, size, scram != NULL ? scram : ret1);
        }
        catch(...)
        {
            if(ret1 != NULL)
                delete ret1;
            if(ret2 != NULL)
                delete ret2;
            if(scram != NULL)
                delete scram;
            if(ret != NULL)
                delete ret;
            throw;
        }
        if(ret1 != NULL)
            delete ret1;
        if(ret2 != NULL)
            delete ret2;
        if(scram != NULL)
            delete scram;

        return ret;
    }

    static void dummy_call(char *x)
    {
        static char id[]="$Id: macro_tools.cpp,v 1.19.2.1 2005/02/05 09:34:13 edrusb Rel $";
        dummy_call(id);
    }

    static void version_check(user_interaction & dialog, const header_version & ver)
    {
        if(atoi(ver.edition) > atoi(macro_tools_supported_version))
            dialog.pause(gettext("The format version of the archive is too high for that software version, try reading anyway?"));
    }

} // end of namespace

Generated by  Doxygen 1.6.0   Back to index