1 /*
2 	*
3 	* Copyright 2018 Britanicus <marcusbritanicus@gmail.com>
4 	*
5 
6 	*
7 	* This program is free software: you can redistribute it and/or modify
8 	* it under the terms of the GNU Lesser General Public License as published by
9 	* the Free Software Foundation, either version 3 of the License, or
10 	* (at your option) any later version.
11 	*
12 
13 	*
14 	* This program is distributed in the hope that it will be useful,
15 	* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 	* GNU Lesser General Public License for more details.
18 	*
19 
20 	*
21 	* You should have received a copy of the GNU Lesser General Public License
22 	* along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 	*
24 */
25 
26 #pragma once
27 
28 // LibArchive
29 #include <archive.h>
30 #include <archive_entry.h>
31 
32 // Qt Headers
33 #include <QtCore>
34 
35 class QMimeType;
36 
37 typedef struct {
38 
39 	/* Name of the entry */
40 	QString name;
41 
42 	/* Size of the entry */
43 	quint64 size;
44 
45 	/* Type of the entry */
46 	int type;
47 
48 	/* Stat equivalent */
49 	struct stat info;
50 } ArchiveEntry;
51 
52 typedef QList<ArchiveEntry*> ArchiveEntries;
53 
54 class LibArchiveQt : public QThread {
55 	Q_OBJECT
56 
57 	public:
58 		/* Used with updateInputFiles, this helps libarchive to choose how to handle paths */
59 		enum InputFileMode {
60 			AbsolutePath = 0x703857,	// Use absolute file paths - Discouraged
61 			RelativeToRoot,				// All paths will be relative to '/' - Useful for packaging of installed files
62 			RelativeToHome,				// Files will have paths relative to home folder - good for saving config files
63 			RelativeToCurrent,			// The paths will be relative to the current path - Useful for archiving files in current dir [Default]
64 			RelativeToWorkDir,			// Set archive paths of the file relative to @src - @src should be set before calling updateInputFiles
65 			CommonRelativePath,			// Added files will have paths relative to path common to all files - Costly for large number of files
66 		};
67 
68 		LibArchiveQt( QString );
69 
70 		// Convenience Functions
71 		void updateInputFiles( QStringList, LibArchiveQt::InputFileMode inMode = LibArchiveQt::RelativeToCurrent );
72 		void setWorkingDir( QString );
73 		void setDestination( QString );
74 		void waitForFinished();
75 
76 		/* Create an archive */
77 		void createArchive();
78 
79 		/* Extract the archive */
80 		void extractArchive();
81 
82 		/* Extract a named member of the archive */
83 		void extractMember( QString );
84 
85 		/* List the contetns of the archive */
86 		ArchiveEntries listArchive();
87 
88 		/* Exit status */
89 		int exitStatus();
90 
91 		/* Convenience functions */
92 		static QString suffix( QString name );
93 		static QStringList supportedFormats();
94 
95 	private:
96 		enum Mode {
97 			None				= 0xF650E7,
98 			Single,
99 			Container
100 		};
101 
102 		enum Job {
103 			NoJob				= 0x25CEE9,
104 			CreateArchive,
105 			ExtractArchive,
106 			ExtractMember,
107 			ListArchive
108 		};
109 
110 		/* Internal worker for copying data */
111 		int copyData( struct archive *ar, struct archive *aw );
112 
113 		/* Set the archive filter format based on extensions */
114 		void setFilterFormat( QMimeType mType );
115 
116 		/* Create an archive - Internal Worker */
117 		bool doCreateArchive();
118 
119 		/* Extract the archive - Internal Worker */
120 		bool doExtractArchive();
121 
122 		/* Extract a named member of the archive - Internal Worker */
123 		bool doExtractMember( QString );
124 
125 		int mArchiveFilter;
126 		int mArchiveFormat;
127 
128 		QString archiveName;
129 
130 		QHash<QString, QString> inputList;
131 		QString dest;
132 		QString src;
133 
134 		ArchiveEntries memberList;
135 		bool readDone;
136 		int archiveType;
137 
138 		/* What job are we doing? */
139 		int mJob;
140 
141 		/* Is the job running? */
142 		bool isRunning;
143 
144 		/* Exit status */
145 		int mExitStatus;
146 
147 		/* Member to be extracted */
148 		QString extractedMember;
149 
150 	protected:
151 		void run();
152 
153 	Q_SIGNALS:
154 		void jobComplete();
155 		void jobFailed();
156 
157 		/* Progress is always in percentage */
158 		void progress( int );
159 };
160