akabeidelta.cpp 3.9 KB
Newer Older
Dario Freddi's avatar
Dario Freddi committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
   This file is part of the Chakra project

   Copyright (C) 2010 Dario Freddi <drf@chakra-project.org>

   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.
*/

#include "akabeidelta_p.h"
#include "akabeihelpers_p.h"
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#include "akabeiconfig.h"
#include <qdir.h>
#include <qtemporaryfile.h>
#include <archive_entry.h>
#include <qdebug.h>

QHash<QString, QString> extractArchive(const QString &path)
{
  struct archive *a;
  struct archive *ext;
  struct archive_entry *entry;
  int flags;
  int r;

  /* Select which attributes we want to restore. */
  flags = ARCHIVE_EXTRACT_TIME;
  flags |= ARCHIVE_EXTRACT_PERM;
  flags |= ARCHIVE_EXTRACT_ACL;
  flags |= ARCHIVE_EXTRACT_FFLAGS;

  a = archive_read_new();
  archive_read_support_format_all(a);
  archive_read_support_compression_all(a);
  ext = archive_write_disk_new();
  archive_write_disk_set_options(ext, flags);
  archive_write_disk_set_standard_lookup(ext);
  QHash<QString, QString> result;
  if ((r = archive_read_open_file(a, path.toStdString().c_str(), 10240)))
    return result;
  
  for (;;) {
    r = archive_read_next_header(a, &entry);
    if (r == ARCHIVE_EOF)
      break;
    QString name = archive_entry_pathname(entry);
    QString fileName = Akabei::Config::instance()->rootDir().absoluteFilePath("tmp/" + name);
    archive_entry_set_pathname(entry, fileName.toStdString().c_str());
    r = archive_write_header(ext, entry);
52 53
    if (archive_entry_size(entry) > 0) {
      r = archive_read_extract2(a, entry, ext);
54 55 56 57 58 59 60 61
      r = archive_write_finish_entry(ext);
    }
    result[name] = fileName;
  }
  archive_read_close(a);
  archive_read_finish(a);
  return result;
}
Dario Freddi's avatar
Dario Freddi committed
62

63 64
namespace Akabei
{
65
Delta::Delta(const QString& targetName, const QByteArray& versionFrom, const QByteArray& versionTo)
Dario Freddi's avatar
Dario Freddi committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    : d_ptr(new DeltaPrivate(targetName, versionFrom, versionTo))
{
}

Delta::~Delta()
{
    delete d_ptr;
}

bool Delta::checkMD5Sum()
{
    Q_D(Delta);

    if (d->_p_md5checked) {
        return true;
    }

Lukas Appelhans's avatar
Lukas Appelhans committed
83
    //FIXME: We should use the md5sum checker of Lisa here! :)
84
    // Check integrity
Dario Freddi's avatar
Dario Freddi committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    if (Helpers::md5sumOfFile(d->pathToDelta) != d->md5sum) {
        d->_p_md5checked = false;
    } else {
        d->_p_md5checked = true;
    }

    return d->_p_md5checked;
}

QString Delta::filename() const
{
    Q_D(const Delta);
    return d->filename;
}

QByteArray Delta::md5sum() const
{
    Q_D(const Delta);
    return d->md5sum;
}

QString Delta::pathToDelta() const
{
    Q_D(const Delta);
    return d->pathToDelta;
}

QString Delta::pathToSource() const
{
    Q_D(const Delta);
    return d->pathToOldFile;
}

void Delta::setPathToDelta(const QString& path)
{
    Q_D(Delta);
    d->pathToDelta = path;
}

void Delta::setPathToSource(const QString& path)
{
    Q_D(Delta);
    d->pathToOldFile = path;
}

QString Delta::targetName() const
{
    Q_D(const Delta);
    return d->name;
}

136
QByteArray Delta::versionFrom() const
Dario Freddi's avatar
Dario Freddi committed
137 138 139 140 141
{
    Q_D(const Delta);
    return d->vFrom;
}

142
QByteArray Delta::versionTo() const
Dario Freddi's avatar
Dario Freddi committed
143 144 145 146 147 148 149 150 151 152 153 154
{
    Q_D(const Delta);
    return d->vTo;
}

QString Delta::xdeltaApplyCommand(const QString& pathToDest) const
{
    Q_D(const Delta);

    if (pathToDest.isEmpty() || d->pathToDelta.isEmpty() || d->pathToOldFile.isEmpty()) {
        return QString();
    }
155 156 157
    
    QHash<QString, QString> files = extractArchive(d->pathToDelta);
    QString deltaPath = files.value(d->pathToDelta.split('/').last().remove(".tar.xz"));
Dario Freddi's avatar
Dario Freddi committed
158 159

    QString retstring;
160 161 162 163 164 165
    if (d->pathToDelta.endsWith(".gz")) {
        retstring = QString("xdelta3 -d -q -R -c -s %1 %2 | gzip -n > %3")
                            .arg(d->pathToOldFile).arg(d->pathToDelta).arg(pathToDest);
    } else {
        retstring = QString("xdelta3 -d -q -s %1 %2 %3").arg(d->pathToOldFile).arg(deltaPath).arg(pathToDest);
    }
Dario Freddi's avatar
Dario Freddi committed
166 167 168 169 170

    return retstring;
}

}
171