Home | History | Annotate | Download | only in squashfs-tools
      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 (at) 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