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 */ 70struct 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 79struct hash_table_entry { 80 long long start; 81 int bytes; 82 struct hash_table_entry *next; 83}; 84 85struct 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 104typedef 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 117struct 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 */ 127struct 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 */ 142struct 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 */ 157struct 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 174struct dir_ent { 175 char name[SQUASHFS_NAME_LEN + 1]; 176 unsigned int start_block; 177 unsigned int offset; 178 unsigned int type; 179}; 180 181struct 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 192struct file_entry { 193 int offset; 194 int size; 195 struct cache_entry *buffer; 196}; 197 198 199struct 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 212struct path_entry { 213 char *name; 214 regex_t *preg; 215 struct pathname *paths; 216}; 217 218struct pathname { 219 int names; 220 struct path_entry *name; 221}; 222 223struct pathnames { 224 int count; 225 struct pathname *path[0]; 226}; 227#define PATHS_ALLOC_SIZE 10 228 229/* globals */ 230extern struct super_block sBlk; 231extern squashfs_operations s_ops; 232extern int swap; 233extern char *inode_table, *directory_table; 234extern struct hash_table_entry *inode_table_hash[65536], 235 *directory_table_hash[65536]; 236extern unsigned int *uid_table, *guid_table; 237extern pthread_mutex_t screen_mutex; 238extern int progress_enabled; 239extern int inode_number; 240extern int lookup_type[]; 241extern int fd; 242extern struct queue *to_reader, *to_inflate, *to_writer; 243extern struct cache *fragment_cache, *data_cache; 244 245/* unsquashfs.c */ 246extern int lookup_entry(struct hash_table_entry **, long long); 247extern int read_fs_bytes(int fd, long long, int, void *); 248extern int read_block(int, long long, long long *, int, void *); 249extern void enable_progress_bar(); 250extern void disable_progress_bar(); 251extern void dump_queue(struct queue *); 252extern void dump_cache(struct cache *); 253 254/* unsquash-1.c */ 255extern void read_block_list_1(unsigned int *, char *, int); 256extern int read_fragment_table_1(long long *); 257extern struct inode *read_inode_1(unsigned int, unsigned int); 258extern struct dir *squashfs_opendir_1(unsigned int, unsigned int, 259 struct inode **); 260extern int read_uids_guids_1(); 261 262/* unsquash-2.c */ 263extern void read_block_list_2(unsigned int *, char *, int); 264extern int read_fragment_table_2(long long *); 265extern void read_fragment_2(unsigned int, long long *, int *); 266extern struct inode *read_inode_2(unsigned int, unsigned int); 267 268/* unsquash-3.c */ 269extern int read_fragment_table_3(long long *); 270extern void read_fragment_3(unsigned int, long long *, int *); 271extern struct inode *read_inode_3(unsigned int, unsigned int); 272extern struct dir *squashfs_opendir_3(unsigned int, unsigned int, 273 struct inode **); 274 275/* unsquash-4.c */ 276extern int read_fragment_table_4(long long *); 277extern void read_fragment_4(unsigned int, long long *, int *); 278extern struct inode *read_inode_4(unsigned int, unsigned int); 279extern struct dir *squashfs_opendir_4(unsigned int, unsigned int, 280 struct inode **); 281extern int read_uids_guids_4(); 282#endif 283