File e2fsimage-0.2.2-alt12.patch of Package e2fsimage

configure         |  6 ++---
 man/Makefile      | 14 +++++-------
 man/e2fsimage.man | 30 ++++++++++++++++++++++++
 src/Makefile      |  6 ++---
 src/copy.c        |  9 ++++----
 src/dirent.c      | 51 +++++++++++++++++++++++++++++++++++++----
 src/e2fsimage.h   | 11 ++++++---
 src/group.c       |  2 +-
 src/initfs.c      |  5 ++--
 src/main.c        | 46 ++++++++++++++++++++++++++++++-------
 src/mkdir.c       | 17 ++++++++++++--
 src/mke2fs.c      | 68 ++++++++++++++++++++++++++++++++-----------------------
 src/passwd.c      |  2 +-
 src/sfile.c       |  4 ++--
 src/symlink.c     | 50 +++++++++++++++++++++++++++++++++++-----
 src/uids.c        |  6 ++++-
 src/util.c        |  2 ++
 17 files changed, 251 insertions(+), 78 deletions(-)

diff --git a/configure b/configure
index 07788d5..48fa798 100755
--- a/configure
+++ b/configure
@@ -46,7 +46,7 @@ add_include() {
 
 add_lib() {
   LIBS="$LIBS -l$2"
-  for _libs in -L/usr/lib ${LDIRS}; do
+  for _libs in -L/usr/lib64 -L/usr/lib ${LDIRS}; do
     if test "-L$1" = "${_libs}"; then
       return 0
     fi
@@ -75,11 +75,11 @@ search_includes() {
 search_lib() {
   for dbn in $@; do
     for dir in ${DIRS};  do
-      for libdir in /lib /lib64 "";  do
+      for libdir in /lib64 /lib "";  do
         for suffix in so dylib obj a; do
           if test -r ${dir}${libdir}/lib${dbn}.${suffix}; then
             add_lib ${dir}${libdir} ${dbn};
-	    echo Found: lib${dbn}.${suffix} at ${dir}/lib
+	    echo Found: lib${dbn}.${suffix} at ${dir}${libdir}
             return 0
 	  fi
         done
diff --git a/man/Makefile b/man/Makefile
index ad1da80..63efb5a 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -6,18 +6,16 @@
 
 sinclude ../Local.mak
 
-MANPAGES= e2fsimage.1.gz
+MANPAGES= e2fsimage.1
 
 all: $(MANPAGES)
 
-%.1.gz:%.man
-	cat $< | sed "s/_VERSION_/$(VERSION)/" | \
-		sed "s/_DATE_/`date '+%B %G'`/" | gzip -9 >$@
+%.1:%.man
+	sed "s/_VERSION_/$(VERSION)/;s/_DATE_/$(date '+%B %G')/" $< > $@
 
 clean:
 	rm -f $(MANPAGES)
-	
+
 install:
-	install -d $(basedir)$(prefix)/$(mandir)/man1
-	install $(MANPAGES) $(basedir)$(prefix)/$(mandir)/man1
-	
+	install -d -m 0755 $(DESTDIR)$(mandir)/man1
+	install -p -m 0644 $(MANPAGES) $(DESTDIR)$(mandir)/man1/
diff --git a/man/e2fsimage.man b/man/e2fsimage.man
index 96eee83..28c3ad6 100644
--- a/man/e2fsimage.man
+++ b/man/e2fsimage.man
@@ -3,6 +3,9 @@
 e2fsimage \- create and populate an ext2 filesystem image as non-root user
 .SH SYNOPSIS
 .B e2fsimage
+.RI [ -t\ fs-type ]
+.RI [ -b\ block-size ]
+.RI [ -L\ volume-label ]
 .RI [ -f\ imgfile ]
 .RI [ -d\ rootdir ]
 .RI [ -u\ uid ]
@@ -12,6 +15,7 @@ e2fsimage \- create and populate an ext2 filesystem image as non-root user
 .RI [ -P\ file ]
 .RI [ -p ]
 .RI [ -v ]
+.RI [ -S ]
 .RI [ -n ]
 .RI [ -s\ size ]
 .SH DESCRIPTION
@@ -60,6 +64,24 @@ It is also not mandatory to have the rootdir on an ext2 filesystem.
 .SH OPTIONS
 
 .TP
+.BI \-t\  fs-type
+Specify the filesystem type (i.e., ext2, ext3, ext4, etc.) that is to be created.
+See
+.BR mke2fs(2).
+
+.TP
+.BI \-b\  block-size
+Specify the size of blocks in bytes. Valid block-size values are  1024, 2048 and
+4096 bytes  per  block.
+See
+.BR mke2fs(2).
+
+.TP
+.BI \-L\  volume-label
+Set the volume label for the filesystem to volume-label. The maximum length of
+the volume label is 16 bytes.
+
+.TP
 .BI \-d\  rootdir
 The content of the filesystemimage is a recursive copy of 
 .IR rootdir . 
@@ -71,6 +93,10 @@ This can be overwritten with the
 options respectively
 
 .TP
+.BI \-e\  pattern
+Exclude files based upon pattern
+
+.TP
 .BI \-D\  devicefile
 The devicefile contains all special devices to be created, see
 .IR DEVICES .
@@ -144,6 +170,10 @@ uids look at the section
 .BI \-v
 Be more verbose.
 
+.TP
+.BI \-S
+Skip unaccessible files and dirs.
+
 .SH DEVICES
 .LP
 Usually the devices are created using
diff --git a/src/Makefile b/src/Makefile
index 3babaa1..03e4ded 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -15,7 +15,7 @@ OBJS=main.o copy.o symlink.o util.o mkdir.o \
 unused_OBJ=initfs.o
 
 e2fsimage: $(OBJS)
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) 
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
 
 %.o: %.c Makefile ../Local.mak e2fsimage.h
 	$(CC) $(CPPFLAGS) -DVER=\"$(VERSION)\" $(CFLAGS) -c -o $@ $<
@@ -24,6 +24,4 @@ clean:
 	rm -f $(OBJS) e2fsimage
 
 install:
-	mkdir -p $(basedir)$(prefix)/bin
-	cp  e2fsimage $(basedir)$(prefix)/bin
-	$(STRIP) $(basedir)$(prefix)/bin/e2fsimage
+	install -pD -m 0755 e2fsimage $(DESTDIR)$(prefix)/bin/e2fsimage
diff --git a/src/copy.c b/src/copy.c
index 5df7c73..fec9f92 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -52,8 +52,9 @@ int e2cp(e2i_ctx_t *e2c)
 	ext2_file_t e2file;
 	ext2_ino_t e2ino;
 	struct ext2_inode inode;
-	int ret, b_read, b_wrote;
-	char *ptr, *ptr1;
+	int ret, b_read;
+	unsigned b_wrote;
+	unsigned char *ptr, *ptr1;
 	off_t size = 0;
 	struct stat s;
 	FILE *fp;
@@ -113,11 +114,11 @@ int e2cp(e2i_ctx_t *e2c)
 
 	/* if this sizes differ its an inconsistency in the base filesystem */
 	if (s.st_size != size) {
-		fprintf(stderr, "Error 'size matters' Inode:%ld, File:%ld\n", s.st_size, size);
+		fprintf(stderr, "Error 'size matters' for %s Inode:%ld, File:%ld\n",e2c->curr_path, s.st_size, size);
 		return -1;
 	}
 	
-	if (e2c->verbose)
+	if (verbose)
 		printf("Copying file %s\n", e2c->curr_path);
 	
 	e2c->cnt->regf++;
diff --git a/src/dirent.c b/src/dirent.c
index 84383dc..5982809 100644
--- a/src/dirent.c
+++ b/src/dirent.c
@@ -40,11 +40,46 @@
  */                           
 
 #include "e2fsimage.h"
+#include <errno.h>
 #include <dirent.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <fnmatch.h>
+
+static char cpath[256] = "";
+
+int filter(const struct dirent *d)
+{
+	const char *n = d->d_name;
+
+	/* skip . and .. */
+	if (n[0] == '.' &&
+	    (n[1] == '\0' ||
+	     (n[1] == '.' && n[2] == '\0')))
+		return 0;
+	/* skip excluded */
+	else {
+		int i;
+		int ret = 1;
+		size_t l = strlen(cpath);
+
+		if (cpath[0]) {
+			cpath[l] = '/';
+			strcpy(cpath + l + 1, n);
+		} else
+			strcpy(cpath, n);
+		for (i = 0; i < excluded_num; i++)
+			if (!fnmatch(excluded[i], cpath, 0)) {
+				if (verbose)
+					printf("Excluded %s\n", cpath);
+				ret = 0;
+			}
+		cpath[l] = '\0';
+		return ret;
+	}
+}
 
 /*
  * Scan a directory and copy all the files to the e2c->curr_e2dir
@@ -61,7 +96,9 @@ int e2cpdir(e2i_ctx_t *e2c_old, ext2_ino_t newdir)
 	memcpy(&e2c, e2c_old, sizeof(e2i_ctx_t));
 	e2c.curr_e2dir = newdir;
 
-	ret = scandir(e2c.curr_path, &namelist, 0, 0);
+	strcpy(cpath, e2c.curr_path + strlen(e2c.root_path) + !!strcmp(e2c.curr_path, e2c.root_path));
+
+	ret = scandir(e2c.curr_path, &namelist, filter, NULL);
 	if (ret < 0) {
 		perror("scandir");
 		return -1;
@@ -98,8 +135,6 @@ int e2cpdir(e2i_ctx_t *e2c_old, ext2_ino_t newdir)
 		strncpy(ppath, namelist[i]->d_name, 256 - len);
 		free(namelist[i]);
 		/* skip . and .. */
-		if (!strncmp(".", ppath, 2)) continue;
-		if (!strncmp("..", ppath, 3)) continue;
 		if (!strncmp(e2c.uid_file, ppath, strlen(e2c.uid_file))) continue;
 		/* is there a special file (.DEVICES) */
 		if (!strncmp(e2c.dev_file, ppath, strlen(e2c.dev_file))) {
@@ -146,7 +181,7 @@ static int e2check_hardlink(e2i_ctx_t *e2c, ino_t ino)
 	E2_ERR(ret, "Ext2 write Inode Error", "");
 
 	/* be verbose and do statistics */
-	if (e2c->verbose)
+	if (verbose)
 		printf("Creating hard link %s\n", e2c->curr_path);
 	
 	e2c->cnt->hardln++;
@@ -163,9 +198,15 @@ int e2filetype_select(e2i_ctx_t *e2c)
 	struct stat s;  
 	ext2_ino_t newe2dir;
 	int ret;
-	
+
 	lstat(e2c->curr_path, &s);
 
+	if ((S_ISREG(s.st_mode) || S_ISDIR(s.st_mode)) &&
+	    access(e2c->curr_path, S_ISDIR(s.st_mode) ? R_OK|X_OK : R_OK)) {
+		fprintf(stderr, "access: %s: '%s'\n", strerror(errno), e2c->curr_path);
+		return e2c->unaccessible;
+	}
+
 	ret = e2check_hardlink(e2c, s.st_ino);
 	if (ret <= 0) return ret;
 	ret = -1;
diff --git a/src/e2fsimage.h b/src/e2fsimage.h
index d6555cd..ea15e52 100644
--- a/src/e2fsimage.h
+++ b/src/e2fsimage.h
@@ -113,6 +113,7 @@ typedef struct {
 	ext2_filsys fs;
 	ext2_ino_t curr_e2dir;
 	const char *curr_path;
+	const char *root_path;
 
 	inodb_t *ino_db;
 	uiddb_t *uid_db;
@@ -120,7 +121,6 @@ typedef struct {
 	uiddb_t *group;
 	int default_uid;
 	int default_gid;
-	int verbose;
 	int preserve_uidgid;
 	const char *dev_file;
 	const char *uid_file;
@@ -128,10 +128,11 @@ typedef struct {
 	const char *grp_file;
 	unsigned char *cp_buf;
 	struct cnt_t *cnt;
+	int unaccessible;
 } e2i_ctx_t;
 
-int mke2fs(const char *fname, int size);
-int init_fs(ext2_filsys *fs, char *fsname, int size);
+int mke2fs(const char *fname, const char *fstype, const char *label, int bsize, int size);
+int init_fs(ext2_filsys *fs, char *fsname, __u32 size);
 
 int e2cp(e2i_ctx_t *e2c);
 int e2symlink(e2i_ctx_t *e2c);
@@ -166,4 +167,8 @@ int modinode(e2i_ctx_t *e2c, const char *fname, ext2_ino_t e2ino);
 
 int read_passwd(e2i_ctx_t *e2c);
 int read_group(e2i_ctx_t *e2c);
+
+extern int verbose;
+extern char const *excluded[];
+extern unsigned short excluded_num;
 #endif
diff --git a/src/group.c b/src/group.c
index c7d9b8e..f456a54 100644
--- a/src/group.c
+++ b/src/group.c
@@ -62,7 +62,7 @@ int read_group(e2i_ctx_t *e2c)
 		return 0;
 	}
 	
-	if (e2c->verbose)
+	if (verbose)
 		printf("Reading username information from %s\n", e2c->grp_file);
 
 	/* iterate over the lines in the device file */
diff --git a/src/initfs.c b/src/initfs.c
index 2a295c2..481bed1 100644
--- a/src/initfs.c
+++ b/src/initfs.c
@@ -165,10 +165,11 @@ static int create_root_dir(ext2_filsys fs)
 }
 
 
-int init_fs(ext2_filsys *fs, char *fsname, int size)
+int init_fs(ext2_filsys *fs, char *fsname, __u32 size)
 {
 	struct ext2_super_block super;
-	int ret, i;
+	int ret;
+	__u32 i;
 	struct stat s;
 	char *buf;
 	FILE *fp;
diff --git a/src/main.c b/src/main.c
index 1ba3006..ffd0491 100644
--- a/src/main.c
+++ b/src/main.c
@@ -48,11 +48,16 @@ static void usage(char *name)
 {
 	printf("%s [-f imgfile] [-d rootdir] [-u uid] [-g gid] [-s size] "
 			"[-v] [-n] [-D devicefile]\n\n"
+			"-t  filesystem type\n"
+			"-b  block size\n"
+			"-L  volume label\n"
 			"-f  filesystem image file\n"
 			"-d  root directory to be copied to the image\n"
+			"-e  exclude dir/file\n"
 			"-u  uid to use instead of the real one\n"
 			"-g  gid to use instead of the real one\n"
 			"-v  be verbose\n"
+			"-S  skip unaccessible files and dirs\n"
 			"-s  size of the filesystem\n"
 			"-D  device filename\n"
 			"-p  preserve uid and gid\n"
@@ -65,7 +70,7 @@ static void usage(char *name)
 }
 
 /* return the size in Kilobyte */
-long getsize(const char *t)
+static long getsize(const char *t)
 {
 	int len, f;
 	char c, *p;
@@ -86,18 +91,31 @@ long getsize(const char *t)
 		
 	if (p - t != len) {
 		fprintf(stderr,
-				"malformed size string: '%s', p-t:%d, len:%d, Size:%ld\n",
+				"malformed size string: '%s', p-t:%zd, len:%d, Size:%ld\n",
 				t, (p-t), len, size);
 		size = -1;
 	}
 	return size;
 }
 
+int verbose;
+char const *excluded[1024];
+unsigned short excluded_num;
+
+static void add_exclude(const char *s)
+{
+	if (excluded_num < sizeof(excluded) / sizeof(excluded[0]))
+		excluded[excluded_num++] = s;
+}
+
 int main(int argc, char *argv[] )
 {
 	int ret = 0, c, create=1;
 	long ksize=4096;
+	int bsize = 0;
 	char *e2fsfile = NULL;
+	char *fstype = NULL;
+	char *label = NULL;
 	char passwd_file[256];
 	char group_file[256];
 	e2i_ctx_t e2c;
@@ -117,26 +135,38 @@ int main(int argc, char *argv[] )
 	e2c.curr_path = NULL;
 	e2c.cnt = &cnt;
 	cnt.dir = cnt.regf = cnt.softln = cnt.hardln = cnt.specf = 0; 
-		
+
+	verbose = 0;
+	e2c.unaccessible = -1;
+	excluded_num = 0;
+
 	printf("%s - Version: %s\n",  argv[0], VER);
 	
 	/* handle arguments and options */
 	do {
-		c = getopt(argc, argv, "vnhpf:d:u:g:s:D:U:P:G:");
+		c = getopt(argc, argv, "vnhpf:d:u:g:s:D:U:P:G:St:234b:L:e:");
 		switch (c) {
-			case 'v': e2c.verbose = 1; break;
+			case 'v': verbose = 1; break;
 			case 'p': e2c.preserve_uidgid = 1; break;
 			case 'u': e2c.default_uid = atoi(optarg); break;
 			case 'g': e2c.default_gid = atoi(optarg); break;
 			case 'f': e2fsfile = optarg; break;
-			case 'd': e2c.curr_path = optarg; break;
+			case 'd': e2c.root_path = e2c.curr_path = optarg; break;
 			case 'h': usage(argv[0]); return 0;
 			case 'n': create = 0; break;
 			case 's': ksize = getsize(optarg); break;
+			case 'b': bsize = atoi(optarg); break;
+			case 't': fstype = optarg; break;
+			case '2': fstype = "ext2"; break;
+			case '3': fstype = "ext3"; break;
+			case '4': fstype = "ext4"; break;
+			case 'L': label = optarg; break;
 			case 'D': e2c.dev_file = optarg; break;
 			case 'U': e2c.uid_file = optarg; break;
 			case 'P': e2c.pw_file = optarg; break;
 			case 'G': e2c.grp_file = optarg; break;
+			case 'S': e2c.unaccessible = 0; break;
+			case 'e': add_exclude(optarg); break;
 		}
 			 
 	} while (c >= 0);
@@ -160,7 +190,7 @@ int main(int argc, char *argv[] )
     }
 	/* call mke2fs to create the initial filesystem */
 	if (create) {
-		ret = mke2fs(e2fsfile, ksize);
+		ret = mke2fs(e2fsfile, fstype, label, bsize, ksize);
 		if (ret !=0 ) return ret;
 	}
 	
@@ -182,7 +212,7 @@ int main(int argc, char *argv[] )
 	/* reserve memory for the file-copy */
 	e2c.cp_buf = malloc(BUF_SIZE);
 	if (!e2c.cp_buf) {
-		printf("Malloc failed\n");
+		fputs("Malloc failed\n", stderr);
 		return -1;
 	}
 	
diff --git a/src/mkdir.c b/src/mkdir.c
index db6d2cb..3292d0a 100644
--- a/src/mkdir.c
+++ b/src/mkdir.c
@@ -54,6 +54,7 @@ int e2mkdir(e2i_ctx_t *e2c, ext2_ino_t *newdir) {
 	struct stat s;
 	const char *dname;
 	ext2_ino_t nd;
+	struct ext2_inode inode;
 	
 	ret = lstat(e2c->curr_path, &s);
 	ERRNO_ERR(ret,"Could not 'stat': ", e2c->curr_path);
@@ -76,7 +77,7 @@ int e2mkdir(e2i_ctx_t *e2c, ext2_ino_t *newdir) {
 	E2_ERR(ret, "Could not create dir: ", dname);
 
 	/* say what we do and increase the counter */
-	if (e2c->verbose)
+	if (verbose)
 		printf ("Creating directory %s\n", dname);
 
 	e2c->cnt->dir++;
@@ -84,7 +85,19 @@ int e2mkdir(e2i_ctx_t *e2c, ext2_ino_t *newdir) {
 	/* lookup the inode of the new directory if requested */
 	ret = ext2fs_lookup(e2c->fs, e2c->curr_e2dir, dname, strlen(dname), 0, &nd);
 	E2_ERR(ret, "Could not Ext2-lookup: ", dname);
-	
+	// fix permissions
+	ret = ext2fs_read_inode(e2c->fs, nd, &inode);
+	E2_ERR(ret, "Ext2 read Inode Error", "");
+
+	inode.i_uid = s.st_uid;
+	ext2fs_set_i_uid_high(inode,s.st_uid);
+	inode.i_gid = s.st_gid;
+	ext2fs_set_i_gid_high(inode,s.st_gid);
+	inode.i_mode = s.st_mode;
+	ret = ext2fs_write_inode(e2c->fs, nd, &inode);
+	E2_ERR(ret, "Ext2 write Inode Error", "");
+
+
 	modinode(e2c, dname, nd);
 	
 	if (newdir) {
diff --git a/src/mke2fs.c b/src/mke2fs.c
index a1a1351..6243eeb 100644
--- a/src/mke2fs.c
+++ b/src/mke2fs.c
@@ -47,53 +47,65 @@
 #include <wait.h>
 #include <string.h>
 
-int mke2fs(const char *fname, int size)
+int mke2fs(const char *fname, const char *fstype, const char *label, int bsize, int size)
 {
 	int pid, status, fd;
-	FILE *fp;
-	char *buf, *bp ;
-	char *newpath = ":/sbin:/usr/sbin:/usr/local/sbin";
-	
+	char buf[4096];
 	/* open the target filesystem image */
-	fp = fopen(fname, "wb+");
+	FILE *fp = fopen(fname, "wb+");
+
 	if (!fp) {
 		perror("Error opening file");
 		return 1;
 	}
 
-	/* fill the image with zeros */
-	buf = malloc(1024);
-	if (!buf) {
-		fclose(fp);
-		return -1;
-	}
-	memset(buf, 0, 1024 );
+	memset(buf, 0, sizeof(buf));
 
-	fseek (fp,(size-1)*1024,SEEK_SET);
-	fwrite (buf,1024,1,fp);
+	fseek(fp, ((size + 3) / 4 - 1) * 4096, SEEK_SET);
+	fwrite(buf, sizeof(buf), 1, fp);
 	fclose(fp);
 
 	/* redirect stdout of mke2fs to dev/null */
 	fd = open("/dev/null", O_WRONLY);
-	
-	/* add /sbin, /usr/sbin and /usr/local/sbin to the PATH */
-	bp = getenv("PATH");
-	strncpy(buf, bp, 1023 - strlen(newpath));
-	strcat(buf, newpath ); 
-	
+
 	pid = fork();
 	if (!pid) {
+		const char newpath[] = ":/sbin:/usr/sbin:/usr/local/sbin";
+		char const *argv[11] = {"mke2fs", "-q", "-F"};
+		int i = 3;
+		/* add /sbin, /usr/sbin and /usr/local/sbin to the PATH */
+		char *bp = getenv("PATH");
+
+		strncpy(buf, bp, sizeof(buf) - sizeof(newpath));
+		strcat(buf, newpath);
+
+		if (label) {
+			argv[i++] = "-L";
+			argv[i++] = label;
+		}
+		if (fstype) {
+			argv[i++] = "-t";
+			argv[i++] = fstype;
+		}
+		if (bsize) {
+			char b[16];
+			if (sprintf(b, "%d", bsize) > 0) {
+				argv[i++] = "-b";
+				argv[i++] = b;
+			}
+		}
+		argv[i] = fname;
+		argv[i + 1] = NULL;
+
 		if (fd) dup2(fd, 1);
-		setenv("PATH", buf, 1);	
-		
-		execlp("mkfs.ext2", "mkfs.ext2", "-F", fname, NULL);
-		execlp("mke2fs", "mke2fs", "-F", fname, NULL);
-		fprintf(stderr,"Could not execute 'mkfs.ext2' or 'mke2fs'\n");
+		setenv("PATH", buf, 1);
+
+		execvp("mke2fs", (char* const*)argv);
+		fputs("Could not execute 'mke2fs'\n", stderr);
 	}
 	waitpid(pid, &status, 0);
 	if (fd) close(fd);
-	free(buf);
-	
+
 	if (WEXITSTATUS(status) !=0 ) {
 		fprintf(stderr, "mke2fs failed with return code %d\n", WEXITSTATUS(status));
 		return -1;
diff --git a/src/passwd.c b/src/passwd.c
index f64e5e8..8185b8b 100644
--- a/src/passwd.c
+++ b/src/passwd.c
@@ -60,7 +60,7 @@ int read_passwd(e2i_ctx_t *e2c)
 		return 0;
 	}
 	
-	if (e2c->verbose)
+	if (verbose)
 		printf("Reading username information from %s\n", e2c->pw_file);
 
 	/* iterate over the lines in the device file */
diff --git a/src/sfile.c b/src/sfile.c
index 0877419..2560c10 100644
--- a/src/sfile.c
+++ b/src/sfile.c
@@ -111,7 +111,7 @@ int e2mknod(e2i_ctx_t *e2c)
 		fprintf(stderr, "File '%s' is not a block or charspecial device\n", e2c->curr_path);
 		return -1;
 	}
-	if (e2c->verbose)
+	if (verbose)
 		printf("Copying special file: %s\n", e2c->curr_path);
 
 	return special_inode(e2c, basename(e2c->curr_path), &s);
@@ -188,7 +188,7 @@ int read_special_file(e2i_ctx_t *e2c)
 				return -1;
 		}
 		
-		if (e2c->verbose)
+		if (verbose)
 			printf("Creating special file: %s (%c, Major %d, Minor: %d)\n",
 					fname, type, major, minor);
 
diff --git a/src/symlink.c b/src/symlink.c
index 6de168e..cce066d 100644
--- a/src/symlink.c
+++ b/src/symlink.c
@@ -54,8 +54,11 @@ int e2symlink(e2i_ctx_t *e2c)
 	ext2_file_t e2file;
 	ext2_ino_t e2ino;
 	struct ext2_inode inode;
-	int ret, written;
+	int ret;
+	unsigned written;
 	char buf[SYM_BUF_SIZE];
+	char * root_ptr;
+	char *tmpptr;
 	off_t size = 0;
 	struct stat s;
 	
@@ -74,6 +77,30 @@ int e2symlink(e2i_ctx_t *e2c)
 	
 	/* populate the new inode */
 	ext2fs_inode_alloc_stats(e2c->fs, e2ino, 1);
+
+	/* open the source file */
+	size = readlink(e2c->curr_path, buf, SYM_BUF_SIZE);
+	if (size < 0 || size >= SYM_BUF_SIZE) {
+		fprintf(stderr, "Error reading symlink '%s': %s\n", e2c->curr_path, strerror(errno));
+		return -1;
+	}
+	buf[size] = '\0';
+	e2c->cnt->softln++;
+
+	if (e2c->root_path != NULL) { 
+	    root_ptr = strstr(buf, e2c->root_path);
+    	    if (root_ptr != buf) {
+		tmpptr = buf;
+	    } else {
+		tmpptr = buf + strlen(e2c->root_path);
+	    }
+	    strcpy(buf, tmpptr);
+	}
+
+	if (verbose)
+		printf("Copying symlink %s -> %s\n",e2c->curr_path,buf);
+	
+	s.st_size = strlen(buf);	
 	
 	init_inode(e2c, &inode, &s);
 
@@ -91,12 +118,23 @@ int e2symlink(e2i_ctx_t *e2c)
 		return -1;
 	}
 	
-	if (e2c->verbose)
-		printf("Copying symlink %s\n",e2c->curr_path);
-	
 	e2c->cnt->softln++;
+
+	if (e2c->root_path != NULL) { 
+	    root_ptr = strstr(buf, e2c->root_path);
+    	    if (root_ptr != buf) {
+		tmpptr = buf;
+	    } else {
+		tmpptr = buf + strlen(e2c->root_path);
+	    }
+	    strcpy(buf, tmpptr);
+	}
+
+	if (verbose)
+		printf("Copying symlink %zu %ld %s -> %s\n", strlen(buf), size, e2c->curr_path, buf);
+	
 	
-	ret = ext2fs_file_write(e2file, buf, size, &written);
+	ret = ext2fs_file_write(e2file, buf, strlen(buf), &written);
 	if (ret) {
 		fprintf(stderr, "Error writing ext2 symlink (%s)\n", error_message(ret));
 		ext2fs_file_close(e2file);
@@ -106,7 +144,7 @@ int e2symlink(e2i_ctx_t *e2c)
 	ext2fs_file_close(e2file);
 	
 	/* if this sizes differ its an inconsistency in the base filesystem */
-	if (size != written) {
+	if (strlen(buf) != written) {
 		fprintf(stderr, "Error 'size matters' Size:%ld, Written:%d\n", size, written);
 		return -1;
 	}
diff --git a/src/uids.c b/src/uids.c
index 409cacc..c6bb7e6 100644
--- a/src/uids.c
+++ b/src/uids.c
@@ -131,15 +131,19 @@ int modinode(e2i_ctx_t *e2c, const char *fname, ext2_ino_t e2ino)
 	/* do the root squash */
 	if (! e2c->preserve_uidgid) {
 		inode.i_uid = e2c->default_uid;
+		ext2fs_set_i_uid_high(inode, e2c->default_uid);
 		inode.i_gid = e2c->default_gid;
+		ext2fs_set_i_gid_high(inode, e2c->default_gid);
 	}
 
 	/* if the filename is mentioned in .UIDGID we must change the owner */
 	if (uiddb_search(e2c->uid_db, fname, &uid, &gid)){
-		if (e2c->verbose)
+		if (verbose)
 			printf("Changing UID and GID for %s (%d:%d)\n", fname, uid, gid);
 		inode.i_uid = uid;
+		ext2fs_set_i_uid_high(inode, uid);
 		inode.i_gid = gid;
+		ext2fs_set_i_gid_high(inode, gid);
 	}		
 		
 	ret = ext2fs_write_inode(e2c->fs, e2ino, &inode);
diff --git a/src/util.c b/src/util.c
index 417c568..f8761b4 100644
--- a/src/util.c
+++ b/src/util.c
@@ -71,7 +71,9 @@ void init_inode(e2i_ctx_t *e2c, struct ext2_inode *i, struct stat *s)
 	i->i_mode = s->st_mode;
 	i->i_size = s->st_size;
 	i->i_uid = s->st_uid;
+	ext2fs_set_i_uid_high(*i,s->st_uid);
 	i->i_gid = s->st_gid;
+	ext2fs_set_i_gid_high(*i,s->st_gid);
 	i->i_atime = s->st_atime;
 	i->i_ctime = s->st_ctime;
 	i->i_mtime = s->st_mtime;
openSUSE Build Service is sponsored by