1 #ifndef UNSQUASHFS_H
2 #define UNSQUASHFS_H
3 /*
4  * Unsquash a squashfs filesystem.  This is a highly compressed read only
5  * filesystem.
6  *
7  * Copyright (c) 2009, 2010, 2013, 2014
8  * Phillip Lougher <phillip@squashfs.org.uk>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2,
13  * or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23  *
24  * unsquashfs.h
25  */
26 
27 #define TRUE 1
28 #define FALSE 0
29 #include <stdio.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <sys/mman.h>
38 #include <utime.h>
39 #include <pwd.h>
40 #include <grp.h>
41 #include <time.h>
42 #include <regex.h>
43 #include <fnmatch.h>
44 #include <signal.h>
45 #include <pthread.h>
46 #include <math.h>
47 #include <sys/ioctl.h>
48 #include <sys/time.h>
49 
50 #ifndef FNM_EXTMATCH /* glibc extension */
51     #define FNM_EXTMATCH 0
52 #endif
53 
54 #ifndef linux
55 #define __BYTE_ORDER BYTE_ORDER
56 #define __BIG_ENDIAN BIG_ENDIAN
57 #define __LITTLE_ENDIAN LITTLE_ENDIAN
58 #else
59 #include <endian.h>
60 #endif
61 
62 #include "squashfs_fs.h"
63 #include "error.h"
64 
65 #define CALCULATE_HASH(start)	(start & 0xffff)
66 
67 /*
68  * Unified superblock containing fields for all superblocks
69  */
70 struct super_block {
71 	struct squashfs_super_block s;
72 	/* fields only used by squashfs 3 and earlier layouts */
73 	unsigned int		no_uids;
74 	unsigned int		no_guids;
75 	long long		uid_start;
76 	long long		guid_start;
77 };
78 
79 struct hash_table_entry {
80 	long long	start;
81 	int		bytes;
82 	struct hash_table_entry *next;
83 };
84 
85 struct inode {
86 	int blocks;
87 	char *block_ptr;
88 	long long data;
89 	int fragment;
90 	int frag_bytes;
91 	gid_t gid;
92 	int inode_number;
93 	int mode;
94 	int offset;
95 	long long start;
96 	char *symlink;
97 	time_t time;
98 	int type;
99 	uid_t uid;
100 	char sparse;
101 	unsigned int xattr;
102 };
103 
104 typedef struct squashfs_operations {
105 	struct dir *(*squashfs_opendir)(unsigned int block_start,
106 		unsigned int offset, struct inode **i);
107 	void (*read_fragment)(unsigned int fragment, long long *start_block,
108 		int *size);
109 	int (*read_fragment_table)(long long *);
110 	void (*read_block_list)(unsigned int *block_list, char *block_ptr,
111 		int blocks);
112 	struct inode *(*read_inode)(unsigned int start_block,
113 		unsigned int offset);
114 	int (*read_uids_guids)();
115 } squashfs_operations;
116 
117 struct test {
118 	int mask;
119 	int value;
120 	int position;
121 	char mode;
122 };
123 
124 
125 /* Cache status struct.  Caches are used to keep
126   track of memory buffers passed between different threads */
127 struct cache {
128 	int	max_buffers;
129 	int	count;
130 	int	used;
131 	int	buffer_size;
132 	int	wait_free;
133 	int	wait_pending;
134 	pthread_mutex_t	mutex;
135 	pthread_cond_t wait_for_free;
136 	pthread_cond_t wait_for_pending;
137 	struct cache_entry *free_list;
138 	struct cache_entry *hash_table[65536];
139 };
140 
141 /* struct describing a cache entry passed between threads */
142 struct cache_entry {
143 	struct cache *cache;
144 	long long block;
145 	int	size;
146 	int	used;
147 	int error;
148 	int	pending;
149 	struct cache_entry *hash_next;
150 	struct cache_entry *hash_prev;
151 	struct cache_entry *free_next;
152 	struct cache_entry *free_prev;
153 	char *data;
154 };
155 
156 /* struct describing queues used to pass data between threads */
157 struct queue {
158 	int	size;
159 	int	readp;
160 	int	writep;
161 	pthread_mutex_t	mutex;
162 	pthread_cond_t empty;
163 	pthread_cond_t full;
164 	void **data;
165 };
166 
167 /* default size of fragment buffer in Mbytes */
168 #define FRAGMENT_BUFFER_DEFAULT 256
169 /* default size of data buffer in Mbytes */
170 #define DATA_BUFFER_DEFAULT 256
171 
172 #define DIR_ENT_SIZE	16
173 
174 struct dir_ent	{
175 	char		name[SQUASHFS_NAME_LEN + 1];
176 	unsigned int	start_block;
177 	unsigned int	offset;
178 	unsigned int	type;
179 };
180 
181 struct dir {
182 	int		dir_count;
183 	int 		cur_entry;
184 	unsigned int	mode;
185 	uid_t		uid;
186 	gid_t		guid;
187 	unsigned int	mtime;
188 	unsigned int xattr;
189 	struct dir_ent	*dirs;
190 };
191 
192 struct file_entry {
193 	int offset;
194 	int size;
195 	struct cache_entry *buffer;
196 };
197 
198 
199 struct squashfs_file {
200 	int fd;
201 	int blocks;
202 	long long file_size;
203 	int mode;
204 	uid_t uid;
205 	gid_t gid;
206 	time_t time;
207 	char *pathname;
208 	char sparse;
209 	unsigned int xattr;
210 };
211 
212 struct path_entry {
213 	char *name;
214 	regex_t *preg;
215 	struct pathname *paths;
216 };
217 
218 struct pathname {
219 	int names;
220 	struct path_entry *name;
221 };
222 
223 struct pathnames {
224 	int count;
225 	struct pathname *path[0];
226 };
227 #define PATHS_ALLOC_SIZE 10
228 
229 /* globals */
230 extern struct super_block sBlk;
231 extern squashfs_operations s_ops;
232 extern int swap;
233 extern char *inode_table, *directory_table;
234 extern struct hash_table_entry *inode_table_hash[65536],
235 	*directory_table_hash[65536];
236 extern unsigned int *uid_table, *guid_table;
237 extern pthread_mutex_t screen_mutex;
238 extern int progress_enabled;
239 extern int inode_number;
240 extern int lookup_type[];
241 extern int fd;
242 extern struct queue *to_reader, *to_inflate, *to_writer;
243 extern struct cache *fragment_cache, *data_cache;
244 
245 /* unsquashfs.c */
246 extern int lookup_entry(struct hash_table_entry **, long long);
247 extern int read_fs_bytes(int fd, long long, int, void *);
248 extern int read_block(int, long long, long long *, int, void *);
249 extern void enable_progress_bar();
250 extern void disable_progress_bar();
251 extern void dump_queue(struct queue *);
252 extern void dump_cache(struct cache *);
253 
254 /* unsquash-1.c */
255 extern void read_block_list_1(unsigned int *, char *, int);
256 extern int read_fragment_table_1(long long *);
257 extern struct inode *read_inode_1(unsigned int, unsigned int);
258 extern struct dir *squashfs_opendir_1(unsigned int, unsigned int,
259 	struct inode **);
260 extern int read_uids_guids_1();
261 
262 /* unsquash-2.c */
263 extern void read_block_list_2(unsigned int *, char *, int);
264 extern int read_fragment_table_2(long long *);
265 extern void read_fragment_2(unsigned int, long long *, int *);
266 extern struct inode *read_inode_2(unsigned int, unsigned int);
267 
268 /* unsquash-3.c */
269 extern int read_fragment_table_3(long long *);
270 extern void read_fragment_3(unsigned int, long long *, int *);
271 extern struct inode *read_inode_3(unsigned int, unsigned int);
272 extern struct dir *squashfs_opendir_3(unsigned int, unsigned int,
273 	struct inode **);
274 
275 /* unsquash-4.c */
276 extern int read_fragment_table_4(long long *);
277 extern void read_fragment_4(unsigned int, long long *, int *);
278 extern struct inode *read_inode_4(unsigned int, unsigned int);
279 extern struct dir *squashfs_opendir_4(unsigned int, unsigned int,
280 	struct inode **);
281 extern int read_uids_guids_4();
282 #endif
283