Home | History | Annotate | Download | only in squashfs-tools
      1 /*
      2  * Unsquash a squashfs filesystem.  This is a highly compressed read only
      3  * filesystem.
      4  *
      5  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
      6  * 2012, 2013, 2014
      7  * Phillip Lougher <phillip (at) squashfs.org.uk>
      8  *
      9  * This program is free software; you can redistribute it and/or
     10  * modify it under the terms of the GNU General Public License
     11  * as published by the Free Software Foundation; either version 2,
     12  * or (at your option) any later version.
     13  *
     14  * This program is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  * GNU General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU General Public License
     20  * along with this program; if not, write to the Free Software
     21  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     22  *
     23  * unsquashfs.c
     24  */
     25 
     26 #include "unsquashfs.h"
     27 #include "squashfs_swap.h"
     28 #include "squashfs_compat.h"
     29 #include "compressor.h"
     30 #include "xattr.h"
     31 #include "unsquashfs_info.h"
     32 #include "stdarg.h"
     33 
     34 #include <sys/sysinfo.h>
     35 #include <sys/types.h>
     36 #include <sys/time.h>
     37 #include <sys/resource.h>
     38 #include <limits.h>
     39 #include <ctype.h>
     40 
     41 struct cache *fragment_cache, *data_cache;
     42 struct queue *to_reader, *to_inflate, *to_writer, *from_writer;
     43 pthread_t *thread, *inflator_thread;
     44 pthread_mutex_t	fragment_mutex;
     45 
     46 /* user options that control parallelisation */
     47 int processors = -1;
     48 
     49 struct super_block sBlk;
     50 squashfs_operations s_ops;
     51 struct compressor *comp;
     52 
     53 int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0,
     54 	dev_count = 0, fifo_count = 0;
     55 char *inode_table = NULL, *directory_table = NULL;
     56 struct hash_table_entry *inode_table_hash[65536], *directory_table_hash[65536];
     57 int fd;
     58 unsigned int *uid_table, *guid_table;
     59 unsigned int cached_frag = SQUASHFS_INVALID_FRAG;
     60 char *fragment_data;
     61 char *file_data;
     62 char *data;
     63 unsigned int block_size;
     64 unsigned int block_log;
     65 int lsonly = FALSE, info = FALSE, force = FALSE, short_ls = TRUE;
     66 int use_regex = FALSE;
     67 char **created_inode;
     68 int root_process;
     69 int columns;
     70 int rotate = 0;
     71 pthread_mutex_t	screen_mutex;
     72 int progress = TRUE, progress_enabled = FALSE;
     73 unsigned int total_blocks = 0, total_files = 0, total_inodes = 0;
     74 unsigned int cur_blocks = 0;
     75 int inode_number = 1;
     76 int no_xattrs = XATTR_DEF;
     77 int user_xattrs = FALSE;
     78 
     79 int lookup_type[] = {
     80 	0,
     81 	S_IFDIR,
     82 	S_IFREG,
     83 	S_IFLNK,
     84 	S_IFBLK,
     85 	S_IFCHR,
     86 	S_IFIFO,
     87 	S_IFSOCK,
     88 	S_IFDIR,
     89 	S_IFREG,
     90 	S_IFLNK,
     91 	S_IFBLK,
     92 	S_IFCHR,
     93 	S_IFIFO,
     94 	S_IFSOCK
     95 };
     96 
     97 struct test table[] = {
     98 	{ S_IFMT, S_IFSOCK, 0, 's' },
     99 	{ S_IFMT, S_IFLNK, 0, 'l' },
    100 	{ S_IFMT, S_IFBLK, 0, 'b' },
    101 	{ S_IFMT, S_IFDIR, 0, 'd' },
    102 	{ S_IFMT, S_IFCHR, 0, 'c' },
    103 	{ S_IFMT, S_IFIFO, 0, 'p' },
    104 	{ S_IRUSR, S_IRUSR, 1, 'r' },
    105 	{ S_IWUSR, S_IWUSR, 2, 'w' },
    106 	{ S_IRGRP, S_IRGRP, 4, 'r' },
    107 	{ S_IWGRP, S_IWGRP, 5, 'w' },
    108 	{ S_IROTH, S_IROTH, 7, 'r' },
    109 	{ S_IWOTH, S_IWOTH, 8, 'w' },
    110 	{ S_IXUSR | S_ISUID, S_IXUSR | S_ISUID, 3, 's' },
    111 	{ S_IXUSR | S_ISUID, S_ISUID, 3, 'S' },
    112 	{ S_IXUSR | S_ISUID, S_IXUSR, 3, 'x' },
    113 	{ S_IXGRP | S_ISGID, S_IXGRP | S_ISGID, 6, 's' },
    114 	{ S_IXGRP | S_ISGID, S_ISGID, 6, 'S' },
    115 	{ S_IXGRP | S_ISGID, S_IXGRP, 6, 'x' },
    116 	{ S_IXOTH | S_ISVTX, S_IXOTH | S_ISVTX, 9, 't' },
    117 	{ S_IXOTH | S_ISVTX, S_ISVTX, 9, 'T' },
    118 	{ S_IXOTH | S_ISVTX, S_IXOTH, 9, 'x' },
    119 	{ 0, 0, 0, 0}
    120 };
    121 
    122 void progress_bar(long long current, long long max, int columns);
    123 
    124 #define MAX_LINE 16384
    125 
    126 void prep_exit()
    127 {
    128 }
    129 
    130 
    131 void sigwinch_handler()
    132 {
    133 	struct winsize winsize;
    134 
    135 	if(ioctl(1, TIOCGWINSZ, &winsize) == -1) {
    136 		if(isatty(STDOUT_FILENO))
    137 			ERROR("TIOCGWINSZ ioctl failed, defaulting to 80 "
    138 				"columns\n");
    139 		columns = 80;
    140 	} else
    141 		columns = winsize.ws_col;
    142 }
    143 
    144 
    145 void sigalrm_handler()
    146 {
    147 	rotate = (rotate + 1) % 4;
    148 }
    149 
    150 
    151 int add_overflow(int a, int b)
    152 {
    153 	return (INT_MAX - a) < b;
    154 }
    155 
    156 
    157 int shift_overflow(int a, int shift)
    158 {
    159 	return (INT_MAX >> shift) < a;
    160 }
    161 
    162 
    163 int multiply_overflow(int a, int multiplier)
    164 {
    165 	return (INT_MAX / multiplier) < a;
    166 }
    167 
    168 
    169 struct queue *queue_init(int size)
    170 {
    171 	struct queue *queue = malloc(sizeof(struct queue));
    172 
    173 	if(queue == NULL)
    174 		EXIT_UNSQUASH("Out of memory in queue_init\n");
    175 
    176 	if(add_overflow(size, 1) ||
    177 				multiply_overflow(size + 1, sizeof(void *)))
    178 		EXIT_UNSQUASH("Size too large in queue_init\n");
    179 
    180 	queue->data = malloc(sizeof(void *) * (size + 1));
    181 	if(queue->data == NULL)
    182 		EXIT_UNSQUASH("Out of memory in queue_init\n");
    183 
    184 	queue->size = size + 1;
    185 	queue->readp = queue->writep = 0;
    186 	pthread_mutex_init(&queue->mutex, NULL);
    187 	pthread_cond_init(&queue->empty, NULL);
    188 	pthread_cond_init(&queue->full, NULL);
    189 
    190 	return queue;
    191 }
    192 
    193 
    194 void queue_put(struct queue *queue, void *data)
    195 {
    196 	int nextp;
    197 
    198 	pthread_mutex_lock(&queue->mutex);
    199 
    200 	while((nextp = (queue->writep + 1) % queue->size) == queue->readp)
    201 		pthread_cond_wait(&queue->full, &queue->mutex);
    202 
    203 	queue->data[queue->writep] = data;
    204 	queue->writep = nextp;
    205 	pthread_cond_signal(&queue->empty);
    206 	pthread_mutex_unlock(&queue->mutex);
    207 }
    208 
    209 
    210 void *queue_get(struct queue *queue)
    211 {
    212 	void *data;
    213 	pthread_mutex_lock(&queue->mutex);
    214 
    215 	while(queue->readp == queue->writep)
    216 		pthread_cond_wait(&queue->empty, &queue->mutex);
    217 
    218 	data = queue->data[queue->readp];
    219 	queue->readp = (queue->readp + 1) % queue->size;
    220 	pthread_cond_signal(&queue->full);
    221 	pthread_mutex_unlock(&queue->mutex);
    222 
    223 	return data;
    224 }
    225 
    226 
    227 void dump_queue(struct queue *queue)
    228 {
    229 	pthread_mutex_lock(&queue->mutex);
    230 
    231 	printf("Max size %d, size %d%s\n", queue->size - 1,
    232 		queue->readp <= queue->writep ? queue->writep - queue->readp :
    233 			queue->size - queue->readp + queue->writep,
    234 		queue->readp == queue->writep ? " (EMPTY)" :
    235 			((queue->writep + 1) % queue->size) == queue->readp ?
    236 			" (FULL)" : "");
    237 
    238 	pthread_mutex_unlock(&queue->mutex);
    239 }
    240 
    241 
    242 /* Called with the cache mutex held */
    243 void insert_hash_table(struct cache *cache, struct cache_entry *entry)
    244 {
    245 	int hash = CALCULATE_HASH(entry->block);
    246 
    247 	entry->hash_next = cache->hash_table[hash];
    248 	cache->hash_table[hash] = entry;
    249 	entry->hash_prev = NULL;
    250 	if(entry->hash_next)
    251 		entry->hash_next->hash_prev = entry;
    252 }
    253 
    254 
    255 /* Called with the cache mutex held */
    256 void remove_hash_table(struct cache *cache, struct cache_entry *entry)
    257 {
    258 	if(entry->hash_prev)
    259 		entry->hash_prev->hash_next = entry->hash_next;
    260 	else
    261 		cache->hash_table[CALCULATE_HASH(entry->block)] =
    262 			entry->hash_next;
    263 	if(entry->hash_next)
    264 		entry->hash_next->hash_prev = entry->hash_prev;
    265 
    266 	entry->hash_prev = entry->hash_next = NULL;
    267 }
    268 
    269 
    270 /* Called with the cache mutex held */
    271 void insert_free_list(struct cache *cache, struct cache_entry *entry)
    272 {
    273 	if(cache->free_list) {
    274 		entry->free_next = cache->free_list;
    275 		entry->free_prev = cache->free_list->free_prev;
    276 		cache->free_list->free_prev->free_next = entry;
    277 		cache->free_list->free_prev = entry;
    278 	} else {
    279 		cache->free_list = entry;
    280 		entry->free_prev = entry->free_next = entry;
    281 	}
    282 }
    283 
    284 
    285 /* Called with the cache mutex held */
    286 void remove_free_list(struct cache *cache, struct cache_entry *entry)
    287 {
    288 	if(entry->free_prev == NULL || entry->free_next == NULL)
    289 		/* not in free list */
    290 		return;
    291 	else if(entry->free_prev == entry && entry->free_next == entry) {
    292 		/* only this entry in the free list */
    293 		cache->free_list = NULL;
    294 	} else {
    295 		/* more than one entry in the free list */
    296 		entry->free_next->free_prev = entry->free_prev;
    297 		entry->free_prev->free_next = entry->free_next;
    298 		if(cache->free_list == entry)
    299 			cache->free_list = entry->free_next;
    300 	}
    301 
    302 	entry->free_prev = entry->free_next = NULL;
    303 }
    304 
    305 
    306 struct cache *cache_init(int buffer_size, int max_buffers)
    307 {
    308 	struct cache *cache = malloc(sizeof(struct cache));
    309 
    310 	if(cache == NULL)
    311 		EXIT_UNSQUASH("Out of memory in cache_init\n");
    312 
    313 	cache->max_buffers = max_buffers;
    314 	cache->buffer_size = buffer_size;
    315 	cache->count = 0;
    316 	cache->used = 0;
    317 	cache->free_list = NULL;
    318 	memset(cache->hash_table, 0, sizeof(struct cache_entry *) * 65536);
    319 	cache->wait_free = FALSE;
    320 	cache->wait_pending = FALSE;
    321 	pthread_mutex_init(&cache->mutex, NULL);
    322 	pthread_cond_init(&cache->wait_for_free, NULL);
    323 	pthread_cond_init(&cache->wait_for_pending, NULL);
    324 
    325 	return cache;
    326 }
    327 
    328 
    329 struct cache_entry *cache_get(struct cache *cache, long long block, int size)
    330 {
    331 	/*
    332 	 * Get a block out of the cache.  If the block isn't in the cache
    333  	 * it is added and queued to the reader() and inflate() threads for
    334  	 * reading off disk and decompression.  The cache grows until max_blocks
    335  	 * is reached, once this occurs existing discarded blocks on the free
    336  	 * list are reused
    337  	 */
    338 	int hash = CALCULATE_HASH(block);
    339 	struct cache_entry *entry;
    340 
    341 	pthread_mutex_lock(&cache->mutex);
    342 
    343 	for(entry = cache->hash_table[hash]; entry; entry = entry->hash_next)
    344 		if(entry->block == block)
    345 			break;
    346 
    347 	if(entry) {
    348 		/*
    349  		 * found the block in the cache.  If the block is currently unused
    350 		 * remove it from the free list and increment cache used count.
    351  		 */
    352 		if(entry->used == 0) {
    353 			cache->used ++;
    354 			remove_free_list(cache, entry);
    355 		}
    356 		entry->used ++;
    357 		pthread_mutex_unlock(&cache->mutex);
    358 	} else {
    359 		/*
    360  		 * not in the cache
    361 		 *
    362 		 * first try to allocate new block
    363 		 */
    364 		if(cache->count < cache->max_buffers) {
    365 			entry = malloc(sizeof(struct cache_entry));
    366 			if(entry == NULL)
    367 				EXIT_UNSQUASH("Out of memory in cache_get\n");
    368 			entry->data = malloc(cache->buffer_size);
    369 			if(entry->data == NULL)
    370 				EXIT_UNSQUASH("Out of memory in cache_get\n");
    371 			entry->cache = cache;
    372 			entry->free_prev = entry->free_next = NULL;
    373 			cache->count ++;
    374 		} else {
    375 			/*
    376 			 * try to get from free list
    377 			 */
    378 			while(cache->free_list == NULL) {
    379 				cache->wait_free = TRUE;
    380 				pthread_cond_wait(&cache->wait_for_free,
    381 					&cache->mutex);
    382 			}
    383 			entry = cache->free_list;
    384 			remove_free_list(cache, entry);
    385 			remove_hash_table(cache, entry);
    386 		}
    387 
    388 		/*
    389 		 * Initialise block and insert into the hash table.
    390 		 * Increment used which tracks how many buffers in the
    391 		 * cache are actively in use (the other blocks, count - used,
    392 		 * are in the cache and available for lookup, but can also be
    393 		 * re-used).
    394 		 */
    395 		entry->block = block;
    396 		entry->size = size;
    397 		entry->used = 1;
    398 		entry->error = FALSE;
    399 		entry->pending = TRUE;
    400 		insert_hash_table(cache, entry);
    401 		cache->used ++;
    402 
    403 		/*
    404 		 * queue to read thread to read and ultimately (via the
    405 		 * decompress threads) decompress the buffer
    406  		 */
    407 		pthread_mutex_unlock(&cache->mutex);
    408 		queue_put(to_reader, entry);
    409 	}
    410 
    411 	return entry;
    412 }
    413 
    414 
    415 void cache_block_ready(struct cache_entry *entry, int error)
    416 {
    417 	/*
    418 	 * mark cache entry as being complete, reading and (if necessary)
    419  	 * decompression has taken place, and the buffer is valid for use.
    420  	 * If an error occurs reading or decompressing, the buffer also
    421  	 * becomes ready but with an error...
    422  	 */
    423 	pthread_mutex_lock(&entry->cache->mutex);
    424 	entry->pending = FALSE;
    425 	entry->error = error;
    426 
    427 	/*
    428 	 * if the wait_pending flag is set, one or more threads may be waiting
    429 	 * on this buffer
    430 	 */
    431 	if(entry->cache->wait_pending) {
    432 		entry->cache->wait_pending = FALSE;
    433 		pthread_cond_broadcast(&entry->cache->wait_for_pending);
    434 	}
    435 
    436 	pthread_mutex_unlock(&entry->cache->mutex);
    437 }
    438 
    439 
    440 void cache_block_wait(struct cache_entry *entry)
    441 {
    442 	/*
    443 	 * wait for this cache entry to become ready, when reading and (if
    444 	 * necessary) decompression has taken place
    445 	 */
    446 	pthread_mutex_lock(&entry->cache->mutex);
    447 
    448 	while(entry->pending) {
    449 		entry->cache->wait_pending = TRUE;
    450 		pthread_cond_wait(&entry->cache->wait_for_pending,
    451 			&entry->cache->mutex);
    452 	}
    453 
    454 	pthread_mutex_unlock(&entry->cache->mutex);
    455 }
    456 
    457 
    458 void cache_block_put(struct cache_entry *entry)
    459 {
    460 	/*
    461 	 * finished with this cache entry, once the usage count reaches zero it
    462  	 * can be reused and is put onto the free list.  As it remains
    463  	 * accessible via the hash table it can be found getting a new lease of
    464  	 * life before it is reused.
    465  	 */
    466 	pthread_mutex_lock(&entry->cache->mutex);
    467 
    468 	entry->used --;
    469 	if(entry->used == 0) {
    470 		insert_free_list(entry->cache, entry);
    471 		entry->cache->used --;
    472 
    473 		/*
    474 		 * if the wait_free flag is set, one or more threads may be
    475 		 * waiting on this buffer
    476 		 */
    477 		if(entry->cache->wait_free) {
    478 			entry->cache->wait_free = FALSE;
    479 			pthread_cond_broadcast(&entry->cache->wait_for_free);
    480 		}
    481 	}
    482 
    483 	pthread_mutex_unlock(&entry->cache->mutex);
    484 }
    485 
    486 
    487 void dump_cache(struct cache *cache)
    488 {
    489 	pthread_mutex_lock(&cache->mutex);
    490 
    491 	printf("Max buffers %d, Current size %d, Used %d,  %s\n",
    492 		cache->max_buffers, cache->count, cache->used,
    493 		cache->free_list ?  "Free buffers" : "No free buffers");
    494 
    495 	pthread_mutex_unlock(&cache->mutex);
    496 }
    497 
    498 
    499 char *modestr(char *str, int mode)
    500 {
    501 	int i;
    502 
    503 	strcpy(str, "----------");
    504 
    505 	for(i = 0; table[i].mask != 0; i++) {
    506 		if((mode & table[i].mask) == table[i].value)
    507 			str[table[i].position] = table[i].mode;
    508 	}
    509 
    510 	return str;
    511 }
    512 
    513 
    514 #define TOTALCHARS  25
    515 int print_filename(char *pathname, struct inode *inode)
    516 {
    517 	char str[11], dummy[12], dummy2[12]; /* overflow safe */
    518 	char *userstr, *groupstr;
    519 	int padchars;
    520 	struct passwd *user;
    521 	struct group *group;
    522 	struct tm *t;
    523 
    524 	if(short_ls) {
    525 		printf("%s\n", pathname);
    526 		return 1;
    527 	}
    528 
    529 	user = getpwuid(inode->uid);
    530 	if(user == NULL) {
    531 		int res = snprintf(dummy, 12, "%d", inode->uid);
    532 		if(res < 0)
    533 			EXIT_UNSQUASH("snprintf failed in print_filename()\n");
    534 		else if(res >= 12)
    535 			/* unsigned int shouldn't ever need more than 11 bytes
    536 			 * (including terminating '\0') to print in base 10 */
    537 			userstr = "*";
    538 		else
    539 			userstr = dummy;
    540 	} else
    541 		userstr = user->pw_name;
    542 
    543 	group = getgrgid(inode->gid);
    544 	if(group == NULL) {
    545 		int res = snprintf(dummy2, 12, "%d", inode->gid);
    546 		if(res < 0)
    547 			EXIT_UNSQUASH("snprintf failed in print_filename()\n");
    548 		else if(res >= 12)
    549 			/* unsigned int shouldn't ever need more than 11 bytes
    550 			 * (including terminating '\0') to print in base 10 */
    551 			groupstr = "*";
    552 		else
    553 			groupstr = dummy2;
    554 	} else
    555 		groupstr = group->gr_name;
    556 
    557 	printf("%s %s/%s ", modestr(str, inode->mode), userstr, groupstr);
    558 
    559 	switch(inode->mode & S_IFMT) {
    560 		case S_IFREG:
    561 		case S_IFDIR:
    562 		case S_IFSOCK:
    563 		case S_IFIFO:
    564 		case S_IFLNK:
    565 			padchars = TOTALCHARS - strlen(userstr) -
    566 				strlen(groupstr);
    567 
    568 			printf("%*lld ", padchars > 0 ? padchars : 0,
    569 				inode->data);
    570 			break;
    571 		case S_IFCHR:
    572 		case S_IFBLK:
    573 			padchars = TOTALCHARS - strlen(userstr) -
    574 				strlen(groupstr) - 7;
    575 
    576 			printf("%*s%3d,%3d ", padchars > 0 ? padchars : 0, " ",
    577 				(int) inode->data >> 8, (int) inode->data &
    578 				0xff);
    579 			break;
    580 	}
    581 
    582 	t = localtime(&inode->time);
    583 
    584 	printf("%d-%02d-%02d %02d:%02d %s", t->tm_year + 1900, t->tm_mon + 1,
    585 		t->tm_mday, t->tm_hour, t->tm_min, pathname);
    586 	if((inode->mode & S_IFMT) == S_IFLNK)
    587 		printf(" -> %s", inode->symlink);
    588 	printf("\n");
    589 
    590 	return 1;
    591 }
    592 
    593 
    594 void add_entry(struct hash_table_entry *hash_table[], long long start,
    595 	int bytes)
    596 {
    597 	int hash = CALCULATE_HASH(start);
    598 	struct hash_table_entry *hash_table_entry;
    599 
    600 	hash_table_entry = malloc(sizeof(struct hash_table_entry));
    601 	if(hash_table_entry == NULL)
    602 		EXIT_UNSQUASH("Out of memory in add_entry\n");
    603 
    604 	hash_table_entry->start = start;
    605 	hash_table_entry->bytes = bytes;
    606 	hash_table_entry->next = hash_table[hash];
    607 	hash_table[hash] = hash_table_entry;
    608 }
    609 
    610 
    611 int lookup_entry(struct hash_table_entry *hash_table[], long long start)
    612 {
    613 	int hash = CALCULATE_HASH(start);
    614 	struct hash_table_entry *hash_table_entry;
    615 
    616 	for(hash_table_entry = hash_table[hash]; hash_table_entry;
    617 				hash_table_entry = hash_table_entry->next)
    618 
    619 		if(hash_table_entry->start == start)
    620 			return hash_table_entry->bytes;
    621 
    622 	return -1;
    623 }
    624 
    625 
    626 int read_fs_bytes(int fd, long long byte, int bytes, void *buff)
    627 {
    628 	off_t off = byte;
    629 	int res, count;
    630 
    631 	TRACE("read_bytes: reading from position 0x%llx, bytes %d\n", byte,
    632 		bytes);
    633 
    634 	if(lseek(fd, off, SEEK_SET) == -1) {
    635 		ERROR("Lseek failed because %s\n", strerror(errno));
    636 		return FALSE;
    637 	}
    638 
    639 	for(count = 0; count < bytes; count += res) {
    640 		res = read(fd, buff + count, bytes - count);
    641 		if(res < 1) {
    642 			if(res == 0) {
    643 				ERROR("Read on filesystem failed because "
    644 					"EOF\n");
    645 				return FALSE;
    646 			} else if(errno != EINTR) {
    647 				ERROR("Read on filesystem failed because %s\n",
    648 						strerror(errno));
    649 				return FALSE;
    650 			} else
    651 				res = 0;
    652 		}
    653 	}
    654 
    655 	return TRUE;
    656 }
    657 
    658 
    659 int read_block(int fd, long long start, long long *next, int expected,
    660 								void *block)
    661 {
    662 	unsigned short c_byte;
    663 	int offset = 2, res, compressed;
    664 	int outlen = expected ? expected : SQUASHFS_METADATA_SIZE;
    665 
    666 	if(swap) {
    667 		if(read_fs_bytes(fd, start, 2, &c_byte) == FALSE)
    668 			goto failed;
    669 		c_byte = (c_byte >> 8) | ((c_byte & 0xff) << 8);
    670 	} else
    671 		if(read_fs_bytes(fd, start, 2, &c_byte) == FALSE)
    672 			goto failed;
    673 
    674 	TRACE("read_block: block @0x%llx, %d %s bytes\n", start,
    675 		SQUASHFS_COMPRESSED_SIZE(c_byte), SQUASHFS_COMPRESSED(c_byte) ?
    676 		"compressed" : "uncompressed");
    677 
    678 	if(SQUASHFS_CHECK_DATA(sBlk.s.flags))
    679 		offset = 3;
    680 
    681 	compressed = SQUASHFS_COMPRESSED(c_byte);
    682 	c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
    683 
    684 	/*
    685 	 * The block size should not be larger than
    686 	 * the uncompressed size (or max uncompressed size if
    687 	 * expected is 0)
    688 	 */
    689 	if(c_byte > outlen)
    690 		return 0;
    691 
    692 	if(compressed) {
    693 		char buffer[c_byte];
    694 		int error;
    695 
    696 		res = read_fs_bytes(fd, start + offset, c_byte, buffer);
    697 		if(res == FALSE)
    698 			goto failed;
    699 
    700 		res = compressor_uncompress(comp, block, buffer, c_byte,
    701 			outlen, &error);
    702 
    703 		if(res == -1) {
    704 			ERROR("%s uncompress failed with error code %d\n",
    705 				comp->name, error);
    706 			goto failed;
    707 		}
    708 	} else {
    709 		res = read_fs_bytes(fd, start + offset, c_byte, block);
    710 		if(res == FALSE)
    711 			goto failed;
    712 		res = c_byte;
    713 	}
    714 
    715 	if(next)
    716 		*next = start + offset + c_byte;
    717 
    718 	/*
    719 	 * if expected, then check the (uncompressed) return data
    720 	 * is of the expected size
    721 	 */
    722 	if(expected && expected != res)
    723 		return 0;
    724 	else
    725 		return res;
    726 
    727 failed:
    728 	ERROR("read_block: failed to read block @0x%llx\n", start);
    729 	return FALSE;
    730 }
    731 
    732 
    733 int read_data_block(long long start, unsigned int size, char *block)
    734 {
    735 	int error, res;
    736 	int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
    737 
    738 	TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start,
    739 		c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" :
    740 		"uncompressed");
    741 
    742 	if(SQUASHFS_COMPRESSED_BLOCK(size)) {
    743 		if(read_fs_bytes(fd, start, c_byte, data) == FALSE)
    744 			goto failed;
    745 
    746 		res = compressor_uncompress(comp, block, data, c_byte,
    747 			block_size, &error);
    748 
    749 		if(res == -1) {
    750 			ERROR("%s uncompress failed with error code %d\n",
    751 				comp->name, error);
    752 			goto failed;
    753 		}
    754 
    755 		return res;
    756 	} else {
    757 		if(read_fs_bytes(fd, start, c_byte, block) == FALSE)
    758 			goto failed;
    759 
    760 		return c_byte;
    761 	}
    762 
    763 failed:
    764 	ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start,
    765 		c_byte);
    766 	return FALSE;
    767 }
    768 
    769 
    770 int read_inode_table(long long start, long long end)
    771 {
    772 	int size = 0, bytes = 0, res;
    773 
    774 	TRACE("read_inode_table: start %lld, end %lld\n", start, end);
    775 
    776 	while(start < end) {
    777 		if(size - bytes < SQUASHFS_METADATA_SIZE) {
    778 			inode_table = realloc(inode_table, size +=
    779 				SQUASHFS_METADATA_SIZE);
    780 			if(inode_table == NULL) {
    781 				ERROR("Out of memory in read_inode_table");
    782 				goto failed;
    783 			}
    784 		}
    785 
    786 		add_entry(inode_table_hash, start, bytes);
    787 
    788 		res = read_block(fd, start, &start, 0, inode_table + bytes);
    789 		if(res == 0) {
    790 			ERROR("read_inode_table: failed to read block\n");
    791 			goto failed;
    792 		}
    793 		bytes += res;
    794 
    795 		/*
    796 		 * If this is not the last metadata block in the inode table
    797 		 * then it should be SQUASHFS_METADATA_SIZE in size.
    798 		 * Note, we can't use expected in read_block() above for this
    799 		 * because we don't know if this is the last block until
    800 		 * after reading.
    801 		 */
    802 		if(start != end && res != SQUASHFS_METADATA_SIZE) {
    803 			ERROR("read_inode_table: metadata block should be %d "
    804 				"bytes in length, it is %d bytes\n",
    805 				SQUASHFS_METADATA_SIZE, res);
    806 
    807 			goto failed;
    808 		}
    809 	}
    810 
    811 	return TRUE;
    812 
    813 failed:
    814 	free(inode_table);
    815 	return FALSE;
    816 }
    817 
    818 
    819 int set_attributes(char *pathname, int mode, uid_t uid, gid_t guid, time_t time,
    820 	unsigned int xattr, unsigned int set_mode)
    821 {
    822 	struct utimbuf times = { time, time };
    823 
    824 	write_xattr(pathname, xattr);
    825 
    826 	if(utime(pathname, &times) == -1) {
    827 		ERROR("set_attributes: failed to set time on %s, because %s\n",
    828 			pathname, strerror(errno));
    829 		return FALSE;
    830 	}
    831 
    832 	if(root_process) {
    833 		if(chown(pathname, uid, guid) == -1) {
    834 			ERROR("set_attributes: failed to change uid and gids "
    835 				"on %s, because %s\n", pathname,
    836 				strerror(errno));
    837 			return FALSE;
    838 		}
    839 	} else
    840 		mode &= ~07000;
    841 
    842 	if((set_mode || (mode & 07000)) && chmod(pathname, (mode_t) mode) == -1) {
    843 		ERROR("set_attributes: failed to change mode %s, because %s\n",
    844 			pathname, strerror(errno));
    845 		return FALSE;
    846 	}
    847 
    848 	return TRUE;
    849 }
    850 
    851 
    852 int write_bytes(int fd, char *buff, int bytes)
    853 {
    854 	int res, count;
    855 
    856 	for(count = 0; count < bytes; count += res) {
    857 		res = write(fd, buff + count, bytes - count);
    858 		if(res == -1) {
    859 			if(errno != EINTR) {
    860 				ERROR("Write on output file failed because "
    861 					"%s\n", strerror(errno));
    862 				return -1;
    863 			}
    864 			res = 0;
    865 		}
    866 	}
    867 
    868 	return 0;
    869 }
    870 
    871 
    872 int lseek_broken = FALSE;
    873 char *zero_data = NULL;
    874 
    875 int write_block(int file_fd, char *buffer, int size, long long hole, int sparse)
    876 {
    877 	off_t off = hole;
    878 
    879 	if(hole) {
    880 		if(sparse && lseek_broken == FALSE) {
    881 			 int error = lseek(file_fd, off, SEEK_CUR);
    882 			 if(error == -1)
    883 				/* failed to seek beyond end of file */
    884 				lseek_broken = TRUE;
    885 		}
    886 
    887 		if((sparse == FALSE || lseek_broken) && zero_data == NULL) {
    888 			if((zero_data = malloc(block_size)) == NULL)
    889 				EXIT_UNSQUASH("write_block: failed to alloc "
    890 					"zero data block\n");
    891 			memset(zero_data, 0, block_size);
    892 		}
    893 
    894 		if(sparse == FALSE || lseek_broken) {
    895 			int blocks = (hole + block_size -1) / block_size;
    896 			int avail_bytes, i;
    897 			for(i = 0; i < blocks; i++, hole -= avail_bytes) {
    898 				avail_bytes = hole > block_size ? block_size :
    899 					hole;
    900 				if(write_bytes(file_fd, zero_data, avail_bytes)
    901 						== -1)
    902 					goto failure;
    903 			}
    904 		}
    905 	}
    906 
    907 	if(write_bytes(file_fd, buffer, size) == -1)
    908 		goto failure;
    909 
    910 	return TRUE;
    911 
    912 failure:
    913 	return FALSE;
    914 }
    915 
    916 
    917 pthread_mutex_t open_mutex = PTHREAD_MUTEX_INITIALIZER;
    918 pthread_cond_t open_empty = PTHREAD_COND_INITIALIZER;
    919 int open_unlimited, open_count;
    920 #define OPEN_FILE_MARGIN 10
    921 
    922 
    923 void open_init(int count)
    924 {
    925 	open_count = count;
    926 	open_unlimited = count == -1;
    927 }
    928 
    929 
    930 int open_wait(char *pathname, int flags, mode_t mode)
    931 {
    932 	if (!open_unlimited) {
    933 		pthread_mutex_lock(&open_mutex);
    934 		while (open_count == 0)
    935 			pthread_cond_wait(&open_empty, &open_mutex);
    936 		open_count --;
    937 		pthread_mutex_unlock(&open_mutex);
    938 	}
    939 
    940 	return open(pathname, flags, mode);
    941 }
    942 
    943 
    944 void close_wake(int fd)
    945 {
    946 	close(fd);
    947 
    948 	if (!open_unlimited) {
    949 		pthread_mutex_lock(&open_mutex);
    950 		open_count ++;
    951 		pthread_cond_signal(&open_empty);
    952 		pthread_mutex_unlock(&open_mutex);
    953 	}
    954 }
    955 
    956 
    957 void queue_file(char *pathname, int file_fd, struct inode *inode)
    958 {
    959 	struct squashfs_file *file = malloc(sizeof(struct squashfs_file));
    960 	if(file == NULL)
    961 		EXIT_UNSQUASH("queue_file: unable to malloc file\n");
    962 
    963 	file->fd = file_fd;
    964 	file->file_size = inode->data;
    965 	file->mode = inode->mode;
    966 	file->gid = inode->gid;
    967 	file->uid = inode->uid;
    968 	file->time = inode->time;
    969 	file->pathname = strdup(pathname);
    970 	file->blocks = inode->blocks + (inode->frag_bytes > 0);
    971 	file->sparse = inode->sparse;
    972 	file->xattr = inode->xattr;
    973 	queue_put(to_writer, file);
    974 }
    975 
    976 
    977 void queue_dir(char *pathname, struct dir *dir)
    978 {
    979 	struct squashfs_file *file = malloc(sizeof(struct squashfs_file));
    980 	if(file == NULL)
    981 		EXIT_UNSQUASH("queue_dir: unable to malloc file\n");
    982 
    983 	file->fd = -1;
    984 	file->mode = dir->mode;
    985 	file->gid = dir->guid;
    986 	file->uid = dir->uid;
    987 	file->time = dir->mtime;
    988 	file->pathname = strdup(pathname);
    989 	file->xattr = dir->xattr;
    990 	queue_put(to_writer, file);
    991 }
    992 
    993 
    994 int write_file(struct inode *inode, char *pathname)
    995 {
    996 	unsigned int file_fd, i;
    997 	unsigned int *block_list;
    998 	int file_end = inode->data / block_size;
    999 	long long start = inode->start;
   1000 
   1001 	TRACE("write_file: regular file, blocks %d\n", inode->blocks);
   1002 
   1003 	file_fd = open_wait(pathname, O_CREAT | O_WRONLY |
   1004 		(force ? O_TRUNC : 0), (mode_t) inode->mode & 0777);
   1005 	if(file_fd == -1) {
   1006 		ERROR("write_file: failed to create file %s, because %s\n",
   1007 			pathname, strerror(errno));
   1008 		return FALSE;
   1009 	}
   1010 
   1011 	block_list = malloc(inode->blocks * sizeof(unsigned int));
   1012 	if(block_list == NULL)
   1013 		EXIT_UNSQUASH("write_file: unable to malloc block list\n");
   1014 
   1015 	s_ops.read_block_list(block_list, inode->block_ptr, inode->blocks);
   1016 
   1017 	/*
   1018 	 * the writer thread is queued a squashfs_file structure describing the
   1019  	 * file.  If the file has one or more blocks or a fragment they are
   1020  	 * queued separately (references to blocks in the cache).
   1021  	 */
   1022 	queue_file(pathname, file_fd, inode);
   1023 
   1024 	for(i = 0; i < inode->blocks; i++) {
   1025 		int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(block_list[i]);
   1026 		struct file_entry *block = malloc(sizeof(struct file_entry));
   1027 
   1028 		if(block == NULL)
   1029 			EXIT_UNSQUASH("write_file: unable to malloc file\n");
   1030 		block->offset = 0;
   1031 		block->size = i == file_end ? inode->data & (block_size - 1) :
   1032 			block_size;
   1033 		if(block_list[i] == 0) /* sparse block */
   1034 			block->buffer = NULL;
   1035 		else {
   1036 			block->buffer = cache_get(data_cache, start,
   1037 				block_list[i]);
   1038 			start += c_byte;
   1039 		}
   1040 		queue_put(to_writer, block);
   1041 	}
   1042 
   1043 	if(inode->frag_bytes) {
   1044 		int size;
   1045 		long long start;
   1046 		struct file_entry *block = malloc(sizeof(struct file_entry));
   1047 
   1048 		if(block == NULL)
   1049 			EXIT_UNSQUASH("write_file: unable to malloc file\n");
   1050 		s_ops.read_fragment(inode->fragment, &start, &size);
   1051 		block->buffer = cache_get(fragment_cache, start, size);
   1052 		block->offset = inode->offset;
   1053 		block->size = inode->frag_bytes;
   1054 		queue_put(to_writer, block);
   1055 	}
   1056 
   1057 	free(block_list);
   1058 	return TRUE;
   1059 }
   1060 
   1061 
   1062 int create_inode(char *pathname, struct inode *i)
   1063 {
   1064 	TRACE("create_inode: pathname %s\n", pathname);
   1065 
   1066 	if(created_inode[i->inode_number - 1]) {
   1067 		TRACE("create_inode: hard link\n");
   1068 		if(force)
   1069 			unlink(pathname);
   1070 
   1071 		if(link(created_inode[i->inode_number - 1], pathname) == -1) {
   1072 			ERROR("create_inode: failed to create hardlink, "
   1073 				"because %s\n", strerror(errno));
   1074 			return FALSE;
   1075 		}
   1076 
   1077 		return TRUE;
   1078 	}
   1079 
   1080 	switch(i->type) {
   1081 		case SQUASHFS_FILE_TYPE:
   1082 		case SQUASHFS_LREG_TYPE:
   1083 			TRACE("create_inode: regular file, file_size %lld, "
   1084 				"blocks %d\n", i->data, i->blocks);
   1085 
   1086 			if(write_file(i, pathname))
   1087 				file_count ++;
   1088 			break;
   1089 		case SQUASHFS_SYMLINK_TYPE:
   1090 		case SQUASHFS_LSYMLINK_TYPE:
   1091 			TRACE("create_inode: symlink, symlink_size %lld\n",
   1092 				i->data);
   1093 
   1094 			if(force)
   1095 				unlink(pathname);
   1096 
   1097 			if(symlink(i->symlink, pathname) == -1) {
   1098 				ERROR("create_inode: failed to create symlink "
   1099 					"%s, because %s\n", pathname,
   1100 					strerror(errno));
   1101 				break;
   1102 			}
   1103 
   1104 			write_xattr(pathname, i->xattr);
   1105 
   1106 			if(root_process) {
   1107 				if(lchown(pathname, i->uid, i->gid) == -1)
   1108 					ERROR("create_inode: failed to change "
   1109 						"uid and gids on %s, because "
   1110 						"%s\n", pathname,
   1111 						strerror(errno));
   1112 			}
   1113 
   1114 			sym_count ++;
   1115 			break;
   1116  		case SQUASHFS_BLKDEV_TYPE:
   1117 	 	case SQUASHFS_CHRDEV_TYPE:
   1118  		case SQUASHFS_LBLKDEV_TYPE:
   1119 	 	case SQUASHFS_LCHRDEV_TYPE: {
   1120 			int chrdev = i->type == SQUASHFS_CHRDEV_TYPE;
   1121 			TRACE("create_inode: dev, rdev 0x%llx\n", i->data);
   1122 
   1123 			if(root_process) {
   1124 				if(force)
   1125 					unlink(pathname);
   1126 
   1127 				if(mknod(pathname, chrdev ? S_IFCHR : S_IFBLK,
   1128 						makedev((i->data >> 8) & 0xff,
   1129 						i->data & 0xff)) == -1) {
   1130 					ERROR("create_inode: failed to create "
   1131 						"%s device %s, because %s\n",
   1132 						chrdev ? "character" : "block",
   1133 						pathname, strerror(errno));
   1134 					break;
   1135 				}
   1136 				set_attributes(pathname, i->mode, i->uid,
   1137 					i->gid, i->time, i->xattr, TRUE);
   1138 				dev_count ++;
   1139 			} else
   1140 				ERROR("create_inode: could not create %s "
   1141 					"device %s, because you're not "
   1142 					"superuser!\n", chrdev ? "character" :
   1143 					"block", pathname);
   1144 			break;
   1145 		}
   1146 		case SQUASHFS_FIFO_TYPE:
   1147 		case SQUASHFS_LFIFO_TYPE:
   1148 			TRACE("create_inode: fifo\n");
   1149 
   1150 			if(force)
   1151 				unlink(pathname);
   1152 
   1153 			if(mknod(pathname, S_IFIFO, 0) == -1) {
   1154 				ERROR("create_inode: failed to create fifo %s, "
   1155 					"because %s\n", pathname,
   1156 					strerror(errno));
   1157 				break;
   1158 			}
   1159 			set_attributes(pathname, i->mode, i->uid, i->gid,
   1160 				i->time, i->xattr, TRUE);
   1161 			fifo_count ++;
   1162 			break;
   1163 		case SQUASHFS_SOCKET_TYPE:
   1164 		case SQUASHFS_LSOCKET_TYPE:
   1165 			TRACE("create_inode: socket\n");
   1166 			ERROR("create_inode: socket %s ignored\n", pathname);
   1167 			break;
   1168 		default:
   1169 			ERROR("Unknown inode type %d in create_inode_table!\n",
   1170 				i->type);
   1171 			return FALSE;
   1172 	}
   1173 
   1174 	created_inode[i->inode_number - 1] = strdup(pathname);
   1175 
   1176 	return TRUE;
   1177 }
   1178 
   1179 
   1180 int read_directory_table(long long start, long long end)
   1181 {
   1182 	int bytes = 0, size = 0, res;
   1183 
   1184 	TRACE("read_directory_table: start %lld, end %lld\n", start, end);
   1185 
   1186 	while(start < end) {
   1187 		if(size - bytes < SQUASHFS_METADATA_SIZE) {
   1188 			directory_table = realloc(directory_table, size +=
   1189 				SQUASHFS_METADATA_SIZE);
   1190 			if(directory_table == NULL) {
   1191 				ERROR("Out of memory in "
   1192 						"read_directory_table\n");
   1193 				goto failed;
   1194 			}
   1195 		}
   1196 
   1197 		add_entry(directory_table_hash, start, bytes);
   1198 
   1199 		res = read_block(fd, start, &start, 0, directory_table + bytes);
   1200 		if(res == 0) {
   1201 			ERROR("read_directory_table: failed to read block\n");
   1202 			goto failed;
   1203 		}
   1204 
   1205 		bytes += res;
   1206 
   1207 		/*
   1208 		 * If this is not the last metadata block in the directory table
   1209 		 * then it should be SQUASHFS_METADATA_SIZE in size.
   1210 		 * Note, we can't use expected in read_block() above for this
   1211 		 * because we don't know if this is the last block until
   1212 		 * after reading.
   1213 		 */
   1214 		if(start != end && res != SQUASHFS_METADATA_SIZE) {
   1215 			ERROR("read_directory_table: metadata block "
   1216 				"should be %d bytes in length, it is %d "
   1217 				"bytes\n", SQUASHFS_METADATA_SIZE, res);
   1218 			goto failed;
   1219 		}
   1220 	}
   1221 
   1222 	return TRUE;
   1223 
   1224 failed:
   1225 	free(directory_table);
   1226 	return FALSE;
   1227 }
   1228 
   1229 
   1230 int squashfs_readdir(struct dir *dir, char **name, unsigned int *start_block,
   1231 unsigned int *offset, unsigned int *type)
   1232 {
   1233 	if(dir->cur_entry == dir->dir_count)
   1234 		return FALSE;
   1235 
   1236 	*name = dir->dirs[dir->cur_entry].name;
   1237 	*start_block = dir->dirs[dir->cur_entry].start_block;
   1238 	*offset = dir->dirs[dir->cur_entry].offset;
   1239 	*type = dir->dirs[dir->cur_entry].type;
   1240 	dir->cur_entry ++;
   1241 
   1242 	return TRUE;
   1243 }
   1244 
   1245 
   1246 void squashfs_closedir(struct dir *dir)
   1247 {
   1248 	free(dir->dirs);
   1249 	free(dir);
   1250 }
   1251 
   1252 
   1253 char *get_component(char *target, char **targname)
   1254 {
   1255 	char *start;
   1256 
   1257 	while(*target == '/')
   1258 		target ++;
   1259 
   1260 	start = target;
   1261 	while(*target != '/' && *target != '\0')
   1262 		target ++;
   1263 
   1264 	*targname = strndup(start, target - start);
   1265 
   1266 	while(*target == '/')
   1267 		target ++;
   1268 
   1269 	return target;
   1270 }
   1271 
   1272 
   1273 void free_path(struct pathname *paths)
   1274 {
   1275 	int i;
   1276 
   1277 	for(i = 0; i < paths->names; i++) {
   1278 		if(paths->name[i].paths)
   1279 			free_path(paths->name[i].paths);
   1280 		free(paths->name[i].name);
   1281 		if(paths->name[i].preg) {
   1282 			regfree(paths->name[i].preg);
   1283 			free(paths->name[i].preg);
   1284 		}
   1285 	}
   1286 
   1287 	free(paths);
   1288 }
   1289 
   1290 
   1291 struct pathname *add_path(struct pathname *paths, char *target, char *alltarget)
   1292 {
   1293 	char *targname;
   1294 	int i, error;
   1295 
   1296 	TRACE("add_path: adding \"%s\" extract file\n", target);
   1297 
   1298 	target = get_component(target, &targname);
   1299 
   1300 	if(paths == NULL) {
   1301 		paths = malloc(sizeof(struct pathname));
   1302 		if(paths == NULL)
   1303 			EXIT_UNSQUASH("failed to allocate paths\n");
   1304 
   1305 		paths->names = 0;
   1306 		paths->name = NULL;
   1307 	}
   1308 
   1309 	for(i = 0; i < paths->names; i++)
   1310 		if(strcmp(paths->name[i].name, targname) == 0)
   1311 			break;
   1312 
   1313 	if(i == paths->names) {
   1314 		/*
   1315 		 * allocate new name entry
   1316 		 */
   1317 		paths->names ++;
   1318 		paths->name = realloc(paths->name, (i + 1) *
   1319 			sizeof(struct path_entry));
   1320 		if(paths->name == NULL)
   1321 			EXIT_UNSQUASH("Out of memory in add_path\n");
   1322 		paths->name[i].name = targname;
   1323 		paths->name[i].paths = NULL;
   1324 		if(use_regex) {
   1325 			paths->name[i].preg = malloc(sizeof(regex_t));
   1326 			if(paths->name[i].preg == NULL)
   1327 				EXIT_UNSQUASH("Out of memory in add_path\n");
   1328 			error = regcomp(paths->name[i].preg, targname,
   1329 				REG_EXTENDED|REG_NOSUB);
   1330 			if(error) {
   1331 				char str[1024]; /* overflow safe */
   1332 
   1333 				regerror(error, paths->name[i].preg, str, 1024);
   1334 				EXIT_UNSQUASH("invalid regex %s in export %s, "
   1335 					"because %s\n", targname, alltarget,
   1336 					str);
   1337 			}
   1338 		} else
   1339 			paths->name[i].preg = NULL;
   1340 
   1341 		if(target[0] == '\0')
   1342 			/*
   1343 			 * at leaf pathname component
   1344 			*/
   1345 			paths->name[i].paths = NULL;
   1346 		else
   1347 			/*
   1348 			 * recurse adding child components
   1349 			 */
   1350 			paths->name[i].paths = add_path(NULL, target, alltarget);
   1351 	} else {
   1352 		/*
   1353 		 * existing matching entry
   1354 		 */
   1355 		free(targname);
   1356 
   1357 		if(paths->name[i].paths == NULL) {
   1358 			/*
   1359 			 * No sub-directory which means this is the leaf
   1360 			 * component of a pre-existing extract which subsumes
   1361 			 * the extract currently being added, in which case stop
   1362 			 * adding components
   1363 			 */
   1364 		} else if(target[0] == '\0') {
   1365 			/*
   1366 			 * at leaf pathname component and child components exist
   1367 			 * from more specific extracts, delete as they're
   1368 			 * subsumed by this extract
   1369 			 */
   1370 			free_path(paths->name[i].paths);
   1371 			paths->name[i].paths = NULL;
   1372 		} else
   1373 			/*
   1374 			 * recurse adding child components
   1375 			 */
   1376 			add_path(paths->name[i].paths, target, alltarget);
   1377 	}
   1378 
   1379 	return paths;
   1380 }
   1381 
   1382 
   1383 struct pathnames *init_subdir()
   1384 {
   1385 	struct pathnames *new = malloc(sizeof(struct pathnames));
   1386 	if(new == NULL)
   1387 		EXIT_UNSQUASH("Out of memory in init_subdir\n");
   1388 	new->count = 0;
   1389 	return new;
   1390 }
   1391 
   1392 
   1393 struct pathnames *add_subdir(struct pathnames *paths, struct pathname *path)
   1394 {
   1395 	if(paths->count % PATHS_ALLOC_SIZE == 0) {
   1396 		paths = realloc(paths, sizeof(struct pathnames *) +
   1397 			(paths->count + PATHS_ALLOC_SIZE) *
   1398 			sizeof(struct pathname *));
   1399 		if(paths == NULL)
   1400 			EXIT_UNSQUASH("Out of memory in add_subdir\n");
   1401 	}
   1402 
   1403 	paths->path[paths->count++] = path;
   1404 	return paths;
   1405 }
   1406 
   1407 
   1408 void free_subdir(struct pathnames *paths)
   1409 {
   1410 	free(paths);
   1411 }
   1412 
   1413 
   1414 int matches(struct pathnames *paths, char *name, struct pathnames **new)
   1415 {
   1416 	int i, n;
   1417 
   1418 	if(paths == NULL) {
   1419 		*new = NULL;
   1420 		return TRUE;
   1421 	}
   1422 
   1423 	*new = init_subdir();
   1424 
   1425 	for(n = 0; n < paths->count; n++) {
   1426 		struct pathname *path = paths->path[n];
   1427 		for(i = 0; i < path->names; i++) {
   1428 			int match = use_regex ?
   1429 				regexec(path->name[i].preg, name, (size_t) 0,
   1430 				NULL, 0) == 0 : fnmatch(path->name[i].name,
   1431 				name, FNM_PATHNAME|FNM_PERIOD|FNM_EXTMATCH) ==
   1432 				0;
   1433 			if(match && path->name[i].paths == NULL)
   1434 				/*
   1435 				 * match on a leaf component, any subdirectories
   1436 				 * will implicitly match, therefore return an
   1437 				 * empty new search set
   1438 				 */
   1439 				goto empty_set;
   1440 
   1441 			if(match)
   1442 				/*
   1443 				 * match on a non-leaf component, add any
   1444 				 * subdirectories to the new set of
   1445 				 * subdirectories to scan for this name
   1446 				 */
   1447 				*new = add_subdir(*new, path->name[i].paths);
   1448 		}
   1449 	}
   1450 
   1451 	if((*new)->count == 0) {
   1452 		/*
   1453 		 * no matching names found, delete empty search set, and return
   1454 		 * FALSE
   1455 		 */
   1456 		free_subdir(*new);
   1457 		*new = NULL;
   1458 		return FALSE;
   1459 	}
   1460 
   1461 	/*
   1462 	 * one or more matches with sub-directories found (no leaf matches),
   1463 	 * return new search set and return TRUE
   1464 	 */
   1465 	return TRUE;
   1466 
   1467 empty_set:
   1468 	/*
   1469 	 * found matching leaf exclude, return empty search set and return TRUE
   1470 	 */
   1471 	free_subdir(*new);
   1472 	*new = NULL;
   1473 	return TRUE;
   1474 }
   1475 
   1476 
   1477 void pre_scan(char *parent_name, unsigned int start_block, unsigned int offset,
   1478 	struct pathnames *paths)
   1479 {
   1480 	unsigned int type;
   1481 	char *name;
   1482 	struct pathnames *new;
   1483 	struct inode *i;
   1484 	struct dir *dir = s_ops.squashfs_opendir(start_block, offset, &i);
   1485 
   1486 	if(dir == NULL)
   1487 		return;
   1488 
   1489 	while(squashfs_readdir(dir, &name, &start_block, &offset, &type)) {
   1490 		struct inode *i;
   1491 		char *pathname;
   1492 		int res;
   1493 
   1494 		TRACE("pre_scan: name %s, start_block %d, offset %d, type %d\n",
   1495 			name, start_block, offset, type);
   1496 
   1497 		if(!matches(paths, name, &new))
   1498 			continue;
   1499 
   1500 		res = asprintf(&pathname, "%s/%s", parent_name, name);
   1501 		if(res == -1)
   1502 			EXIT_UNSQUASH("asprintf failed in dir_scan\n");
   1503 
   1504 		if(type == SQUASHFS_DIR_TYPE)
   1505 			pre_scan(parent_name, start_block, offset, new);
   1506 		else if(new == NULL) {
   1507 			if(type == SQUASHFS_FILE_TYPE ||
   1508 					type == SQUASHFS_LREG_TYPE) {
   1509 				i = s_ops.read_inode(start_block, offset);
   1510 				if(created_inode[i->inode_number - 1] == NULL) {
   1511 					created_inode[i->inode_number - 1] =
   1512 						(char *) i;
   1513 					total_blocks += (i->data +
   1514 						(block_size - 1)) >> block_log;
   1515 				}
   1516 				total_files ++;
   1517 			}
   1518 			total_inodes ++;
   1519 		}
   1520 
   1521 		free_subdir(new);
   1522 		free(pathname);
   1523 	}
   1524 
   1525 	squashfs_closedir(dir);
   1526 }
   1527 
   1528 
   1529 void dir_scan(char *parent_name, unsigned int start_block, unsigned int offset,
   1530 	struct pathnames *paths)
   1531 {
   1532 	unsigned int type;
   1533 	char *name;
   1534 	struct pathnames *new;
   1535 	struct inode *i;
   1536 	struct dir *dir = s_ops.squashfs_opendir(start_block, offset, &i);
   1537 
   1538 	if(dir == NULL) {
   1539 		ERROR("dir_scan: failed to read directory %s, skipping\n",
   1540 			parent_name);
   1541 		return;
   1542 	}
   1543 
   1544 	if(lsonly || info)
   1545 		print_filename(parent_name, i);
   1546 
   1547 	if(!lsonly) {
   1548 		/*
   1549 		 * Make directory with default User rwx permissions rather than
   1550 		 * the permissions from the filesystem, as these may not have
   1551 		 * write/execute permission.  These are fixed up later in
   1552 		 * set_attributes().
   1553 		 */
   1554 		int res = mkdir(parent_name, S_IRUSR|S_IWUSR|S_IXUSR);
   1555 		if(res == -1) {
   1556 			/*
   1557 			 * Skip directory if mkdir fails, unless we're
   1558 			 * forcing and the error is -EEXIST
   1559 			 */
   1560 			if(!force || errno != EEXIST) {
   1561 				ERROR("dir_scan: failed to make directory %s, "
   1562 					"because %s\n", parent_name,
   1563 					strerror(errno));
   1564 				squashfs_closedir(dir);
   1565 				return;
   1566 			}
   1567 
   1568 			/*
   1569 			 * Try to change permissions of existing directory so
   1570 			 * that we can write to it
   1571 			 */
   1572 			res = chmod(parent_name, S_IRUSR|S_IWUSR|S_IXUSR);
   1573 			if (res == -1)
   1574 				ERROR("dir_scan: failed to change permissions "
   1575 					"for directory %s, because %s\n",
   1576 					parent_name, strerror(errno));
   1577 		}
   1578 	}
   1579 
   1580 	while(squashfs_readdir(dir, &name, &start_block, &offset, &type)) {
   1581 		char *pathname;
   1582 		int res;
   1583 
   1584 		TRACE("dir_scan: name %s, start_block %d, offset %d, type %d\n",
   1585 			name, start_block, offset, type);
   1586 
   1587 
   1588 		if(!matches(paths, name, &new))
   1589 			continue;
   1590 
   1591 		res = asprintf(&pathname, "%s/%s", parent_name, name);
   1592 		if(res == -1)
   1593 			EXIT_UNSQUASH("asprintf failed in dir_scan\n");
   1594 
   1595 		if(type == SQUASHFS_DIR_TYPE) {
   1596 			dir_scan(pathname, start_block, offset, new);
   1597 			free(pathname);
   1598 		} else if(new == NULL) {
   1599 			update_info(pathname);
   1600 
   1601 			i = s_ops.read_inode(start_block, offset);
   1602 
   1603 			if(lsonly || info)
   1604 				print_filename(pathname, i);
   1605 
   1606 			if(!lsonly)
   1607 				create_inode(pathname, i);
   1608 
   1609 			if(i->type == SQUASHFS_SYMLINK_TYPE ||
   1610 					i->type == SQUASHFS_LSYMLINK_TYPE)
   1611 				free(i->symlink);
   1612 		} else
   1613 			free(pathname);
   1614 
   1615 		free_subdir(new);
   1616 	}
   1617 
   1618 	if(!lsonly)
   1619 		queue_dir(parent_name, dir);
   1620 
   1621 	squashfs_closedir(dir);
   1622 	dir_count ++;
   1623 }
   1624 
   1625 
   1626 void squashfs_stat(char *source)
   1627 {
   1628 	time_t mkfs_time = (time_t) sBlk.s.mkfs_time;
   1629 	char *mkfs_str = ctime(&mkfs_time);
   1630 
   1631 #if __BYTE_ORDER == __BIG_ENDIAN
   1632 	printf("Found a valid %sSQUASHFS %d:%d superblock on %s.\n",
   1633 		sBlk.s.s_major == 4 ? "" : swap ? "little endian " :
   1634 		"big endian ", sBlk.s.s_major, sBlk.s.s_minor, source);
   1635 #else
   1636 	printf("Found a valid %sSQUASHFS %d:%d superblock on %s.\n",
   1637 		sBlk.s.s_major == 4 ? "" : swap ? "big endian " :
   1638 		"little endian ", sBlk.s.s_major, sBlk.s.s_minor, source);
   1639 #endif
   1640 
   1641 	printf("Creation or last append time %s", mkfs_str ? mkfs_str :
   1642 		"failed to get time\n");
   1643 	printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n",
   1644 		sBlk.s.bytes_used / 1024.0, sBlk.s.bytes_used /
   1645 		(1024.0 * 1024.0));
   1646 
   1647 	if(sBlk.s.s_major == 4) {
   1648 		printf("Compression %s\n", comp->name);
   1649 
   1650 		if(SQUASHFS_COMP_OPTS(sBlk.s.flags)) {
   1651 			char buffer[SQUASHFS_METADATA_SIZE] __attribute__ ((aligned));
   1652 			int bytes;
   1653 
   1654 			bytes = read_block(fd, sizeof(sBlk.s), NULL, 0, buffer);
   1655 			if(bytes == 0) {
   1656 				ERROR("Failed to read compressor options\n");
   1657 				return;
   1658 			}
   1659 
   1660 			compressor_display_options(comp, buffer, bytes);
   1661 		}
   1662 	}
   1663 
   1664 	printf("Block size %d\n", sBlk.s.block_size);
   1665 	printf("Filesystem is %sexportable via NFS\n",
   1666 		SQUASHFS_EXPORTABLE(sBlk.s.flags) ? "" : "not ");
   1667 	printf("Inodes are %scompressed\n",
   1668 		SQUASHFS_UNCOMPRESSED_INODES(sBlk.s.flags) ? "un" : "");
   1669 	printf("Data is %scompressed\n",
   1670 		SQUASHFS_UNCOMPRESSED_DATA(sBlk.s.flags) ? "un" : "");
   1671 
   1672 	if(sBlk.s.s_major > 1) {
   1673 		if(SQUASHFS_NO_FRAGMENTS(sBlk.s.flags))
   1674 			printf("Fragments are not stored\n");
   1675 		else {
   1676 			printf("Fragments are %scompressed\n",
   1677 				SQUASHFS_UNCOMPRESSED_FRAGMENTS(sBlk.s.flags) ?
   1678 				"un" : "");
   1679 			printf("Always-use-fragments option is %sspecified\n",
   1680 				SQUASHFS_ALWAYS_FRAGMENTS(sBlk.s.flags) ? "" :
   1681 				"not ");
   1682 		}
   1683 	}
   1684 
   1685 	if(sBlk.s.s_major == 4) {
   1686 		if(SQUASHFS_NO_XATTRS(sBlk.s.flags))
   1687 			printf("Xattrs are not stored\n");
   1688 		else
   1689 			printf("Xattrs are %scompressed\n",
   1690 				SQUASHFS_UNCOMPRESSED_XATTRS(sBlk.s.flags) ?
   1691 				"un" : "");
   1692 	}
   1693 
   1694 	if(sBlk.s.s_major < 4)
   1695 			printf("Check data is %spresent in the filesystem\n",
   1696 				SQUASHFS_CHECK_DATA(sBlk.s.flags) ? "" :
   1697 				"not ");
   1698 
   1699 	if(sBlk.s.s_major > 1)
   1700 		printf("Duplicates are %sremoved\n",
   1701 			SQUASHFS_DUPLICATES(sBlk.s.flags) ? "" : "not ");
   1702 	else
   1703 		printf("Duplicates are removed\n");
   1704 
   1705 	if(sBlk.s.s_major > 1)
   1706 		printf("Number of fragments %d\n", sBlk.s.fragments);
   1707 
   1708 	printf("Number of inodes %d\n", sBlk.s.inodes);
   1709 
   1710 	if(sBlk.s.s_major == 4)
   1711 		printf("Number of ids %d\n", sBlk.s.no_ids);
   1712 	else {
   1713 		printf("Number of uids %d\n", sBlk.no_uids);
   1714 		printf("Number of gids %d\n", sBlk.no_guids);
   1715 	}
   1716 
   1717 	TRACE("sBlk.s.inode_table_start 0x%llx\n", sBlk.s.inode_table_start);
   1718 	TRACE("sBlk.s.directory_table_start 0x%llx\n",
   1719 		sBlk.s.directory_table_start);
   1720 
   1721 	if(sBlk.s.s_major > 1)
   1722 		TRACE("sBlk.s.fragment_table_start 0x%llx\n\n",
   1723 			sBlk.s.fragment_table_start);
   1724 
   1725 	if(sBlk.s.s_major > 2)
   1726 		TRACE("sBlk.s.lookup_table_start 0x%llx\n\n",
   1727 			sBlk.s.lookup_table_start);
   1728 
   1729 	if(sBlk.s.s_major == 4) {
   1730 		TRACE("sBlk.s.id_table_start 0x%llx\n", sBlk.s.id_table_start);
   1731 		TRACE("sBlk.s.xattr_id_table_start 0x%llx\n",
   1732 			sBlk.s.xattr_id_table_start);
   1733 	} else {
   1734 		TRACE("sBlk.uid_start 0x%llx\n", sBlk.uid_start);
   1735 		TRACE("sBlk.guid_start 0x%llx\n", sBlk.guid_start);
   1736 	}
   1737 }
   1738 
   1739 
   1740 int check_compression(struct compressor *comp)
   1741 {
   1742 	int res, bytes = 0;
   1743 	char buffer[SQUASHFS_METADATA_SIZE] __attribute__ ((aligned));
   1744 
   1745 	if(!comp->supported) {
   1746 		ERROR("Filesystem uses %s compression, this is "
   1747 			"unsupported by this version\n", comp->name);
   1748 		ERROR("Decompressors available:\n");
   1749 		display_compressors("", "");
   1750 		return 0;
   1751 	}
   1752 
   1753 	/*
   1754 	 * Read compression options from disk if present, and pass to
   1755 	 * the compressor to ensure we know how to decompress a filesystem
   1756 	 * compressed with these compression options.
   1757 	 *
   1758 	 * Note, even if there is no compression options we still call the
   1759 	 * compressor because some compression options may be mandatory
   1760 	 * for some compressors.
   1761 	 */
   1762 	if(SQUASHFS_COMP_OPTS(sBlk.s.flags)) {
   1763 		bytes = read_block(fd, sizeof(sBlk.s), NULL, 0, buffer);
   1764 		if(bytes == 0) {
   1765 			ERROR("Failed to read compressor options\n");
   1766 			return 0;
   1767 		}
   1768 	}
   1769 
   1770 	res = compressor_check_options(comp, sBlk.s.block_size, buffer, bytes);
   1771 
   1772 	return res != -1;
   1773 }
   1774 
   1775 
   1776 int read_super(char *source)
   1777 {
   1778 	squashfs_super_block_3 sBlk_3;
   1779 	struct squashfs_super_block sBlk_4;
   1780 
   1781 	/*
   1782 	 * Try to read a Squashfs 4 superblock
   1783 	 */
   1784 	read_fs_bytes(fd, SQUASHFS_START, sizeof(struct squashfs_super_block),
   1785 		&sBlk_4);
   1786 	swap = sBlk_4.s_magic != SQUASHFS_MAGIC;
   1787 	SQUASHFS_INSWAP_SUPER_BLOCK(&sBlk_4);
   1788 
   1789 	if(sBlk_4.s_magic == SQUASHFS_MAGIC && sBlk_4.s_major == 4 &&
   1790 			sBlk_4.s_minor == 0) {
   1791 		s_ops.squashfs_opendir = squashfs_opendir_4;
   1792 		s_ops.read_fragment = read_fragment_4;
   1793 		s_ops.read_fragment_table = read_fragment_table_4;
   1794 		s_ops.read_block_list = read_block_list_2;
   1795 		s_ops.read_inode = read_inode_4;
   1796 		s_ops.read_uids_guids = read_uids_guids_4;
   1797 		memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4));
   1798 
   1799 		/*
   1800 		 * Check the compression type
   1801 		 */
   1802 		comp = lookup_compressor_id(sBlk.s.compression);
   1803 		return TRUE;
   1804 	}
   1805 
   1806 	/*
   1807  	 * Not a Squashfs 4 superblock, try to read a squashfs 3 superblock
   1808  	 * (compatible with 1 and 2 filesystems)
   1809  	 */
   1810 	read_fs_bytes(fd, SQUASHFS_START, sizeof(squashfs_super_block_3),
   1811 		&sBlk_3);
   1812 
   1813 	/*
   1814 	 * Check it is a SQUASHFS superblock
   1815 	 */
   1816 	swap = 0;
   1817 	if(sBlk_3.s_magic != SQUASHFS_MAGIC) {
   1818 		if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP) {
   1819 			squashfs_super_block_3 sblk;
   1820 			ERROR("Reading a different endian SQUASHFS filesystem "
   1821 				"on %s\n", source);
   1822 			SQUASHFS_SWAP_SUPER_BLOCK_3(&sblk, &sBlk_3);
   1823 			memcpy(&sBlk_3, &sblk, sizeof(squashfs_super_block_3));
   1824 			swap = 1;
   1825 		} else  {
   1826 			ERROR("Can't find a SQUASHFS superblock on %s\n",
   1827 				source);
   1828 			goto failed_mount;
   1829 		}
   1830 	}
   1831 
   1832 	sBlk.s.s_magic = sBlk_3.s_magic;
   1833 	sBlk.s.inodes = sBlk_3.inodes;
   1834 	sBlk.s.mkfs_time = sBlk_3.mkfs_time;
   1835 	sBlk.s.block_size = sBlk_3.block_size;
   1836 	sBlk.s.fragments = sBlk_3.fragments;
   1837 	sBlk.s.block_log = sBlk_3.block_log;
   1838 	sBlk.s.flags = sBlk_3.flags;
   1839 	sBlk.s.s_major = sBlk_3.s_major;
   1840 	sBlk.s.s_minor = sBlk_3.s_minor;
   1841 	sBlk.s.root_inode = sBlk_3.root_inode;
   1842 	sBlk.s.bytes_used = sBlk_3.bytes_used;
   1843 	sBlk.s.inode_table_start = sBlk_3.inode_table_start;
   1844 	sBlk.s.directory_table_start = sBlk_3.directory_table_start;
   1845 	sBlk.s.fragment_table_start = sBlk_3.fragment_table_start;
   1846 	sBlk.s.lookup_table_start = sBlk_3.lookup_table_start;
   1847 	sBlk.no_uids = sBlk_3.no_uids;
   1848 	sBlk.no_guids = sBlk_3.no_guids;
   1849 	sBlk.uid_start = sBlk_3.uid_start;
   1850 	sBlk.guid_start = sBlk_3.guid_start;
   1851 	sBlk.s.xattr_id_table_start = SQUASHFS_INVALID_BLK;
   1852 
   1853 	/* Check the MAJOR & MINOR versions */
   1854 	if(sBlk.s.s_major == 1 || sBlk.s.s_major == 2) {
   1855 		sBlk.s.bytes_used = sBlk_3.bytes_used_2;
   1856 		sBlk.uid_start = sBlk_3.uid_start_2;
   1857 		sBlk.guid_start = sBlk_3.guid_start_2;
   1858 		sBlk.s.inode_table_start = sBlk_3.inode_table_start_2;
   1859 		sBlk.s.directory_table_start = sBlk_3.directory_table_start_2;
   1860 
   1861 		if(sBlk.s.s_major == 1) {
   1862 			sBlk.s.block_size = sBlk_3.block_size_1;
   1863 			sBlk.s.fragment_table_start = sBlk.uid_start;
   1864 			s_ops.squashfs_opendir = squashfs_opendir_1;
   1865 			s_ops.read_fragment_table = read_fragment_table_1;
   1866 			s_ops.read_block_list = read_block_list_1;
   1867 			s_ops.read_inode = read_inode_1;
   1868 			s_ops.read_uids_guids = read_uids_guids_1;
   1869 		} else {
   1870 			sBlk.s.fragment_table_start =
   1871 				sBlk_3.fragment_table_start_2;
   1872 			s_ops.squashfs_opendir = squashfs_opendir_1;
   1873 			s_ops.read_fragment = read_fragment_2;
   1874 			s_ops.read_fragment_table = read_fragment_table_2;
   1875 			s_ops.read_block_list = read_block_list_2;
   1876 			s_ops.read_inode = read_inode_2;
   1877 			s_ops.read_uids_guids = read_uids_guids_1;
   1878 		}
   1879 	} else if(sBlk.s.s_major == 3) {
   1880 		s_ops.squashfs_opendir = squashfs_opendir_3;
   1881 		s_ops.read_fragment = read_fragment_3;
   1882 		s_ops.read_fragment_table = read_fragment_table_3;
   1883 		s_ops.read_block_list = read_block_list_2;
   1884 		s_ops.read_inode = read_inode_3;
   1885 		s_ops.read_uids_guids = read_uids_guids_1;
   1886 	} else {
   1887 		ERROR("Filesystem on %s is (%d:%d), ", source, sBlk.s.s_major,
   1888 			sBlk.s.s_minor);
   1889 		ERROR("which is a later filesystem version than I support!\n");
   1890 		goto failed_mount;
   1891 	}
   1892 
   1893 	/*
   1894 	 * 1.x, 2.x and 3.x filesystems use gzip compression.
   1895 	 */
   1896 	comp = lookup_compressor("gzip");
   1897 	return TRUE;
   1898 
   1899 failed_mount:
   1900 	return FALSE;
   1901 }
   1902 
   1903 
   1904 struct pathname *process_extract_files(struct pathname *path, char *filename)
   1905 {
   1906 	FILE *fd;
   1907 	char buffer[MAX_LINE + 1]; /* overflow safe */
   1908 	char *name;
   1909 
   1910 	fd = fopen(filename, "r");
   1911 	if(fd == NULL)
   1912 		EXIT_UNSQUASH("Failed to open extract file \"%s\" because %s\n",
   1913 			filename, strerror(errno));
   1914 
   1915 	while(fgets(name = buffer, MAX_LINE + 1, fd) != NULL) {
   1916 		int len = strlen(name);
   1917 
   1918 		if(len == MAX_LINE && name[len - 1] != '\n')
   1919 			/* line too large */
   1920 			EXIT_UNSQUASH("Line too long when reading "
   1921 				"extract file \"%s\", larger than %d "
   1922 				"bytes\n", filename, MAX_LINE);
   1923 
   1924 		/*
   1925 		 * Remove '\n' terminator if it exists (the last line
   1926 		 * in the file may not be '\n' terminated)
   1927 		 */
   1928 		if(len && name[len - 1] == '\n')
   1929 			name[len - 1] = '\0';
   1930 
   1931 		/* Skip any leading whitespace */
   1932 		while(isspace(*name))
   1933 			name ++;
   1934 
   1935 		/* if comment line, skip */
   1936 		if(*name == '#')
   1937 			continue;
   1938 
   1939 		/* check for initial backslash, to accommodate
   1940 		 * filenames with leading space or leading # character
   1941 		 */
   1942 		if(*name == '\\')
   1943 			name ++;
   1944 
   1945 		/* if line is now empty after skipping characters, skip it */
   1946 		if(*name == '\0')
   1947 			continue;
   1948 
   1949 		path = add_path(path, name, name);
   1950 	}
   1951 
   1952 	if(ferror(fd))
   1953 		EXIT_UNSQUASH("Reading extract file \"%s\" failed because %s\n",
   1954 			filename, strerror(errno));
   1955 
   1956 	fclose(fd);
   1957 	return path;
   1958 }
   1959 
   1960 
   1961 /*
   1962  * reader thread.  This thread processes read requests queued by the
   1963  * cache_get() routine.
   1964  */
   1965 void *reader(void *arg)
   1966 {
   1967 	while(1) {
   1968 		struct cache_entry *entry = queue_get(to_reader);
   1969 		int res = read_fs_bytes(fd, entry->block,
   1970 			SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size),
   1971 			entry->data);
   1972 
   1973 		if(res && SQUASHFS_COMPRESSED_BLOCK(entry->size))
   1974 			/*
   1975 			 * queue successfully read block to the inflate
   1976 			 * thread(s) for further processing
   1977  			 */
   1978 			queue_put(to_inflate, entry);
   1979 		else
   1980 			/*
   1981 			 * block has either been successfully read and is
   1982 			 * uncompressed, or an error has occurred, clear pending
   1983 			 * flag, set error appropriately, and wake up any
   1984 			 * threads waiting on this buffer
   1985 			 */
   1986 			cache_block_ready(entry, !res);
   1987 	}
   1988 }
   1989 
   1990 
   1991 /*
   1992  * writer thread.  This processes file write requests queued by the
   1993  * write_file() routine.
   1994  */
   1995 void *writer(void *arg)
   1996 {
   1997 	int i;
   1998 
   1999 	while(1) {
   2000 		struct squashfs_file *file = queue_get(to_writer);
   2001 		int file_fd;
   2002 		long long hole = 0;
   2003 		int failed = FALSE;
   2004 		int error;
   2005 
   2006 		if(file == NULL) {
   2007 			queue_put(from_writer, NULL);
   2008 			continue;
   2009 		} else if(file->fd == -1) {
   2010 			/* write attributes for directory file->pathname */
   2011 			set_attributes(file->pathname, file->mode, file->uid,
   2012 				file->gid, file->time, file->xattr, TRUE);
   2013 			free(file->pathname);
   2014 			free(file);
   2015 			continue;
   2016 		}
   2017 
   2018 		TRACE("writer: regular file, blocks %d\n", file->blocks);
   2019 
   2020 		file_fd = file->fd;
   2021 
   2022 		for(i = 0; i < file->blocks; i++, cur_blocks ++) {
   2023 			struct file_entry *block = queue_get(to_writer);
   2024 
   2025 			if(block->buffer == 0) { /* sparse file */
   2026 				hole += block->size;
   2027 				free(block);
   2028 				continue;
   2029 			}
   2030 
   2031 			cache_block_wait(block->buffer);
   2032 
   2033 			if(block->buffer->error)
   2034 				failed = TRUE;
   2035 
   2036 			if(failed)
   2037 				continue;
   2038 
   2039 			error = write_block(file_fd, block->buffer->data +
   2040 				block->offset, block->size, hole, file->sparse);
   2041 
   2042 			if(error == FALSE) {
   2043 				ERROR("writer: failed to write data block %d\n",
   2044 					i);
   2045 				failed = TRUE;
   2046 			}
   2047 
   2048 			hole = 0;
   2049 			cache_block_put(block->buffer);
   2050 			free(block);
   2051 		}
   2052 
   2053 		if(hole && failed == FALSE) {
   2054 			/*
   2055 			 * corner case for hole extending to end of file
   2056 			 */
   2057 			if(file->sparse == FALSE ||
   2058 					lseek(file_fd, hole, SEEK_CUR) == -1) {
   2059 				/*
   2060 				 * for files which we don't want to write
   2061 				 * sparsely, or for broken lseeks which cannot
   2062 				 * seek beyond end of file, write_block will do
   2063 				 * the right thing
   2064 				 */
   2065 				hole --;
   2066 				if(write_block(file_fd, "\0", 1, hole,
   2067 						file->sparse) == FALSE) {
   2068 					ERROR("writer: failed to write sparse "
   2069 						"data block\n");
   2070 					failed = TRUE;
   2071 				}
   2072 			} else if(ftruncate(file_fd, file->file_size) == -1) {
   2073 				ERROR("writer: failed to write sparse data "
   2074 					"block\n");
   2075 				failed = TRUE;
   2076 			}
   2077 		}
   2078 
   2079 		close_wake(file_fd);
   2080 		if(failed == FALSE)
   2081 			set_attributes(file->pathname, file->mode, file->uid,
   2082 				file->gid, file->time, file->xattr, force);
   2083 		else {
   2084 			ERROR("Failed to write %s, skipping\n", file->pathname);
   2085 			unlink(file->pathname);
   2086 		}
   2087 		free(file->pathname);
   2088 		free(file);
   2089 
   2090 	}
   2091 }
   2092 
   2093 
   2094 /*
   2095  * decompress thread.  This decompresses buffers queued by the read thread
   2096  */
   2097 void *inflator(void *arg)
   2098 {
   2099 	char tmp[block_size];
   2100 
   2101 	while(1) {
   2102 		struct cache_entry *entry = queue_get(to_inflate);
   2103 		int error, res;
   2104 
   2105 		res = compressor_uncompress(comp, tmp, entry->data,
   2106 			SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size,
   2107 			&error);
   2108 
   2109 		if(res == -1)
   2110 			ERROR("%s uncompress failed with error code %d\n",
   2111 				comp->name, error);
   2112 		else
   2113 			memcpy(entry->data, tmp, res);
   2114 
   2115 		/*
   2116 		 * block has been either successfully decompressed, or an error
   2117  		 * occurred, clear pending flag, set error appropriately and
   2118  		 * wake up any threads waiting on this block
   2119  		 */
   2120 		cache_block_ready(entry, res == -1);
   2121 	}
   2122 }
   2123 
   2124 
   2125 void *progress_thread(void *arg)
   2126 {
   2127 	struct timespec requested_time, remaining;
   2128 	struct itimerval itimerval;
   2129 	struct winsize winsize;
   2130 
   2131 	if(ioctl(1, TIOCGWINSZ, &winsize) == -1) {
   2132 		if(isatty(STDOUT_FILENO))
   2133 			ERROR("TIOCGWINSZ ioctl failed, defaulting to 80 "
   2134 				"columns\n");
   2135 		columns = 80;
   2136 	} else
   2137 		columns = winsize.ws_col;
   2138 	signal(SIGWINCH, sigwinch_handler);
   2139 	signal(SIGALRM, sigalrm_handler);
   2140 
   2141 	itimerval.it_value.tv_sec = 0;
   2142 	itimerval.it_value.tv_usec = 250000;
   2143 	itimerval.it_interval.tv_sec = 0;
   2144 	itimerval.it_interval.tv_usec = 250000;
   2145 	setitimer(ITIMER_REAL, &itimerval, NULL);
   2146 
   2147 	requested_time.tv_sec = 0;
   2148 	requested_time.tv_nsec = 250000000;
   2149 
   2150 	while(1) {
   2151 		int res = nanosleep(&requested_time, &remaining);
   2152 
   2153 		if(res == -1 && errno != EINTR)
   2154 			EXIT_UNSQUASH("nanosleep failed in progress thread\n");
   2155 
   2156 		if(progress_enabled) {
   2157 			pthread_mutex_lock(&screen_mutex);
   2158 			progress_bar(sym_count + dev_count +
   2159 				fifo_count + cur_blocks, total_inodes -
   2160 				total_files + total_blocks, columns);
   2161 			pthread_mutex_unlock(&screen_mutex);
   2162 		}
   2163 	}
   2164 }
   2165 
   2166 
   2167 void initialise_threads(int fragment_buffer_size, int data_buffer_size)
   2168 {
   2169 	struct rlimit rlim;
   2170 	int i, max_files, res;
   2171 	sigset_t sigmask, old_mask;
   2172 
   2173 	/* block SIGQUIT and SIGHUP, these are handled by the info thread */
   2174 	sigemptyset(&sigmask);
   2175 	sigaddset(&sigmask, SIGQUIT);
   2176 	sigaddset(&sigmask, SIGHUP);
   2177 	if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == -1)
   2178 		EXIT_UNSQUASH("Failed to set signal mask in initialise_threads"
   2179 			"\n");
   2180 
   2181 	/*
   2182 	 * temporarily block these signals so the created sub-threads will
   2183 	 * ignore them, ensuring the main thread handles them
   2184 	 */
   2185 	sigemptyset(&sigmask);
   2186 	sigaddset(&sigmask, SIGINT);
   2187 	sigaddset(&sigmask, SIGTERM);
   2188 	if(pthread_sigmask(SIG_BLOCK, &sigmask, &old_mask) == -1)
   2189 		EXIT_UNSQUASH("Failed to set signal mask in initialise_threads"
   2190 			"\n");
   2191 
   2192 	if(processors == -1) {
   2193 #ifndef linux
   2194 		int mib[2];
   2195 		size_t len = sizeof(processors);
   2196 
   2197 		mib[0] = CTL_HW;
   2198 #ifdef HW_AVAILCPU
   2199 		mib[1] = HW_AVAILCPU;
   2200 #else
   2201 		mib[1] = HW_NCPU;
   2202 #endif
   2203 
   2204 		if(sysctl(mib, 2, &processors, &len, NULL, 0) == -1) {
   2205 			ERROR("Failed to get number of available processors.  "
   2206 				"Defaulting to 1\n");
   2207 			processors = 1;
   2208 		}
   2209 #else
   2210 		processors = sysconf(_SC_NPROCESSORS_ONLN);
   2211 #endif
   2212 	}
   2213 
   2214 	if(add_overflow(processors, 3) ||
   2215 			multiply_overflow(processors + 3, sizeof(pthread_t)))
   2216 		EXIT_UNSQUASH("Processors too large\n");
   2217 
   2218 	thread = malloc((3 + processors) * sizeof(pthread_t));
   2219 	if(thread == NULL)
   2220 		EXIT_UNSQUASH("Out of memory allocating thread descriptors\n");
   2221 	inflator_thread = &thread[3];
   2222 
   2223 	/*
   2224 	 * dimensioning the to_reader and to_inflate queues.  The size of
   2225 	 * these queues is directly related to the amount of block
   2226 	 * read-ahead possible.  To_reader queues block read requests to
   2227 	 * the reader thread and to_inflate queues block decompression
   2228 	 * requests to the inflate thread(s) (once the block has been read by
   2229 	 * the reader thread).  The amount of read-ahead is determined by
   2230 	 * the combined size of the data_block and fragment caches which
   2231 	 * determine the total number of blocks which can be "in flight"
   2232 	 * at any one time (either being read or being decompressed)
   2233 	 *
   2234 	 * The maximum file open limit, however, affects the read-ahead
   2235 	 * possible, in that for normal sizes of the fragment and data block
   2236 	 * caches, where the incoming files have few data blocks or one fragment
   2237 	 * only, the file open limit is likely to be reached before the
   2238 	 * caches are full.  This means the worst case sizing of the combined
   2239 	 * sizes of the caches is unlikely to ever be necessary.  However, is is
   2240 	 * obvious read-ahead up to the data block cache size is always possible
   2241 	 * irrespective of the file open limit, because a single file could
   2242 	 * contain that number of blocks.
   2243 	 *
   2244 	 * Choosing the size as "file open limit + data block cache size" seems
   2245 	 * to be a reasonable estimate.  We can reasonably assume the maximum
   2246 	 * likely read-ahead possible is data block cache size + one fragment
   2247 	 * per open file.
   2248 	 *
   2249 	 * dimensioning the to_writer queue.  The size of this queue is
   2250 	 * directly related to the amount of block read-ahead possible.
   2251 	 * However, unlike the to_reader and to_inflate queues, this is
   2252 	 * complicated by the fact the to_writer queue not only contains
   2253 	 * entries for fragments and data_blocks but it also contains
   2254 	 * file entries, one per open file in the read-ahead.
   2255 	 *
   2256 	 * Choosing the size as "2 * (file open limit) +
   2257 	 * data block cache size" seems to be a reasonable estimate.
   2258 	 * We can reasonably assume the maximum likely read-ahead possible
   2259 	 * is data block cache size + one fragment per open file, and then
   2260 	 * we will have a file_entry for each open file.
   2261 	 */
   2262 	res = getrlimit(RLIMIT_NOFILE, &rlim);
   2263 	if (res == -1) {
   2264 		ERROR("failed to get open file limit!  Defaulting to 1\n");
   2265 		rlim.rlim_cur = 1;
   2266 	}
   2267 
   2268 	if (rlim.rlim_cur != RLIM_INFINITY) {
   2269 		/*
   2270 		 * leave OPEN_FILE_MARGIN free (rlim_cur includes fds used by
   2271 		 * stdin, stdout, stderr and filesystem fd
   2272 		 */
   2273 		if (rlim.rlim_cur <= OPEN_FILE_MARGIN)
   2274 			/* no margin, use minimum possible */
   2275 			max_files = 1;
   2276 		else
   2277 			max_files = rlim.rlim_cur - OPEN_FILE_MARGIN;
   2278 	} else
   2279 		max_files = -1;
   2280 
   2281 	/* set amount of available files for use by open_wait and close_wake */
   2282 	open_init(max_files);
   2283 
   2284 	/*
   2285 	 * allocate to_reader, to_inflate and to_writer queues.  Set based on
   2286 	 * open file limit and cache size, unless open file limit is unlimited,
   2287 	 * in which case set purely based on cache limits
   2288 	 *
   2289 	 * In doing so, check that the user supplied values do not overflow
   2290 	 * a signed int
   2291 	 */
   2292 	if (max_files != -1) {
   2293 		if(add_overflow(data_buffer_size, max_files) ||
   2294 				add_overflow(data_buffer_size, max_files * 2))
   2295 			EXIT_UNSQUASH("Data queue size is too large\n");
   2296 
   2297 		to_reader = queue_init(max_files + data_buffer_size);
   2298 		to_inflate = queue_init(max_files + data_buffer_size);
   2299 		to_writer = queue_init(max_files * 2 + data_buffer_size);
   2300 	} else {
   2301 		int all_buffers_size;
   2302 
   2303 		if(add_overflow(fragment_buffer_size, data_buffer_size))
   2304 			EXIT_UNSQUASH("Data and fragment queues combined are"
   2305 							" too large\n");
   2306 
   2307 		all_buffers_size = fragment_buffer_size + data_buffer_size;
   2308 
   2309 		if(add_overflow(all_buffers_size, all_buffers_size))
   2310 			EXIT_UNSQUASH("Data and fragment queues combined are"
   2311 							" too large\n");
   2312 
   2313 		to_reader = queue_init(all_buffers_size);
   2314 		to_inflate = queue_init(all_buffers_size);
   2315 		to_writer = queue_init(all_buffers_size * 2);
   2316 	}
   2317 
   2318 	from_writer = queue_init(1);
   2319 
   2320 	fragment_cache = cache_init(block_size, fragment_buffer_size);
   2321 	data_cache = cache_init(block_size, data_buffer_size);
   2322 	pthread_create(&thread[0], NULL, reader, NULL);
   2323 	pthread_create(&thread[1], NULL, writer, NULL);
   2324 	pthread_create(&thread[2], NULL, progress_thread, NULL);
   2325 	init_info();
   2326 	pthread_mutex_init(&fragment_mutex, NULL);
   2327 
   2328 	for(i = 0; i < processors; i++) {
   2329 		if(pthread_create(&inflator_thread[i], NULL, inflator, NULL) !=
   2330 				 0)
   2331 			EXIT_UNSQUASH("Failed to create thread\n");
   2332 	}
   2333 
   2334 	printf("Parallel unsquashfs: Using %d processor%s\n", processors,
   2335 			processors == 1 ? "" : "s");
   2336 
   2337 	if(pthread_sigmask(SIG_SETMASK, &old_mask, NULL) == -1)
   2338 		EXIT_UNSQUASH("Failed to set signal mask in initialise_threads"
   2339 			"\n");
   2340 }
   2341 
   2342 
   2343 void enable_progress_bar()
   2344 {
   2345 	pthread_mutex_lock(&screen_mutex);
   2346 	progress_enabled = progress;
   2347 	pthread_mutex_unlock(&screen_mutex);
   2348 }
   2349 
   2350 
   2351 void disable_progress_bar()
   2352 {
   2353 	pthread_mutex_lock(&screen_mutex);
   2354 	if(progress_enabled) {
   2355 		progress_bar(sym_count + dev_count + fifo_count + cur_blocks,
   2356 			total_inodes - total_files + total_blocks, columns);
   2357 		printf("\n");
   2358 	}
   2359 	progress_enabled = FALSE;
   2360 	pthread_mutex_unlock(&screen_mutex);
   2361 }
   2362 
   2363 
   2364 void progressbar_error(char *fmt, ...)
   2365 {
   2366 	va_list ap;
   2367 
   2368 	pthread_mutex_lock(&screen_mutex);
   2369 
   2370 	if(progress_enabled)
   2371 		fprintf(stderr, "\n");
   2372 
   2373 	va_start(ap, fmt);
   2374 	vfprintf(stderr, fmt, ap);
   2375 	va_end(ap);
   2376 
   2377 	pthread_mutex_unlock(&screen_mutex);
   2378 }
   2379 
   2380 
   2381 void progressbar_info(char *fmt, ...)
   2382 {
   2383 	va_list ap;
   2384 
   2385 	pthread_mutex_lock(&screen_mutex);
   2386 
   2387 	if(progress_enabled)
   2388 		printf("\n");
   2389 
   2390 	va_start(ap, fmt);
   2391 	vprintf(fmt, ap);
   2392 	va_end(ap);
   2393 
   2394 	pthread_mutex_unlock(&screen_mutex);
   2395 }
   2396 
   2397 void progress_bar(long long current, long long max, int columns)
   2398 {
   2399 	char rotate_list[] = { '|', '/', '-', '\\' };
   2400 	int max_digits, used, hashes, spaces;
   2401 	static int tty = -1;
   2402 
   2403 	if(max == 0)
   2404 		return;
   2405 
   2406 	max_digits = floor(log10(max)) + 1;
   2407 	used = max_digits * 2 + 11;
   2408 	hashes = (current * (columns - used)) / max;
   2409 	spaces = columns - used - hashes;
   2410 
   2411 	if((current > max) || (columns - used < 0))
   2412 		return;
   2413 
   2414 	if(tty == -1)
   2415 		tty = isatty(STDOUT_FILENO);
   2416 	if(!tty) {
   2417 		static long long previous = -1;
   2418 
   2419 		/*
   2420 		 * Updating much more frequently than this results in huge
   2421 		 * log files.
   2422 		 */
   2423 		if((current % 100) != 0 && current != max)
   2424 			return;
   2425 		/* Don't update just to rotate the spinner. */
   2426 		if(current == previous)
   2427 			return;
   2428 		previous = current;
   2429 	}
   2430 
   2431 	printf("\r[");
   2432 
   2433 	while (hashes --)
   2434 		putchar('=');
   2435 
   2436 	putchar(rotate_list[rotate]);
   2437 
   2438 	while(spaces --)
   2439 		putchar(' ');
   2440 
   2441 	printf("] %*lld/%*lld", max_digits, current, max_digits, max);
   2442 	printf(" %3lld%%", current * 100 / max);
   2443 	fflush(stdout);
   2444 }
   2445 
   2446 
   2447 int parse_number(char *arg, int *res)
   2448 {
   2449 	char *b;
   2450 	long number = strtol(arg, &b, 10);
   2451 
   2452 	/* check for trailing junk after number */
   2453 	if(*b != '\0')
   2454 		return 0;
   2455 
   2456 	/*
   2457 	 * check for strtol underflow or overflow in conversion.
   2458 	 * Note: strtol can validly return LONG_MIN and LONG_MAX
   2459 	 * if the user entered these values, but, additional code
   2460 	 * to distinguish this scenario is unnecessary, because for
   2461 	 * our purposes LONG_MIN and LONG_MAX are too large anyway
   2462 	 */
   2463 	if(number == LONG_MIN || number == LONG_MAX)
   2464 		return 0;
   2465 
   2466 	/* reject negative numbers as invalid */
   2467 	if(number < 0)
   2468 		return 0;
   2469 
   2470 	/* check if long result will overflow signed int */
   2471 	if(number > INT_MAX)
   2472 		return 0;
   2473 
   2474 	*res = number;
   2475 	return 1;
   2476 }
   2477 
   2478 
   2479 #define VERSION() \
   2480 	printf("unsquashfs version 4.3 (2014/05/12)\n");\
   2481 	printf("copyright (C) 2014 Phillip Lougher "\
   2482 		"<phillip (at) squashfs.org.uk>\n\n");\
   2483     	printf("This program is free software; you can redistribute it and/or"\
   2484 		"\n");\
   2485 	printf("modify it under the terms of the GNU General Public License"\
   2486 		"\n");\
   2487 	printf("as published by the Free Software Foundation; either version "\
   2488 		"2,\n");\
   2489 	printf("or (at your option) any later version.\n\n");\
   2490 	printf("This program is distributed in the hope that it will be "\
   2491 		"useful,\n");\
   2492 	printf("but WITHOUT ANY WARRANTY; without even the implied warranty of"\
   2493 		"\n");\
   2494 	printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"\
   2495 		"\n");\
   2496 	printf("GNU General Public License for more details.\n");
   2497 int main(int argc, char *argv[])
   2498 {
   2499 	char *dest = "squashfs-root";
   2500 	int i, stat_sys = FALSE, version = FALSE;
   2501 	int n;
   2502 	struct pathnames *paths = NULL;
   2503 	struct pathname *path = NULL;
   2504 	long long directory_table_end;
   2505 	int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT;
   2506 	int data_buffer_size = DATA_BUFFER_DEFAULT;
   2507 
   2508 	pthread_mutex_init(&screen_mutex, NULL);
   2509 	root_process = geteuid() == 0;
   2510 	if(root_process)
   2511 		umask(0);
   2512 
   2513 	for(i = 1; i < argc; i++) {
   2514 		if(*argv[i] != '-')
   2515 			break;
   2516 		if(strcmp(argv[i], "-version") == 0 ||
   2517 				strcmp(argv[i], "-v") == 0) {
   2518 			VERSION();
   2519 			version = TRUE;
   2520 		} else if(strcmp(argv[i], "-info") == 0 ||
   2521 				strcmp(argv[i], "-i") == 0)
   2522 			info = TRUE;
   2523 		else if(strcmp(argv[i], "-ls") == 0 ||
   2524 				strcmp(argv[i], "-l") == 0)
   2525 			lsonly = TRUE;
   2526 		else if(strcmp(argv[i], "-no-progress") == 0 ||
   2527 				strcmp(argv[i], "-n") == 0)
   2528 			progress = FALSE;
   2529 		else if(strcmp(argv[i], "-no-xattrs") == 0 ||
   2530 				strcmp(argv[i], "-no") == 0)
   2531 			no_xattrs = TRUE;
   2532 		else if(strcmp(argv[i], "-xattrs") == 0 ||
   2533 				strcmp(argv[i], "-x") == 0)
   2534 			no_xattrs = FALSE;
   2535 		else if(strcmp(argv[i], "-user-xattrs") == 0 ||
   2536 				strcmp(argv[i], "-u") == 0) {
   2537 			user_xattrs = TRUE;
   2538 			no_xattrs = FALSE;
   2539 		} else if(strcmp(argv[i], "-dest") == 0 ||
   2540 				strcmp(argv[i], "-d") == 0) {
   2541 			if(++i == argc) {
   2542 				fprintf(stderr, "%s: -dest missing filename\n",
   2543 					argv[0]);
   2544 				exit(1);
   2545 			}
   2546 			dest = argv[i];
   2547 		} else if(strcmp(argv[i], "-processors") == 0 ||
   2548 				strcmp(argv[i], "-p") == 0) {
   2549 			if((++i == argc) ||
   2550 					!parse_number(argv[i],
   2551 						&processors)) {
   2552 				ERROR("%s: -processors missing or invalid "
   2553 					"processor number\n", argv[0]);
   2554 				exit(1);
   2555 			}
   2556 			if(processors < 1) {
   2557 				ERROR("%s: -processors should be 1 or larger\n",
   2558 					argv[0]);
   2559 				exit(1);
   2560 			}
   2561 		} else if(strcmp(argv[i], "-data-queue") == 0 ||
   2562 					 strcmp(argv[i], "-da") == 0) {
   2563 			if((++i == argc) ||
   2564 					!parse_number(argv[i],
   2565 						&data_buffer_size)) {
   2566 				ERROR("%s: -data-queue missing or invalid "
   2567 					"queue size\n", argv[0]);
   2568 				exit(1);
   2569 			}
   2570 			if(data_buffer_size < 1) {
   2571 				ERROR("%s: -data-queue should be 1 Mbyte or "
   2572 					"larger\n", argv[0]);
   2573 				exit(1);
   2574 			}
   2575 		} else if(strcmp(argv[i], "-frag-queue") == 0 ||
   2576 					strcmp(argv[i], "-fr") == 0) {
   2577 			if((++i == argc) ||
   2578 					!parse_number(argv[i],
   2579 						&fragment_buffer_size)) {
   2580 				ERROR("%s: -frag-queue missing or invalid "
   2581 					"queue size\n", argv[0]);
   2582 				exit(1);
   2583 			}
   2584 			if(fragment_buffer_size < 1) {
   2585 				ERROR("%s: -frag-queue should be 1 Mbyte or "
   2586 					"larger\n", argv[0]);
   2587 				exit(1);
   2588 			}
   2589 		} else if(strcmp(argv[i], "-force") == 0 ||
   2590 				strcmp(argv[i], "-f") == 0)
   2591 			force = TRUE;
   2592 		else if(strcmp(argv[i], "-stat") == 0 ||
   2593 				strcmp(argv[i], "-s") == 0)
   2594 			stat_sys = TRUE;
   2595 		else if(strcmp(argv[i], "-lls") == 0 ||
   2596 				strcmp(argv[i], "-ll") == 0) {
   2597 			lsonly = TRUE;
   2598 			short_ls = FALSE;
   2599 		} else if(strcmp(argv[i], "-linfo") == 0 ||
   2600 				strcmp(argv[i], "-li") == 0) {
   2601 			info = TRUE;
   2602 			short_ls = FALSE;
   2603 		} else if(strcmp(argv[i], "-ef") == 0 ||
   2604 				strcmp(argv[i], "-e") == 0) {
   2605 			if(++i == argc) {
   2606 				fprintf(stderr, "%s: -ef missing filename\n",
   2607 					argv[0]);
   2608 				exit(1);
   2609 			}
   2610 			path = process_extract_files(path, argv[i]);
   2611 		} else if(strcmp(argv[i], "-regex") == 0 ||
   2612 				strcmp(argv[i], "-r") == 0)
   2613 			use_regex = TRUE;
   2614 		else
   2615 			goto options;
   2616 	}
   2617 
   2618 	if(lsonly || info)
   2619 		progress = FALSE;
   2620 
   2621 #ifdef SQUASHFS_TRACE
   2622 	/*
   2623 	 * Disable progress bar if full debug tracing is enabled.
   2624 	 * The progress bar in this case just gets in the way of the
   2625 	 * debug trace output
   2626 	 */
   2627 	progress = FALSE;
   2628 #endif
   2629 
   2630 	if(i == argc) {
   2631 		if(!version) {
   2632 options:
   2633 			ERROR("SYNTAX: %s [options] filesystem [directories or "
   2634 				"files to extract]\n", argv[0]);
   2635 			ERROR("\t-v[ersion]\t\tprint version, licence and "
   2636 				"copyright information\n");
   2637 			ERROR("\t-d[est] <pathname>\tunsquash to <pathname>, "
   2638 				"default \"squashfs-root\"\n");
   2639 			ERROR("\t-n[o-progress]\t\tdon't display the progress "
   2640 				"bar\n");
   2641 			ERROR("\t-no[-xattrs]\t\tdon't extract xattrs in file system"
   2642 				NOXOPT_STR"\n");
   2643 			ERROR("\t-x[attrs]\t\textract xattrs in file system"
   2644 				XOPT_STR "\n");
   2645 			ERROR("\t-u[ser-xattrs]\t\tonly extract user xattrs in "
   2646 				"file system.\n\t\t\t\tEnables extracting "
   2647 				"xattrs\n");
   2648 			ERROR("\t-p[rocessors] <number>\tuse <number> "
   2649 				"processors.  By default will use\n");
   2650 			ERROR("\t\t\t\tnumber of processors available\n");
   2651 			ERROR("\t-i[nfo]\t\t\tprint files as they are "
   2652 				"unsquashed\n");
   2653 			ERROR("\t-li[nfo]\t\tprint files as they are "
   2654 				"unsquashed with file\n");
   2655 			ERROR("\t\t\t\tattributes (like ls -l output)\n");
   2656 			ERROR("\t-l[s]\t\t\tlist filesystem, but don't unsquash"
   2657 				"\n");
   2658 			ERROR("\t-ll[s]\t\t\tlist filesystem with file "
   2659 				"attributes (like\n");
   2660 			ERROR("\t\t\t\tls -l output), but don't unsquash\n");
   2661 			ERROR("\t-f[orce]\t\tif file already exists then "
   2662 				"overwrite\n");
   2663 			ERROR("\t-s[tat]\t\t\tdisplay filesystem superblock "
   2664 				"information\n");
   2665 			ERROR("\t-e[f] <extract file>\tlist of directories or "
   2666 				"files to extract.\n\t\t\t\tOne per line\n");
   2667 			ERROR("\t-da[ta-queue] <size>\tSet data queue to "
   2668 				"<size> Mbytes.  Default %d\n\t\t\t\tMbytes\n",
   2669 				DATA_BUFFER_DEFAULT);
   2670 			ERROR("\t-fr[ag-queue] <size>\tSet fragment queue to "
   2671 				"<size> Mbytes.  Default\n\t\t\t\t%d Mbytes\n",
   2672 				FRAGMENT_BUFFER_DEFAULT);
   2673 			ERROR("\t-r[egex]\t\ttreat extract names as POSIX "
   2674 				"regular expressions\n");
   2675 			ERROR("\t\t\t\trather than use the default shell "
   2676 				"wildcard\n\t\t\t\texpansion (globbing)\n");
   2677 			ERROR("\nDecompressors available:\n");
   2678 			display_compressors("", "");
   2679 		}
   2680 		exit(1);
   2681 	}
   2682 
   2683 	for(n = i + 1; n < argc; n++)
   2684 		path = add_path(path, argv[n], argv[n]);
   2685 
   2686 	if((fd = open(argv[i], O_RDONLY)) == -1) {
   2687 		ERROR("Could not open %s, because %s\n", argv[i],
   2688 			strerror(errno));
   2689 		exit(1);
   2690 	}
   2691 
   2692 	if(read_super(argv[i]) == FALSE)
   2693 		exit(1);
   2694 
   2695 	if(stat_sys) {
   2696 		squashfs_stat(argv[i]);
   2697 		exit(0);
   2698 	}
   2699 
   2700 	if(!check_compression(comp))
   2701 		exit(1);
   2702 
   2703 	block_size = sBlk.s.block_size;
   2704 	block_log = sBlk.s.block_log;
   2705 
   2706 	/*
   2707 	 * Sanity check block size and block log.
   2708 	 *
   2709 	 * Check they're within correct limits
   2710 	 */
   2711 	if(block_size > SQUASHFS_FILE_MAX_SIZE ||
   2712 					block_log > SQUASHFS_FILE_MAX_LOG)
   2713 		EXIT_UNSQUASH("Block size or block_log too large."
   2714 			"  File system is corrupt.\n");
   2715 
   2716 	/*
   2717 	 * Check block_size and block_log match
   2718 	 */
   2719 	if(block_size != (1 << block_log))
   2720 		EXIT_UNSQUASH("Block size and block_log do not match."
   2721 			"  File system is corrupt.\n");
   2722 
   2723 	/*
   2724 	 * convert from queue size in Mbytes to queue size in
   2725 	 * blocks.
   2726 	 *
   2727 	 * In doing so, check that the user supplied values do not
   2728 	 * overflow a signed int
   2729 	 */
   2730 	if(shift_overflow(fragment_buffer_size, 20 - block_log))
   2731 		EXIT_UNSQUASH("Fragment queue size is too large\n");
   2732 	else
   2733 		fragment_buffer_size <<= 20 - block_log;
   2734 
   2735 	if(shift_overflow(data_buffer_size, 20 - block_log))
   2736 		EXIT_UNSQUASH("Data queue size is too large\n");
   2737 	else
   2738 		data_buffer_size <<= 20 - block_log;
   2739 
   2740 	initialise_threads(fragment_buffer_size, data_buffer_size);
   2741 
   2742 	fragment_data = malloc(block_size);
   2743 	if(fragment_data == NULL)
   2744 		EXIT_UNSQUASH("failed to allocate fragment_data\n");
   2745 
   2746 	file_data = malloc(block_size);
   2747 	if(file_data == NULL)
   2748 		EXIT_UNSQUASH("failed to allocate file_data");
   2749 
   2750 	data = malloc(block_size);
   2751 	if(data == NULL)
   2752 		EXIT_UNSQUASH("failed to allocate data\n");
   2753 
   2754 	created_inode = malloc(sBlk.s.inodes * sizeof(char *));
   2755 	if(created_inode == NULL)
   2756 		EXIT_UNSQUASH("failed to allocate created_inode\n");
   2757 
   2758 	memset(created_inode, 0, sBlk.s.inodes * sizeof(char *));
   2759 
   2760 	if(s_ops.read_uids_guids() == FALSE)
   2761 		EXIT_UNSQUASH("failed to uid/gid table\n");
   2762 
   2763 	if(s_ops.read_fragment_table(&directory_table_end) == FALSE)
   2764 		EXIT_UNSQUASH("failed to read fragment table\n");
   2765 
   2766 	if(read_inode_table(sBlk.s.inode_table_start,
   2767 				sBlk.s.directory_table_start) == FALSE)
   2768 		EXIT_UNSQUASH("failed to read inode table\n");
   2769 
   2770 	if(read_directory_table(sBlk.s.directory_table_start,
   2771 				directory_table_end) == FALSE)
   2772 		EXIT_UNSQUASH("failed to read directory table\n");
   2773 
   2774 	if(no_xattrs)
   2775 		sBlk.s.xattr_id_table_start = SQUASHFS_INVALID_BLK;
   2776 
   2777 	if(read_xattrs_from_disk(fd, &sBlk.s) == 0)
   2778 		EXIT_UNSQUASH("failed to read the xattr table\n");
   2779 
   2780 	if(path) {
   2781 		paths = init_subdir();
   2782 		paths = add_subdir(paths, path);
   2783 	}
   2784 
   2785 	pre_scan(dest, SQUASHFS_INODE_BLK(sBlk.s.root_inode),
   2786 		SQUASHFS_INODE_OFFSET(sBlk.s.root_inode), paths);
   2787 
   2788 	memset(created_inode, 0, sBlk.s.inodes * sizeof(char *));
   2789 	inode_number = 1;
   2790 
   2791 	printf("%d inodes (%d blocks) to write\n\n", total_inodes,
   2792 		total_inodes - total_files + total_blocks);
   2793 
   2794 	enable_progress_bar();
   2795 
   2796 	dir_scan(dest, SQUASHFS_INODE_BLK(sBlk.s.root_inode),
   2797 		SQUASHFS_INODE_OFFSET(sBlk.s.root_inode), paths);
   2798 
   2799 	queue_put(to_writer, NULL);
   2800 	queue_get(from_writer);
   2801 
   2802 	disable_progress_bar();
   2803 
   2804 	if(!lsonly) {
   2805 		printf("\n");
   2806 		printf("created %d files\n", file_count);
   2807 		printf("created %d directories\n", dir_count);
   2808 		printf("created %d symlinks\n", sym_count);
   2809 		printf("created %d devices\n", dev_count);
   2810 		printf("created %d fifos\n", fifo_count);
   2811 	}
   2812 
   2813 	return 0;
   2814 }
   2815