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 #include <glib.h>
15 #include "file-data.h"
16 #include "file-utils.h"
17 #include "glib-utils.h"
18 #include "fr-command.h"
19 #include "fr-command-lrzip.h"
20
21
22 struct _FrCommandLrzip
23 {
24 FrCommand parent_instance;
25 };
26
27
G_DEFINE_TYPE(FrCommandLrzip,fr_command_lrzip,fr_command_get_type ())28 G_DEFINE_TYPE (FrCommandLrzip, fr_command_lrzip, fr_command_get_type ())
29
30
31 /* -- list -- */
32
33
34 static void
35 list__process_line (char *line,
36 gpointer data)
37 {
38 FileData *fdata;
39 FrCommand *comm = FR_COMMAND (data);
40
41 g_return_if_fail (line != NULL);
42
43 if (strlen (line) == 0)
44 return;
45
46 if (! g_str_has_prefix (line, "Decompressed file size:"))
47 return;
48
49 fdata = file_data_new ();
50 fdata->size = g_ascii_strtoull (_g_str_get_last_field (line, 4), NULL, 10);
51
52 struct stat st;
53 if (stat (comm->filename, &st) == 0)
54 #ifdef __APPLE__
55 fdata->modified = st.st_mtime;
56 #else
57 fdata->modified = st.st_mtim.tv_sec;
58 #endif
59 else
60 time(&(fdata->modified));
61
62 fdata->encrypted = FALSE;
63
64 char *new_fname = g_strdup (_g_path_get_basename (comm->filename));
65 if (g_str_has_suffix (new_fname, ".lrz"))
66 new_fname[strlen (new_fname) - 4] = '\0';
67
68 if (*new_fname == '/') {
69 fdata->full_path = g_strdup (new_fname);
70 fdata->original_path = fdata->full_path;
71 }
72 else {
73 fdata->full_path = g_strconcat ("/", new_fname, NULL);
74 fdata->original_path = fdata->full_path + 1;
75 }
76 fdata->path = _g_path_remove_level (fdata->full_path);
77 fdata->name = new_fname;
78 fdata->dir = FALSE;
79 fdata->link = NULL;
80
81 if (fdata->name == 0)
82 file_data_free (fdata);
83 else
84 fr_archive_add_file (FR_ARCHIVE (comm), fdata);
85 }
86
87
88 static gboolean
fr_command_lrzip_list(FrCommand * comm)89 fr_command_lrzip_list (FrCommand *comm)
90 {
91 fr_process_set_err_line_func (comm->process, list__process_line, comm);
92
93 fr_process_begin_command (comm->process, "lrzip");
94 fr_process_add_arg (comm->process, "-i");
95 fr_process_add_arg (comm->process, comm->filename);
96 fr_process_end_command (comm->process);
97
98 return TRUE;
99 }
100
101
102 static void
fr_command_lrzip_add(FrCommand * comm,const char * from_file,GList * file_list,const char * base_dir,gboolean update,gboolean follow_links)103 fr_command_lrzip_add (FrCommand *comm,
104 const char *from_file,
105 GList *file_list,
106 const char *base_dir,
107 gboolean update,
108 gboolean follow_links)
109 {
110 fr_process_begin_command (comm->process, "lrzip");
111
112 if (base_dir != NULL)
113 fr_process_set_working_dir (comm->process, base_dir);
114
115 /* preserve links. */
116
117 switch (FR_ARCHIVE (comm)->compression) {
118 case FR_COMPRESSION_VERY_FAST:
119 fr_process_add_arg (comm->process, "-l"); break;
120 case FR_COMPRESSION_FAST:
121 fr_process_add_arg (comm->process, "-g"); break;
122 case FR_COMPRESSION_NORMAL:
123 fr_process_add_arg (comm->process, "-b"); break;
124 case FR_COMPRESSION_MAXIMUM:
125 fr_process_add_arg (comm->process, "-z"); break;
126 }
127
128 fr_process_add_arg (comm->process, "-o");
129 fr_process_add_arg (comm->process, comm->filename);
130 fr_process_add_arg (comm->process, (char *) file_list->data);
131
132 fr_process_end_command (comm->process);
133 }
134
135 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)136 fr_command_lrzip_extract (FrCommand *comm,
137 const char *from_file,
138 GList *file_list,
139 const char *dest_dir,
140 gboolean overwrite,
141 gboolean skip_older,
142 gboolean junk_paths)
143 {
144 fr_process_begin_command (comm->process, "lrzip");
145 fr_process_add_arg (comm->process, "-d");
146
147 if (dest_dir != NULL) {
148 fr_process_add_arg (comm->process, "-O");
149 fr_process_add_arg (comm->process, dest_dir);
150 }
151 if (overwrite)
152 fr_process_add_arg (comm->process, "-f");
153
154 fr_process_add_arg (comm->process, comm->filename);
155 fr_process_end_command (comm->process);
156 }
157
158
159 /*
160 static void
161 fr_command_lrzip_test (FrCommand *comm)
162 {
163 fr_process_begin_command (comm->process, "lrzip");
164 fr_process_add_arg (comm->process, "-t");
165 fr_process_add_arg (comm->process, comm->filename);
166 fr_process_end_command (comm->process);
167 }
168 */
169
170
171 const char *lrzip_mime_type[] = { "application/x-lrzip", NULL };
172
173
174 static const char **
fr_command_lrzip_get_mime_types(FrArchive * archive)175 fr_command_lrzip_get_mime_types (FrArchive *archive)
176 {
177 return lrzip_mime_type;
178 }
179
180
181 static FrArchiveCap
fr_command_lrzip_get_capabilities(FrArchive * archive,const char * mime_type,gboolean check_command)182 fr_command_lrzip_get_capabilities (FrArchive *archive,
183 const char *mime_type,
184 gboolean check_command)
185 {
186 FrArchiveCap capabilities = FR_ARCHIVE_CAN_DO_NOTHING;
187
188 if (_g_program_is_available ("lrzip", check_command))
189 capabilities |= FR_ARCHIVE_CAN_READ_WRITE;
190
191 return capabilities;
192 }
193
194
195 static const char *
fr_command_lrzip_get_packages(FrArchive * archive,const char * mime_type)196 fr_command_lrzip_get_packages (FrArchive *archive,
197 const char *mime_type)
198 {
199 return PACKAGES ("lrzip");
200 }
201
202
203 static void
fr_command_lrzip_finalize(GObject * object)204 fr_command_lrzip_finalize (GObject *object)
205 {
206 g_return_if_fail (object != NULL);
207 g_return_if_fail (FR_IS_COMMAND_LRZIP (object));
208
209 if (G_OBJECT_CLASS (fr_command_lrzip_parent_class)->finalize)
210 G_OBJECT_CLASS (fr_command_lrzip_parent_class)->finalize (object);
211 }
212
213
214 static void
fr_command_lrzip_class_init(FrCommandLrzipClass * klass)215 fr_command_lrzip_class_init (FrCommandLrzipClass *klass)
216 {
217 GObjectClass *gobject_class;
218 FrArchiveClass *archive_class;
219 FrCommandClass *command_class;
220
221 fr_command_lrzip_parent_class = g_type_class_peek_parent (klass);
222
223 gobject_class = G_OBJECT_CLASS (klass);
224 gobject_class->finalize = fr_command_lrzip_finalize;
225
226 archive_class = FR_ARCHIVE_CLASS (klass);
227 archive_class->get_mime_types = fr_command_lrzip_get_mime_types;
228 archive_class->get_capabilities = fr_command_lrzip_get_capabilities;
229 archive_class->get_packages = fr_command_lrzip_get_packages;
230
231 command_class = FR_COMMAND_CLASS (klass);
232 command_class->list = fr_command_lrzip_list;
233 command_class->add = fr_command_lrzip_add;
234 command_class->extract = fr_command_lrzip_extract;
235 }
236
237
238 static void
fr_command_lrzip_init(FrCommandLrzip * self)239 fr_command_lrzip_init (FrCommandLrzip *self)
240 {
241 FrArchive *base = FR_ARCHIVE (self);
242
243 base->propAddCanUpdate = FALSE;
244 base->propAddCanReplace = FALSE;
245 base->propAddCanStoreFolders = FALSE;
246 base->propAddCanStoreLinks = FALSE;
247 base->propExtractCanAvoidOverwrite = TRUE;
248 base->propExtractCanSkipOlder = FALSE;
249 base->propExtractCanJunkPaths = FALSE;
250 base->propPassword = FALSE;
251 base->propTest = FALSE;
252 }
253