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 "config.h"
21 #include <stdlib.h>
22 #include <string.h>
23 #include "main.h"
24 #include "7zip.h"
25 #include "add_dialog.h"
26 #include "ar.h"
27 #include "arj.h"
28 #include "cpio.h"
29 #include "extract_dialog.h"
30 #include "interface.h"
31 #include "lha.h"
32 #include "new_dialog.h"
33 #include "pref_dialog.h"
34 #include "rar.h"
35 #include "rpm.h"
36 #include "string_utils.h"
37 #include "support.h"
38 #include "tar.h"
39 #include "unar.h"
40 #include "window.h"
41 #include "zip.h"
42
43 #ifdef HAVE_SOCKET
44 #include "socket.h"
45 #endif
46
47 #define FUNC(cond1, func1, cond2, func2, cond3, func3) (cond1 ? func1 : (cond2 ? func2 : (cond3 ? func3 : NULL)))
48
49 GtkWidget *xa_main_window;
50
51 XArchiver archiver[XARCHIVETYPE_TYPES];
52
53 gchar *xdg_open;
54
55 Add_dialog_data *add_window;
56 Extract_dialog_data *extract_window;
57 Multi_extract_data *multi_extract_window;
58 Prefs_dialog_data *prefs_window;
59
60 static gchar *opt_extract_path, *opt_compress;
61 static gboolean opt_extract, opt_ensure_dir, opt_multi_extract, opt_add, opt_info, opt_version;
62
63 static GOptionEntry entries[] =
64 {
65 { "extract-to", 'x', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_FILENAME, &opt_extract_path,
66 N_("Extract archive to the destination\n directory and quit"),
67 N_("destination")
68 },
69 { "extract", 'e', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_extract,
70 N_("Extract archive by asking the extraction\n directory and quit"),
71 NULL
72 },
73 { "ensure-directory", 'd', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_ensure_dir,
74 N_("Extract archive to a containing directory\n and quit"),
75 NULL
76 },
77 { "multi-extract", 'm', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_multi_extract,
78 N_("Extract multiple archives by asking the\n extraction directory and quit"),
79 NULL
80 },
81 { "compress", 'c', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &opt_compress,
82 N_("Add the given files by asking the name of\n the archive and quit"),
83 N_("file1 ... fileN")
84 },
85 { "add", 'a', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_add,
86 N_("Add to archive by asking which files and\n quit"),
87 NULL
88 },
89 { "info", 'i', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_info,
90 N_("Show found command line programs to be\n used and exit"),
91 NULL
92 },
93 { "version", 'v', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_version,
94 N_("Show version and exit\n"), NULL },
95 { NULL }
96 };
97
xa_check_available_archivers()98 static void xa_check_available_archivers ()
99 {
100 XArchiveType type;
101 gchar *path, *cpio, *lbzip2, *lsar, *pbzip2, *pigz, *plzip, *sevenz, *unar, *xz, *zstd;
102 gboolean is7z = TRUE, is7za = TRUE, is7zr = TRUE, standard;
103
104 /* (un)compressors that can handle various types */
105
106 sevenz = g_find_program_in_path("7z");
107
108 if (!sevenz)
109 {
110 is7z = FALSE;
111 sevenz = g_find_program_in_path("7za");
112
113 if (!sevenz)
114 {
115 is7za = FALSE;
116 sevenz = g_find_program_in_path("7zr");
117
118 if (!sevenz)
119 is7zr = FALSE;
120 }
121 }
122
123 cpio = g_find_program_in_path("cpio");
124 lbzip2 = g_find_program_in_path("lbzip2");
125 lsar = g_find_program_in_path("lsar");
126 pbzip2 = g_find_program_in_path("pbzip2");
127 pigz = g_find_program_in_path("pigz");
128 plzip = g_find_program_in_path("plzip");
129 unar = g_find_program_in_path("unar");
130 xz = g_find_program_in_path("xz");
131 zstd = xa_gzip_et_al_check_zstd("zstd", "unzstd", &archiver[XARCHIVETYPE_ZSTD].is_compressor);
132
133 /* 7-zip */
134
135 type = XARCHIVETYPE_7ZIP;
136 path = sevenz;
137
138 standard = (path != NULL);
139
140 if (!standard)
141 {
142 if (lsar)
143 /* alternative ... */
144 path = g_strdup(lsar);
145 if (unar)
146 /* ... uncompressor */
147 archiver[type].program[1] = g_strdup(unar);
148 }
149
150 if (path)
151 {
152 archiver[type].program[0] = path;
153 archiver[type].is_compressor = standard;
154 archiver[type].type = g_slist_append(archiver[type].type, "7zip");
155 archiver[type].glob = g_slist_append(archiver[type].glob, "*.7z");
156 /* self-extracting Nullsoft Installer */
157 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('n'));
158 archiver[type].tags = g_slist_append(archiver[type].tags, _("Nullsoft Installer"));
159
160 archiver[type].ask = (standard ? xa_7zip_ask : xa_unar_ask);
161 archiver[type].list = (standard ? xa_7zip_list : xa_unar_list);
162 archiver[type].test = (standard ? xa_7zip_test : xa_unar_test);
163 archiver[type].extract = (standard ? xa_7zip_extract : (unar ? xa_unar_extract : NULL));
164 archiver[type].add = (standard ? xa_7zip_add : NULL);
165 archiver[type].delete = (standard ? xa_7zip_delete : NULL);
166 }
167
168 /* archiver */
169
170 type = XARCHIVETYPE_AR;
171 path = g_find_program_in_path("ar");
172
173 standard = (path != NULL);
174
175 if (!standard)
176 {
177 if (lsar && unar)
178 {
179 /* alternative ... */
180 path = g_strdup(lsar);
181 /* ... uncompressor */
182 archiver[type].program[1] = g_strdup(unar);
183 }
184 else if (is7z)
185 /* alternative uncompressor */
186 path = g_strconcat(sevenz, " -tar", NULL);
187 }
188
189 if (path)
190 {
191 archiver[type].program[0] = path;
192 archiver[type].type = g_slist_append(archiver[type].type, "ar");
193 archiver[type].glob = g_slist_append(archiver[type].glob, "*.a");
194 /* debian package */
195 archiver[type].type = g_slist_append(archiver[type].type, "deb");
196 archiver[type].glob = g_slist_append(archiver[type].glob, "*.deb");
197 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('d'));
198 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
199
200 archiver[type].ask = FUNC(standard, xa_ar_ask, lsar && unar, xa_unar_ask, is7z, xa_7zip_ask);
201 archiver[type].list = FUNC(standard, xa_ar_list, lsar && unar, xa_unar_list, is7z, xa_7zip_list);
202 archiver[type].extract = FUNC(standard, xa_ar_extract, lsar && unar, xa_unar_extract, is7z, xa_7zip_extract);
203 }
204
205 /* ARJ */
206
207 type = XARCHIVETYPE_ARJ;
208 path = g_find_program_in_path("arj");
209
210 if (path)
211 archiver[type].is_compressor = TRUE;
212 else
213 path = g_find_program_in_path("unarj");
214
215 standard = (path != NULL);
216
217 if (!standard)
218 {
219 if (is7z)
220 /* alternative uncompressor */
221 path = g_strconcat(sevenz, " -tarj", NULL);
222 else
223 {
224 if (lsar)
225 /* alternative ... */
226 path = g_strdup(lsar);
227 if (unar)
228 /* ... uncompressor */
229 archiver[type].program[1] = g_strdup(unar);
230 }
231 }
232
233 if (path)
234 {
235 archiver[type].program[0] = path;
236 archiver[type].type = g_slist_append(archiver[type].type, "arj");
237 archiver[type].glob = g_slist_append(archiver[type].glob, "*.arj");
238
239 archiver[type].ask = FUNC(standard, xa_arj_ask, is7z, xa_7zip_ask, lsar, xa_unar_ask);
240 archiver[type].list = FUNC(standard, xa_arj_list, is7z, xa_7zip_list, lsar, xa_unar_list);
241 archiver[type].test = FUNC(standard, xa_arj_test, is7z, xa_7zip_test, lsar, xa_unar_test);
242 archiver[type].extract = FUNC(standard, xa_arj_extract, is7z, xa_7zip_extract, unar, xa_unar_extract);
243 archiver[type].add = FUNC(standard, xa_arj_add, is7z, NULL, lsar, NULL);
244 archiver[type].delete = FUNC(standard, xa_arj_delete, is7z, NULL, lsar, NULL);
245 }
246
247 /* bzip2 */
248
249 type = XARCHIVETYPE_BZIP2;
250 path = g_find_program_in_path("bzip2");
251
252 if (path)
253 archiver[type].is_compressor = TRUE;
254 else
255 path = g_find_program_in_path("bunzip2");
256
257 standard = (path && archiver[type].is_compressor);
258
259 if (!standard)
260 {
261 if (lbzip2)
262 {
263 g_free(path);
264 /* alternative compressor */
265 path = g_strdup(lbzip2);
266 archiver[type].is_compressor = TRUE;
267 standard = TRUE;
268 }
269 else if (pbzip2)
270 {
271 g_free(path);
272 /* alternative compressor */
273 path = g_strdup(pbzip2);
274 archiver[type].is_compressor = TRUE;
275 standard = TRUE;
276 }
277 else if (is7za)
278 {
279 g_free(path);
280 /* alternative compressor */
281 path = g_strconcat(sevenz, " -tbzip2", NULL);
282 archiver[type].is_compressor = TRUE;
283 }
284 else if (!path)
285 {
286 if (lsar)
287 /* alternative ... */
288 path = g_strdup(lsar);
289 if (unar)
290 /* ... uncompressor */
291 archiver[type].program[1] = g_strdup(unar);
292 }
293 else
294 standard = TRUE;
295 }
296
297 if (path)
298 {
299 archiver[type].program[0] = path;
300 archiver[type].type = g_slist_append(archiver[type].type, "bzip2");
301 archiver[type].glob = g_slist_append(archiver[type].glob, "*.bz2");
302
303 archiver[type].ask = FUNC(standard, xa_gzip_et_al_ask, is7za, xa_7zip_ask, lsar, xa_unar_ask);
304 archiver[type].list = FUNC(standard, xa_gzip_et_al_list, is7za, xa_7zip_list, lsar, xa_unar_list);
305 archiver[type].test = FUNC(standard, xa_gzip_et_al_test, is7za, xa_7zip_test, lsar, xa_unar_test);
306 archiver[type].extract = FUNC(standard, xa_gzip_et_al_extract, is7za, xa_7zip_extract, unar, xa_unar_extract);
307 archiver[type].add = FUNC(standard, xa_gzip_et_al_add, is7za, xa_7zip_add, lsar, NULL);
308 }
309
310 /* compress */
311
312 type = XARCHIVETYPE_COMPRESS;
313 path = g_find_program_in_path("compress");
314
315 if (path)
316 archiver[type].is_compressor = TRUE;
317 else
318 path = g_find_program_in_path("uncompress");
319
320 standard = (path != NULL);
321
322 if (!standard)
323 {
324 if (is7za)
325 /* alternative uncompressor */
326 path = g_strconcat(sevenz, " -tZ", NULL);
327 else
328 {
329 if (lsar)
330 /* alternative ... */
331 path = g_strdup(lsar);
332 if (unar)
333 /* ... uncompressor */
334 archiver[type].program[1] = g_strdup(unar);
335 }
336 }
337
338 if (path)
339 {
340 archiver[type].program[0] = path;
341 archiver[type].type = g_slist_append(archiver[type].type, "compress");
342 archiver[type].glob = g_slist_append(archiver[type].glob, "*.Z");
343
344 archiver[type].ask = FUNC(standard, xa_gzip_et_al_ask, is7za, xa_7zip_ask, lsar, xa_unar_ask);
345 archiver[type].list = FUNC(standard, xa_gzip_et_al_list, is7za, xa_7zip_list, lsar, xa_unar_list);
346 archiver[type].test = FUNC(standard, xa_gzip_et_al_test, is7za, xa_7zip_test, lsar, NULL);
347 archiver[type].extract = FUNC(standard, xa_gzip_et_al_extract, is7za, xa_7zip_extract, unar, xa_unar_extract);
348 archiver[type].add = FUNC(standard, xa_gzip_et_al_add, is7za, NULL, lsar, NULL);
349 }
350
351 /* cpio */
352
353 type = XARCHIVETYPE_CPIO;
354 path = cpio;
355
356 standard = (path != NULL);
357
358 if (!standard)
359 {
360 if (is7z)
361 /* alternative uncompressor */
362 path = g_strconcat(sevenz, " -tcpio", NULL);
363 else
364 {
365 if (lsar)
366 /* alternative ... */
367 path = g_strdup(lsar);
368 if (unar)
369 /* ... uncompressor */
370 archiver[type].program[1] = g_strdup(unar);
371 }
372 }
373
374 if (path)
375 {
376 archiver[type].program[0] = path;
377 archiver[type].is_compressor = standard;
378 archiver[type].type = g_slist_append(archiver[type].type, "cpio");
379 archiver[type].glob = g_slist_append(archiver[type].glob, "*.cpio");
380
381 archiver[type].ask = FUNC(standard, xa_cpio_ask, is7z, xa_7zip_ask, lsar, xa_unar_ask);
382 archiver[type].list = FUNC(standard, xa_cpio_list, is7z, xa_7zip_list, lsar, xa_unar_list);
383 archiver[type].test = FUNC(standard, NULL, is7z, xa_7zip_test, lsar, NULL);
384 archiver[type].extract = FUNC(standard, xa_cpio_extract, is7z, xa_7zip_extract, unar, xa_unar_extract);
385 archiver[type].add = FUNC(standard, xa_cpio_add, is7z, NULL, lsar, NULL);
386 }
387
388 /* GNU zip */
389
390 type = XARCHIVETYPE_GZIP;
391 path = g_find_program_in_path("/usr/local/bin/gzip");
392
393 if (path)
394 archiver[type].is_compressor = TRUE;
395 else
396 path = g_find_program_in_path("gunzip");
397
398 standard = (path && archiver[type].is_compressor);
399
400 if (!standard)
401 {
402 if (pigz)
403 {
404 g_free(path);
405 /* alternative compressor */
406 path = g_strdup(pigz);
407 archiver[type].is_compressor = TRUE;
408 standard = TRUE;
409 }
410 else if (is7za)
411 {
412 g_free(path);
413 /* alternative compressor */
414 path = g_strconcat(sevenz, " -tgzip", NULL);
415 archiver[type].is_compressor = TRUE;
416 }
417 else if (!path)
418 {
419 if (lsar)
420 /* alternative ... */
421 path = g_strdup(lsar);
422 if (unar)
423 /* ... uncompressor */
424 archiver[type].program[1] = g_strdup(unar);
425 }
426 else
427 standard = TRUE;
428 }
429
430 if (path)
431 {
432 archiver[type].program[0] = path;
433 archiver[type].type = g_slist_append(archiver[type].type, "gzip");
434 archiver[type].glob = g_slist_append(archiver[type].glob, "*.gz");
435
436 archiver[type].ask = FUNC(standard, xa_gzip_et_al_ask, is7za, xa_7zip_ask, lsar, xa_unar_ask);
437 archiver[type].list = FUNC(standard, xa_gzip_et_al_list, is7za, xa_7zip_list, lsar, xa_unar_list);
438 archiver[type].test = FUNC(standard, xa_gzip_et_al_test, is7za, xa_7zip_test, lsar, xa_unar_test);
439 archiver[type].extract = FUNC(standard, xa_gzip_et_al_extract, is7za, xa_7zip_extract, unar, xa_unar_extract);
440 archiver[type].add = FUNC(standard, xa_gzip_et_al_add, is7za, xa_7zip_add, lsar, NULL);
441 }
442
443 /* LHA */
444
445 type = XARCHIVETYPE_LHA;
446 path = g_find_program_in_path("lha");
447
448 standard = (path != NULL);
449
450 if (!standard)
451 {
452 if (is7z)
453 /* alternative uncompressor */
454 path = g_strconcat(sevenz, " -tlzh", NULL);
455 else
456 {
457 if (lsar)
458 /* alternative ... */
459 path = g_strdup(lsar);
460 if (unar)
461 /* ... uncompressor */
462 archiver[type].program[1] = g_strdup(unar);
463 }
464 }
465
466 if (path)
467 {
468 archiver[type].program[0] = path;
469 archiver[type].is_compressor = (standard && xa_lha_check_program(path));
470 archiver[type].type = g_slist_append(archiver[type].type, "lha");
471 archiver[type].glob = g_slist_append(archiver[type].glob, "*.lzh");
472
473 archiver[type].ask = FUNC(standard, xa_lha_ask, is7z, xa_7zip_ask, lsar, xa_unar_ask);
474 archiver[type].list = FUNC(standard, xa_lha_list, is7z, xa_7zip_list, lsar, xa_unar_list);
475 archiver[type].test = FUNC(standard, xa_lha_test, is7z, xa_7zip_test, lsar, xa_unar_test);
476 archiver[type].extract = FUNC(standard, xa_lha_extract, is7z, xa_7zip_extract, unar, xa_unar_extract);
477 archiver[type].add = FUNC(standard, xa_lha_add, is7z, NULL, lsar, NULL);
478 archiver[type].delete = FUNC(standard, xa_lha_delete, is7z, NULL, lsar, NULL);
479 }
480
481 /* lrzip */
482
483 type = XARCHIVETYPE_LRZIP;
484 path = g_find_program_in_path("lrzip");
485
486 if (path)
487 archiver[type].is_compressor = TRUE;
488 else
489 path = g_find_program_in_path("lrunzip");
490
491 if (path)
492 {
493 xa_gzip_et_al_check_lrzip(path);
494
495 archiver[type].program[0] = path;
496 archiver[type].type = g_slist_append(archiver[type].type, "lrzip");
497 archiver[type].glob = g_slist_append(archiver[type].glob, "*.lrz");
498
499 archiver[type].ask = xa_gzip_et_al_ask;
500 archiver[type].list = xa_gzip_et_al_list;
501 archiver[type].test = xa_gzip_et_al_test;
502 archiver[type].extract = xa_gzip_et_al_extract;
503 archiver[type].add = xa_gzip_et_al_add;
504 }
505
506 /* lz4 */
507
508 type = XARCHIVETYPE_LZ4;
509 path = g_find_program_in_path("lz4");
510
511 if (path)
512 archiver[type].is_compressor = TRUE;
513 else
514 path = g_find_program_in_path("unlz4");
515
516 if (path)
517 {
518 archiver[type].program[0] = path;
519 archiver[type].type = g_slist_append(archiver[type].type, "lz4");
520 archiver[type].glob = g_slist_append(archiver[type].glob, "*.lz4");
521
522 archiver[type].ask = xa_gzip_et_al_ask;
523 archiver[type].list = xa_gzip_et_al_list;
524 archiver[type].test = xa_gzip_et_al_test;
525 archiver[type].extract = xa_gzip_et_al_extract;
526 archiver[type].add = xa_gzip_et_al_add;
527 }
528
529 /* lzip */
530
531 type = XARCHIVETYPE_LZIP;
532 path = g_find_program_in_path("lzip");
533
534 if (!path && plzip)
535 /* alternative compressor */
536 path = g_strdup(plzip);
537
538 if (path)
539 {
540 archiver[type].program[0] = path;
541 archiver[type].is_compressor = TRUE;
542 archiver[type].type = g_slist_append(archiver[type].type, "lzip");
543 archiver[type].glob = g_slist_append(archiver[type].glob, "*.lz");
544
545 archiver[type].ask = xa_gzip_et_al_ask;
546 archiver[type].list = xa_gzip_et_al_list;
547 archiver[type].test = xa_gzip_et_al_test;
548 archiver[type].extract = xa_gzip_et_al_extract;
549 archiver[type].add = xa_gzip_et_al_add;
550 }
551
552 /* lzma */
553
554 type = XARCHIVETYPE_LZMA;
555 path = g_find_program_in_path("lzma");
556
557 if (!path && xz)
558 /* alternative compressor */
559 path = g_strconcat(xz, " --format=lzma", NULL);
560
561 if (path)
562 archiver[type].is_compressor = TRUE;
563 else
564 path = g_find_program_in_path("unlzma");
565
566 standard = (path != NULL);
567
568 if (!standard)
569 {
570 if (is7zr)
571 /* alternative uncompressor */
572 path = g_strconcat(sevenz, " -tlzma", NULL);
573 else
574 {
575 if (lsar)
576 /* alternative ... */
577 path = g_strdup(lsar);
578 if (unar)
579 /* ... uncompressor */
580 archiver[type].program[1] = g_strdup(unar);
581 }
582 }
583
584 if (path)
585 {
586 archiver[type].program[0] = path;
587 archiver[type].type = g_slist_append(archiver[type].type, "lzma");
588 archiver[type].glob = g_slist_append(archiver[type].glob, "*.lzma");
589
590 archiver[type].ask = FUNC(standard, xa_gzip_et_al_ask, is7zr, xa_7zip_ask, lsar, xa_unar_ask);
591 archiver[type].list = FUNC(standard, xa_gzip_et_al_list, is7zr, xa_7zip_list, lsar, xa_unar_list);
592 archiver[type].test = FUNC(standard, xa_gzip_et_al_test, is7zr, xa_7zip_test, lsar, NULL);
593 archiver[type].extract = FUNC(standard, xa_gzip_et_al_extract, is7zr, xa_7zip_extract, unar, xa_unar_extract);
594 archiver[type].add = FUNC(standard, xa_gzip_et_al_add, is7zr, NULL, lsar, NULL);
595 }
596
597 /* lzop */
598
599 type = XARCHIVETYPE_LZOP;
600 path = g_find_program_in_path("lzop");
601
602 if (path)
603 archiver[type].is_compressor = TRUE;
604 else
605 path = g_find_program_in_path("unlzop");
606
607 if (path)
608 {
609 archiver[type].program[0] = path;
610 archiver[type].type = g_slist_append(archiver[type].type, "lzop");
611 archiver[type].glob = g_slist_append(archiver[type].glob, "*.lzo");
612
613 archiver[type].ask = xa_gzip_et_al_ask;
614 archiver[type].list = xa_gzip_et_al_list;
615 archiver[type].test = xa_gzip_et_al_test;
616 archiver[type].extract = xa_gzip_et_al_extract;
617 archiver[type].add = xa_gzip_et_al_add;
618 }
619
620 /* RAR */
621
622 type = XARCHIVETYPE_RAR;
623 path = g_find_program_in_path("rar");
624
625 if (path)
626 archiver[type].is_compressor = TRUE;
627 else
628 path = g_find_program_in_path("unrar");
629
630 if (path)
631 {
632 xa_rar_check_version(path);
633
634 if (!rar_version)
635 {
636 /* reject incompatible program */
637 g_free(path);
638 path = NULL;
639 }
640 }
641
642 standard = (path != NULL);
643
644 if (!standard)
645 {
646 if (is7z)
647 {
648 /* alternative uncompressor */
649 path = g_strconcat(sevenz, " -trar", NULL);
650 archiver[type].program[1] = g_strconcat(sevenz, " -trar5", NULL);
651 }
652 else
653 {
654 if (lsar)
655 /* alternative ... */
656 path = g_strdup(lsar);
657 if (unar)
658 /* ... uncompressor */
659 archiver[type].program[1] = g_strdup(unar);
660 }
661 }
662
663 if (path)
664 {
665 archiver[type].program[0] = path;
666 archiver[type].type = g_slist_append(archiver[type].type, "rar");
667 archiver[type].glob = g_slist_append(archiver[type].glob, "*.rar");
668
669 if (!standard || (rar_version >= 5))
670 {
671 archiver[type].type = g_slist_append(archiver[type].type, "rar5");
672 archiver[type].glob = g_slist_append(archiver[type].glob, " .rar");
673 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER(5));
674 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
675 }
676
677 archiver[type].ask = FUNC(standard, xa_rar_ask, is7z, xa_7zip_ask, lsar, xa_unar_ask);
678 archiver[type].list = FUNC(standard, xa_rar_list, is7z, xa_7zip_list, lsar, xa_unar_list);
679 archiver[type].test = FUNC(standard, xa_rar_test, is7z, xa_7zip_test, lsar, xa_unar_test);
680 archiver[type].extract = FUNC(standard, xa_rar_extract, is7z, xa_7zip_extract, unar, xa_unar_extract);
681 archiver[type].add = FUNC(standard, xa_rar_add, is7z, NULL, lsar, NULL);
682 archiver[type].delete = FUNC(standard, xa_rar_delete, is7z, NULL, lsar, NULL);
683 }
684
685 /* RPM package */
686
687 type = XARCHIVETYPE_RPM;
688 path = g_strdup(cpio);
689
690 standard = (path != NULL);
691
692 if (!standard)
693 {
694 if (is7z)
695 /* alternative uncompressor */
696 path = g_strconcat(sevenz, " -trpm", NULL);
697 else
698 {
699 if (lsar)
700 /* alternative ... */
701 path = g_strdup(lsar);
702 if (unar)
703 /* ... uncompressor */
704 archiver[type].program[1] = g_strdup(unar);
705 }
706 }
707
708 if (path)
709 {
710 archiver[type].program[0] = path;
711 archiver[type].type = g_slist_append(archiver[type].type, "rpm");
712 archiver[type].glob = g_slist_append(archiver[type].glob, "*.rpm");
713
714 archiver[type].ask = FUNC(standard, xa_rpm_ask, is7z, xa_7zip_ask, lsar, xa_unar_ask);
715 archiver[type].list = FUNC(standard, xa_rpm_list, is7z, xa_7zip_list, lsar, xa_unar_list);
716 archiver[type].test = FUNC(standard, NULL, is7z, xa_7zip_test, lsar, xa_unar_test);
717 archiver[type].extract = FUNC(standard, xa_rpm_extract, is7z, xa_7zip_extract, unar, xa_unar_extract);
718 }
719
720 /* tape archive */
721
722 type = XARCHIVETYPE_TAR;
723 path = g_find_program_in_path("gtar");
724
725 if (!path)
726 path = g_find_program_in_path("tar");
727
728 standard = (path != NULL);
729
730 if (!standard)
731 {
732 if (is7za)
733 /* alternative compressor */
734 path = g_strconcat(sevenz, " -ttar", NULL);
735 else
736 {
737 if (lsar)
738 /* alternative ... */
739 path = g_strdup(lsar);
740 if (unar)
741 /* ... uncompressor */
742 archiver[type].program[1] = g_strdup(unar);
743 }
744 }
745
746 if (path)
747 {
748 archiver[type].program[0] = path;
749 archiver[type].is_compressor = (standard || is7za);
750 archiver[type].type = g_slist_append(archiver[type].type, "tar");
751 archiver[type].glob = g_slist_append(archiver[type].glob, "*.tar");
752
753 archiver[type].ask = FUNC(standard, xa_tar_ask, is7za, xa_7zip_ask, lsar, xa_unar_ask);
754 archiver[type].list = FUNC(standard, xa_tar_list, is7za, xa_7zip_list, lsar, xa_unar_list);
755 archiver[type].test = FUNC(standard, NULL, is7za, xa_7zip_test, lsar, NULL);
756 archiver[type].extract = FUNC(standard, xa_tar_extract, is7za, xa_7zip_extract, unar, xa_unar_extract);
757 archiver[type].add = FUNC(standard, xa_tar_add, is7za, xa_7zip_add, lsar, NULL);
758 archiver[type].delete = FUNC(standard, xa_tar_delete, is7za, xa_7zip_delete, lsar, NULL);
759 }
760
761 /* xz */
762
763 type = XARCHIVETYPE_XZ;
764 path = xz;
765
766 if (path)
767 archiver[type].is_compressor = TRUE;
768 else
769 path = g_find_program_in_path("unxz");
770
771 standard = (path && archiver[type].is_compressor);
772
773 if (!standard)
774 {
775 if (is7zr)
776 {
777 g_free(path);
778 /* alternative compressor */
779 path = g_strconcat(sevenz, " -txz", NULL);
780 archiver[type].is_compressor = TRUE;
781 }
782 else if (!path)
783 {
784 if (lsar)
785 /* alternative ... */
786 path = g_strdup(lsar);
787 if (unar)
788 /* ... uncompressor */
789 archiver[type].program[1] = g_strdup(unar);
790 }
791 else
792 standard = TRUE;
793 }
794
795 if (path)
796 {
797 archiver[type].program[0] = path;
798 archiver[type].type = g_slist_append(archiver[type].type, "xz");
799 archiver[type].glob = g_slist_append(archiver[type].glob, "*.xz");
800
801 archiver[type].ask = FUNC(standard, xa_gzip_et_al_ask, is7zr, xa_7zip_ask, lsar, xa_unar_ask);
802 archiver[type].list = FUNC(standard, xa_gzip_et_al_list, is7zr, xa_7zip_list, lsar, xa_unar_list);
803 archiver[type].test = FUNC(standard, xa_gzip_et_al_test, is7zr, xa_7zip_test, lsar, xa_unar_test);
804 archiver[type].extract = FUNC(standard, xa_gzip_et_al_extract, is7zr, xa_7zip_extract, unar, xa_unar_extract);
805 archiver[type].add = FUNC(standard, xa_gzip_et_al_add, is7zr, xa_7zip_add, lsar, NULL);
806 }
807
808 /* zip */
809
810 type = XARCHIVETYPE_ZIP;
811
812 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs_window->prefer_unzip)) ||
813 (!is7za && !lsar))
814 {
815 path = g_find_program_in_path("/usr/local/bin/unzip");
816
817 if (path)
818 {
819 gchar *zip = g_find_program_in_path("/usr/local/bin/zip");
820
821 if (zip)
822 {
823 archiver[type].program[1] = zip;
824 archiver[type].is_compressor = TRUE;
825 }
826 }
827 }
828 else
829 path = NULL;
830
831 standard = (path && archiver[type].is_compressor);
832
833 if (!standard)
834 {
835 if (is7za)
836 {
837 g_free(path);
838 /* alternative compressor */
839 path = g_strconcat(sevenz, " -tzip", NULL);
840 archiver[type].is_compressor = TRUE;
841 }
842 else if (!path)
843 {
844 if (lsar)
845 /* alternative ... */
846 path = g_strdup(lsar);
847 if (unar)
848 /* ... uncompressor */
849 archiver[type].program[1] = g_strdup(unar);
850 }
851 else
852 standard = TRUE;
853 }
854
855 if (path)
856 {
857 archiver[type].program[0] = path;
858 archiver[type].type = g_slist_append(archiver[type].type, "zip");
859 archiver[type].glob = g_slist_append(archiver[type].glob, "*.zip");
860 /* Android application package */
861 archiver[type].type = g_slist_append(archiver[type].type, "apk");
862 archiver[type].glob = g_slist_append(archiver[type].glob, "*.apk");
863 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('a'));
864 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
865 /* comic book */
866 archiver[type].type = g_slist_append(archiver[type].type, "cbz");
867 archiver[type].glob = g_slist_append(archiver[type].glob, "*.cbz");
868 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('c'));
869 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
870 /* electronic publication */
871 archiver[type].type = g_slist_append(archiver[type].type, "epub");
872 archiver[type].glob = g_slist_append(archiver[type].glob, "*.epub");
873 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('e'));
874 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
875 /* java archive */
876 archiver[type].type = g_slist_append(archiver[type].type, "jar");
877 archiver[type].glob = g_slist_append(archiver[type].glob, "*.jar");
878 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('j'));
879 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
880 /* OpenOffice.org extension */
881 archiver[type].type = g_slist_append(archiver[type].type, "oxt");
882 archiver[type].glob = g_slist_append(archiver[type].glob, "*.oxt");
883 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('o'));
884 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
885 /* XPInstall */
886 archiver[type].type = g_slist_append(archiver[type].type, "xpi");
887 archiver[type].glob = g_slist_append(archiver[type].glob, "*.xpi");
888 archiver[type].tags = g_slist_append(archiver[type].tags, GUINT_TO_POINTER('x'));
889 archiver[type].tags = g_slist_append(archiver[type].tags, g_slist_last(archiver[type].type)->data);
890
891 archiver[type].ask = FUNC(standard, xa_zip_ask, is7za, xa_7zip_ask, lsar, xa_unar_ask);
892 archiver[type].list = FUNC(standard, xa_zip_list, is7za, xa_7zip_list, lsar, xa_unar_list);
893 archiver[type].test = FUNC(standard, xa_zip_test, is7za, xa_7zip_test, lsar, xa_unar_test);
894 archiver[type].extract = FUNC(standard, xa_zip_extract, is7za, xa_7zip_extract, unar, xa_unar_extract);
895 archiver[type].add = FUNC(standard, xa_zip_add, is7za, xa_7zip_add, lsar, NULL);
896 archiver[type].delete = FUNC(standard, xa_zip_delete, is7za, xa_7zip_delete, lsar, NULL);
897 }
898
899 /* Zstandard */
900
901 type = XARCHIVETYPE_ZSTD;
902 path = zstd; // either zstd or unzstd
903
904 if (path)
905 {
906 archiver[type].program[0] = path;
907 archiver[type].type = g_slist_append(archiver[type].type, "zstd");
908 archiver[type].glob = g_slist_append(archiver[type].glob, "*.zst");
909
910 archiver[type].ask = xa_gzip_et_al_ask;
911 archiver[type].list = xa_gzip_et_al_list;
912 archiver[type].test = xa_gzip_et_al_test;
913 archiver[type].extract = xa_gzip_et_al_extract;
914 archiver[type].add = xa_gzip_et_al_add;
915 }
916
917 /* compressed tar */
918
919 if (archiver[XARCHIVETYPE_TAR].ask == xa_tar_ask || archiver[XARCHIVETYPE_TAR].ask == xa_unar_ask)
920 {
921 struct
922 {
923 XArchiveType compressor;
924 gchar *type[2];
925 gchar *glob[2];
926 } compressed_tar_infos[] =
927 {
928 {XARCHIVETYPE_BZIP2, {"tar.bzip2", NULL}, {"*.tar.bz2", "*.tbz2"}},
929 {XARCHIVETYPE_COMPRESS, {"tar.compress", NULL}, {"*.tar.Z", ""}},
930 {XARCHIVETYPE_GZIP, {"tar.gzip", NULL}, {"*.tar.gz", "*.tgz"}},
931 {XARCHIVETYPE_LRZIP, {"tar.lrzip", NULL}, {"*.tar.lrz", "*.tlrz"}},
932 {XARCHIVETYPE_LZ4, {"tar.lz4", NULL}, {"*.tar.lz4", ""}},
933 {XARCHIVETYPE_LZIP, {"tar.lzip", NULL}, {"*.tar.lz", ""}},
934 {XARCHIVETYPE_LZMA, {"tar.lzma", NULL}, {"*.tar.lzma", "*.tlz"}},
935 {XARCHIVETYPE_LZOP, {"tar.lzop", NULL}, {"*.tar.lzo", "*.tzo"}},
936 {XARCHIVETYPE_XZ, {"tar.xz", NULL}, {"*.tar.xz", "*.txz"}},
937 {XARCHIVETYPE_ZSTD, {"tar.zstd", NULL}, {"*.tar.zst", "*.tzst"}},
938 {XARCHIVETYPE_UNKNOWN, {NULL, NULL}, {NULL, NULL}}
939 }, *i;
940
941 for (i = compressed_tar_infos; i->compressor != XARCHIVETYPE_UNKNOWN; i++)
942 {
943 if (archiver[i->compressor].type)
944 {
945 type = i->compressor;
946
947 if (!xa_get_compressed_tar_type(&type))
948 continue;
949
950 if ((archiver[XARCHIVETYPE_TAR].ask == xa_tar_ask && archiver[i->compressor].ask == xa_gzip_et_al_ask) ||
951 (archiver[XARCHIVETYPE_TAR].ask == xa_unar_ask && archiver[i->compressor].ask == xa_unar_ask))
952 {
953 archiver[type].is_compressor = archiver[i->compressor].is_compressor;
954 archiver[type].type = g_slist_append(archiver[type].type, i->type[0]);
955 archiver[type].glob = g_slist_append(archiver[type].glob, i->glob[0]);
956 archiver[type].type = g_slist_append(archiver[type].type, i->type[1]);
957 archiver[type].glob = g_slist_append(archiver[type].glob, i->glob[1]);
958
959 archiver[type].ask = archiver[XARCHIVETYPE_TAR].ask;
960 archiver[type].list = archiver[XARCHIVETYPE_TAR].list;
961 archiver[type].extract = archiver[XARCHIVETYPE_TAR].extract;
962 archiver[type].add = archiver[XARCHIVETYPE_TAR].add;
963 archiver[type].delete = archiver[XARCHIVETYPE_TAR].delete;
964 }
965 }
966 }
967 }
968
969 g_free(lbzip2);
970 g_free(lsar);
971 g_free(pbzip2);
972 g_free(pigz);
973 g_free(plzip);
974 g_free(unar);
975 }
976
xa_init_structure_from_cmd_line(char * filename)977 static XArchive *xa_init_structure_from_cmd_line (char *filename)
978 {
979 XArchive *archive;
980 ArchiveType xa;
981 gchar *path;
982
983 xa = xa_detect_archive_type(filename);
984
985 if (xa.type == XARCHIVETYPE_UNKNOWN || xa.type == XARCHIVETYPE_NOT_FOUND)
986 return NULL;
987
988 if (!archiver[xa.type].list)
989 {
990 xa_show_message_dialog(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Sorry, this archive format is not supported:"), _("The proper archiver is not installed!"));
991 return NULL;
992 }
993
994 archive = xa_init_archive_structure(xa);
995
996 if (archive == NULL)
997 {
998 xa_show_message_dialog (NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,_("Can't allocate memory for the archive structure!"),"" );
999 return NULL;
1000 }
1001
1002 if (*filename != '/')
1003 {
1004 gchar *cur_dir = g_get_current_dir();
1005 path = g_strconcat(cur_dir, "/", filename, NULL);
1006 g_free(cur_dir);
1007 }
1008 else
1009 path = g_strdup(filename);
1010
1011 archive->path[0] = g_strdup(path);
1012 archive->path[1] = xa_escape_bad_chars(path, ESCAPES);
1013
1014 g_free(path);
1015
1016 return archive;
1017 }
1018
xa_cmd_line_error(const char * argv1,const gchar * header)1019 static void xa_cmd_line_error (const char *argv1, const gchar *header)
1020 {
1021 if (argv1)
1022 xa_show_message_dialog(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, header, _("Can't open the archive!\n"));
1023 else
1024 xa_show_message_dialog(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, header, _("You missed the archive name!\n"));
1025 }
1026
main(int argc,char ** argv)1027 int main (int argc, char **argv)
1028 {
1029 GError *cli_error = NULL;
1030 XArchive *archive;
1031 gchar *current_dir;
1032 int i, result = -1;
1033
1034 #ifdef ENABLE_NLS
1035 GTK_COMPAT_PARAMETER_STRING;
1036 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
1037 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1038 textdomain (GETTEXT_PACKAGE);
1039 #endif
1040
1041 #ifdef HAVE_SOCKET
1042 socket_info.lock_socket = -1;
1043 socket_info.lock_socket_tag = 0;
1044 socket_info.lock_socket = socket_init(argc, argv);
1045
1046 if (socket_info.lock_socket < 0)
1047 {
1048 /* Socket exists; filenames were sent to first instance, so quit */
1049 if (argc > 1)
1050 return 0;
1051 }
1052 #endif
1053 gtk_init_with_args(&argc, &argv, _("[ARCHIVE]"), entries, GETTEXT_PACKAGE, &cli_error);
1054
1055 if ( cli_error != NULL )
1056 {
1057 g_print (_("xarchiver: %s\nTry xarchiver --help to see a full list of available command line options.\n"),cli_error->message);
1058 g_error_free (cli_error);
1059 return 0;
1060 }
1061 /* print version information */
1062 if (opt_version)
1063 {
1064 g_print("%s %s \n\n", PACKAGE_NAME, PACKAGE_VERSION);
1065 g_print (_("Maintained by "));
1066 g_print (MAINTAINER ".\n\n");
1067 g_print ("%s\n", "Copyright (c) " COPYRIGHT_YEAR);
1068 g_print ("\t%s\n\n", COPYRIGHT_HOLDER " - Colossus <colossus73@gmail.com>");
1069 g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
1070 g_print ("\n");
1071
1072 return EXIT_SUCCESS;
1073 }
1074
1075 xdg_open = g_find_program_in_path("xdg-open");
1076
1077 prefs_window = xa_create_prefs_dialog();
1078 extract_window = xa_create_extract_dialog();
1079 add_window = xa_create_add_dialog();
1080 multi_extract_window = xa_create_multi_extract_dialog();
1081
1082 xa_prefs_load_options(prefs_window);
1083 xa_check_available_archivers();
1084 xa_prefs_adapt_options(prefs_window);
1085
1086 if (opt_extract || opt_extract_path || opt_ensure_dir || opt_multi_extract || opt_add || opt_compress || opt_info)
1087 {
1088 archive = xa_init_structure_from_cmd_line (argv[1]);
1089 g_print(PACKAGE_NAME " 0.5.4 \xC2\xA9 " COPYRIGHT_YEAR " " COPYRIGHT_HOLDER "\n");
1090 g_print(PACKAGE_NAME " %-8s " MAINTAINER "\n", VERSION);
1091
1092 /* Switches -d and -x */
1093 if (opt_ensure_dir || opt_extract_path)
1094 {
1095 gchar *extraction_dir = NULL;
1096
1097 if (!archive)
1098 {
1099 xa_cmd_line_error(argv[1], _("Can't extract files from the archive:"));
1100 goto leave;
1101 }
1102
1103 if (!archive->can_extract)
1104 {
1105 xa_show_message_dialog(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Can't extract files from the archive:"), argv[1]);
1106 goto leave;
1107 }
1108
1109 xa_detect_encrypted_archive(archive);
1110
1111 if (archive->status == XARCHIVESTATUS_ERROR)
1112 goto leave;
1113
1114 if (archive->has_password)
1115 {
1116 if (!xa_check_password(archive))
1117 goto leave;
1118 }
1119
1120 if (opt_ensure_dir)
1121 {
1122 current_dir = g_get_current_dir();
1123
1124 if (xa_has_containing_directory(archive))
1125 extraction_dir = g_strdup(current_dir);
1126 else
1127 {
1128 extraction_dir = xa_create_containing_directory(archive, current_dir);
1129
1130 if (!extraction_dir)
1131 {
1132 xa_show_message_dialog(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Can't create directory!"), "");
1133 g_free(current_dir);
1134 goto leave;
1135 }
1136 }
1137
1138 opt_extract_path = extraction_dir;
1139 g_free(current_dir);
1140 }
1141
1142 archive->do_full_path = TRUE;
1143 archive->do_overwrite = TRUE;
1144 archive->extraction_dir = xa_escape_bad_chars(opt_extract_path, ESCAPES);
1145 g_free(extraction_dir);
1146
1147 archive->status = XARCHIVESTATUS_EXTRACT;
1148 (*archive->archiver->extract)(archive, NULL);
1149 }
1150 /* Switch -e */
1151 else if (opt_extract)
1152 {
1153 if (!archive)
1154 {
1155 xa_cmd_line_error(argv[1], _("Can't extract files from the archive:"));
1156 goto leave;
1157 }
1158
1159 if (!archive->can_extract)
1160 {
1161 xa_show_message_dialog(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Can't extract files from the archive:"), argv[1]);
1162 goto leave;
1163 }
1164
1165 xa_detect_encrypted_archive(archive);
1166
1167 if (archive->status == XARCHIVESTATUS_ERROR)
1168 goto leave;
1169
1170 if (archive->has_password)
1171 {
1172 if (!xa_check_password(archive))
1173 goto leave;
1174 }
1175
1176 xa_set_extract_dialog_options(extract_window,0,archive);
1177 xa_parse_extract_dialog_options (archive,extract_window,NULL);
1178 gtk_widget_destroy (extract_window->dialog1);
1179 g_free (extract_window);
1180 }
1181 /* Switch -m */
1182 else if (opt_multi_extract)
1183 {
1184 Multi_extract_data *multi_extract = NULL;
1185 multi_extract = xa_create_multi_extract_dialog();
1186 for (i = 1; i < argc; i++)
1187 if (!g_file_test(argv[i], G_FILE_TEST_IS_DIR))
1188 xa_multi_extract_dialog_add_file(argv[i], multi_extract);
1189
1190 xa_multi_extract_dialog(multi_extract);
1191 gtk_widget_destroy (multi_extract->multi_extract);
1192 g_free(multi_extract);
1193 }
1194 /* Switch -c */
1195 else if (opt_compress)
1196 {
1197 archive = xa_new_archive_dialog(opt_compress, NULL);
1198
1199 if (archive == NULL)
1200 goto leave;
1201
1202 if (archive->path[0] != NULL)
1203 {
1204 xa_create_working_directory(archive);
1205 current_dir = g_path_get_dirname(opt_compress);
1206 chdir(current_dir);
1207 g_free(current_dir);
1208 GSList *files = NULL;
1209 current_dir = g_path_get_basename(opt_compress);
1210 files = g_slist_append(files, g_strdup(current_dir));
1211 g_free(current_dir);
1212 g_free(opt_compress);
1213 for (i = 1; i < argc; i++)
1214 {
1215 current_dir = g_path_get_basename(argv[i]);
1216 files = g_slist_append(files, g_strdup(current_dir));
1217 g_free(current_dir);
1218 }
1219 xa_execute_add_commands(archive, files, TRUE, NULL);
1220 }
1221 }
1222 /* Switch -a */
1223 else if (opt_add)
1224 {
1225 if (!archive)
1226 {
1227 xa_cmd_line_error(argv[1], _("Can't add files to the archive:"));
1228 goto leave;
1229 }
1230 if (!archive->can_add)
1231 {
1232 xa_show_message_dialog(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Can't add files to the archive:"), argv[1]);
1233 goto leave;
1234 }
1235
1236 xa_detect_encrypted_archive(archive);
1237
1238 if (archive->status == XARCHIVESTATUS_ERROR)
1239 goto leave;
1240
1241 if (archive->has_password)
1242 {
1243 if (!xa_check_password(archive))
1244 goto leave;
1245 }
1246
1247 xa_set_add_dialog_options(add_window, archive);
1248 xa_parse_add_dialog_options(archive, add_window);
1249 gtk_widget_destroy(add_window->dialog1);
1250 g_free(add_window);
1251 }
1252 /* Switch -i */
1253 else if (opt_info)
1254 {
1255 GSList *list;
1256
1257 for (i = XARCHIVETYPE_FIRST; i < XARCHIVETYPE_TYPES; i++)
1258 {
1259 list = archiver[i].type;
1260
1261 while (list)
1262 {
1263 if (list->data)
1264 {
1265 if (strncmp(list->data, "tar.", 4) == 0)
1266 break;
1267
1268 g_print("%s", (char *) list->data);
1269 }
1270
1271 list = list->next;
1272
1273 if (list && list->data)
1274 g_print(", ");
1275 else
1276 {
1277 g_print(":\n %s\n", archiver[i].program[0]);
1278
1279 if (archiver[i].program[1])
1280 g_print(" %s\n", archiver[i].program[1]);
1281 }
1282 }
1283 }
1284 }
1285
1286 result = EXIT_SUCCESS;
1287
1288 leave:
1289
1290 if (progress)
1291 {
1292 gtk_widget_destroy(progress->window);
1293 g_free(progress);
1294 progress = NULL;
1295 }
1296 if (archive != NULL)
1297 xa_clean_archive_structure (archive);
1298 #ifdef HAVE_SOCKET
1299 socket_finalize();
1300 #endif
1301 }
1302 else
1303 {
1304 xa_main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1305 xa_create_main_window (xa_main_window, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs_window->show_location_bar)),
1306 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs_window->show_sidebar)),
1307 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs_window->show_toolbar)));
1308
1309 gtk_window_set_transient_for (GTK_WINDOW (extract_window->dialog1),GTK_WINDOW (xa_main_window));
1310 gtk_window_set_transient_for (GTK_WINDOW (add_window->dialog1),GTK_WINDOW (xa_main_window));
1311 gtk_window_set_transient_for (GTK_WINDOW (prefs_window->dialog1),GTK_WINDOW (xa_main_window));
1312 gtk_window_set_transient_for (GTK_WINDOW (multi_extract_window->multi_extract),GTK_WINDOW (xa_main_window));
1313 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs_window->check_save_geometry)) && prefs_window->geometry[0] != -1)
1314 {
1315 gtk_window_move (GTK_WINDOW(xa_main_window), prefs_window->geometry[0], prefs_window->geometry[1]);
1316 gtk_window_set_default_size(GTK_WINDOW(xa_main_window), prefs_window->geometry[2], prefs_window->geometry[3]);
1317 gtk_paned_set_position(GTK_PANED(hpaned1), prefs_window->geometry[4]);
1318 }
1319 else
1320 {
1321 gtk_window_set_position (GTK_WINDOW(xa_main_window),GTK_WIN_POS_CENTER);
1322 gtk_window_set_default_size (GTK_WINDOW(xa_main_window), 600, 400);
1323 gtk_paned_set_position (GTK_PANED (hpaned1),200);
1324 }
1325 gtk_label_set_text(GTK_LABEL(total_label),_("Select \"New\" to create or \"Open\" to open an archive"));
1326 gtk_widget_show (xa_main_window);
1327
1328 /* This to open the archive from the command line */
1329 if ( argc == 2 )
1330 {
1331 gchar *dummy;
1332 if (g_str_has_prefix(argv[1], "file://") == TRUE)
1333 dummy = g_strdup(argv[1]+6);
1334 else
1335 dummy = g_strdup(argv[1]);
1336
1337 current_open_directory = g_path_get_dirname (dummy);
1338 if (strcmp(current_open_directory,"..") == 0)
1339 {
1340 g_free (current_open_directory);
1341 current_open_directory = g_get_current_dir();
1342 }
1343 xa_open_archive (NULL,dummy);
1344 }
1345 #ifdef HAVE_SOCKET
1346 if (! socket_info.ignore_socket && socket_info.lock_socket > 0)
1347 {
1348 socket_info.read_ioc = g_io_channel_unix_new(socket_info.lock_socket);
1349 socket_info.lock_socket_tag = g_io_add_watch(socket_info.read_ioc, G_IO_IN | G_IO_ERR, socket_lock_input_cb, xa_main_window);
1350 }
1351 #endif
1352 gtk_main ();
1353
1354 result = EXIT_SUCCESS;
1355 }
1356
1357 for (i = XARCHIVETYPE_FIRST; i < XARCHIVETYPE_TYPES; i++)
1358 {
1359 g_free(archiver[i].program[0]);
1360 g_free(archiver[i].program[1]);
1361 g_slist_free(archiver[i].type);
1362 g_slist_free(archiver[i].glob);
1363 g_slist_free(archiver[i].tags);
1364 }
1365
1366 g_free(xdg_open);
1367
1368 return result;
1369 }
1370