1 /*
2  *  Copyright (C) 2008 Giuseppe Torelli - <colossus73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  *  MA 02110-1301 USA.
18  */
19 
20 #include <string.h>
21 #include "zip.h"
22 #include "date_utils.h"
23 #include "main.h"
24 #include "string_utils.h"
25 #include "support.h"
26 #include "window.h"
27 
xa_zip_ask(XArchive * archive)28 void xa_zip_ask (XArchive *archive)
29 {
30 	gchar *sfx;
31 
32 	sfx = g_find_program_in_path("unzipsfx");
33 
34 	archive->can_test = TRUE;
35 	archive->can_extract = TRUE;
36 	archive->can_add = archiver[archive->type].is_compressor;
37 	archive->can_delete = archiver[archive->type].is_compressor;
38 	archive->can_sfx = (sfx && archiver[archive->type].is_compressor);
39 	archive->can_password = TRUE;
40 	archive->can_full_path[0] = TRUE;
41 	archive->can_full_path[1] = archiver[archive->type].is_compressor;
42 	archive->can_touch = TRUE;
43 	archive->can_overwrite = TRUE;
44 	archive->can_update[0] = TRUE;
45 	archive->can_update[1] = archiver[archive->type].is_compressor;
46 	archive->can_freshen[0] = TRUE;
47 	archive->can_freshen[1] = archiver[archive->type].is_compressor;
48 	archive->can_move = archiver[archive->type].is_compressor;
49 
50 	g_free(sfx);
51 }
52 
xa_zip_password_str(XArchive * archive)53 static gchar *xa_zip_password_str (XArchive *archive)
54 {
55 	if (archive->password)
56 		return g_strconcat(" -P", archive->password, NULL);
57 	else
58 		return g_strdup("");
59 }
60 
xa_zip_parse_output(gchar * line,XArchive * archive)61 static void xa_zip_parse_output (gchar *line, XArchive *archive)
62 {
63 	XEntry *entry = NULL;
64 
65 	gchar *filename;
66 	gpointer item[9];
67 	unsigned int linesize,n,a;
68 	gboolean encrypted,dir;
69 	guint64 size;
70 
71 	encrypted = dir = FALSE;
72 	if ((line[0] != '-') && (line[0] != 'd') && (line[0] != 'l') && (line[0] != '?'))
73 		return;
74 
75 	linesize = strlen(line);
76 
77 	/* permissions */
78 	for(n=0; n < linesize && line[n] == ' '; n++);
79 	a = n;
80 	for(; n < linesize && line[n] != ' '; n++);
81 
82 	line[n]='\0';
83 	item[5] = line + a;
84 	if ( (line+a)[0] == 'd')
85 		dir = TRUE;
86 	n++;
87 
88 	/* version */
89 	for(; n < linesize && line[n] == ' '; n++);
90 	a = n;
91 	for(; n < linesize && line[n] != ' '; n++);
92 
93 	line[n] = '\0';
94 	item[8] = line + a;
95 	n++;
96 
97 	/* OS */
98 	for(; n < linesize && line[n] == ' '; n++);
99 	a = n;
100 	for(; n < linesize && line[n] != ' '; n++);
101 
102 	line[n]='\0';
103 	item[7] = line + a;
104 	n++;
105 
106 	/* size */
107 	for(; n < linesize && line[n] == ' '; n++);
108 	a = n;
109 	for(; n < linesize && line[n] != ' '; n++);
110 
111 	line[n]='\0';
112 	item[0] = line + a;
113 	size = g_ascii_strtoull(item[0], NULL, 0);
114 	n++;
115 
116 	/* text/binary */
117 	for(; n < linesize && line[n] == ' '; n++);
118 	a = n;
119 	for(; n < linesize && line[n] != ' '; n++);
120 
121 	line[n]='\0';
122 	if ((line+a)[0] == 'B' || (line+a)[0] == 'T')
123 	{
124 		archive->has_password = TRUE;
125 		encrypted = TRUE;
126 	}
127 	n++;
128 
129 	/* compressed size */
130 	for(; n < linesize && line[n] == ' '; n++);
131 	a = n;
132 	for(; n < linesize && line[n] != ' '; n++);
133 
134 	line[n]='\0';
135 	item[1] = line + a;
136 	n++;
137 
138 	/* method */
139 	for(; n < linesize && line[n] == ' '; n++);
140 	a = n;
141 	for(; n < linesize && line[n] != ' '; n++);
142 
143 	line[n]='\0';
144 	item[6] = line + a;
145 	n++;
146 
147 	/* date */
148 	for(; n < linesize && line[n] == ' '; n++);
149 	a = n;
150 	for(; n < linesize && line[n] != ' '; n++);
151 
152 	line[n]='\0';
153 	item[3] = date_YY_MMM_DD(line + a);
154 	n++;
155 
156 	/* time */
157 	for(; n < linesize && line[n] == ' '; n++);
158 	a = n;
159 	for(; n < linesize && line[n] != ' '; n++);
160 
161 	line[n]='\0';
162 	item[4] = line + a;
163 	n++;
164 
165 	/* filename */
166 	line[linesize-1] = '\0';
167 	filename = line + n;
168 
169 	/* saving */
170 	if (size)
171 		item[2] = g_strdup_printf("%.1f%%", 100.0 - 100.0 * g_ascii_strtoull(item[1], NULL, 0) / size);
172 	else
173 		item[2] = g_strdup("-");
174 
175 	entry = xa_set_archive_entries_for_each_row(archive, filename, item);
176 
177 	if (entry)
178 	{
179 		if (dir)
180 			 entry->is_dir = TRUE;
181 
182 		entry->is_encrypted = encrypted;
183 
184 		if (!entry->is_dir)
185 			archive->files++;
186 
187 		archive->files_size += size;
188 	}
189 
190 	g_free(item[2]);
191 }
192 
xa_zip_list(XArchive * archive)193 void xa_zip_list (XArchive *archive)
194 {
195 	const GType types[] = {GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_UINT64, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER};
196 	const gchar *titles[] = {_("Original Size"), _("Compressed"), _("Saving"), _("Date"), _("Time"), _("Permissions"), _("Method"), _("OS"), _("Version")};
197 	guint i;
198 
199 	gchar *command = g_strconcat(archiver[archive->type].program[0], " -Z -l ", archive->path[1], NULL);
200 	archive->files_size  = 0;
201 	archive->files = 0;
202 	archive->parse_output = xa_zip_parse_output;
203 	xa_spawn_async_process (archive,command);
204 	g_free ( command );
205 
206 	archive->columns = 12;
207 	archive->size_column = 2;
208 	archive->column_types = g_malloc0(sizeof(types));
209 
210 	for (i = 0; i < archive->columns; i++)
211 		archive->column_types[i] = types[i];
212 
213 	xa_create_liststore(archive, titles);
214 }
215 
xa_zip_test(XArchive * archive)216 void xa_zip_test (XArchive *archive)
217 {
218 	gchar *password_str, *command;
219 
220 	password_str = xa_zip_password_str(archive);
221 	command = g_strconcat(archiver[archive->type].program[0], " -t", password_str, " ", archive->path[1], NULL);
222 	g_free(password_str);
223 
224 	xa_run_command(archive, command);
225 	g_free(command);
226 }
227 
xa_zip_extract(XArchive * archive,GSList * file_list)228 gboolean xa_zip_extract (XArchive *archive, GSList *file_list)
229 {
230 	GString *files;
231 	gchar *password_str, *command;
232 	gboolean result;
233 
234 	files = xa_quote_filenames(file_list, "*?[]", TRUE);
235 	password_str = xa_zip_password_str(archive);
236 	command = g_strconcat(archiver[archive->type].program[0],
237 	                      archive->do_full_path ? "" : " -j",
238 	                      archive->do_touch ? " -DD" : "",
239 	                      archive->do_overwrite ? " -o" : (archive->do_update ? " -ou" : (archive->do_freshen ? " -of" : " -n")),
240 	                      password_str, " ",
241 	                      archive->path[1], files->str,
242 	                      " -d ", archive->extraction_dir, NULL);
243 	g_free(password_str);
244 	g_string_free(files,TRUE);
245 
246 	result = xa_run_command(archive, command);
247 	g_free(command);
248 
249 	return result;
250 }
251 
xa_zip_add(XArchive * archive,GSList * file_list,gchar * compression)252 void xa_zip_add (XArchive *archive, GSList *file_list, gchar *compression)
253 {
254 	GString *files;
255 	gchar *password_str, *command;
256 
257 	if (archive->location_path != NULL)
258 		archive->child_dir = g_strdup(archive->working_dir);
259 
260 	if (!compression)
261 		compression = "6";
262 
263 	files = xa_quote_filenames(file_list, NULL, TRUE);   // no escaping for adding!
264 	password_str = xa_zip_password_str(archive);
265 	command = g_strconcat(archiver[archive->type].program[1],
266 	                      archive->do_update ? " -ou" : "",
267 	                      archive->do_freshen ? " -of" : "",
268 	                      archive->do_move ? " -m" : "",
269 	                      " -", compression,
270 	                      password_str, " ",
271 	                      archive->path[1], files->str, NULL);
272 	g_free(password_str);
273 	g_string_free(files,TRUE);
274 
275 	xa_run_command(archive, command);
276 	g_free(command);
277 }
278 
xa_zip_delete(XArchive * archive,GSList * file_list)279 void xa_zip_delete (XArchive *archive, GSList *file_list)
280 {
281 	GString *files;
282 	gchar *command;
283 
284 	files = xa_quote_filenames(file_list, "*?[]", TRUE);
285 	command = g_strconcat(archiver[archive->type].program[1], " -d ", archive->path[1], files->str, NULL);
286 	g_string_free(files,TRUE);
287 
288 	xa_run_command(archive, command);
289 	g_free(command);
290 }
291