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