1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 
3 /*
4  *  Engrampa
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, write to the Free Software
20  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02110-1301, USA.
21  */
22 
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 
30 #include <glib.h>
31 
32 #include "file-data.h"
33 #include "file-utils.h"
34 #include "glib-utils.h"
35 #include "fr-command.h"
36 #include "fr-command-cfile.h"
37 
38 
39 /* Parent Class */
40 
41 static FrCommandClass *parent_class = NULL;
42 
43 
44 static char *
get_uncompressed_name_from_archive(FrCommand * comm,const char * archive)45 get_uncompressed_name_from_archive (FrCommand  *comm,
46 				    const char *archive)
47 {
48 	GFile        *file;
49 	GInputStream *stream;
50 	char         *filename = NULL;
51 
52 	if (! is_mime_type (comm->mime_type, "application/gzip"))
53 		return NULL;
54 
55 	file = g_file_new_for_path (archive);
56 
57 	stream = (GInputStream *) g_file_read (file, NULL, NULL);
58 	if (stream != NULL) {
59 		gboolean filename_present = TRUE;
60 		char     buffer[10];
61 
62 		if (g_input_stream_read (stream, buffer, 10, NULL, NULL) >= 0) {
63 			/* Check whether the FLG.FNAME is set */
64 			if (((unsigned char)(buffer[3]) & 0x08) != 0x08)
65 				filename_present = FALSE;
66 
67 			/* Check whether the FLG.FEXTRA is set */
68 			if (((unsigned char)(buffer[3]) & 0x04) == 0x04)
69 				filename_present = FALSE;
70 		}
71 
72 		if (filename_present) {
73 			GString *str = NULL;
74 
75 			str = g_string_new ("");
76 			while (g_input_stream_read (stream, buffer, 1, NULL, NULL) > 0) {
77 				if (buffer[0] == '\0') {
78 					filename = g_strdup (file_name_from_path (str->str));
79 #ifdef DEBUG
80 					g_message ("filename is: %s", filename);
81 #endif
82 					break;
83 				}
84 				g_string_append_c (str, buffer[0]);
85 			}
86 			g_string_free (str, TRUE);
87 		}
88 		g_object_unref (stream);
89 	}
90 	g_object_unref (file);
91 
92 	return filename;
93 }
94 
95 
96 static void
list__process_line(char * line,gpointer data)97 list__process_line (char     *line,
98 		    gpointer  data)
99 {
100 	FrCommand  *comm = FR_COMMAND (data);
101 	FileData   *fdata;
102 	char      **fields;
103 	char       *filename;
104 
105 	fdata = file_data_new ();
106 
107 	fields = split_line (line, 2);
108 	if (strcmp (fields[1], "-1") != 0)
109 		fdata->size = g_ascii_strtoull (fields[1], NULL, 10);
110 	g_strfreev (fields);
111 
112 	if (fdata->size == 0)
113 		fdata->size = get_file_size (comm->filename);
114 
115 	filename = get_uncompressed_name_from_archive (comm, comm->filename);
116 	if (filename == NULL)
117 		filename = remove_extension_from_path (comm->filename);
118 
119 	fdata->full_path = g_strconcat ("/",
120 					file_name_from_path (filename),
121 					NULL);
122 	g_free (filename);
123 
124 	fdata->original_path = fdata->full_path + 1;
125 	fdata->link = NULL;
126 	fdata->modified = get_file_mtime_for_path (comm->filename);
127 
128 	fdata->name = g_strdup (file_name_from_path (fdata->full_path));
129 	fdata->path = remove_level_from_path (fdata->full_path);
130 
131 	if (*fdata->name == 0)
132 		file_data_free (fdata);
133 	else
134 		fr_command_add_file (comm, fdata);
135 }
136 
137 
138 static void
fr_command_cfile_list(FrCommand * comm)139 fr_command_cfile_list (FrCommand  *comm)
140 {
141 	FrCommandCFile *comm_cfile = FR_COMMAND_CFILE (comm);
142 
143 	if (is_mime_type (comm->mime_type, "application/gzip")) {
144 		/* gzip let us known the uncompressed size */
145 
146 		fr_process_set_out_line_func (FR_COMMAND (comm)->process,
147 					      list__process_line,
148 					      comm);
149 
150 		fr_process_begin_command (comm->process, "gzip");
151 		fr_process_add_arg (comm->process, "-l");
152 		fr_process_add_arg (comm->process, "-q");
153 		fr_process_add_arg (comm->process, comm->filename);
154 		fr_process_end_command (comm->process);
155 		fr_process_start (comm->process);
156 	}
157 	else {
158 		/* ... other compressors do not support this feature so
159 		 * simply use the archive size, suboptimal but there is no
160 		 * alternative. */
161 
162 		FileData *fdata;
163 		char     *filename;
164 
165 		fdata = file_data_new ();
166 
167 		filename = remove_extension_from_path (comm->filename);
168 		fdata->full_path = g_strconcat ("/",
169 						file_name_from_path (filename),
170 						NULL);
171 		g_free (filename);
172 
173 		fdata->original_path = fdata->full_path + 1;
174 		fdata->link = NULL;
175 		fdata->size = get_file_size_for_path (comm->filename);
176 		fdata->modified = get_file_mtime_for_path (comm->filename);
177 
178 		fdata->name = g_strdup (file_name_from_path (fdata->full_path));
179 		fdata->path = remove_level_from_path (fdata->full_path);
180 
181 		if (*fdata->name == 0)
182 			file_data_free (fdata);
183 		else
184 			fr_command_add_file (comm, fdata);
185 
186 		comm_cfile->error.type = FR_PROC_ERROR_NONE;
187 		comm_cfile->error.status = 0;
188 		g_signal_emit_by_name (G_OBJECT (comm),
189 				       "done",
190 				       comm->action,
191 				       &comm_cfile->error);
192 	}
193 }
194 
195 
196 static void
fr_command_cfile_add(FrCommand * comm,const char * from_file,GList * file_list,const char * base_dir,gboolean update,gboolean recursive)197 fr_command_cfile_add (FrCommand     *comm,
198 		      const char    *from_file,
199 		      GList         *file_list,
200 		      const char    *base_dir,
201 		      gboolean       update,
202 		      gboolean       recursive)
203 {
204 	const char *filename = NULL;
205 	char       *temp_dir = NULL;
206 	char       *temp_file = NULL;
207 	char       *compressed_filename = NULL;
208 
209 	if ((file_list == NULL) || (file_list->data == NULL))
210 		return;
211 
212 	/* copy file to the temp dir */
213 
214 	temp_dir = get_temp_work_dir (NULL);
215 	filename = file_list->data;
216 	temp_file = g_strconcat (temp_dir, "/", filename, NULL);
217 
218 	fr_process_begin_command (comm->process, "cp");
219 	fr_process_set_working_dir (comm->process, base_dir);
220 	fr_process_add_arg (comm->process, "-f");
221 	fr_process_add_arg (comm->process, "--");
222 	fr_process_add_arg (comm->process, filename);
223 	fr_process_add_arg (comm->process, temp_file);
224 	fr_process_end_command (comm->process);
225 
226 	/**/
227 
228 	if (is_mime_type (comm->mime_type, "application/gzip")) {
229 		fr_process_begin_command (comm->process, "gzip");
230 		fr_process_set_working_dir (comm->process, temp_dir);
231 		fr_process_add_arg (comm->process, "--");
232 		fr_process_add_arg (comm->process, filename);
233 		fr_process_end_command (comm->process);
234 		compressed_filename = g_strconcat (filename, ".gz", NULL);
235 	}
236 	else if (is_mime_type (comm->mime_type, "application/x-bzip")) {
237 		fr_process_begin_command (comm->process, "bzip2");
238 		fr_process_set_working_dir (comm->process, temp_dir);
239 		fr_process_add_arg (comm->process, "--");
240 		fr_process_add_arg (comm->process, filename);
241 		fr_process_end_command (comm->process);
242 		compressed_filename = g_strconcat (filename, ".bz2", NULL);
243 	}
244 	else if (is_mime_type (comm->mime_type, "application/x-compress")) {
245 		fr_process_begin_command (comm->process, "compress");
246 		fr_process_set_working_dir (comm->process, temp_dir);
247 		fr_process_add_arg (comm->process, "-f");
248 		fr_process_add_arg (comm->process, filename);
249 		fr_process_end_command (comm->process);
250 		compressed_filename = g_strconcat (filename, ".Z", NULL);
251 	}
252 	else if (is_mime_type (comm->mime_type, "application/x-lzip")) {
253 		fr_process_begin_command (comm->process, "lzip");
254 		fr_process_set_working_dir (comm->process, temp_dir);
255 		fr_process_add_arg (comm->process, "--");
256 		fr_process_add_arg (comm->process, filename);
257 		fr_process_end_command (comm->process);
258 		compressed_filename = g_strconcat (filename, ".lz", NULL);
259 	}
260 	else if (is_mime_type (comm->mime_type, "application/x-lzma")) {
261 		fr_process_begin_command (comm->process, "lzma");
262 		fr_process_set_working_dir (comm->process, temp_dir);
263 		fr_process_add_arg (comm->process, "--");
264 		fr_process_add_arg (comm->process, filename);
265 		fr_process_end_command (comm->process);
266 		compressed_filename = g_strconcat (filename, ".lzma", NULL);
267 	}
268 	else if (is_mime_type (comm->mime_type, "application/x-xz")) {
269 		fr_process_begin_command (comm->process, "xz");
270 		fr_process_set_working_dir (comm->process, temp_dir);
271 		fr_process_add_arg (comm->process, "--");
272 		fr_process_add_arg (comm->process, filename);
273 		fr_process_end_command (comm->process);
274 		compressed_filename = g_strconcat (filename, ".xz", NULL);
275 	}
276 	else if (is_mime_type (comm->mime_type, "application/x-zstd")) {
277 		fr_process_begin_command (comm->process, "zstd");
278 		fr_process_set_working_dir (comm->process, temp_dir);
279 		fr_process_add_arg (comm->process, "--");
280 		fr_process_add_arg (comm->process, filename);
281 		fr_process_end_command (comm->process);
282 		compressed_filename = g_strconcat (filename, ".zst", NULL);
283 	}
284 	else if (is_mime_type (comm->mime_type, "application/x-lzop")) {
285 		fr_process_begin_command (comm->process, "lzop");
286 		fr_process_set_working_dir (comm->process, temp_dir);
287 		fr_process_add_arg (comm->process, "-fU");
288 		fr_process_add_arg (comm->process, "--no-stdin");
289 		fr_process_add_arg (comm->process, "--");
290 		fr_process_add_arg (comm->process, filename);
291 		fr_process_end_command (comm->process);
292 		compressed_filename = g_strconcat (filename, ".lzo", NULL);
293 	}
294 	else if (is_mime_type (comm->mime_type, "application/x-rzip")) {
295 		fr_process_begin_command (comm->process, "rzip");
296 		fr_process_set_working_dir (comm->process, temp_dir);
297 		fr_process_add_arg (comm->process, filename);
298 		fr_process_end_command (comm->process);
299 		compressed_filename = g_strconcat (filename, ".rz", NULL);
300 	}
301 
302       	/* copy compressed file to the dest dir */
303 
304 	fr_process_begin_command (comm->process, "cp");
305 	fr_process_set_working_dir (comm->process, temp_dir);
306 	fr_process_add_arg (comm->process, "-f");
307 	fr_process_add_arg (comm->process, "--");
308 	fr_process_add_arg (comm->process, compressed_filename);
309 	fr_process_add_arg (comm->process, comm->filename);
310 	fr_process_end_command (comm->process);
311 
312 	/* remove the temp dir */
313 
314 	fr_process_begin_command (comm->process, "rm");
315 	fr_process_set_sticky (comm->process, TRUE);
316 	fr_process_add_arg (comm->process, "-rf");
317 	fr_process_add_arg (comm->process, "--");
318 	fr_process_add_arg (comm->process, temp_dir);
319 	fr_process_end_command (comm->process);
320 
321 	g_free (compressed_filename);
322 	g_free (temp_file);
323 	g_free (temp_dir);
324 }
325 
326 
327 static void
fr_command_cfile_delete(FrCommand * comm,const char * from_file,GList * file_list)328 fr_command_cfile_delete (FrCommand  *comm,
329 			 const char *from_file,
330 			 GList      *file_list)
331 {
332 	/* never called */
333 }
334 
335 
336 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)337 fr_command_cfile_extract (FrCommand  *comm,
338 			  const char *from_file,
339 			  GList      *file_list,
340 			  const char *dest_dir,
341 			  gboolean    overwrite,
342 			  gboolean    skip_older,
343 			  gboolean    junk_paths)
344 {
345 	char *temp_dir;
346 	char *dest_file;
347 	char *temp_file;
348 	char *uncompr_file;
349 	char *compr_file;
350 
351 	/* copy file to the temp dir, remove the already existing file first */
352 
353 	temp_dir = get_temp_work_dir (NULL);
354 	temp_file = g_strconcat (temp_dir,
355 				 "/",
356 				 file_name_from_path (comm->filename),
357 				 NULL);
358 
359 	fr_process_begin_command (comm->process, "cp");
360 	fr_process_add_arg (comm->process, "-f");
361 	fr_process_add_arg (comm->process, comm->filename);
362 	fr_process_add_arg (comm->process, temp_file);
363 	fr_process_end_command (comm->process);
364 
365 	/* uncompress the file */
366 
367 	if (is_mime_type (comm->mime_type, "application/gzip")) {
368 		fr_process_begin_command (comm->process, "gzip");
369 		fr_process_add_arg (comm->process, "-f");
370 		fr_process_add_arg (comm->process, "-d");
371 		fr_process_add_arg (comm->process, "-n");
372 		fr_process_add_arg (comm->process, temp_file);
373 		fr_process_end_command (comm->process);
374 	}
375 	else if (is_mime_type (comm->mime_type, "application/x-bzip")) {
376 		fr_process_begin_command (comm->process, "bzip2");
377 		fr_process_add_arg (comm->process, "-f");
378 		fr_process_add_arg (comm->process, "-d");
379 		fr_process_add_arg (comm->process, temp_file);
380 		fr_process_end_command (comm->process);
381 	}
382 	else if (is_mime_type (comm->mime_type, "application/x-compress")) {
383 		if (is_program_in_path ("gzip")) {
384 			fr_process_begin_command (comm->process, "gzip");
385 			fr_process_add_arg (comm->process, "-d");
386 			fr_process_add_arg (comm->process, "-n");
387 		}
388 		else
389 			fr_process_begin_command (comm->process, "uncompress");
390 		fr_process_add_arg (comm->process, "-f");
391 		fr_process_add_arg (comm->process, temp_file);
392 		fr_process_end_command (comm->process);
393 	}
394 	else if (is_mime_type (comm->mime_type, "application/x-lzip")) {
395 		fr_process_begin_command (comm->process, "lzip");
396 		fr_process_add_arg (comm->process, "-f");
397 		fr_process_add_arg (comm->process, "-d");
398 		fr_process_add_arg (comm->process, temp_file);
399 		fr_process_end_command (comm->process);
400 	}
401 	else if (is_mime_type (comm->mime_type, "application/x-lzma")) {
402 		fr_process_begin_command (comm->process, "lzma");
403 		fr_process_add_arg (comm->process, "-f");
404 		fr_process_add_arg (comm->process, "-d");
405 		fr_process_add_arg (comm->process, temp_file);
406 		fr_process_end_command (comm->process);
407 	}
408 	else if (is_mime_type (comm->mime_type, "application/x-xz")) {
409 		fr_process_begin_command (comm->process, "xz");
410 		fr_process_add_arg (comm->process, "-f");
411 		fr_process_add_arg (comm->process, "-d");
412 		fr_process_add_arg (comm->process, temp_file);
413 		fr_process_end_command (comm->process);
414 	}
415 	else if (is_mime_type (comm->mime_type, "application/x-zstd")) {
416 		fr_process_begin_command (comm->process, "zstd");
417 		fr_process_add_arg (comm->process, "-f");
418 		fr_process_add_arg (comm->process, "-d");
419 		fr_process_add_arg (comm->process, temp_file);
420 		fr_process_end_command (comm->process);
421 	}
422 	else if (is_mime_type (comm->mime_type, "application/x-lzop")) {
423 		fr_process_begin_command (comm->process, "lzop");
424 		fr_process_set_working_dir (comm->process, temp_dir);
425 		fr_process_add_arg (comm->process, "-d");
426 		fr_process_add_arg (comm->process, "-fU");
427 		fr_process_add_arg (comm->process, "--no-stdin");
428 		fr_process_add_arg (comm->process, temp_file);
429 		fr_process_end_command (comm->process);
430 	}
431 	else if (is_mime_type (comm->mime_type, "application/x-rzip")) {
432 		fr_process_begin_command (comm->process, "rzip");
433 		fr_process_add_arg (comm->process, "-f");
434 		fr_process_add_arg (comm->process, "-d");
435 		fr_process_add_arg (comm->process, temp_file);
436 		fr_process_end_command (comm->process);
437 	}
438 
439 	/* copy uncompress file to the dest dir */
440 
441 	uncompr_file = remove_extension_from_path (temp_file);
442 
443 	compr_file = get_uncompressed_name_from_archive (comm, comm->filename);
444 	if (compr_file == NULL)
445 		compr_file = remove_extension_from_path (file_name_from_path (comm->filename));
446 	dest_file = g_strconcat (dest_dir,
447 				 "/",
448 				 compr_file,
449 				 NULL);
450 
451 	fr_process_begin_command (comm->process, "cp");
452 	fr_process_add_arg (comm->process, "-f");
453 	fr_process_add_arg (comm->process, uncompr_file);
454 	fr_process_add_arg (comm->process, dest_file);
455 	fr_process_end_command (comm->process);
456 
457 	/* remove the temp dir */
458 
459 	fr_process_begin_command (comm->process, "rm");
460 	fr_process_set_sticky (comm->process, TRUE);
461 	fr_process_add_arg (comm->process, "-rf");
462 	fr_process_add_arg (comm->process, temp_dir);
463 	fr_process_end_command (comm->process);
464 
465 	g_free (dest_file);
466 	g_free (compr_file);
467 	g_free (uncompr_file);
468 	g_free (temp_file);
469 	g_free (temp_dir);
470 }
471 
472 
473 const char *cfile_mime_type[] = { "application/gzip",
474 				  "application/x-bzip",
475 				  "application/x-compress",
476 				  "application/x-lzip",
477 				  "application/x-lzma",
478 				  "application/x-lzop",
479 				  "application/x-rzip",
480 				  "application/x-xz",
481 				  "application/x-zstd",
482 				  NULL };
483 
484 
485 static const char **
fr_command_cfile_get_mime_types(FrCommand * comm)486 fr_command_cfile_get_mime_types (FrCommand *comm)
487 {
488 	return cfile_mime_type;
489 }
490 
491 
492 static FrCommandCap
fr_command_cfile_get_capabilities(FrCommand * comm,const char * mime_type,gboolean check_command)493 fr_command_cfile_get_capabilities (FrCommand  *comm,
494 			           const char *mime_type,
495 				   gboolean    check_command)
496 {
497 	FrCommandCap capabilities;
498 
499 	capabilities = FR_COMMAND_CAN_DO_NOTHING;
500 	if (is_mime_type (mime_type, "application/gzip")) {
501 		if (is_program_available ("gzip", check_command))
502 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
503 	}
504 	else if (is_mime_type (mime_type, "application/x-bzip")) {
505 		if (is_program_available ("bzip2", check_command))
506 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
507 	}
508 	else if (is_mime_type (mime_type, "application/x-compress")) {
509 		if (is_program_available ("compress", check_command))
510 			capabilities |= FR_COMMAND_CAN_WRITE;
511 		if (is_program_available ("uncompress", check_command) || is_program_available ("gzip", check_command))
512 			capabilities |= FR_COMMAND_CAN_READ;
513 	}
514 	else if (is_mime_type (mime_type, "application/x-lzip")) {
515 		if (is_program_available ("lzip", check_command))
516 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
517 	}
518 	else if (is_mime_type (mime_type, "application/x-lzma")) {
519 		if (is_program_available ("lzma", check_command))
520 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
521 	}
522 	else if (is_mime_type (mime_type, "application/x-xz")) {
523 		if (is_program_available ("xz", check_command))
524 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
525 	}
526 	else if (is_mime_type (mime_type, "application/x-zstd")) {
527 		if (is_program_available ("zstd", check_command))
528 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
529 	}
530 	else if (is_mime_type (mime_type, "application/x-lzop")) {
531 		if (is_program_available ("lzop", check_command))
532 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
533 	}
534 	else if (is_mime_type (mime_type, "application/x-rzip")) {
535 		if (is_program_available ("rzip", check_command))
536 			capabilities |= FR_COMMAND_CAN_READ_WRITE;
537 	}
538 
539 	return capabilities;
540 }
541 
542 
543 static void
fr_command_cfile_finalize(GObject * object)544 fr_command_cfile_finalize (GObject *object)
545 {
546         g_return_if_fail (object != NULL);
547         g_return_if_fail (FR_IS_COMMAND_CFILE (object));
548 
549 	/* Chain up */
550         if (G_OBJECT_CLASS (parent_class)->finalize)
551                 G_OBJECT_CLASS (parent_class)->finalize (object);
552 }
553 
554 
555 static const char *
fr_command_cfile_get_packages(FrCommand * comm,const char * mime_type)556 fr_command_cfile_get_packages (FrCommand  *comm,
557 			       const char *mime_type)
558 {
559 	if (is_mime_type (mime_type, "application/gzip"))
560 		return PACKAGES ("gzip");
561 	else if (is_mime_type (mime_type, "application/x-bzip"))
562 		return PACKAGES ("bzip2");
563 	else if (is_mime_type (mime_type, "application/x-compress"))
564 		return PACKAGES ("ncompress");
565 	else if (is_mime_type (mime_type, "application/x-lzip"))
566 		return PACKAGES ("lzip");
567 	else if (is_mime_type (mime_type, "application/x-lzma"))
568 		return PACKAGES ("lzma");
569 	else if (is_mime_type (mime_type, "application/x-xz"))
570 		return PACKAGES ("xz");
571 	else if (is_mime_type (mime_type, "application/x-zstd"))
572 		return PACKAGES ("zstd");
573 	else if (is_mime_type (mime_type, "application/x-lzop"))
574 		return PACKAGES ("lzop");
575 	else if (is_mime_type (mime_type, "application/x-rzip"))
576 		return PACKAGES ("rzip");
577 
578 	return NULL;
579 }
580 
581 
582 static void
fr_command_cfile_class_init(FrCommandCFileClass * class)583 fr_command_cfile_class_init (FrCommandCFileClass *class)
584 {
585         GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
586         FrCommandClass *afc;
587 
588         parent_class = g_type_class_peek_parent (class);
589 	afc = (FrCommandClass*) class;
590 
591         gobject_class->finalize = fr_command_cfile_finalize;
592 
593         afc->list             = fr_command_cfile_list;
594 	afc->add              = fr_command_cfile_add;
595 	afc->delete_           = fr_command_cfile_delete;
596 	afc->extract          = fr_command_cfile_extract;
597 	afc->get_mime_types   = fr_command_cfile_get_mime_types;
598 	afc->get_capabilities = fr_command_cfile_get_capabilities;
599 	afc->get_packages     = fr_command_cfile_get_packages;
600 }
601 
602 
603 static void
fr_command_cfile_init(FrCommand * comm)604 fr_command_cfile_init (FrCommand *comm)
605 {
606 	comm->propAddCanUpdate             = TRUE;
607 	comm->propAddCanReplace            = TRUE;
608 	comm->propExtractCanAvoidOverwrite = FALSE;
609 	comm->propExtractCanSkipOlder      = FALSE;
610 	comm->propExtractCanJunkPaths      = FALSE;
611 	comm->propPassword                 = FALSE;
612 	comm->propTest                     = FALSE;
613 }
614 
615 
616 GType
fr_command_cfile_get_type()617 fr_command_cfile_get_type ()
618 {
619         static GType type = 0;
620 
621         if (! type) {
622                 GTypeInfo type_info = {
623 			sizeof (FrCommandCFileClass),
624 			NULL,
625 			NULL,
626 			(GClassInitFunc) fr_command_cfile_class_init,
627 			NULL,
628 			NULL,
629 			sizeof (FrCommandCFile),
630 			0,
631 			(GInstanceInitFunc) fr_command_cfile_init
632 		};
633 
634 		type = g_type_register_static (FR_TYPE_COMMAND,
635 					       "FRCommandCFile",
636 					       &type_info,
637 					       0);
638         }
639 
640         return type;
641 }
642