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