2 * Copyright (C) 2008 - 2016 The Geeqie Team
4 * Authors: Vladimir Nadvornik, Laurent Monin
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include <archive_entry.h>
39 #include "main-defines.h"
41 #include "ui-fileops.h"
43 /* Copied from the libarchive .repo. examples */
50 void msg(const char *m)
52 log_printf("Open Archive - libarchive error: %s \n", m);
55 void errmsg(const char *m)
59 m = "Error: No error description provided.\n";
64 int copy_data(struct archive *ar, struct archive *aw)
73 r = archive_read_data_block(ar, &buff, &size, &offset);
78 errmsg(archive_error_string(ar));
81 r = archive_write_data_block(aw, buff, size, offset);
84 errmsg(archive_error_string(ar));
90 gboolean extract(const char *filename, bool do_extract, int flags)
94 struct archive_entry *entry;
97 a = archive_read_new();
98 ext = archive_write_disk_new();
99 archive_write_disk_set_options(ext, flags);
100 archive_write_disk_set_standard_lookup(ext);
101 archive_read_support_filter_all(a);
102 archive_read_support_format_all(a);
104 if (filename != nullptr && strcmp(filename, "-") == 0)
108 if ((r = archive_read_open_filename(a, filename, 10240)))
110 errmsg(archive_error_string(a));
118 r = archive_read_next_header(a, &entry);
119 if (r == ARCHIVE_EOF)
125 errmsg(archive_error_string(a));
129 if (verbose && do_extract)
133 if (verbose || !do_extract)
135 msg(archive_entry_pathname(entry));
141 r = archive_write_header(ext, entry);
144 errmsg(archive_error_string(a));
149 r = copy_data(a, ext);
161 archive_read_close(a);
162 archive_read_free(a);
164 archive_write_close(ext);
165 archive_write_free(ext);
171 gchar *open_archive(const FileData *fd)
175 gchar *destination_dir;
179 destination_dir = g_build_filename(g_get_tmp_dir(), GQ_ARCHIVE_DIR, instance_identifier, fd->path, NULL);
181 if (!recursive_mkdir_if_not_exists(destination_dir, 0755))
183 log_printf("%s%s%s", _("Open Archive - Cannot create directory: "), destination_dir, "\n");
184 g_free(destination_dir);
188 current_dir = g_get_current_dir();
189 error = chdir(destination_dir);
192 log_printf("%s%s%s%s%s", _("Open Archive - Cannot change directory to: "), destination_dir, _("\n Error code: "), strerror(errno), "\n");
193 g_free(destination_dir);
198 flags = ARCHIVE_EXTRACT_TIME;
199 success = extract(fd->path, true, flags);
201 error = chdir(current_dir);
204 log_printf("%s%s%s%s%s", _("Open Archive - Cannot change directory to: "), current_dir, _("\n Error code: "), strerror(errno), "\n");
205 g_free(destination_dir);
213 g_free(destination_dir);
214 destination_dir = nullptr;
217 return destination_dir;
220 gchar *open_archive(const FileData *)
222 log_printf("%s", _("Warning: libarchive not installed"));
225 #endif /* HAVE_ARCHIVE */
226 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */