X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/95278287f4e1eeaf5d96749d6fc9bfc53fb400d0..769e9f3ea1cbe67d3b98e6db6c956abde2384868:/methods/rred.cc?ds=sidebyside diff --git a/methods/rred.cc b/methods/rred.cc index d2cefc943..51af37557 100644 --- a/methods/rred.cc +++ b/methods/rred.cc @@ -7,12 +7,13 @@ #include +#include #include #include -#include #include #include #include +#include "aptmethod.h" #include #include @@ -38,7 +39,7 @@ class MemBlock { char *free; MemBlock *next; - MemBlock(size_t size) : size(size), next(NULL) + explicit MemBlock(size_t size) : size(size), next(NULL) { free = start = new char[size]; } @@ -117,7 +118,7 @@ struct Change { size_t add_len; /* bytes */ char *add; - Change(size_t off) + explicit Change(size_t off) { offset = off; del_cnt = add_cnt = add_len = 0; @@ -489,7 +490,11 @@ class Patch { for (ch = filechanges.rbegin(); ch != filechanges.rend(); ++ch) { std::list::reverse_iterator mg_i, mg_e = ch; while (ch->del_cnt == 0 && ch->offset == 0) + { ++ch; + if (unlikely(ch == filechanges.rend())) + return; + } line -= ch->del_cnt; std::string buf; if (ch->add_cnt > 0) { @@ -529,10 +534,11 @@ class Patch { dump_mem(out, ch->add, ch->add_len, hash); } dump_rest(out, in, hash); + out.Flush(); } }; -class RredMethod : public pkgAcqMethod { +class RredMethod : public aptMethod { private: bool Debug; @@ -641,7 +647,7 @@ class RredMethod : public pkgAcqMethod { std::cerr << "FAILED to open inp " << Path << std::endl; return _error->Error("Failed to open inp %s", Path.c_str()); } - if (out.Open(Itm->DestFile, FileFd::WriteOnly | FileFd::Create, FileFd::Extension) == false) + if (out.Open(Itm->DestFile, FileFd::WriteOnly | FileFd::Create | FileFd::BufferedWrite, FileFd::Extension) == false) { std::cerr << "FAILED to open out " << Itm->DestFile << std::endl; return _error->Error("Failed to open out %s", Itm->DestFile.c_str()); @@ -653,6 +659,11 @@ class RredMethod : public pkgAcqMethod { out.Close(); inp.Close(); + if (_error->PendingError() == true) { + std::cerr << "FAILED to read or write files" << std::endl; + return false; + } + if (Debug == true) { std::clog << "rred: finished file patching of " << Path << "." << std::endl; } @@ -660,7 +671,7 @@ class RredMethod : public pkgAcqMethod { struct stat bufbase, bufpatch; if (stat(Path.c_str(), &bufbase) != 0 || stat(patch_name.c_str(), &bufpatch) != 0) - return _error->Errno("stat", _("Failed to stat")); + return _error->Errno("stat", _("Failed to stat %s"), Path.c_str()); struct timeval times[2]; times[0].tv_sec = bufbase.st_atime; @@ -670,7 +681,7 @@ class RredMethod : public pkgAcqMethod { return _error->Errno("utimes",_("Failed to set modification time")); if (stat(Itm->DestFile.c_str(), &bufbase) != 0) - return _error->Errno("stat", _("Failed to stat")); + return _error->Errno("stat", _("Failed to stat %s"), Itm->DestFile.c_str()); Res.LastModified = bufbase.st_mtime; Res.Size = bufbase.st_size; @@ -680,32 +691,29 @@ class RredMethod : public pkgAcqMethod { return true; } - bool Configuration(std::string Message) APT_OVERRIDE - { - if (pkgAcqMethod::Configuration(Message) == false) - return false; - - DropPrivsOrDie(); - - return true; - } - public: - RredMethod() : pkgAcqMethod("2.0",SingleInstance | SendConfig), Debug(false) {} + RredMethod() : aptMethod("rred", "2.0", SendConfig), Debug(false) {} }; int main(int argc, char **argv) { int i; bool just_diff = true; + bool test = false; Patch patch; if (argc <= 1) { - RredMethod Mth; - return Mth.Run(); + return RredMethod().Run(); } - if (argc > 1 && strcmp(argv[1], "-f") == 0) { + // Usage: rred -t input output diff ... + if (argc > 1 && strcmp(argv[1], "-t") == 0) { + // Read config files so we see compressors. + pkgInitConfig(*_config); + just_diff = false; + test = true; + i = 4; + } else if (argc > 1 && strcmp(argv[1], "-f") == 0) { just_diff = false; i = 2; } else { @@ -725,15 +733,24 @@ int main(int argc, char **argv) } } - if (just_diff) { + if (test) { + FileFd out, inp; + std::cerr << "Patching " << argv[2] << " into " << argv[3] << "\n"; + inp.Open(argv[2], FileFd::ReadOnly,FileFd::Extension); + out.Open(argv[3], FileFd::WriteOnly | FileFd::Create | FileFd::BufferedWrite, FileFd::Extension); + patch.apply_against_file(out, inp); + out.Close(); + } else if (just_diff) { FileFd out; out.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::Create); patch.write_diff(out); + out.Close(); } else { FileFd out, inp; - out.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::Create); + out.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly | FileFd::Create | FileFd::BufferedWrite); inp.OpenDescriptor(STDIN_FILENO, FileFd::ReadOnly); patch.apply_against_file(out, inp); + out.Close(); } return 0; }