1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 
3 /*
4  *  File-Roller
5  *
6  *  Copyright (C) 2001, 2003, 2012 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 #ifndef FR_ARCHIVE_H
23 #define FR_ARCHIVE_H
24 
25 #include <glib.h>
26 #include "file-data.h"
27 #include "typedefs.h"
28 
29 typedef enum {
30 	FR_ACTION_NONE,
31 	FR_ACTION_CREATING_NEW_ARCHIVE,
32 	FR_ACTION_LOADING_ARCHIVE,            /* loading the archive from a remote location */
33 	FR_ACTION_LISTING_CONTENT,            /* listing the content of the archive */
34 	FR_ACTION_DELETING_FILES,             /* deleting files from the archive */
35 	FR_ACTION_TESTING_ARCHIVE,            /* testing the archive integrity */
36 	FR_ACTION_GETTING_FILE_LIST,          /* getting the file list (when fr_archive_add_with_wildcard or
37 						 fr_archive_add_directory are used, we need to scan a directory
38 						 and collect the files to add to the archive, this
39 						 may require some time to complete, so the operation
40 						 is asynchronous) */
41 	FR_ACTION_COPYING_FILES_FROM_REMOTE,  /* copying files to be added to the archive from a remote location */
42 	FR_ACTION_ADDING_FILES,               /* adding files to an archive */
43 	FR_ACTION_EXTRACTING_FILES,           /* extracting files */
44 	FR_ACTION_COPYING_FILES_TO_REMOTE,    /* copying extracted files to a remote location */
45 	FR_ACTION_CREATING_ARCHIVE,           /* creating a local archive */
46 	FR_ACTION_SAVING_REMOTE_ARCHIVE,      /* copying the archive to a remote location */
47 	FR_ACTION_RENAMING_FILES,             /* renaming files stored in the archive */
48 	FR_ACTION_PASTING_FILES,              /* pasting files from the clipboard into the archive */
49 	FR_ACTION_UPDATING_FILES,             /* updating the files modified with an external application */
50 	FR_ACTION_ENCRYPTING_ARCHIVE          /* saving the archive with a different password */
51 } FrAction;
52 
53 #ifdef DEBUG
54 extern char *action_names[];
55 #endif
56 
57 #define FR_TYPE_ARCHIVE            (fr_archive_get_type ())
58 #define FR_ARCHIVE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), FR_TYPE_ARCHIVE, FrArchive))
59 #define FR_ARCHIVE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), FR_TYPE_ARCHIVE, FrArchiveClass))
60 #define FR_IS_ARCHIVE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FR_TYPE_ARCHIVE))
61 #define FR_IS_ARCHIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FR_TYPE_ARCHIVE))
62 #define FR_ARCHIVE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), FR_TYPE_ARCHIVE, FrArchiveClass))
63 
64 typedef struct _FrArchive         FrArchive;
65 typedef struct _FrArchiveClass    FrArchiveClass;
66 typedef struct _FrArchivePrivate  FrArchivePrivate;
67 
68 typedef gboolean (*FakeLoadFunc) (FrArchive *archive, gpointer data);
69 
70 struct _FrArchive {
71 	GObject  __parent;
72 	FrArchivePrivate *priv;
73 
74 	/*<public, read only>*/
75 
76 	const char    *mime_type;
77 	GPtrArray     *files;                      /* Array of FileData */
78 	GHashTable    *files_hash;                 /* Hash of FileData with original_path as key */
79 	int            n_regular_files;
80 
81 	/*<public>*/
82 
83 	char          *password;
84 	gboolean       encrypt_header;
85 	FrCompression  compression;
86 	gboolean       multi_volume;
87 	guint          volume_size;
88 	gboolean       read_only;                  /* Whether archive is
89 						    * read-only for whatever
90 						    * reason. */
91 
92 	/*<protected>*/
93 
94 	gssize         files_to_add_size;
95 
96 	/* features. */
97 
98 	/* propAddCanReplace:
99 	 *
100 	 * TRUE if the command can overwrite a file in the archive.
101 	 */
102 	guint          propAddCanReplace : 1;
103 
104 	/* propAddCanReplace:
105 	 *
106 	 * TRUE if the command can overwrite a file in the archive if older
107 	 * then the file on disk.
108 	 */
109 	guint          propAddCanUpdate : 1;
110 
111 	/* propAddCanStoreFolders:
112 	 *
113 	 * TRUE if the command can store folder entries inside the archive.
114 	 */
115 	guint          propAddCanStoreFolders : 1;
116 
117 	/*
118 	 * propAddCanStoreLinks
119 	 *
120 	 * TRUE if the command can store symbolic links
121 	 */
122 	guint          propAddCanStoreLinks : 1;
123 
124 	/* propAddCanFollowDirectoryLinksWithoutDereferencing:
125 	 *
126 	 * is used to overcome an issue with 7zip when adding a file in a
127 	 * subfolder.  For example if we want to add to an archive
128 	 *
129 	 * /home/user/index.html
130 	 *
131 	 * in the folder 'doc'
132 	 *
133 	 * we create a symbolic link doc -> /home/user
134 	 *
135 	 * and use the following command to add the file
136 	 *
137 	 * 7z a -bd -y -mx=7 -- /home/user/archive.7z doc/index.html
138 	 *
139 	 * this gives an error because 7zip doesn't see the doc/index.html file
140 	 * for some reason, in this case we have to add the -l option to always
141 	 * deference the links.
142 	 *
143 	 * This means that when adding files to a subfolder in an 7zip archive
144 	 * we cannot store symbolic links as such, suboptimal but more
145 	 * acceptable than an error.
146 	 */
147 	guint          propAddCanFollowDirectoryLinksWithoutDereferencing : 1;
148 
149 	/* propExtractCanAvoidOverwrite:
150 	 *
151 	 * TRUE if the command can avoid to overwrite the files on disk.
152 	 */
153 	guint          propExtractCanAvoidOverwrite : 1;
154 
155 	/* propExtractCanSkipOlder:
156 	 *
157 	 * TRUE if the command can avoid to overwrite a file on disk when it is
158 	 * newer than the file in the archive.
159 	 */
160 	guint          propExtractCanSkipOlder : 1;
161 
162 	/* propExtractCanJunkPaths:
163 	 *
164 	 * TRUE if the command can extract the files in the current folder
165 	 * without recreating the directory structure.
166 	 */
167 	guint          propExtractCanJunkPaths : 1;
168 
169 	/* propPassword:
170 	 *
171 	 * TRUE if the command can use passwords for adding or extracting files.
172 	 */
173 	guint          propPassword : 1;
174 
175 	/* propTest:
176 	 *
177 	 * TRUE if the command can test the archive integrity.
178 	 */
179 	guint          propTest : 1;
180 
181 	/* propCanExtractAll:
182 	 *
183 	 * TRUE if the command extract all the files when no file is specified.
184 	 */
185 	guint          propCanExtractAll : 1;
186 
187 	/* propCanDeleteNonEmptyFolders:
188 	 *
189 	 * is used to overcome an issue with tar, that deletes only the folder
190 	 * entry in the archive instead of deleting the folder content
191 	 * recursively.
192 	 */
193 	guint          propCanDeleteNonEmptyFolders : 1;
194 
195 	/* propCanDeleteAllFiles:
196 	 *
197 	 * TRUE if the command does not delete the archive itself if all the
198 	 * files in the archive are deleted.
199 	 */
200 
201 	guint          propCanDeleteAllFiles : 1;
202 
203 	/* propCanExtractNonEmptyFolders:
204 	 *
205 	 * is used to overcome an issue with tar.  For example if
206 	 * the content of a tar archive is
207 	 *
208 	 * readme.txt
209 	 * doc/
210 	 * doc/page1.html
211 	 * doc/page2.html
212 	 *
213 	 * and we want to extract the content of the doc folder, the command:
214 	 *
215 	 * tar -xf archive.tar doc doc/page1.html doc/page2.html
216 	 *
217 	 * gives an error.
218 	 * To fix the issue we have to remove the files inside the doc
219 	 * folder from the command line, getting the following command:
220 	 *
221 	 * tar -xf archive.tar doc
222 	 */
223 	guint          propCanExtractNonEmptyFolders : 1;
224 
225 	/* propListFromFile:
226 	 *
227 	 * if TRUE the command has an option to read the file list from a file
228 	 */
229 	guint          propListFromFile : 1;
230 };
231 
232 struct _FrArchiveClass {
233 	GObjectClass __parent_class;
234 
235 	/*< signals >*/
236 
237 	void          (*start)             (FrArchive           *archive,
238 					    FrAction             action);
239 	void          (*progress)          (FrArchive           *archive,
240 			           	    double               fraction);
241 	void          (*message)           (FrArchive           *archive,
242 			           	    const char          *msg);
243 	void          (*stoppable)         (FrArchive           *archive,
244 			           	    gboolean             value);
245 	void          (*working_archive)   (FrArchive           *archive,
246 			           	    const char          *uri);
247 
248 	/*< virtual functions >*/
249 
250 	const char ** (*get_mime_types)    (FrArchive           *archive);
251 	FrArchiveCap  (*get_capabilities)  (FrArchive           *archive,
252 					    const char          *mime_type,
253 					    gboolean             check_command);
254 	void          (*set_mime_type)     (FrArchive           *archive,
255 				            const char          *mime_type);
256 	const char *  (*get_packages)      (FrArchive           *archive,
257 					    const char          *mime_type);
258 	void          (*open)              (FrArchive           *archive,
259 					    GCancellable        *cancellable,
260 					    GAsyncReadyCallback  callback,
261 					    gpointer             user_data);
262 	void          (*list)              (FrArchive           *archive,
263 					    const char          *password,
264 					    GCancellable        *cancellable,
265 					    GAsyncReadyCallback  callback,
266 					    gpointer             user_data);
267 	void          (*add_files)         (FrArchive           *archive,
268 					    GList               *file_list, /* GFile list */
269 					    GFile               *base_dir,
270 					    const char          *dest_dir,
271 					    gboolean             update,
272 					    gboolean             follow_links,
273 					    const char          *password,
274 					    gboolean             encrypt_header,
275 					    FrCompression        compression,
276 					    guint                volume_size,
277 					    GCancellable        *cancellable,
278 					    GAsyncReadyCallback  callback,
279 					    gpointer             user_data);
280 	void          (*extract_files)     (FrArchive           *archive,
281 	    				    GList               *file_list,
282 	    				    GFile               *destination,
283 	    				    const char          *base_dir,
284 	    				    gboolean             skip_older,
285 	    				    gboolean             overwrite,
286 	    				    gboolean             junk_paths,
287 	    				    const char          *password,
288 					    GCancellable        *cancellable,
289 					    GAsyncReadyCallback  callback,
290 					    gpointer             user_data);
291 	void          (*remove_files)      (FrArchive           *archive,
292 				   	    GList               *file_list,
293 				   	    FrCompression        compression,
294 				   	    GCancellable        *cancellable,
295 				   	    GAsyncReadyCallback  callback,
296 				   	    gpointer             user_data);
297 	void          (*test_integrity)    (FrArchive           *archive,
298 			 	   	    const char          *password,
299 			 	   	    GCancellable        *cancellable,
300 			 	   	    GAsyncReadyCallback  callback,
301 			 	   	    gpointer             user_data);
302 	void          (*rename)            (FrArchive           *archive,
303 					    GList               *file_list,
304 				   	    const char          *old_name,
305 				   	    const char          *new_name,
306 				   	    const char          *current_dir,
307 				   	    gboolean             is_dir,
308 				   	    gboolean             dir_in_archive,
309 				   	    const char          *original_path,
310 					    GCancellable        *cancellable,
311 					    GAsyncReadyCallback  callback,
312 					    gpointer             user_data);
313 	void          (*paste_clipboard)   (FrArchive           *archive,
314 					    GFile               *archive_file,
315 					    char                *password,
316 					    gboolean             encrypt_header,
317 					    FrCompression        compression,
318 					    guint                volume_size,
319 					    FrClipboardOp        op,
320 					    char                *base_dir,
321 					    GList               *files,
322 					    GFile               *tmp_dir,
323 					    char                *current_dir,
324 					    GCancellable        *cancellable,
325 					    GAsyncReadyCallback  callback,
326 					    gpointer             user_data);
327 	void          (*add_dropped_files) (FrArchive           *archive,
328 				   	    GList               *item_list,
329 				   	    const char          *dest_dir,
330 				   	    const char          *password,
331 				   	    gboolean             encrypt_header,
332 				   	    FrCompression        compression,
333 				   	    guint                volume_size,
334 					    GCancellable        *cancellable,
335 					    GAsyncReadyCallback  callback,
336 					    gpointer             user_data);
337 	void          (*update_open_files) (FrArchive           *archive,
338 					    GList               *file_list,
339 					    GList               *dir_list,
340 					    const char          *password,
341 					    gboolean             encrypt_header,
342 					    FrCompression        compression,
343 					    guint                volume_size,
344 					    GCancellable        *cancellable,
345 					    GAsyncReadyCallback  callback,
346 					    gpointer             user_data);
347 };
348 
349 GType         fr_archive_get_type                (void);
350 GFile *       fr_archive_get_file                (FrArchive           *archive);
351 gboolean      fr_archive_is_capable_of           (FrArchive           *archive,
352 						  FrArchiveCaps        capabilities);
353 const char ** fr_archive_get_supported_types     (FrArchive           *archive);
354 void          fr_archive_update_capabilities     (FrArchive           *archive);
355 FrArchiveCap  fr_archive_get_capabilities        (FrArchive           *archive,
356 						  const char          *mime_type,
357 						  gboolean             check_command);
358 void          fr_archive_set_mime_type           (FrArchive           *archive,
359 						  const char          *mime_type);
360 const char *  fr_archive_get_mime_type           (FrArchive           *archive);
361 const char *  fr_archive_get_packages            (FrArchive           *archive,
362 						  const char          *mime_type);
363 void          fr_archive_set_stoppable           (FrArchive           *archive,
364 						  gboolean             stoppable);
365 FrArchive *   fr_archive_create                  (GFile               *file,
366 						  const char          *mime_type);
367 void          fr_archive_open                    (GFile               *file,
368 		       	       	       	          GCancellable        *cancellable,
369 		       	       	       	          GAsyncReadyCallback  callback,
370 		       	       	       	          gpointer             user_data);
371 FrArchive *   fr_archive_open_finish             (GFile               *file,
372 						  GAsyncResult        *result,
373 						  GError             **error);
374 void          fr_archive_list                    (FrArchive           *archive,
375 						  const char          *password,
376 						  GCancellable        *cancellable,
377 		       	       	       	          GAsyncReadyCallback  callback,
378 		       	       	       	          gpointer             user_data);
379 gboolean      fr_archive_operation_finish        (FrArchive           *archive,
380 						  GAsyncResult        *result,
381 						  GError             **error);
382 void          fr_archive_add_files               (FrArchive           *archive,
383 						  GList               *file_list, /* GFile list */
384 						  GFile               *base_dir,
385 						  const char          *dest_dir,
386 						  gboolean             update,
387 						  gboolean             follow_links,
388 						  const char          *password,
389 						  gboolean             encrypt_header,
390 						  FrCompression        compression,
391 						  guint                volume_size,
392 						  GCancellable        *cancellable,
393 						  GAsyncReadyCallback  callback,
394 						  gpointer             user_data);
395 void          fr_archive_add_files_with_filter   (FrArchive           *archive,
396 						  GList               *file_list, /* GFile list */
397 						  GFile               *base_dir,
398 						  const char          *include_files,
399 						  const char          *exclude_files,
400 						  const char          *exclude_folders,
401 						  const char          *dest_dir,
402 						  gboolean             update,
403 						  gboolean             follow_links,
404 						  const char          *password,
405 						  gboolean             encrypt_header,
406 						  FrCompression        compression,
407 						  guint                volume_size,
408 						  GCancellable        *cancellable,
409 						  GAsyncReadyCallback  callback,
410 						  gpointer             user_data);
411 void          fr_archive_remove                  (FrArchive           *archive,
412 						  GList               *file_list,
413 						  FrCompression        compression,
414 						  GCancellable        *cancellable,
415 						  GAsyncReadyCallback  callback,
416 						  gpointer             user_data);
417 void          fr_archive_extract                 (FrArchive           *archive,
418 						  GList               *file_list,
419 						  GFile               *destination,
420 						  const char          *base_dir,
421 						  gboolean             skip_older,
422 						  gboolean             overwrite,
423 						  gboolean             junk_path,
424 						  const char          *password,
425 		       	       	       	          GCancellable        *cancellable,
426 		       	       	       	          GAsyncReadyCallback  callback,
427 		       	       	       	          gpointer             user_data);
428 gboolean      fr_archive_extract_here            (FrArchive           *archive,
429 						  gboolean             skip_older,
430 						  gboolean             overwrite,
431 						  gboolean             junk_path,
432 						  const char          *password,
433 		       	       	       	          GCancellable        *cancellable,
434 		       	       	       	          GAsyncReadyCallback  callback,
435 		       	       	       	          gpointer             user_data);
436 void          fr_archive_set_last_extraction_destination
437 						 (FrArchive           *archive,
438 						  GFile               *folder);
439 GFile *       fr_archive_get_last_extraction_destination
440 						 (FrArchive           *archive);
441 void          fr_archive_test                    (FrArchive           *archive,
442 						  const char          *password,
443 		       	       	       	          GCancellable        *cancellable,
444 		       	       	       	          GAsyncReadyCallback  callback,
445 		       	       	       	          gpointer             user_data);
446 void          fr_archive_rename                  (FrArchive           *archive,
447 						  GList               *file_list,
448 						  const char          *old_name,
449 						  const char          *new_name,
450 						  const char          *current_dir,
451 						  gboolean             is_dir,
452 						  gboolean             dir_in_archive,
453 						  const char          *original_path,
454 						  GCancellable        *cancellable,
455 						  GAsyncReadyCallback  callback,
456 						  gpointer             user_data);
457 void          fr_archive_paste_clipboard         (FrArchive           *archive,
458 						  GFile               *file,
459 						  char                *password,
460 						  gboolean             encrypt_header,
461 						  FrCompression        compression,
462 						  guint                volume_size,
463 						  FrClipboardOp        op,
464 						  char                *base_dir,
465 						  GList               *files,
466 						  GFile               *tmp_dir,
467 						  char                *current_dir,
468 		       	       	       	          GCancellable        *cancellable,
469 		       	       	       	          GAsyncReadyCallback  callback,
470 		       	       	       	          gpointer             user_data);
471 void          fr_archive_add_dropped_items       (FrArchive           *archive,
472 						  GList               *item_list,
473 						  const char          *dest_dir,
474 						  const char          *password,
475 						  gboolean             encrypt_header,
476 						  FrCompression        compression,
477 						  guint                volume_size,
478 						  GCancellable        *cancellable,
479 						  GAsyncReadyCallback  callback,
480 						  gpointer             user_data);
481 void          fr_archive_update_open_files       (FrArchive           *archive,
482 						  GList               *file_list,
483 						  GList               *dir_list,
484 						  const char          *password,
485 						  gboolean             encrypt_header,
486 						  FrCompression        compression,
487 						  guint                volume_size,
488 						  GCancellable        *cancellable,
489 						  GAsyncReadyCallback  callback,
490 						  gpointer             user_data);
491 
492 /* protected */
493 
494 void          fr_archive_set_multi_volume        (FrArchive           *archive,
495 					          GFile               *file);
496 void          fr_archive_change_name             (FrArchive           *archive,
497 						  const char          *filename);
498 void          fr_archive_action_started          (FrArchive           *archive,
499                                                   FrAction             action);
500 void          fr_archive_progress                (FrArchive           *archive,
501 						  double               fraction);
502 void          fr_archive_message                 (FrArchive           *archive,
503 						  const char          *msg);
504 void          fr_archive_working_archive         (FrArchive           *archive,
505 						  const char          *archive_name);
506 void          fr_archive_progress_set_total_files(FrArchive           *archive,
507 						  int                  total);
508 int           fr_archive_progress_get_total_files(FrArchive           *archive);
509 int           fr_archive_progress_get_completed_files
510 						 (FrArchive           *archive);
511 double        fr_archive_progress_inc_completed_files
512 						 (FrArchive           *archive,
513 						  int                  new_completed);
514 void          fr_archive_progress_set_total_bytes (FrArchive           *archive,
515 						  gsize                total);
516 double        fr_archive_progress_set_completed_bytes
517 						 (FrArchive           *self,
518 						  gsize                completed_bytes);
519 double        fr_archive_progress_inc_completed_bytes
520 						 (FrArchive           *archive,
521 						  gsize                new_completed);
522 double        fr_archive_progress_get_fraction   (FrArchive           *archive);
523 void          fr_archive_add_file                (FrArchive           *archive,
524 						  FileData            *file_data);
525 
526 /* utilities */
527 
528 gboolean      _g_file_is_archive                 (GFile               *file);
529 
530 #endif /* FR_ARCHIVE_H */
531