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