1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * File-Roller
5 *
6 * Copyright (C) 2001 The Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28 #include <fcntl.h>
29 #include <glib.h>
30 #include "file-data.h"
31 #include "file-utils.h"
32 #include "glib-utils.h"
33 #include "fr-command.h"
34 #include "fr-command-cfile.h"
35
36
37 struct _FrCommandCFile
38 {
39 FrCommand parent_instance;
40
41 FrError error;
42 };
43
44
G_DEFINE_TYPE(FrCommandCFile,fr_command_cfile,fr_command_get_type ())45 G_DEFINE_TYPE (FrCommandCFile, fr_command_cfile, fr_command_get_type ())
46
47
48 static char *
49 get_uncompressed_name_from_archive (FrCommand *comm,
50 const char *archive)
51 {
52 GFile *file;
53 GInputStream *stream;
54 char *filename = NULL;
55
56 if (! _g_mime_type_matches (FR_ARCHIVE (comm)->mime_type, "application/x-gzip"))
57 return NULL;
58
59 file = g_file_new_for_path (archive);
60
61 stream = (GInputStream *) g_file_read (file, NULL, NULL);
62 if (stream != NULL) {
63 gboolean filename_present = TRUE;
64 char buffer[10];
65
66 if (g_input_stream_read (stream, buffer, 10, NULL, NULL) >= 0) {
67 /* Check whether the FLG.FNAME is set */
68 if (((unsigned char)(buffer[3]) & 0x08) != 0x08)
69 filename_present = FALSE;
70
71 /* Check whether the FLG.FEXTRA is set */
72 if (((unsigned char)(buffer[3]) & 0x04) == 0x04)
73 filename_present = FALSE;
74 }
75
76 if (filename_present) {
77 GString *str = NULL;
78
79 str = g_string_new ("");
80 while (g_input_stream_read (stream, buffer, 1, NULL, NULL) > 0) {
81 if (buffer[0] == '\0') {
82 filename = g_strdup (_g_path_get_basename (str->str));
83 #ifdef DEBUG
84 g_message ("filename is: %s", filename);
85 #endif
86 break;
87 }
88 g_string_append_c (str, buffer[0]);
89 }
90 g_string_free (str, TRUE);
91 }
92 g_object_unref (stream);
93 }
94 g_object_unref (file);
95
96 return filename;
97 }
98
99
100 static void
list__process_line(char * line,gpointer data)101 list__process_line (char *line,
102 gpointer data)
103 {
104 FrCommand *comm = FR_COMMAND (data);
105 FileData *fdata;
106 char **fields;
107 GFile *file;
108 char *filename;
109
110 fdata = file_data_new ();
111
112 fields = _g_str_split_line (line, 2);
113 if (strcmp (fields[1], "-1") != 0)
114 fdata->size = g_ascii_strtoull (fields[1], NULL, 10);
115 g_strfreev (fields);
116
117 file = g_file_new_for_path (comm->filename);
118
119 if (fdata->size == 0)
120 fdata->size = _g_file_get_file_size (file);
121
122 filename = get_uncompressed_name_from_archive (comm, comm->filename);
123 if (filename == NULL)
124 filename = _g_path_remove_first_extension (comm->filename);
125
126 fdata->full_path = g_strconcat ("/", _g_path_get_basename (filename), NULL);
127 g_free (filename);
128
129 fdata->original_path = fdata->full_path + 1;
130 fdata->link = NULL;
131 fdata->modified = _g_file_get_file_mtime (file);
132
133 fdata->name = g_strdup (_g_path_get_basename (fdata->full_path));
134 fdata->path = _g_path_remove_level (fdata->full_path);
135
136 if (*fdata->name == 0)
137 file_data_free (fdata);
138 else
139 fr_archive_add_file (FR_ARCHIVE (comm), fdata);
140
141 g_object_unref (file);
142 }
143
144
145 static gboolean
fr_command_cfile_list(FrCommand * comm)146 fr_command_cfile_list (FrCommand *comm)
147 {
148 if (_g_mime_type_matches (FR_ARCHIVE (comm)->mime_type, "application/x-gzip")) {
149 /* gzip let us known the uncompressed size */
150
151 fr_process_set_out_line_func (comm->process,
152 list__process_line,
153 comm);
154
155 fr_process_begin_command (comm->process, "gzip");
156 fr_process_add_arg (comm->process, "-l");
157 fr_process_add_arg (comm->process, "-q");
158 fr_process_add_arg (comm->process, comm->filename);
159 fr_process_end_command (comm->process);
160 }
161 else {
162 /* ... other compressors do not support this feature so
163 * simply use the archive size, suboptimal but there is no
164 * alternative. */
165
166 FileData *fdata;
167 char *filename;
168 GFile *file;
169
170 fdata = file_data_new ();
171
172 filename = _g_path_remove_first_extension (comm->filename);
173 fdata->full_path = g_strconcat ("/",
174 _g_path_get_basename (filename),
175 NULL);
176 g_free (filename);
177
178 file = g_file_new_for_path (comm->filename);
179
180 fdata->original_path = fdata->full_path + 1;
181 fdata->link = NULL;
182 fdata->size = _g_file_get_file_size (file);
183 fdata->modified = _g_file_get_file_mtime (file);
184 fdata->name = g_strdup (_g_path_get_basename (fdata->full_path));
185 fdata->path = _g_path_remove_level (fdata->full_path);
186
187 if (*fdata->name == 0)
188 file_data_free (fdata);
189 else
190 fr_archive_add_file (FR_ARCHIVE (comm), fdata);
191
192 g_object_unref (file);
193
194 return FALSE;
195 }
196
197 return TRUE;
198 }
199
200
201 static void
fr_command_cfile_add(FrCommand * comm,const char * from_file,GList * file_list,const char * base_dir,gboolean update,gboolean follow_links)202 fr_command_cfile_add (FrCommand *comm,
203 const char *from_file,
204 GList *file_list,
205 const char *base_dir,
206 gboolean update,
207 gboolean follow_links)
208 {
209 FrArchive *archive = FR_ARCHIVE (comm);
210 const char *filename;
211 char *temp_dir;
212 char *temp_file;
213 char *compressed_filename;
214
215 if ((file_list == NULL) || (file_list->data == NULL))
216 return;
217
218 /* copy file to the temp dir */
219
220 temp_dir = _g_path_get_temp_work_dir (NULL);
221 filename = file_list->data;
222 temp_file = g_strconcat (temp_dir, "/", filename, NULL);
223
224 fr_process_begin_command (comm->process, "cp");
225 fr_process_set_working_dir (comm->process, base_dir);
226 fr_process_add_arg (comm->process, "-f");
227 fr_process_add_arg (comm->process, "--");
228 fr_process_add_arg (comm->process, filename);
229 fr_process_add_arg (comm->process, temp_file);
230 fr_process_end_command (comm->process);
231
232 /**/
233
234 if (_g_mime_type_matches (archive->mime_type, "application/x-gzip")) {
235 fr_process_begin_command (comm->process, "gzip");
236 fr_process_set_working_dir (comm->process, temp_dir);
237 fr_process_add_arg (comm->process, "--");
238 fr_process_add_arg (comm->process, filename);
239 fr_process_end_command (comm->process);
240 compressed_filename = g_strconcat (filename, ".gz", NULL);
241 }
242 else if (_g_mime_type_matches (archive->mime_type, "application/x-brotli")) {
243 fr_process_begin_command (comm->process, "brotli");
244 fr_process_set_working_dir (comm->process, temp_dir);
245 fr_process_add_arg (comm->process, "--");
246 fr_process_add_arg (comm->process, filename);
247 fr_process_end_command (comm->process);
248 compressed_filename = g_strconcat (filename, ".br", NULL);
249 }
250 else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip")) {
251 fr_process_begin_command (comm->process, "bzip2");
252 fr_process_set_working_dir (comm->process, temp_dir);
253 fr_process_add_arg (comm->process, "--");
254 fr_process_add_arg (comm->process, filename);
255 fr_process_end_command (comm->process);
256 compressed_filename = g_strconcat (filename, ".bz2", NULL);
257 }
258 else if (_g_mime_type_matches (archive->mime_type, "application/x-compress")) {
259 fr_process_begin_command (comm->process, "compress");
260 fr_process_set_working_dir (comm->process, temp_dir);
261 fr_process_add_arg (comm->process, "-f");
262 fr_process_add_arg (comm->process, filename);
263 fr_process_end_command (comm->process);
264 compressed_filename = g_strconcat (filename, ".Z", NULL);
265 }
266 else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip")) {
267 fr_process_begin_command (comm->process, "lzip");
268 fr_process_set_working_dir (comm->process, temp_dir);
269 fr_process_add_arg (comm->process, "--");
270 fr_process_add_arg (comm->process, filename);
271 fr_process_end_command (comm->process);
272 compressed_filename = g_strconcat (filename, ".lz", NULL);
273 }
274 else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma")) {
275 fr_process_begin_command (comm->process, "lzma");
276 fr_process_set_working_dir (comm->process, temp_dir);
277 fr_process_add_arg (comm->process, "--");
278 fr_process_add_arg (comm->process, filename);
279 fr_process_end_command (comm->process);
280 compressed_filename = g_strconcat (filename, ".lzma", NULL);
281 }
282 else if (_g_mime_type_matches (archive->mime_type, "application/x-xz")) {
283 fr_process_begin_command (comm->process, "xz");
284 fr_process_set_working_dir (comm->process, temp_dir);
285 fr_process_add_arg (comm->process, "--");
286 fr_process_add_arg (comm->process, filename);
287 fr_process_end_command (comm->process);
288 compressed_filename = g_strconcat (filename, ".xz", NULL);
289 }
290 else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop")) {
291 fr_process_begin_command (comm->process, "lzop");
292 fr_process_set_working_dir (comm->process, temp_dir);
293 fr_process_add_arg (comm->process, "-fU");
294 fr_process_add_arg (comm->process, "--no-stdin");
295 fr_process_add_arg (comm->process, "--");
296 fr_process_add_arg (comm->process, filename);
297 fr_process_end_command (comm->process);
298 compressed_filename = g_strconcat (filename, ".lzo", NULL);
299 }
300 else if (_g_mime_type_matches (archive->mime_type, "application/x-rzip")) {
301 fr_process_begin_command (comm->process, "rzip");
302 fr_process_set_working_dir (comm->process, temp_dir);
303 fr_process_add_arg (comm->process, filename);
304 fr_process_end_command (comm->process);
305 compressed_filename = g_strconcat (filename, ".rz", NULL);
306 }
307 else if (_g_mime_type_matches (archive->mime_type, "application/x-lz4")) {
308 compressed_filename = g_strconcat (filename, ".lz4", NULL);
309 fr_process_begin_command (comm->process, "lz4");
310 fr_process_set_working_dir (comm->process, temp_dir);
311 fr_process_add_arg (comm->process, "-f");
312 fr_process_add_arg (comm->process, "-z");
313 fr_process_add_arg (comm->process, filename);
314 fr_process_add_arg (comm->process, compressed_filename);
315 fr_process_end_command (comm->process);
316 }
317 else if (_g_mime_type_matches (archive->mime_type, "application/zstd")) {
318 fr_process_begin_command (comm->process, "zstd");
319 fr_process_set_working_dir (comm->process, temp_dir);
320 fr_process_add_arg (comm->process, "--");
321 fr_process_add_arg (comm->process, filename);
322 fr_process_end_command (comm->process);
323 compressed_filename = g_strconcat (filename, ".zst", NULL);
324 }
325 else {
326 g_warning ("Unhandled mime type: '%s'", archive->mime_type);
327 g_warn_if_reached ();
328 g_free (temp_file);
329 g_free (temp_dir);
330 return;
331 }
332
333 /* copy compressed file to the dest dir */
334
335 fr_process_begin_command (comm->process, "cp");
336 fr_process_set_working_dir (comm->process, temp_dir);
337 fr_process_add_arg (comm->process, "-f");
338 fr_process_add_arg (comm->process, "--");
339 fr_process_add_arg (comm->process, compressed_filename);
340 fr_process_add_arg (comm->process, comm->filename);
341 fr_process_end_command (comm->process);
342
343 /* remove the temp dir */
344
345 fr_process_begin_command (comm->process, "rm");
346 fr_process_set_sticky (comm->process, TRUE);
347 fr_process_add_arg (comm->process, "-rf");
348 fr_process_add_arg (comm->process, "--");
349 fr_process_add_arg (comm->process, temp_dir);
350 fr_process_end_command (comm->process);
351
352 g_free (compressed_filename);
353 g_free (temp_file);
354 g_free (temp_dir);
355 }
356
357
358 static void
fr_command_cfile_delete(FrCommand * comm,const char * from_file,GList * file_list)359 fr_command_cfile_delete (FrCommand *comm,
360 const char *from_file,
361 GList *file_list)
362 {
363 /* never called */
364 }
365
366
367 static void
fr_command_cfile_extract(FrCommand * comm,const char * from_file,GList * file_list,const char * dest_dir,gboolean overwrite,gboolean skip_older,gboolean junk_paths)368 fr_command_cfile_extract (FrCommand *comm,
369 const char *from_file,
370 GList *file_list,
371 const char *dest_dir,
372 gboolean overwrite,
373 gboolean skip_older,
374 gboolean junk_paths)
375 {
376 FrArchive *archive = FR_ARCHIVE (comm);
377 char *temp_dir;
378 char *dest_file;
379 char *temp_file;
380 char *uncompr_file;
381 char *compr_file;
382
383 /* copy file to the temp dir, remove the already existing file first */
384
385 temp_dir = _g_path_get_temp_work_dir (NULL);
386 temp_file = g_strconcat (temp_dir,
387 "/",
388 _g_path_get_basename (comm->filename),
389 NULL);
390
391 fr_process_begin_command (comm->process, "cp");
392 fr_process_add_arg (comm->process, "-f");
393 fr_process_add_arg (comm->process, comm->filename);
394 fr_process_add_arg (comm->process, temp_file);
395 fr_process_end_command (comm->process);
396
397 /* uncompress the file */
398
399 uncompr_file = _g_path_remove_first_extension (temp_file);
400
401 if (_g_mime_type_matches (archive->mime_type, "application/x-gzip")) {
402 fr_process_begin_command (comm->process, "gzip");
403 fr_process_set_working_dir (comm->process, temp_dir);
404 fr_process_add_arg (comm->process, "-f");
405 fr_process_add_arg (comm->process, "-d");
406 fr_process_add_arg (comm->process, "-n");
407 fr_process_add_arg (comm->process, temp_file);
408 fr_process_end_command (comm->process);
409 }
410 else if (_g_mime_type_matches (archive->mime_type, "application/x-brotli")) {
411 fr_process_begin_command (comm->process, "brotli");
412 fr_process_set_working_dir (comm->process, temp_dir);
413 fr_process_add_arg (comm->process, "-f");
414 fr_process_add_arg (comm->process, "-d");
415 fr_process_add_arg (comm->process, temp_file);
416 fr_process_end_command (comm->process);
417 }
418 else if (_g_mime_type_matches (archive->mime_type, "application/x-bzip")) {
419 fr_process_begin_command (comm->process, "bzip2");
420 fr_process_set_working_dir (comm->process, temp_dir);
421 fr_process_add_arg (comm->process, "-f");
422 fr_process_add_arg (comm->process, "-d");
423 fr_process_add_arg (comm->process, temp_file);
424 fr_process_end_command (comm->process);
425 }
426 else if (_g_mime_type_matches (archive->mime_type, "application/x-compress")) {
427 if (_g_program_is_in_path ("gzip")) {
428 fr_process_begin_command (comm->process, "gzip");
429 fr_process_add_arg (comm->process, "-d");
430 fr_process_add_arg (comm->process, "-n");
431 }
432 else
433 fr_process_begin_command (comm->process, "uncompress");
434 fr_process_set_working_dir (comm->process, temp_dir);
435 fr_process_add_arg (comm->process, "-f");
436 fr_process_add_arg (comm->process, temp_file);
437 fr_process_end_command (comm->process);
438 }
439 else if (_g_mime_type_matches (archive->mime_type, "application/x-lzip")) {
440 fr_process_begin_command (comm->process, "lzip");
441 fr_process_set_working_dir (comm->process, temp_dir);
442 fr_process_add_arg (comm->process, "-f");
443 fr_process_add_arg (comm->process, "-d");
444 fr_process_add_arg (comm->process, temp_file);
445 fr_process_end_command (comm->process);
446 }
447 else if (_g_mime_type_matches (archive->mime_type, "application/x-lzma")) {
448 fr_process_begin_command (comm->process, "lzma");
449 fr_process_set_working_dir (comm->process, temp_dir);
450 fr_process_add_arg (comm->process, "-f");
451 fr_process_add_arg (comm->process, "-d");
452 fr_process_add_arg (comm->process, temp_file);
453 fr_process_end_command (comm->process);
454 }
455 else if (_g_mime_type_matches (archive->mime_type, "application/x-xz")) {
456 fr_process_begin_command (comm->process, "xz");
457 fr_process_set_working_dir (comm->process, temp_dir);
458 fr_process_add_arg (comm->process, "-f");
459 fr_process_add_arg (comm->process, "-d");
460 fr_process_add_arg (comm->process, temp_file);
461 fr_process_end_command (comm->process);
462 }
463 else if (_g_mime_type_matches (archive->mime_type, "application/x-lzop")) {
464 fr_process_begin_command (comm->process, "lzop");
465 fr_process_set_working_dir (comm->process, temp_dir);
466 fr_process_add_arg (comm->process, "-d");
467 fr_process_add_arg (comm->process, "-fU");
468 fr_process_add_arg (comm->process, "--no-stdin");
469 fr_process_add_arg (comm->process, temp_file);
470 fr_process_end_command (comm->process);
471 }
472 else if (_g_mime_type_matches (archive->mime_type, "application/x-rzip")) {
473 fr_process_begin_command (comm->process, "rzip");
474 fr_process_set_working_dir (comm->process, temp_dir);
475 fr_process_add_arg (comm->process, "-f");
476 fr_process_add_arg (comm->process, "-d");
477 fr_process_add_arg (comm->process, temp_file);
478 fr_process_end_command (comm->process);
479 }
480 else if (_g_mime_type_matches (archive->mime_type, "application/x-lz4")) {
481 fr_process_begin_command (comm->process, "lz4");
482 fr_process_set_working_dir (comm->process, temp_dir);
483 fr_process_add_arg (comm->process, "-f");
484 fr_process_add_arg (comm->process, "-d");
485 fr_process_add_arg (comm->process, temp_file);
486 fr_process_add_arg (comm->process, uncompr_file);
487 fr_process_end_command (comm->process);
488 }
489 else if (_g_mime_type_matches (archive->mime_type, "application/zstd")) {
490 fr_process_begin_command (comm->process, "zstd");
491 fr_process_set_working_dir (comm->process, temp_dir);
492 fr_process_add_arg (comm->process, "-f");
493 fr_process_add_arg (comm->process, "-d");
494 fr_process_add_arg (comm->process, temp_file);
495 fr_process_end_command (comm->process);
496 }
497
498 /* copy uncompress file to the dest dir */
499
500 compr_file = get_uncompressed_name_from_archive (comm, comm->filename);
501 if (compr_file == NULL)
502 compr_file = _g_path_remove_first_extension (_g_path_get_basename (comm->filename));
503 dest_file = g_strconcat (dest_dir,
504 "/",
505 compr_file,
506 NULL);
507
508 fr_process_begin_command (comm->process, "cp");
509 fr_process_add_arg (comm->process, "-f");
510 fr_process_add_arg (comm->process, uncompr_file);
511 fr_process_add_arg (comm->process, dest_file);
512 fr_process_end_command (comm->process);
513
514 /* remove the temp dir */
515
516 fr_process_begin_command (comm->process, "rm");
517 fr_process_set_sticky (comm->process, TRUE);
518 fr_process_add_arg (comm->process, "-rf");
519 fr_process_add_arg (comm->process, temp_dir);
520 fr_process_end_command (comm->process);
521
522 g_free (dest_file);
523 g_free (compr_file);
524 g_free (uncompr_file);
525 g_free (temp_file);
526 g_free (temp_dir);
527 }
528
529
530 const char *cfile_mime_type[] = { "application/x-gzip",
531 "application/x-brotli",
532 "application/x-bzip",
533 "application/x-compress",
534 "application/x-lz4",
535 "application/x-lzip",
536 "application/x-lzma",
537 "application/x-lzop",
538 "application/x-rzip",
539 "application/x-xz",
540 "application/zstd",
541 NULL };
542
543
544 static const char **
fr_command_cfile_get_mime_types(FrArchive * archive)545 fr_command_cfile_get_mime_types (FrArchive *archive)
546 {
547 return cfile_mime_type;
548 }
549
550
551 static FrArchiveCap
fr_command_cfile_get_capabilities(FrArchive * archive,const char * mime_type,gboolean check_command)552 fr_command_cfile_get_capabilities (FrArchive *archive,
553 const char *mime_type,
554 gboolean check_command)
555 {
556 FrArchiveCap capabilities;
557
558 capabilities = FR_ARCHIVE_CAN_DO_NOTHING;
559 if (_g_mime_type_matches (mime_type, "application/x-gzip")) {
560 if (_g_program_is_available ("gzip", check_command))
561 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
562 }
563 else if (_g_mime_type_matches (mime_type, "application/x-brotli")) {
564 if (_g_program_is_available ("brotli", check_command))
565 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
566 }
567 else if (_g_mime_type_matches (mime_type, "application/x-bzip")) {
568 if (_g_program_is_available ("bzip2", check_command))
569 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
570 }
571 else if (_g_mime_type_matches (mime_type, "application/x-compress")) {
572 if (_g_program_is_available ("compress", check_command))
573 capabilities |= FR_ARCHIVE_CAN_WRITE;
574 if (_g_program_is_available ("uncompress", check_command) || _g_program_is_available ("gzip", check_command))
575 capabilities |= FR_ARCHIVE_CAN_READ;
576 }
577 else if (_g_mime_type_matches (mime_type, "application/x-lzip")) {
578 if (_g_program_is_available ("lzip", check_command))
579 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
580 }
581 else if (_g_mime_type_matches (mime_type, "application/x-lzma")) {
582 if (_g_program_is_available ("lzma", check_command))
583 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
584 }
585 else if (_g_mime_type_matches (mime_type, "application/x-xz")) {
586 if (_g_program_is_available ("xz", check_command))
587 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
588 }
589 else if (_g_mime_type_matches (mime_type, "application/x-lzop")) {
590 if (_g_program_is_available ("lzop", check_command))
591 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
592 }
593 else if (_g_mime_type_matches (mime_type, "application/x-rzip") ||
594 _g_mime_type_matches (mime_type, "application/x-rzip-compressed-tar")) {
595 if (_g_program_is_available ("rzip", check_command))
596 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
597 }
598 else if (_g_mime_type_matches (mime_type, "application/x-lz4")) {
599 if (_g_program_is_available ("lz4", check_command))
600 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
601 }
602 else if (_g_mime_type_matches (mime_type, "application/zstd")) {
603 if (_g_program_is_available ("zstd", check_command))
604 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
605 }
606 return capabilities;
607 }
608
609
610 static const char *
fr_command_cfile_get_packages(FrArchive * archive,const char * mime_type)611 fr_command_cfile_get_packages (FrArchive *archive,
612 const char *mime_type)
613 {
614 if (_g_mime_type_matches (mime_type, "application/x-gzip"))
615 return PACKAGES ("gzip");
616 else if (_g_mime_type_matches (mime_type, "application/x-brotli"))
617 return PACKAGES ("brotli");
618 else if (_g_mime_type_matches (mime_type, "application/x-bzip"))
619 return PACKAGES ("bzip2");
620 else if (_g_mime_type_matches (mime_type, "application/x-compress"))
621 return PACKAGES ("ncompress");
622 else if (_g_mime_type_matches (mime_type, "application/x-lzip"))
623 return PACKAGES ("lzip");
624 else if (_g_mime_type_matches (mime_type, "application/x-lzma"))
625 return PACKAGES ("lzma");
626 else if (_g_mime_type_matches (mime_type, "application/x-xz"))
627 return PACKAGES ("xz");
628 else if (_g_mime_type_matches (mime_type, "application/x-lzop"))
629 return PACKAGES ("lzop");
630 else if (_g_mime_type_matches (mime_type, "application/x-rzip"))
631 return PACKAGES ("rzip");
632 else if (_g_mime_type_matches (mime_type, "application/x-lz4"))
633 return PACKAGES ("lz4");
634 else if (_g_mime_type_matches (mime_type, "application/zstd"))
635 return PACKAGES ("zstd");
636
637 return NULL;
638 }
639
640
641 static void
fr_command_cfile_finalize(GObject * object)642 fr_command_cfile_finalize (GObject *object)
643 {
644 g_return_if_fail (object != NULL);
645 g_return_if_fail (FR_IS_COMMAND_CFILE (object));
646
647 /* Chain up */
648 if (G_OBJECT_CLASS (fr_command_cfile_parent_class)->finalize)
649 G_OBJECT_CLASS (fr_command_cfile_parent_class)->finalize (object);
650 }
651
652
653 static void
fr_command_cfile_class_init(FrCommandCFileClass * klass)654 fr_command_cfile_class_init (FrCommandCFileClass *klass)
655 {
656 GObjectClass *gobject_class;
657 FrArchiveClass *archive_class;
658 FrCommandClass *command_class;
659
660 fr_command_cfile_parent_class = g_type_class_peek_parent (klass);
661
662 gobject_class = G_OBJECT_CLASS (klass);
663 gobject_class->finalize = fr_command_cfile_finalize;
664
665 archive_class = FR_ARCHIVE_CLASS (klass);
666 archive_class->get_mime_types = fr_command_cfile_get_mime_types;
667 archive_class->get_capabilities = fr_command_cfile_get_capabilities;
668 archive_class->get_packages = fr_command_cfile_get_packages;
669
670 command_class = FR_COMMAND_CLASS (klass);
671 command_class->list = fr_command_cfile_list;
672 command_class->add = fr_command_cfile_add;
673 command_class->delete = fr_command_cfile_delete;
674 command_class->extract = fr_command_cfile_extract;
675 }
676
677
678 static void
fr_command_cfile_init(FrCommandCFile * self)679 fr_command_cfile_init (FrCommandCFile *self)
680 {
681 FrArchive *base = FR_ARCHIVE (self);
682
683 base->propAddCanUpdate = TRUE;
684 base->propAddCanReplace = TRUE;
685 base->propAddCanStoreLinks = FALSE;
686 base->propExtractCanAvoidOverwrite = FALSE;
687 base->propExtractCanSkipOlder = FALSE;
688 base->propExtractCanJunkPaths = FALSE;
689 base->propPassword = FALSE;
690 base->propTest = FALSE;
691 }
692