1 /*
2 * fr-command-lrzip.c
3 *
4 * Created on: 10.04.2010
5 * Author: Alexander Saprykin
6 */
7
8 #include <config.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14
15 #include <glib.h>
16
17 #include "file-data.h"
18 #include "file-utils.h"
19 #include "glib-utils.h"
20 #include "fr-command.h"
21 #include "fr-command-lrzip.h"
22
23 static void fr_command_lrzip_class_init (FrCommandLrzipClass *class);
24 static void fr_command_lrzip_init (FrCommand *afile);
25 static void fr_command_lrzip_finalize (GObject *object);
26
27 /* Parent Class */
28
29 static FrCommandClass *parent_class = NULL;
30
31
32 /* -- list -- */
33
34
35 static void
list__process_line(char * line,gpointer data)36 list__process_line (char *line,
37 gpointer data)
38 {
39 FileData *fdata;
40 FrCommand *comm = FR_COMMAND (data);
41
42 g_return_if_fail (line != NULL);
43
44 if (strlen (line) == 0)
45 return;
46
47 if (! g_str_has_prefix (line, "Decompressed file size:"))
48 return;
49
50 fdata = file_data_new ();
51 fdata->size = g_ascii_strtoull (get_last_field (line, 4), NULL, 10);
52
53 struct stat st;
54
55 if (stat (comm->filename, &st) == 0)
56 fdata->modified = st.st_mtim.tv_sec;
57 else
58 time(&(fdata->modified));
59
60 fdata->encrypted = FALSE;
61
62 char *new_fname = g_strdup (file_name_from_path (comm->filename));
63 if (g_str_has_suffix (new_fname, ".lrz"))
64 new_fname[strlen (new_fname) - 4] = '\0';
65
66 if (*new_fname == '/') {
67 fdata->full_path = g_strdup (new_fname);
68 fdata->original_path = fdata->full_path;
69 }
70 else {
71 fdata->full_path = g_strconcat ("/", new_fname, NULL);
72 fdata->original_path = fdata->full_path + 1;
73 }
74 fdata->path = remove_level_from_path (fdata->full_path);
75 fdata->name = new_fname;
76 fdata->dir = FALSE;
77 fdata->link = NULL;
78
79 if (fdata->name == 0)
80 file_data_free (fdata);
81 else
82 fr_command_add_file (comm, fdata);
83 }
84
85
86 static void
fr_command_lrzip_list(FrCommand * comm)87 fr_command_lrzip_list (FrCommand *comm)
88 {
89 fr_process_set_err_line_func (comm->process, list__process_line, comm);
90
91 fr_process_begin_command (comm->process, "lrzip");
92 fr_process_add_arg (comm->process, "-i");
93 fr_process_add_arg (comm->process, comm->filename);
94 fr_process_end_command (comm->process);
95 fr_process_start (comm->process);
96 }
97
98
99 static void
fr_command_lrzip_add(FrCommand * comm,const char * from_file,GList * file_list,const char * base_dir,gboolean update,gboolean recursive)100 fr_command_lrzip_add (FrCommand *comm,
101 const char *from_file,
102 GList *file_list,
103 const char *base_dir,
104 gboolean update,
105 gboolean recursive)
106 {
107 fr_process_begin_command (comm->process, "lrzip");
108
109 if (base_dir != NULL)
110 fr_process_set_working_dir (comm->process, base_dir);
111
112 /* preserve links. */
113
114 switch (comm->compression) {
115 case FR_COMPRESSION_VERY_FAST:
116 fr_process_add_arg (comm->process, "-l"); break;
117 case FR_COMPRESSION_FAST:
118 fr_process_add_arg (comm->process, "-g"); break;
119 case FR_COMPRESSION_NORMAL:
120 fr_process_add_arg (comm->process, "-b"); break;
121 case FR_COMPRESSION_MAXIMUM:
122 fr_process_add_arg (comm->process, "-z"); break;
123 }
124
125 fr_process_add_arg (comm->process, "-o");
126 fr_process_add_arg (comm->process, comm->filename);
127 fr_process_add_arg (comm->process, (char *) file_list->data);
128
129 fr_process_end_command (comm->process);
130 }
131
132 static void
fr_command_lrzip_extract(FrCommand * comm,const char * from_file,GList * file_list,const char * dest_dir,gboolean overwrite,gboolean skip_older,gboolean junk_paths)133 fr_command_lrzip_extract (FrCommand *comm,
134 const char *from_file,
135 GList *file_list,
136 const char *dest_dir,
137 gboolean overwrite,
138 gboolean skip_older,
139 gboolean junk_paths)
140 {
141 fr_process_begin_command (comm->process, "lrzip");
142 fr_process_add_arg (comm->process, "-d");
143
144 if (dest_dir != NULL) {
145 fr_process_add_arg (comm->process, "-O");
146 fr_process_add_arg (comm->process, dest_dir);
147 }
148 if (overwrite)
149 fr_process_add_arg (comm->process, "-f");
150
151 fr_process_add_arg (comm->process, comm->filename);
152 fr_process_end_command (comm->process);
153 }
154
155
156 /*
157 static void
158 fr_command_lrzip_test (FrCommand *comm)
159 {
160 fr_process_begin_command (comm->process, "lrzip");
161 fr_process_add_arg (comm->process, "-t");
162 fr_process_add_arg (comm->process, comm->filename);
163 fr_process_end_command (comm->process);
164 }
165 */
166
167
168 const char *lrzip_mime_type[] = { "application/x-lrzip", NULL };
169
170
171 static const char **
fr_command_lrzip_get_mime_types(FrCommand * comm)172 fr_command_lrzip_get_mime_types (FrCommand *comm)
173 {
174 return lrzip_mime_type;
175 }
176
177
178 static FrCommandCap
fr_command_lrzip_get_capabilities(FrCommand * comm,const char * mime_type,gboolean check_command)179 fr_command_lrzip_get_capabilities (FrCommand *comm,
180 const char *mime_type,
181 gboolean check_command)
182 {
183 FrCommandCap capabilities = FR_COMMAND_CAN_DO_NOTHING;
184
185 if (is_program_available ("lrzip", check_command))
186 capabilities |= FR_COMMAND_CAN_READ_WRITE;
187
188 return capabilities;
189 }
190
191
192 static const char *
fr_command_lrzip_get_packages(FrCommand * comm,const char * mime_type)193 fr_command_lrzip_get_packages (FrCommand *comm,
194 const char *mime_type)
195 {
196 return PACKAGES ("lrzip");
197 }
198
199
200 static void
fr_command_lrzip_class_init(FrCommandLrzipClass * class)201 fr_command_lrzip_class_init (FrCommandLrzipClass *class)
202 {
203 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
204 FrCommandClass *afc;
205
206 parent_class = g_type_class_peek_parent (class);
207 afc = (FrCommandClass*) class;
208
209 gobject_class->finalize = fr_command_lrzip_finalize;
210
211 afc->list = fr_command_lrzip_list;
212 afc->add = fr_command_lrzip_add;
213 afc->extract = fr_command_lrzip_extract;
214 afc->get_mime_types = fr_command_lrzip_get_mime_types;
215 afc->get_capabilities = fr_command_lrzip_get_capabilities;
216 afc->get_packages = fr_command_lrzip_get_packages;
217 }
218
219
220 static void
fr_command_lrzip_init(FrCommand * comm)221 fr_command_lrzip_init (FrCommand *comm)
222 {
223 comm->propAddCanUpdate = FALSE;
224 comm->propAddCanReplace = FALSE;
225 comm->propAddCanStoreFolders = FALSE;
226 comm->propExtractCanAvoidOverwrite = TRUE;
227 comm->propExtractCanSkipOlder = FALSE;
228 comm->propExtractCanJunkPaths = FALSE;
229 comm->propPassword = FALSE;
230 comm->propTest = FALSE;
231 }
232
233
234 static void
fr_command_lrzip_finalize(GObject * object)235 fr_command_lrzip_finalize (GObject *object)
236 {
237 g_return_if_fail (object != NULL);
238 g_return_if_fail (FR_IS_COMMAND_LRZIP (object));
239
240 /* Chain up */
241 if (G_OBJECT_CLASS (parent_class)->finalize)
242 G_OBJECT_CLASS (parent_class)->finalize (object);
243 }
244
245
246 GType
fr_command_lrzip_get_type()247 fr_command_lrzip_get_type ()
248 {
249 static GType type = 0;
250
251 if (! type) {
252 GTypeInfo type_info = {
253 sizeof (FrCommandLrzipClass),
254 NULL,
255 NULL,
256 (GClassInitFunc) fr_command_lrzip_class_init,
257 NULL,
258 NULL,
259 sizeof (FrCommandLrzip),
260 0,
261 (GInstanceInitFunc) fr_command_lrzip_init
262 };
263
264 type = g_type_register_static (FR_TYPE_COMMAND,
265 "FRCommandLrzip",
266 &type_info,
267 0);
268 }
269
270 return type;
271 }
272