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 linux
51 #define __BYTE_ORDER BYTE_ORDER
52 #define __BIG_ENDIAN BIG_ENDIAN
53 #define __LITTLE_ENDIAN LITTLE_ENDIAN
54 #else
55 #include <endian.h>
56 #endif
57 
58 #include "squashfs_fs.h"
59 #include "error.h"
60 
61 #define CALCULATE_HASH(start)	(start & 0xffff)
62 
63 /*
64  * Unified superblock containing fields for all superblocks
65  */
66 struct super_block {
67 	struct squashfs_super_block s;
68 	/* fields only used by squashfs 3 and earlier layouts */
69 	unsigned int		no_uids;
70 	unsigned int		no_guids;
71 	long long		uid_start;
72 	long long		guid_start;
73 };
74 
75 struct hash_table_entry {
76 	long long	start;
77 	int		bytes;
78 	struct hash_table_entry *next;
79 };
80 
81 struct inode {
82 	int blocks;
83 	char *block_ptr;
84 	long long data;
85 	int fragment;
86 	int frag_bytes;
87 	gid_t gid;
88 	int inode_number;
89 	int mode;
90 	int offset;
91 	long long start;
92 	char *symlink;
93 	time_t time;
94 	int type;
95 	uid_t uid;
96 	char sparse;
97 	unsigned int xattr;
98 };
99 
100 typedef struct squashfs_operations {
101 	struct dir *(*squashfs_opendir)(unsigned int block_start,
102 		unsigned int offset, struct inode **i);
103 	void (*read_fragment)(unsigned int fragment, long long *start_block,
104 		int *size);
105 	int (*read_fragment_table)(long long *);
106 	void (*read_block_list)(unsigned int *block_list, char *block_ptr,
107 		int blocks);
108 	struct inode *(*read_inode)(unsigned int start_block,
109 		unsigned int offset);
110 	int (*read_uids_guids)();
111 } squashfs_operations;
112 
113 struct test {
114 	int mask;
115 	int value;
116 	int position;
117 	char mode;
118 };
119 
120 
121 /* Cache status struct.  Caches are used to keep
122   track of memory buffers passed between different threads */
123 struct cache {
124 	int	max_buffers;
125 	int	count;
126 	int	used;
127 	int	buffer_size;
128 	int	wait_free;
129 	int	wait_pending;
130 	pthread_mutex_t	mutex;
131 	pthread_cond_t wait_for_free;
132 	pthread_cond_t wait_for_pending;
133 	struct cache_entry *free_list;
134 	struct cache_entry *hash_table[65536];
135 };
136 
137 /* struct describing a cache entry passed between threads */
138 struct cache_entry {
139 	struct cache *cache;
140 	long long block;
141 	int	size;
142 	int	used;
143 	int error;
144 	int	pending;
145 	struct cache_entry *hash_next;
146 	struct cache_entry *hash_prev;
147 	struct cache_entry *free_next;
148 	struct cache_entry *free_prev;
149 	char *data;
150 };
151 
152 /* struct describing queues used to pass data between threads */
153 struct queue {
154 	int	size;
155 	int	readp;
156 	int	writep;
157 	pthread_mutex_t	mutex;
158 	pthread_cond_t empty;
159 	pthread_cond_t full;
160 	void **data;
161 };
162 
163 /* default size of fragment buffer in Mbytes */
164 #define FRAGMENT_BUFFER_DEFAULT 256
165 /* default size of data buffer in Mbytes */
166 #define DATA_BUFFER_DEFAULT 256
167 
168 #define DIR_ENT_SIZE	16
169 
170 struct dir_ent	{
171 	char		name[SQUASHFS_NAME_LEN + 1];
172 	unsigned int	start_block;
173 	unsigned int	offset;
174 	unsigned int	type;
175 };
176 
177 struct dir {
178 	int		dir_count;
179 	int 		cur_entry;
180 	unsigned int	mode;
181 	uid_t		uid;
182 	gid_t		guid;
183 	unsigned int	mtime;
184 	unsigned int xattr;
185 	struct dir_ent	*dirs;
186 };
187 
188 struct file_entry {
189 	int offset;
190 	int size;
191 	struct cache_entry *buffer;
192 };
193 
194 
195 struct squashfs_file {
196 	int fd;
197 	int blocks;
198 	long long file_size;
199 	int mode;
200 	uid_t uid;
201 	gid_t gid;
202 	time_t time;
203 	char *pathname;
204 	char sparse;
205 	unsigned int xattr;
206 };
207 
208 struct path_entry {
209 	char *name;
210 	regex_t *preg;
211 	struct pathname *paths;
212 };
213 
214 struct pathname {
215 	int names;
216 	struct path_entry *name;
217 };
218 
219 struct pathnames {
220 	int count;
221 	struct pathname *path[0];
222 };
223 #define PATHS_ALLOC_SIZE 10
224 
225 /* globals */
226 extern struct super_block sBlk;
227 extern squashfs_operations s_ops;
228 extern int swap;
229 extern char *inode_table, *directory_table;
230 extern struct hash_table_entry *inode_table_hash[65536],
231 	*directory_table_hash[65536];
232 extern unsigned int *uid_table, *guid_table;
233 extern pthread_mutex_t screen_mutex;
234 extern int progress_enabled;
235 extern int inode_number;
236 extern int lookup_type[];
237 extern int fd;
238 extern struct queue *to_reader, *to_inflate, *to_writer;
239 extern struct cache *fragment_cache, *data_cache;
240 
241 /* unsquashfs.c */
242 extern int lookup_entry(struct hash_table_entry **, long long);
243 extern int read_fs_bytes(int fd, long long, int, void *);
244 extern int read_block(int, long long, long long *, int, void *);
245 extern void enable_progress_bar();
246 extern void disable_progress_bar();
247 extern void dump_queue(struct queue *);
248 extern void dump_cache(struct cache *);
249 
250 /* unsquash-1.c */
251 extern void read_block_list_1(unsigned int *, char *, int);
252 extern int read_fragment_table_1(long long *);
253 extern struct inode *read_inode_1(unsigned int, unsigned int);
254 extern struct dir *squashfs_opendir_1(unsigned int, unsigned int,
255 	struct inode **);
256 extern int read_uids_guids_1();
257 
258 /* unsquash-2.c */
259 extern void read_block_list_2(unsigned int *, char *, int);
260 extern int read_fragment_table_2(long long *);
261 extern void read_fragment_2(unsigned int, long long *, int *);
262 extern struct inode *read_inode_2(unsigned int, unsigned int);
263 
264 /* unsquash-3.c */
265 extern int read_fragment_table_3(long long *);
266 extern void read_fragment_3(unsigned int, long long *, int *);
267 extern struct inode *read_inode_3(unsigned int, unsigned int);
268 extern struct dir *squashfs_opendir_3(unsigned int, unsigned int,
269 	struct inode **);
270 
271 /* unsquash-4.c */
272 extern int read_fragment_table_4(long long *);
273 extern void read_fragment_4(unsigned int, long long *, int *);
274 extern struct inode *read_inode_4(unsigned int, unsigned int);
275 extern struct dir *squashfs_opendir_4(unsigned int, unsigned int,
276 	struct inode **);
277 extern int read_uids_guids_4();
278 #endif
279