/*
 * Create a squashfs filesystem.  This is a highly compressed read only
 * filesystem.
 *
 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012,
 * 2013
 * Phillip Lougher <phillip@squashfs.org.uk>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2,
 * or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * sort.c
 */

#define TRUE 1
#define FALSE 0
#define MAX_LINE 16384

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "squashfs_fs.h"
#include "mksquashfs.h"
#include "sort.h"
#include "error.h"

int mkisofs_style = -1;

struct sort_info {
	dev_t			st_dev;
	ino_t			st_ino;
	int			priority;
	struct sort_info	*next;
};

struct sort_info *sort_info_list[65536];

struct priority_entry *priority_list[65536];

extern int silent;
extern void write_file(squashfs_inode *inode, struct dir_ent *dir_ent,
	int *c_size);
extern char *pathname(struct dir_ent *dir_ent);


void add_priority_list(struct dir_ent *dir, int priority)
{
	struct priority_entry *new_priority_entry;

	priority += 32768;
	new_priority_entry = malloc(sizeof(struct priority_entry));
	if(new_priority_entry == NULL)
		MEM_ERROR();

	new_priority_entry->dir = dir;;
	new_priority_entry->next = priority_list[priority];
	priority_list[priority] = new_priority_entry;
}


int get_priority(char *filename, struct stat *buf, int priority)
{
	int hash = buf->st_ino & 0xffff;
	struct sort_info *s;

	for(s = sort_info_list[hash]; s; s = s->next)
		if((s->st_dev == buf->st_dev) && (s->st_ino == buf->st_ino)) {
			TRACE("returning priority %d (%s)\n", s->priority,
				filename);
			return s->priority;
		}
	TRACE("returning priority %d (%s)\n", priority, filename);
	return priority;
}


#define ADD_ENTRY(buf, priority) {\
	int hash = buf.st_ino & 0xffff;\
	struct sort_info *s;\
	if((s = malloc(sizeof(struct sort_info))) == NULL) \
		MEM_ERROR(); \
	s->st_dev = buf.st_dev;\
	s->st_ino = buf.st_ino;\
	s->priority = priority;\
	s->next = sort_info_list[hash];\
	sort_info_list[hash] = s;\
	}
int add_sort_list(char *path, int priority, int source, char *source_path[])
{
	int i, n;
	struct stat buf;

	TRACE("add_sort_list: filename %s, priority %d\n", path, priority);
	if(strlen(path) > 1 && strcmp(path + strlen(path) - 2, "/*") == 0)
		path[strlen(path) - 2] = '\0';

	TRACE("add_sort_list: filename %s, priority %d\n", path, priority);
re_read:
	if(path[0] == '/' || strncmp(path, "./", 2) == 0 ||
			strncmp(path, "../", 3) == 0 || mkisofs_style == 1) {
		if(lstat(path, &buf) == -1)
			goto error;
		TRACE("adding filename %s, priority %d, st_dev %d, st_ino "
			"%lld\n", path, priority, (int) buf.st_dev,
			(long long) buf.st_ino);
		ADD_ENTRY(buf, priority);
		return TRUE;
	}

	for(i = 0, n = 0; i < source; i++) {
		char *filename;
		int res = asprintf(&filename, "%s/%s", source_path[i], path);
		if(res == -1)
			BAD_ERROR("asprintf failed in add_sort_list\n");
		res = lstat(filename, &buf);
		free(filename);
		if(res == -1) {
			if(!(errno == ENOENT || errno == ENOTDIR))
				goto error;
			continue;
		}
		ADD_ENTRY(buf, priority);
		n ++;
	}

	if(n == 0 && mkisofs_style == -1 && lstat(path, &buf) != -1) {
		ERROR("WARNING: Mkisofs style sortlist detected! This is "
			"supported but please\n");
		ERROR("convert to mksquashfs style sortlist! A sortlist entry");
	        ERROR(" should be\neither absolute (starting with ");
		ERROR("'/') start with './' or '../' (taken to be\nrelative to "
			"$PWD), otherwise it ");
		ERROR("is assumed the entry is relative to one\nof the source "
			"directories, i.e. with ");
		ERROR("\"mksquashfs test test.sqsh\",\nthe sortlist ");
		ERROR("entry \"file\" is assumed to be inside the directory "
			"test.\n\n");
		mkisofs_style = 1;
		goto re_read;
	}

	mkisofs_style = 0;

	if(n == 1)
		return TRUE;
	if(n > 1) {
		ERROR(" Ambiguous sortlist entry \"%s\"\n\nIt maps to more "
			"than one source entry!  Please use an absolute path."
			"\n", path);
		return FALSE;
	}

error:
        ERROR("Cannot stat sortlist entry \"%s\"\n", path);
        ERROR("This is probably because you're using the wrong file\n");
        ERROR("path relative to the source directories\n");
	/*
	 * Historical note
	 * Failure to stat a sortlist entry is deliberately ignored, even
	 * though it is an error.  Squashfs release 2.2 changed the behaviour
	 * to treat it as a fatal error, but it was changed back to
	 * the original behaviour to ignore it in release 2.2-r2 following
	 * feedback from users at the time.
	 */
        return TRUE;
}


void generate_file_priorities(struct dir_info *dir, int priority,
	struct stat *buf)
{
	struct dir_ent *dir_ent = dir->list;

	priority = get_priority(dir->pathname, buf, priority);

	for(; dir_ent; dir_ent = dir_ent->next) {
		struct stat *buf = &dir_ent->inode->buf;
		if(dir_ent->inode->root_entry)
			continue;

		switch(buf->st_mode & S_IFMT) {
			case S_IFREG:
				add_priority_list(dir_ent,
					get_priority(pathname(dir_ent), buf,
					priority));
				break;
			case S_IFDIR:
				generate_file_priorities(dir_ent->dir,
					priority, buf);
				break;
		}
	}
}


int read_sort_file(char *filename, int source, char *source_path[])
{
	FILE *fd;
	char line_buffer[MAX_LINE + 1]; /* overflow safe */
	char sort_filename[MAX_LINE + 1]; /* overflow safe */
	char *line, *name;
	int n, priority, res;

	if((fd = fopen(filename, "r")) == NULL) {
		ERROR("Failed to open sort file \"%s\" because %s\n",
			filename, strerror(errno));
		return FALSE;
	}

	while(fgets(line = line_buffer, MAX_LINE + 1, fd) != NULL) {
		int len = strlen(line);

		if(len == MAX_LINE && line[len - 1] != '\n') {
			/* line too large */
			ERROR("Line too long when reading "
				"sort file \"%s\", larger than %d "
				"bytes\n", filename, MAX_LINE);
			goto failed;
		}

		/*
		 * Remove '\n' terminator if it exists (the last line
		 * in the file may not be '\n' terminated)
		 */
		if(len && line[len - 1] == '\n')
			line[len - 1] = '\0';

		/* Skip any leading whitespace */
		while(isspace(*line))
			line ++;

		/* if comment line, skip */
		if(*line == '#')
			continue;

		/*
		 * Scan for filename, don't use sscanf() and "%s" because
		 * that can't handle filenames with spaces
		 */
		for(name = sort_filename; !isspace(*line) && *line != '\0';) {
			if(*line == '\\') {
				line ++;
				if (*line == '\0')
					break;
			}
			*name ++ = *line ++;
		}
		*name = '\0';

		/*
		 * if filename empty, then line was empty of anything but
		 * whitespace or a backslash character.  Skip empy lines
		 */
		if(sort_filename[0] == '\0')
			continue;

		/*
		 * Scan the rest of the line, we expect a decimal number
		 * which is the filename priority
		 */
		errno = 0;
		res = sscanf(line, "%d%n", &priority, &n);

		if((res < 1 || errno) && errno != ERANGE) {
			if(errno == 0)
				/* No error, assume EOL or match failure */
				ERROR("Sort file \"%s\", can't find priority "
					"in entry \"%s\", EOL or match "
					"failure\n", filename, line_buffer);
			else
				/* Some other failure not ERANGE */
				ERROR("Sscanf failed reading sort file \"%s\" "
					"because %s\n", filename,
					strerror(errno));
			goto failed;
		} else if((errno == ERANGE) ||
				(priority < -32768 || priority > 32767)) {
			ERROR("Sort file \"%s\", entry \"%s\" has priority "
				"outside range of -32767:32768.\n", filename,
				line_buffer);
			goto failed;
		}

		/* Skip any trailing whitespace */
		line += n;
		while(isspace(*line))
			line ++;

		if(*line != '\0') {
			ERROR("Sort file \"%s\", trailing characters after "
				"priority in entry \"%s\"\n", filename,
				line_buffer);
			goto failed;
		}

		res = add_sort_list(sort_filename, priority, source,
			source_path);
		if(res == FALSE)
			goto failed;
	}

	if(ferror(fd)) {
		ERROR("Reading sort file \"%s\" failed because %s\n", filename,
			strerror(errno));
		goto failed;
	}

	fclose(fd);
	return TRUE;

failed:
	fclose(fd);
	return FALSE;
}


void sort_files_and_write(struct dir_info *dir)
{
	int i;
	struct priority_entry *entry;
	squashfs_inode inode;
	int duplicate_file;

	for(i = 65535; i >= 0; i--)
		for(entry = priority_list[i]; entry; entry = entry->next) {
			TRACE("%d: %s\n", i - 32768, pathname(entry->dir));
			if(entry->dir->inode->inode == SQUASHFS_INVALID_BLK) {
				write_file(&inode, entry->dir, &duplicate_file);
				INFO("file %s, uncompressed size %lld bytes %s"
					"\n", pathname(entry->dir),
					(long long)
					entry->dir->inode->buf.st_size,
					duplicate_file ? "DUPLICATE" : "");
				entry->dir->inode->inode = inode;
				entry->dir->inode->type = SQUASHFS_FILE_TYPE;
			} else
				INFO("file %s, uncompressed size %lld bytes "
					"LINK\n", pathname(entry->dir),
					(long long)
					entry->dir->inode->buf.st_size);
		}
}
