diff options
Diffstat (limited to 'src/utilities/archiveWriter.vala')
-rw-r--r-- | src/utilities/archiveWriter.vala | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/utilities/archiveWriter.vala b/src/utilities/archiveWriter.vala new file mode 100644 index 0000000..92bd31b --- /dev/null +++ b/src/utilities/archiveWriter.vala @@ -0,0 +1,139 @@ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// 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 3 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, see <http://www.gnu.org/licenses/>. +///////////////////////////////////////////////////////////////////////// + +namespace GnomePie { + +///////////////////////////////////////////////////////////////////////// +/// This class can be used to pack a directory of files recursively into +/// a *.tar.gz archive. +///////////////////////////////////////////////////////////////////////// + +public class ArchiveWriter : GLib.Object { + + private Archive.Write archive; + + ///////////////////////////////////////////////////////////////////// + /// Constructs a new ArchiveWriter + ///////////////////////////////////////////////////////////////////// + + public ArchiveWriter() { + this.archive = new Archive.Write(); + this.archive.add_filter_gzip(); + this.archive.set_format_pax_restricted(); + + } + + ///////////////////////////////////////////////////////////////////// + /// Call this once after you created the ArchiveWriter. Pass the + /// path to the target archive location. + ///////////////////////////////////////////////////////////////////// + + public bool open(string path) { + return this.archive.open_filename(path) == Archive.Result.OK; + } + + ///////////////////////////////////////////////////////////////////// + /// Adds all files of a given directory to the previously opened + /// archive. + ///////////////////////////////////////////////////////////////////// + + public bool add(string directory) { + return add_directory(directory, directory); + } + + ///////////////////////////////////////////////////////////////////// + /// When all files have been added, close the directory again. + ///////////////////////////////////////////////////////////////////// + + public void close() { + this.archive.close(); + } + + ///////////////////////////////////////////////////////////////////// + /// Private helper function which traveres a directory recursively. + ///////////////////////////////////////////////////////////////////// + + private bool add_directory(string directory, string relative_to) { + try { + var d = Dir.open(directory); + string name; + while ((name = d.read_name()) != null) { + string path = Path.build_filename(directory, name); + if (FileUtils.test(path, FileTest.IS_DIR)) { + if (!add_directory(path, relative_to)) { + return false; + } + + } else if (FileUtils.test(path, FileTest.IS_REGULAR)) { + if (!add_file(path, relative_to)) { + return false; + } + + } else { + warning("Packaging theme: Ignoring irregular file " + name); + } + } + } catch (Error e) { + warning (e.message); + return false; + } + + return true; + + } + + ///////////////////////////////////////////////////////////////////// + /// Private halper which adds a file to the archive. + ///////////////////////////////////////////////////////////////////// + + public bool add_file(string path, string relative_to) { + var entry = new Archive.Entry(); + entry.set_pathname(path.replace(relative_to, "")); + + Posix.Stat st; + Posix.stat(path, out st); + entry.copy_stat(st); + entry.set_size(st.st_size); + + if (this.archive.write_header(entry) == Archive.Result.OK) { + try { + var reader = File.new_for_path(path).read(); + uint8 buffer[4096]; + + var len = reader.read(buffer); + + while(len > 0) { + this.archive.write_data(buffer, len); + len = reader.read(buffer); + } + + this.archive.finish_entry(); + } catch (Error e) { + warning (e.message); + return false; + } + + } else { + warning("Failed to include file " + path + " into archive"); + return false; + } + + return true; + } +} + +} |