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 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