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