summaryrefslogtreecommitdiff
path: root/release/src/linux/linux/scripts/squashfs/sort.c
diff options
context:
space:
mode:
Diffstat (limited to 'release/src/linux/linux/scripts/squashfs/sort.c')
-rw-r--r--release/src/linux/linux/scripts/squashfs/sort.c227
1 files changed, 90 insertions, 137 deletions
diff --git a/release/src/linux/linux/scripts/squashfs/sort.c b/release/src/linux/linux/scripts/squashfs/sort.c
index b5371280..c30093fa 100644
--- a/release/src/linux/linux/scripts/squashfs/sort.c
+++ b/release/src/linux/linux/scripts/squashfs/sort.c
@@ -1,7 +1,8 @@
/*
* Create a squashfs filesystem. This is a highly compressed read only filesystem.
*
- * Copyright (c) 2002, 2003, 2004 Phillip Lougher <plougher@users.sourceforge.net>
+ * Copyright (c) 2002, 2003, 2004, 2005
+ * Phillip Lougher <phillip@lougher.org.uk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -34,20 +35,32 @@
#include <stdlib.h>
#include <squashfs_fs.h>
+#include "global.h"
+#include "sort.h"
#ifdef SQUASHFS_TRACE
-#define TRACE(s, args...) printf("mksquashfs: "s, ## args)
+#define TRACE(s, args...) do { \
+ printf("mksquashfs: "s, ## args); \
+ } while(0)
#else
#define TRACE(s, args...)
#endif
-#define INFO(s, args...) if(!silent) printf("mksquashfs: "s, ## args)
-#define ERROR(s, args...) fprintf(stderr, s, ## args)
-#define EXIT_MKSQUASHFS() exit(1)
-#define BAD_ERROR(s, args...) {\
- fprintf(stderr, "FATAL ERROR:" s, ##args);\
- EXIT_MKSQUASHFS();\
- }
+#define INFO(s, args...) do { \
+ if(!silent) printf("mksquashfs: "s, ## args); \
+ } while(0)
+#define ERROR(s, args...) do { \
+ fprintf(stderr, s, ## args); \
+ } while(0)
+#define EXIT_MKSQUASHFS() do { \
+ exit(1); \
+ } while(0)
+#define BAD_ERROR(s, args...) do {\
+ fprintf(stderr, "FATAL ERROR:" s, ##args);\
+ EXIT_MKSQUASHFS();\
+ } while(0);
+
+int mkisofs_style = -1;
struct sort_info {
dev_t st_dev;
@@ -59,66 +72,17 @@ struct sort_info {
struct sort_info *sort_info_list[65536];
struct priority_entry {
- char *filename;
- long long size;
- ino_t st_ino;
- dev_t st_dev;
+ struct dir_ent *dir;
struct priority_entry *next;
};
struct priority_entry *priority_list[65536];
-struct sorted_inode_entry {
- squashfs_inode inode;
- ino_t st_ino;
- dev_t st_dev;
- struct sorted_inode_entry *next;
-};
-
-struct sorted_inode_entry *sorted_inode_list[65536];
-
extern int silent;
-extern int excluded(char *filename, struct stat *buf);
-extern squashfs_inode write_file(char *filename, long long size, int *c_size);
-
-
-int add_to_sorted_inode_list(squashfs_inode inode, dev_t st_dev, ino_t st_ino)
-{
- int hash = st_ino & 0xffff;
- struct sorted_inode_entry *new_sorted_inode_entry;
-
- if((new_sorted_inode_entry = malloc(sizeof(struct sorted_inode_entry))) == NULL) {
- ERROR("Out of memory allocating sorted inode entry\n");
- return FALSE;
- }
-
- new_sorted_inode_entry->inode = inode;
- new_sorted_inode_entry->st_ino = st_ino;
- new_sorted_inode_entry->st_dev = st_dev;
- new_sorted_inode_entry->next = sorted_inode_list[hash];
- sorted_inode_list[hash] = new_sorted_inode_entry;
-
- return TRUE;
-}
-
-
-squashfs_inode get_sorted_inode(struct stat *buf)
-{
- int hash = buf->st_ino & 0xffff;
- struct sorted_inode_entry *sorted_inode_entry;
-
- for(sorted_inode_entry = sorted_inode_list[hash]; sorted_inode_entry; sorted_inode_entry = sorted_inode_entry->next)
- if(buf->st_ino == sorted_inode_entry->st_ino && buf->st_dev == sorted_inode_entry->st_dev)
- break;
-
- if(sorted_inode_entry)
- return sorted_inode_entry->inode;
- else
- return (squashfs_inode) 0;
-}
+extern squashfs_inode write_file(squashfs_inode *inode, struct dir_ent *dir_ent, long long size, int *c_size);
-int add_priority_list(char *filename, struct stat *buf, int priority)
+int add_priority_list(struct dir_ent *dir, int priority)
{
struct priority_entry *new_priority_entry;
@@ -128,10 +92,7 @@ int add_priority_list(char *filename, struct stat *buf, int priority)
return FALSE;
}
- new_priority_entry->filename = strdup(filename);
- new_priority_entry->size = buf->st_size;
- new_priority_entry->st_dev = buf->st_dev;
- new_priority_entry->st_ino = buf->st_ino;
+ new_priority_entry->dir = dir;;
new_priority_entry->next = priority_list[priority];
priority_list[priority] = new_priority_entry;
return TRUE;
@@ -168,8 +129,8 @@ int get_priority(char *filename, struct stat *buf, int priority)
}
int add_sort_list(char *path, int priority, int source, char *source_path[])
{
- int i;
- char buffer[4096], filename[4096];
+ int i, n;
+ char filename[4096];
struct stat buf;
TRACE("add_sort_list: filename %s, priority %d\n", path, priority);
@@ -177,71 +138,73 @@ int add_sort_list(char *path, int priority, int source, char *source_path[])
path[strlen(path) - 2] = '\0';
TRACE("add_sort_list: filename %s, priority %d\n", path, priority);
- if(path[0] == '/' || strncmp(path, "./", 2) == 0 || strncmp(path, "../", 3) == 0) {
- if(lstat(path, &buf) == -1) {
- sprintf(buffer, "Cannot stat sort_list dir/file %s, ignoring", path);
- perror(buffer);
- return TRUE;
- }
- TRACE("adding filename %s, priority %d, st_dev %Lx, st_ino %Lx\n", path, priority, buf.st_dev, buf.st_ino);
+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 %llx, st_ino %llx\n", path, priority, buf.st_dev, buf.st_ino);
ADD_ENTRY(buf, priority);
return TRUE;
}
- for(i = 0; i < source; i++) {
+ for(i = 0, n = 0; i < source; i++) {
strcat(strcat(strcpy(filename, source_path[i]), "/"), path);
if(lstat(filename, &buf) == -1) {
- if(!(errno == ENOENT || errno == ENOTDIR)) {
- sprintf(buffer, "Cannot stat sort_list dir/file %s, ignoring", filename);
- perror(buffer);
- }
+ if(!(errno == ENOENT || errno == ENOTDIR))
+ goto error;
continue;
}
ADD_ENTRY(buf, priority);
+ n ++;
}
- return TRUE;
+
+ 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)
+ BAD_ERROR(" Ambiguous sortlist entry \"%s\"\n\nIt maps to more than one source entry! Please use an absolute path.\n", path);
+
+error:
+ fprintf(stderr, "Cannot stat sortlist entry \"%s\"\n", path);
+ fprintf(stderr, "This is probably because you're using the wrong file\n");
+ fprintf(stderr, "path relative to the source directories\n");
+ return FALSE;
}
-void generate_file_priorities(char *pathname, int priority, struct stat *buf)
+void generate_file_priorities(struct dir_info *dir, int priority, struct stat *buf)
{
- char filename[8192];
- DIR *linuxdir;
- struct dirent *d_name;
-
- priority = get_priority(pathname, buf, priority);
-
- if((linuxdir = opendir(pathname)) == NULL) {
- ERROR("Could not open %s, skipping...\n", pathname);
- return;
- }
-
- while((d_name = readdir(linuxdir)) != NULL) {
- if(strcmp(d_name->d_name, ".") == 0 || strcmp(d_name->d_name, "..") == 0)
- continue;
- strcat(strcat(strcpy(filename, pathname), "/"), d_name->d_name);
+ priority = get_priority(dir->pathname, buf, priority);
- if(lstat(filename, buf) == -1) {
- char buffer[8192];
- sprintf(buffer, "Cannot stat dir/file %s, ignoring", filename);
- perror(buffer);
- continue;
- }
-
- if(excluded(filename, buf))
+ while(dir->current_count < dir->count) {
+ struct dir_ent *dir_ent = dir->list[dir->current_count++];
+ struct stat *buf = &dir_ent->inode->buf;
+ if(dir_ent->data)
continue;
switch(buf->st_mode & S_IFMT) {
case S_IFREG:
- add_priority_list(filename, buf, get_priority(filename, buf, priority));
+ add_priority_list(dir_ent, get_priority(dir_ent->pathname, buf, priority));
break;
case S_IFDIR:
- generate_file_priorities(filename, priority, buf);
+ generate_file_priorities(dir_ent->dir, priority, buf);
break;
}
}
-
- closedir(linuxdir);
+ dir->current_count = 0;
}
@@ -265,40 +228,30 @@ int read_sort_file(char *filename, int source, char *source_path[])
}
-void sort_files_and_write(int source, char *source_path[])
+void sort_files_and_write(struct dir_info *dir)
{
- struct stat buf;
- int i, c_size;
+ int i;
struct priority_entry *entry;
squashfs_inode inode;
+ int duplicate_file;
- for(i = 0; i < source; i++) {
- if(lstat(source_path[i], &buf) == -1) {
- char buffer[8192];
- sprintf(buffer, "Cannot stat dir/file %s, ignoring", source_path[i]);
- perror(buffer);
- continue;
- }
-
- if(excluded(source_path[i], &buf))
- continue;
-
- switch(buf.st_mode & S_IFMT) {
- case S_IFREG:
- add_priority_list(source_path[i], &buf, get_priority(source_path[i], &buf, 0));
- break;
- case S_IFDIR:
- generate_file_priorities(source_path[i], 0, &buf);
- break;
- }
- }
+ generate_file_priorities(dir, 0, &dir->dir_ent->inode->buf);
- for(i = 0; i < 65536; i++)
+ for(i = 65535; i >= 0; i--)
for(entry = priority_list[i]; entry; entry = entry->next) {
- TRACE("%d: %s\n", i - 32768, entry->filename);
- inode = write_file(entry->filename, entry->size, &c_size);
- INFO("file %s, size %d bytes, inode 0x%Lx\n", entry->filename, c_size, inode);
- INFO("\t%.2f%% of uncompressed file size (%Ld bytes)\n", ((float) c_size / entry->size) * 100.0, entry->size);
- add_to_sorted_inode_list(inode, entry->st_dev, entry->st_ino);
+ TRACE("%d: %s\n", i - 32768, entry->dir->pathname);
+ if(entry->dir->inode->inode == SQUASHFS_INVALID_BLK) {
+ if(write_file(&inode, entry->dir, entry->dir->inode->buf.st_size,
+ &duplicate_file)) {
+ INFO("file %s, uncompressed size %lld bytes %s\n",
+ entry->dir->pathname,
+ 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",
+ entry->dir->pathname, entry->dir->inode->buf.st_size);
}
}