blob: 4836b8d371b8221ed15c5a5a61ce76bb907f50c7 [file] [log] [blame]
#ifndef UNSQUASHFS_H
#define UNSQUASHFS_H
/*
* Unsquash a squashfs filesystem. This is a highly compressed read only
* filesystem.
*
* Copyright (c) 2009, 2010, 2013, 2014
* Phillip Lougher <phillip@squashfs.org.uk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* unsquashfs.h
*/
#define TRUE 1
#define FALSE 0
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <utime.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <regex.h>
#include <fnmatch.h>
#include <signal.h>
#include <pthread.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#ifndef FNM_EXTMATCH /* glibc extension */
#define FNM_EXTMATCH 0
#endif
#ifndef linux
#define __BYTE_ORDER BYTE_ORDER
#define __BIG_ENDIAN BIG_ENDIAN
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#else
#include <endian.h>
#endif
#include "squashfs_fs.h"
#include "error.h"
#define CALCULATE_HASH(start) (start & 0xffff)
/*
* Unified superblock containing fields for all superblocks
*/
struct super_block {
struct squashfs_super_block s;
/* fields only used by squashfs 3 and earlier layouts */
unsigned int no_uids;
unsigned int no_guids;
long long uid_start;
long long guid_start;
};
struct hash_table_entry {
long long start;
int bytes;
struct hash_table_entry *next;
};
struct inode {
int blocks;
char *block_ptr;
long long data;
int fragment;
int frag_bytes;
gid_t gid;
int inode_number;
int mode;
int offset;
long long start;
char *symlink;
time_t time;
int type;
uid_t uid;
char sparse;
unsigned int xattr;
};
typedef struct squashfs_operations {
struct dir *(*squashfs_opendir)(unsigned int block_start,
unsigned int offset, struct inode **i);
void (*read_fragment)(unsigned int fragment, long long *start_block,
int *size);
int (*read_fragment_table)(long long *);
void (*read_block_list)(unsigned int *block_list, char *block_ptr,
int blocks);
struct inode *(*read_inode)(unsigned int start_block,
unsigned int offset);
int (*read_uids_guids)();
} squashfs_operations;
struct test {
int mask;
int value;
int position;
char mode;
};
/* Cache status struct. Caches are used to keep
track of memory buffers passed between different threads */
struct cache {
int max_buffers;
int count;
int used;
int buffer_size;
int wait_free;
int wait_pending;
pthread_mutex_t mutex;
pthread_cond_t wait_for_free;
pthread_cond_t wait_for_pending;
struct cache_entry *free_list;
struct cache_entry *hash_table[65536];
};
/* struct describing a cache entry passed between threads */
struct cache_entry {
struct cache *cache;
long long block;
int size;
int used;
int error;
int pending;
struct cache_entry *hash_next;
struct cache_entry *hash_prev;
struct cache_entry *free_next;
struct cache_entry *free_prev;
char *data;
};
/* struct describing queues used to pass data between threads */
struct queue {
int size;
int readp;
int writep;
pthread_mutex_t mutex;
pthread_cond_t empty;
pthread_cond_t full;
void **data;
};
/* default size of fragment buffer in Mbytes */
#define FRAGMENT_BUFFER_DEFAULT 256
/* default size of data buffer in Mbytes */
#define DATA_BUFFER_DEFAULT 256
#define DIR_ENT_SIZE 16
struct dir_ent {
char name[SQUASHFS_NAME_LEN + 1];
unsigned int start_block;
unsigned int offset;
unsigned int type;
};
struct dir {
int dir_count;
int cur_entry;
unsigned int mode;
uid_t uid;
gid_t guid;
unsigned int mtime;
unsigned int xattr;
struct dir_ent *dirs;
};
struct file_entry {
int offset;
int size;
struct cache_entry *buffer;
};
struct squashfs_file {
int fd;
int blocks;
long long file_size;
int mode;
uid_t uid;
gid_t gid;
time_t time;
char *pathname;
char sparse;
unsigned int xattr;
};
struct path_entry {
char *name;
regex_t *preg;
struct pathname *paths;
};
struct pathname {
int names;
struct path_entry *name;
};
struct pathnames {
int count;
struct pathname *path[0];
};
#define PATHS_ALLOC_SIZE 10
/* globals */
extern struct super_block sBlk;
extern squashfs_operations s_ops;
extern int swap;
extern char *inode_table, *directory_table;
extern struct hash_table_entry *inode_table_hash[65536],
*directory_table_hash[65536];
extern unsigned int *uid_table, *guid_table;
extern pthread_mutex_t screen_mutex;
extern int progress_enabled;
extern int inode_number;
extern int lookup_type[];
extern int fd;
extern struct queue *to_reader, *to_inflate, *to_writer;
extern struct cache *fragment_cache, *data_cache;
/* unsquashfs.c */
extern int lookup_entry(struct hash_table_entry **, long long);
extern int read_fs_bytes(int fd, long long, int, void *);
extern int read_block(int, long long, long long *, int, void *);
extern void enable_progress_bar();
extern void disable_progress_bar();
extern void dump_queue(struct queue *);
extern void dump_cache(struct cache *);
/* unsquash-1.c */
extern void read_block_list_1(unsigned int *, char *, int);
extern int read_fragment_table_1(long long *);
extern struct inode *read_inode_1(unsigned int, unsigned int);
extern struct dir *squashfs_opendir_1(unsigned int, unsigned int,
struct inode **);
extern int read_uids_guids_1();
/* unsquash-2.c */
extern void read_block_list_2(unsigned int *, char *, int);
extern int read_fragment_table_2(long long *);
extern void read_fragment_2(unsigned int, long long *, int *);
extern struct inode *read_inode_2(unsigned int, unsigned int);
/* unsquash-3.c */
extern int read_fragment_table_3(long long *);
extern void read_fragment_3(unsigned int, long long *, int *);
extern struct inode *read_inode_3(unsigned int, unsigned int);
extern struct dir *squashfs_opendir_3(unsigned int, unsigned int,
struct inode **);
/* unsquash-4.c */
extern int read_fragment_table_4(long long *);
extern void read_fragment_4(unsigned int, long long *, int *);
extern struct inode *read_inode_4(unsigned int, unsigned int);
extern struct dir *squashfs_opendir_4(unsigned int, unsigned int,
struct inode **);
extern int read_uids_guids_4();
#endif