Some busybox updates.  You no longer _have_ to put a "-" in front of tar
options, logger is better behaved and has a "-t" option now.  init now supports
the kernel chroot patch, so you can chroot to a new device and umount the old
root.
 -Erik
diff --git a/Changelog b/Changelog
index 095a529..4b65b3b 100644
--- a/Changelog
+++ b/Changelog
@@ -1,10 +1,18 @@
 0.42
 	* Made tar creation support in busybox tar optional.
+	You no longer _have_ to put a "-" in front of tar options.
 	* Made grep and grep -h do the right thing wrt printing
 	    the file name (it failed to print files names in many cases).
 	* Fix a namespace aliasing problem wereby if du was built in, the 
 	    symlink for both du and dutmp would be installed, or then rm was 
 	    built in, the symlinks for both rm and rmmod would be installed.
+	* Added a closelog() to init.c after loging -- fix thanks to 
+	    Taketoshi Sano <kgh12351@nifty.ne.jp>
+	* Rewrote and simplified logger.  Added the "-t" option, and made it
+	    behave itself a bit better.
+	* Optional support contributed by Ben Collins <bcollins@debian.org> 
+	    for the kernel init chroot patch by Werner Almesberger, which 
+	    allows init to chroot to a new device, and umount the old one.
 
 
 	-Erik Andersen
diff --git a/Makefile b/Makefile
index 91d4bd1..554dd00 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@
 
 
 PROG=busybox
-VERSION=0.41
+VERSION=0.42
 BUILDTIME=$(shell date "+%Y%m%d-%H%M")
 
 # Comment out the following to make a debuggable build
@@ -33,7 +33,6 @@
 
 GCCMAJVERSION=$(shell $(CC) --version | sed -n "s/^\([^\.]*\).*/\1/p" )
 GCCMINVERSION=$(shell $(CC) --version | sed -n "s/^[^\.]*\.\([^\.]*\)[\.].*/\1/p" )
-GCCEGCS=$(shell $(CC) --version | sed -n "s/.*\(egcs\).*/\1/p" )
 
 GCCSUPPORTSOPTSIZE=$(shell \
 if ( test $(GCCMAJVERSION) -eq 2 ) ; then \
@@ -50,26 +49,11 @@
     fi; \
 fi; )
 
-GCCISEGCS=$(shell \
-if ( test "x$(GCCEGCS)" == "xegcs" ) ; then \
-		echo "true"; \
-	else \
-		echo "false"; \
-	fi; )
-
-EGCSEXTREMEFLAGS = -m386 -mcpu=i386 -march=i386 -malign-jumps=1 -malign-loops=1 -malign-functions=1
-GCCEXTREMEFLAGS  = -m386 -malign-jumps=1 -malign-loops=1 -malign-functions=1
-
-ifeq ($(GCCISEGCS), true)
-	EXTREMEFLAGS = $(EGCSEXTREMEFLAGS)
-else
-	EXTREMEFLAGS = $(GCCEXTREMEFLAGS)
-endif
 
 ifeq ($(GCCSUPPORTSOPTSIZE), true)
-	OPTIMIZATION=-Os $(EXTREMEFLAGS)
+    OPTIMIZATION=-Os
 else
-	OPTIMIZATION=-O2 $(EXTREMEFLAGS)
+    OPTIMIZATION=-O2
 endif
 
 # -D_GNU_SOURCE is needed because environ is used in init.c
diff --git a/archival/tar.c b/archival/tar.c
index 5c40786..adae6c9 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -108,9 +108,7 @@
  */
 static int listFlag;
 static int extractFlag;
-#ifdef BB_FEATURE_TAR_CREATE
 static int createFlag;
-#endif
 static int verboseFlag;
 static int tostdoutFlag;
 
@@ -185,9 +183,7 @@
 
     errorFlag = FALSE;
     extractFlag = FALSE;
-#ifdef BB_FEATURE_TAR_CREATE
     createFlag = FALSE;
-#endif
     listFlag = FALSE;
     verboseFlag = FALSE;
     tostdoutFlag = FALSE;
@@ -199,90 +195,85 @@
     /* 
      * Parse the options.
      */
-    if (**argv == '-') {
+    if (**argv == '-')
 	options = (*argv++) + 1;
-	argc--;
-	for (; *options; options++) {
-	    switch (*options) {
-	    case 'f':
-		if (tarName != NULL) {
-		    fprintf (stderr, "Only one 'f' option allowed\n");
+    else 
+	options = (*argv++);
+    argc--;
 
-		    exit (FALSE);
-		}
-
-		tarName = *argv++;
-		argc--;
-
-		break;
-
-	    case 't':
-		listFlag = TRUE;
-		break;
-
-	    case 'x':
-		extractFlag = TRUE;
-		break;
-#ifdef BB_FEATURE_TAR_CREATE
-	    case 'c':
-		createFlag = TRUE;
-		break;
-#else
-	    case 'c':
-		fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
-
-		exit (FALSE);
-#endif
-
-	    case 'v':
-		verboseFlag = TRUE;
-		break;
-
-	    case 'O':
-		tostdoutFlag = TRUE;
-		break;
-
-	    case '-':
-		usage( tar_usage);
-		break;
-
-	    default:
-		fprintf (stderr, "Unknown tar flag '%c'\n"
-			"Try `tar --help' for more information\n", 
-			*options);
+    for (; *options; options++) {
+	switch (*options) {
+	case 'f':
+	    if (tarName != NULL) {
+		fprintf (stderr, "Only one 'f' option allowed\n");
 
 		exit (FALSE);
 	    }
+
+	    tarName = *argv++;
+	    argc--;
+
+	    break;
+
+	case 't':
+	    if (extractFlag == TRUE || createFlag == TRUE )
+		goto flagError;
+	    listFlag = TRUE;
+	    break;
+
+	case 'x':
+	    if (listFlag == TRUE || createFlag == TRUE )
+		goto flagError;
+	    extractFlag = TRUE;
+	    break;
+	case 'c':
+	    if (extractFlag == TRUE || listFlag == TRUE)
+		goto flagError;
+	    createFlag = TRUE;
+	    break;
+
+	case 'v':
+	    verboseFlag = TRUE;
+	    break;
+
+	case 'O':
+	    tostdoutFlag = TRUE;
+	    break;
+
+	case '-':
+	    usage( tar_usage);
+	    break;
+
+	default:
+	    fprintf (stderr, "Unknown tar flag '%c'\n"
+		    "Try `tar --help' for more information\n", 
+		    *options);
+	    exit (FALSE);
 	}
     }
 
     /* 
-     * Validate the options.
-     */
-    if (extractFlag + listFlag 
-#ifdef BB_FEATURE_TAR_CREATE
-	    + createFlag 
-#endif 
-	    != (TRUE+FALSE+FALSE)) {
-	fprintf (stderr,
-		 "Exactly one of 'c', 'x' or 't' must be specified\n");
-
-	exit (FALSE);
-    }
-
-    /* 
      * Do the correct type of action supplying the rest of the
      * command line arguments as the list of files to process.
      */
-#ifdef BB_FEATURE_TAR_CREATE
-    if (createFlag==TRUE)
+    if (createFlag==TRUE) {
+#ifndef BB_FEATURE_TAR_CREATE
+	fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
+	exit (FALSE);
+#else
 	writeTarFile (argc, argv);
-    else
 #endif 
+    } else {
 	readTarFile (argc, argv);
-    if (errorFlag==TRUE)
+    }
+    if (errorFlag==TRUE) {
 	fprintf (stderr, "\n");
+    }
     exit (!errorFlag);
+
+flagError:
+    fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
+    exit (FALSE);
 }
 
 
diff --git a/busybox.def.h b/busybox.def.h
index 871b152..c56f151 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -139,3 +139,10 @@
 // Enable support for creation of tar files.
 //#define BB_FEATURE_TAR_CREATE
 //
+// Allow init to permenently chroot, and umount the old root fs
+// just like an initrd does.  Requires a kernel patch by Werner Almesberger.
+// ftp://icaftp.epfl.ch/pub/people/almesber/misc/umount-root-*.tar.gz
+#ifdef BB_MOUNT
+#define BB_FEATURE_INIT_CHROOT
+#endif
+//
diff --git a/busybox.spec b/busybox.spec
index 73f47e1..03e4feb 100644
--- a/busybox.spec
+++ b/busybox.spec
@@ -1,13 +1,13 @@
 Name: busybox
-Version: 0.41
+Version: 0.42
 Release: 1
 Group: System/Utilities
 Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
 Copyright: GPL
 Packager : Erik Andersen <andersen@lineo.com>
 Conflicts: fileutils grep shellutils
-Buildroot: /tmp/%{name}-%{version}
-Source: %{name}-%{version}.tar.gz
+Buildroot: /tmp/%{Name}-%{Version}
+Source: %{Name}-%{Version}.tar.gz
 
 %Description
 BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It
@@ -18,7 +18,7 @@
 embedded system.
 
 %Prep
-%setup -q -n %{name}-%{version}
+%setup -q -n %{Name}-%{Version}
 
 %Build
 make
diff --git a/examples/busybox.spec b/examples/busybox.spec
index 73f47e1..03e4feb 100644
--- a/examples/busybox.spec
+++ b/examples/busybox.spec
@@ -1,13 +1,13 @@
 Name: busybox
-Version: 0.41
+Version: 0.42
 Release: 1
 Group: System/Utilities
 Summary: BusyBox is a tiny suite of Unix utilities in a multi-call binary.
 Copyright: GPL
 Packager : Erik Andersen <andersen@lineo.com>
 Conflicts: fileutils grep shellutils
-Buildroot: /tmp/%{name}-%{version}
-Source: %{name}-%{version}.tar.gz
+Buildroot: /tmp/%{Name}-%{Version}
+Source: %{Name}-%{Version}.tar.gz
 
 %Description
 BusyBox is a suite of "tiny" Unix utilities in a multi-call binary. It
@@ -18,7 +18,7 @@
 embedded system.
 
 %Prep
-%setup -q -n %{name}-%{version}
+%setup -q -n %{Name}-%{Version}
 
 %Build
 make
diff --git a/init.c b/init.c
index 9134363..b0a8582 100644
--- a/init.c
+++ b/init.c
@@ -147,7 +147,9 @@
 	va_start(arguments, fmt);
 	vsnprintf(msg, sizeof(msg), fmt, arguments);
 	va_end(arguments);
+	openlog( "init", 0, LOG_DAEMON);
 	syslog(LOG_DAEMON|LOG_NOTICE, msg);
+	closelog();
     }
 
 #else
@@ -268,7 +270,7 @@
 #if #cpu(sparc)
     /* sparc kernel supports console=tty[ab] parameter which is also 
      * passed to init, so catch it here */
-    else if ((s = getenv("console")) != NULL) {*/
+    else if ((s = getenv("console")) != NULL) {
 	/* remap tty[ab] to /dev/ttyS[01] */
 	if (strcmp( s, "ttya" )==0)
 	    snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
@@ -507,7 +509,83 @@
     exit(0);
 }
 
-#endif
+#if defined BB_FEATURE_INIT_CHROOT
+static void check_chroot(int sig)
+{
+    char *argv_init[2] = { "init", NULL, };
+    char *envp_init[3] = { "HOME=/", "TERM=linux", NULL, };
+    char rootpath[256], *tc;
+    int fd;
+
+    if ((fd = open("/proc/sys/kernel/init-chroot", O_RDONLY)) == -1) {
+	message(CONSOLE, "SIGHUP recived, but could not open proc file\r\n");
+	sleep(2);
+	return;
+    }
+    if (read(fd, rootpath, sizeof(rootpath)) == -1) {
+	message(CONSOLE, "SIGHUP recived, but could not read proc file\r\n");
+	sleep(2);
+	return;
+    }
+    close(fd);
+
+    if (rootpath[0] == '\0') {
+	message(CONSOLE, "SIGHUP recived, but new root is not valid: %s\r\n",
+		rootpath);
+	sleep(2);
+	return;
+    }
+
+    tc = strrchr(rootpath, '\n');
+    *tc = '\0';
+    
+    /* Ok, making it this far means we commit */
+    message(CONSOLE, "Please stand by, changing root to `%s'.\r\n", rootpath);
+
+    /* kill all other programs first */
+    message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
+    kill(-1, SIGTERM);
+    sleep(2);
+    sync();
+
+    message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
+    kill(-1, SIGKILL);
+    sleep(2);
+    sync();
+
+    /* ok, we don't need /proc anymore. we also assume that the signaling
+     * process left the rest of the filesystems alone for us */
+    umount("/proc");
+
+    /* Ok, now we chroot. Hopefully we only have two things mounted, the
+     * new chroot'd mount point, and the old "/" mount. s,
+     * we go ahead and unmount the old "/". This should trigger the kernel
+     * to set things up the Right Way(tm). */
+
+    if (!chroot(rootpath))
+	umount("/dev/root");
+
+    /* If the chroot fails, we are already too far to turn back, so we
+     * continue and hope that executing init below will revive the system */
+
+    /* close all of our descriptors and open new ones */
+    close(0);
+    close(1);
+    close(2);
+    open("/dev/console", O_RDWR, 0);
+    dup(0);
+    dup(0);
+
+    message(CONSOLE, "Executing real init...\r\n");
+    /* execute init in the (hopefully) new root */
+    execve("/sbin/init",argv_init,envp_init);
+
+    message(CONSOLE, "ERROR: Could not exec new init. Hit ctrl+alt+delete to reboot.\r\n");
+    return;
+} 
+#endif /* BB_FEATURE_INIT_CHROOT */
+
+#endif /* ! DEBUG_INIT */
 
 void new_initAction (initActionEnum action,
 	char* process, char* cons)
@@ -516,10 +594,10 @@
 
     /* If BusyBox detects that a serial console is in use, 
      * then entries containing non-empty id fields will _not_ be run.
+     * The exception to this rule is the null device.
      */
-    if (secondConsole == NULL && *cons != '\0') {
+    if (secondConsole == NULL && (*cons != '\0' || strncmp(cons, "null", 4)))
 	return;
-    }
 
     newAction = calloc ((size_t)(1), sizeof(initAction));
     if (!newAction) {
@@ -662,7 +740,7 @@
     int status;
 
 #ifndef DEBUG_INIT
-    /* Expect to be PID 1 iff we are run as init (not linuxrc) */
+    /* Expect to be PID 1 if we are run as init (not linuxrc) */
     if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
 	usage( "init\n\nInit is the parent of all processes.\n\n"
 		"This version of init is designed to be run only by the kernel\n");
@@ -676,6 +754,9 @@
     signal(SIGUSR2, reboot_signal);
     signal(SIGINT, reboot_signal);
     signal(SIGTERM, reboot_signal);
+#if defined BB_FEATURE_INIT_CHROOT
+    signal(SIGHUP, check_chroot);
+#endif
 
     /* Turn off rebooting via CTL-ALT-DEL -- we get a 
      * SIGINT on CAD so we can shut things down gracefully... */
diff --git a/init/init.c b/init/init.c
index 9134363..b0a8582 100644
--- a/init/init.c
+++ b/init/init.c
@@ -147,7 +147,9 @@
 	va_start(arguments, fmt);
 	vsnprintf(msg, sizeof(msg), fmt, arguments);
 	va_end(arguments);
+	openlog( "init", 0, LOG_DAEMON);
 	syslog(LOG_DAEMON|LOG_NOTICE, msg);
+	closelog();
     }
 
 #else
@@ -268,7 +270,7 @@
 #if #cpu(sparc)
     /* sparc kernel supports console=tty[ab] parameter which is also 
      * passed to init, so catch it here */
-    else if ((s = getenv("console")) != NULL) {*/
+    else if ((s = getenv("console")) != NULL) {
 	/* remap tty[ab] to /dev/ttyS[01] */
 	if (strcmp( s, "ttya" )==0)
 	    snprintf(console, sizeof(console)-1, "%s", SERIAL_CON0);
@@ -507,7 +509,83 @@
     exit(0);
 }
 
-#endif
+#if defined BB_FEATURE_INIT_CHROOT
+static void check_chroot(int sig)
+{
+    char *argv_init[2] = { "init", NULL, };
+    char *envp_init[3] = { "HOME=/", "TERM=linux", NULL, };
+    char rootpath[256], *tc;
+    int fd;
+
+    if ((fd = open("/proc/sys/kernel/init-chroot", O_RDONLY)) == -1) {
+	message(CONSOLE, "SIGHUP recived, but could not open proc file\r\n");
+	sleep(2);
+	return;
+    }
+    if (read(fd, rootpath, sizeof(rootpath)) == -1) {
+	message(CONSOLE, "SIGHUP recived, but could not read proc file\r\n");
+	sleep(2);
+	return;
+    }
+    close(fd);
+
+    if (rootpath[0] == '\0') {
+	message(CONSOLE, "SIGHUP recived, but new root is not valid: %s\r\n",
+		rootpath);
+	sleep(2);
+	return;
+    }
+
+    tc = strrchr(rootpath, '\n');
+    *tc = '\0';
+    
+    /* Ok, making it this far means we commit */
+    message(CONSOLE, "Please stand by, changing root to `%s'.\r\n", rootpath);
+
+    /* kill all other programs first */
+    message(CONSOLE, "Sending SIGTERM to all processes.\r\n");
+    kill(-1, SIGTERM);
+    sleep(2);
+    sync();
+
+    message(CONSOLE, "Sending SIGKILL to all processes.\r\n");
+    kill(-1, SIGKILL);
+    sleep(2);
+    sync();
+
+    /* ok, we don't need /proc anymore. we also assume that the signaling
+     * process left the rest of the filesystems alone for us */
+    umount("/proc");
+
+    /* Ok, now we chroot. Hopefully we only have two things mounted, the
+     * new chroot'd mount point, and the old "/" mount. s,
+     * we go ahead and unmount the old "/". This should trigger the kernel
+     * to set things up the Right Way(tm). */
+
+    if (!chroot(rootpath))
+	umount("/dev/root");
+
+    /* If the chroot fails, we are already too far to turn back, so we
+     * continue and hope that executing init below will revive the system */
+
+    /* close all of our descriptors and open new ones */
+    close(0);
+    close(1);
+    close(2);
+    open("/dev/console", O_RDWR, 0);
+    dup(0);
+    dup(0);
+
+    message(CONSOLE, "Executing real init...\r\n");
+    /* execute init in the (hopefully) new root */
+    execve("/sbin/init",argv_init,envp_init);
+
+    message(CONSOLE, "ERROR: Could not exec new init. Hit ctrl+alt+delete to reboot.\r\n");
+    return;
+} 
+#endif /* BB_FEATURE_INIT_CHROOT */
+
+#endif /* ! DEBUG_INIT */
 
 void new_initAction (initActionEnum action,
 	char* process, char* cons)
@@ -516,10 +594,10 @@
 
     /* If BusyBox detects that a serial console is in use, 
      * then entries containing non-empty id fields will _not_ be run.
+     * The exception to this rule is the null device.
      */
-    if (secondConsole == NULL && *cons != '\0') {
+    if (secondConsole == NULL && (*cons != '\0' || strncmp(cons, "null", 4)))
 	return;
-    }
 
     newAction = calloc ((size_t)(1), sizeof(initAction));
     if (!newAction) {
@@ -662,7 +740,7 @@
     int status;
 
 #ifndef DEBUG_INIT
-    /* Expect to be PID 1 iff we are run as init (not linuxrc) */
+    /* Expect to be PID 1 if we are run as init (not linuxrc) */
     if (getpid() != 1 && strstr(argv[0], "init")!=NULL ) {
 	usage( "init\n\nInit is the parent of all processes.\n\n"
 		"This version of init is designed to be run only by the kernel\n");
@@ -676,6 +754,9 @@
     signal(SIGUSR2, reboot_signal);
     signal(SIGINT, reboot_signal);
     signal(SIGTERM, reboot_signal);
+#if defined BB_FEATURE_INIT_CHROOT
+    signal(SIGHUP, check_chroot);
+#endif
 
     /* Turn off rebooting via CTL-ALT-DEL -- we get a 
      * SIGINT on CAD so we can shut things down gracefully... */
diff --git a/logger.c b/logger.c
index 7aada5d..d7ae023 100644
--- a/logger.c
+++ b/logger.c
@@ -22,16 +22,11 @@
 
 #include "internal.h"
 #include <stdio.h>
-#include <sys/socket.h>
-#include <sys/un.h>
 #include <unistd.h>
-#include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <signal.h>
 #include <ctype.h>
-#include <netdb.h>
 
 #if !defined BB_SYSLOGD
 
@@ -56,6 +51,7 @@
     "Write MESSAGE to the system log.  If MESSAGE is '-', log stdin.\n\n"
     "Options:\n"
     "\t-s\tLog to stderr as well as the system log.\n"
+    "\t-t\tLog using the specified tag (defaults to user name).\n"
     "\t-p\tEnter the message with the specified priority.\n"
     "\t\tThis may be numerical or a ``facility.level'' pair.\n";
 
@@ -116,14 +112,14 @@
 
 extern int logger_main(int argc, char **argv)
 {
-    struct sockaddr_un sunx;
-    int fd, pri = LOG_USER|LOG_NOTICE;
+    int pri = LOG_USER|LOG_NOTICE;
+    int option = 0;
     int fromStdinFlag=FALSE;
-    int toStdErrFlag=FALSE;
     int stopLookingAtMeLikeThat=FALSE;
-    char *message, buf[1024], buf1[1024];
-    time_t  now;
-    size_t addrLength;
+    char *message, buf[1024], name[128];
+    
+    /* Fill out the name string early (may be overwritten later */
+    my_getpwuid(name, geteuid());
 
     /* Parse any options */
     while (--argc > 0 && **(++argv) == '-') {
@@ -134,7 +130,7 @@
 	while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
 	    switch (**argv) {
 	    case 's':
-		toStdErrFlag = TRUE;
+		option |= LOG_PERROR;
 		break;
 	    case 'p':
 		if (--argc == 0) {
@@ -143,6 +139,13 @@
 		pri = pencode(*(++argv));
 		stopLookingAtMeLikeThat=TRUE;
 		break;
+	    case 't':
+		if (--argc == 0) {
+		    usage(logger_usage);
+		}
+		strncpy(name, *(++argv), sizeof(name));
+		stopLookingAtMeLikeThat=TRUE;
+		break;
 	    default:
 		usage(logger_usage);
 	    }
@@ -152,10 +155,10 @@
     if (fromStdinFlag==TRUE) {
 	/* read from stdin */
 	int c, i=0;
-	while ((c = getc(stdin)) != EOF && i<sizeof(buf1)) {
-	    buf1[i++]=c;
+	while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
+	    buf[i++]=c;
 	}
-	message=buf1;
+	message=buf;
     } else {
 	if (argc>=1) {
 		message=*argv;
@@ -165,30 +168,10 @@
 	}
     }
 
-    memset(&sunx, 0, sizeof(sunx));
-    sunx.sun_family = AF_UNIX;	/* Unix domain socket */
-    strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
-    if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
-        perror("Couldn't obtain descriptor for socket " _PATH_LOG);
-	exit( FALSE);
-    }
+    openlog( name, option, (pri | LOG_FACMASK)); 
+    syslog( pri, message);
+    closelog();
 
-    addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
-
-    if (connect(fd, (struct sockaddr *) &sunx, addrLength)) {
-	perror("Could not connect to socket " _PATH_LOG);
-	exit( FALSE);
-    }
-
-    time(&now);
-    snprintf (buf, sizeof(buf), "<%d>%.15s %s", pri, ctime(&now)+4, message);
-    
-    if (toStdErrFlag==TRUE)
-	fprintf(stderr, "%s\n", buf);
-
-    write( fd, buf, strlen(buf)+1);
-
-    close(fd);
     exit( TRUE);
 }
 
diff --git a/sysklogd/logger.c b/sysklogd/logger.c
index 7aada5d..d7ae023 100644
--- a/sysklogd/logger.c
+++ b/sysklogd/logger.c
@@ -22,16 +22,11 @@
 
 #include "internal.h"
 #include <stdio.h>
-#include <sys/socket.h>
-#include <sys/un.h>
 #include <unistd.h>
-#include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <signal.h>
 #include <ctype.h>
-#include <netdb.h>
 
 #if !defined BB_SYSLOGD
 
@@ -56,6 +51,7 @@
     "Write MESSAGE to the system log.  If MESSAGE is '-', log stdin.\n\n"
     "Options:\n"
     "\t-s\tLog to stderr as well as the system log.\n"
+    "\t-t\tLog using the specified tag (defaults to user name).\n"
     "\t-p\tEnter the message with the specified priority.\n"
     "\t\tThis may be numerical or a ``facility.level'' pair.\n";
 
@@ -116,14 +112,14 @@
 
 extern int logger_main(int argc, char **argv)
 {
-    struct sockaddr_un sunx;
-    int fd, pri = LOG_USER|LOG_NOTICE;
+    int pri = LOG_USER|LOG_NOTICE;
+    int option = 0;
     int fromStdinFlag=FALSE;
-    int toStdErrFlag=FALSE;
     int stopLookingAtMeLikeThat=FALSE;
-    char *message, buf[1024], buf1[1024];
-    time_t  now;
-    size_t addrLength;
+    char *message, buf[1024], name[128];
+    
+    /* Fill out the name string early (may be overwritten later */
+    my_getpwuid(name, geteuid());
 
     /* Parse any options */
     while (--argc > 0 && **(++argv) == '-') {
@@ -134,7 +130,7 @@
 	while (*(++(*argv)) && stopLookingAtMeLikeThat==FALSE) {
 	    switch (**argv) {
 	    case 's':
-		toStdErrFlag = TRUE;
+		option |= LOG_PERROR;
 		break;
 	    case 'p':
 		if (--argc == 0) {
@@ -143,6 +139,13 @@
 		pri = pencode(*(++argv));
 		stopLookingAtMeLikeThat=TRUE;
 		break;
+	    case 't':
+		if (--argc == 0) {
+		    usage(logger_usage);
+		}
+		strncpy(name, *(++argv), sizeof(name));
+		stopLookingAtMeLikeThat=TRUE;
+		break;
 	    default:
 		usage(logger_usage);
 	    }
@@ -152,10 +155,10 @@
     if (fromStdinFlag==TRUE) {
 	/* read from stdin */
 	int c, i=0;
-	while ((c = getc(stdin)) != EOF && i<sizeof(buf1)) {
-	    buf1[i++]=c;
+	while ((c = getc(stdin)) != EOF && i<sizeof(buf)) {
+	    buf[i++]=c;
 	}
-	message=buf1;
+	message=buf;
     } else {
 	if (argc>=1) {
 		message=*argv;
@@ -165,30 +168,10 @@
 	}
     }
 
-    memset(&sunx, 0, sizeof(sunx));
-    sunx.sun_family = AF_UNIX;	/* Unix domain socket */
-    strncpy(sunx.sun_path, _PATH_LOG, sizeof(sunx.sun_path));
-    if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) {
-        perror("Couldn't obtain descriptor for socket " _PATH_LOG);
-	exit( FALSE);
-    }
+    openlog( name, option, (pri | LOG_FACMASK)); 
+    syslog( pri, message);
+    closelog();
 
-    addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
-
-    if (connect(fd, (struct sockaddr *) &sunx, addrLength)) {
-	perror("Could not connect to socket " _PATH_LOG);
-	exit( FALSE);
-    }
-
-    time(&now);
-    snprintf (buf, sizeof(buf), "<%d>%.15s %s", pri, ctime(&now)+4, message);
-    
-    if (toStdErrFlag==TRUE)
-	fprintf(stderr, "%s\n", buf);
-
-    write( fd, buf, strlen(buf)+1);
-
-    close(fd);
     exit( TRUE);
 }
 
diff --git a/tar.c b/tar.c
index 5c40786..adae6c9 100644
--- a/tar.c
+++ b/tar.c
@@ -108,9 +108,7 @@
  */
 static int listFlag;
 static int extractFlag;
-#ifdef BB_FEATURE_TAR_CREATE
 static int createFlag;
-#endif
 static int verboseFlag;
 static int tostdoutFlag;
 
@@ -185,9 +183,7 @@
 
     errorFlag = FALSE;
     extractFlag = FALSE;
-#ifdef BB_FEATURE_TAR_CREATE
     createFlag = FALSE;
-#endif
     listFlag = FALSE;
     verboseFlag = FALSE;
     tostdoutFlag = FALSE;
@@ -199,90 +195,85 @@
     /* 
      * Parse the options.
      */
-    if (**argv == '-') {
+    if (**argv == '-')
 	options = (*argv++) + 1;
-	argc--;
-	for (; *options; options++) {
-	    switch (*options) {
-	    case 'f':
-		if (tarName != NULL) {
-		    fprintf (stderr, "Only one 'f' option allowed\n");
+    else 
+	options = (*argv++);
+    argc--;
 
-		    exit (FALSE);
-		}
-
-		tarName = *argv++;
-		argc--;
-
-		break;
-
-	    case 't':
-		listFlag = TRUE;
-		break;
-
-	    case 'x':
-		extractFlag = TRUE;
-		break;
-#ifdef BB_FEATURE_TAR_CREATE
-	    case 'c':
-		createFlag = TRUE;
-		break;
-#else
-	    case 'c':
-		fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
-
-		exit (FALSE);
-#endif
-
-	    case 'v':
-		verboseFlag = TRUE;
-		break;
-
-	    case 'O':
-		tostdoutFlag = TRUE;
-		break;
-
-	    case '-':
-		usage( tar_usage);
-		break;
-
-	    default:
-		fprintf (stderr, "Unknown tar flag '%c'\n"
-			"Try `tar --help' for more information\n", 
-			*options);
+    for (; *options; options++) {
+	switch (*options) {
+	case 'f':
+	    if (tarName != NULL) {
+		fprintf (stderr, "Only one 'f' option allowed\n");
 
 		exit (FALSE);
 	    }
+
+	    tarName = *argv++;
+	    argc--;
+
+	    break;
+
+	case 't':
+	    if (extractFlag == TRUE || createFlag == TRUE )
+		goto flagError;
+	    listFlag = TRUE;
+	    break;
+
+	case 'x':
+	    if (listFlag == TRUE || createFlag == TRUE )
+		goto flagError;
+	    extractFlag = TRUE;
+	    break;
+	case 'c':
+	    if (extractFlag == TRUE || listFlag == TRUE)
+		goto flagError;
+	    createFlag = TRUE;
+	    break;
+
+	case 'v':
+	    verboseFlag = TRUE;
+	    break;
+
+	case 'O':
+	    tostdoutFlag = TRUE;
+	    break;
+
+	case '-':
+	    usage( tar_usage);
+	    break;
+
+	default:
+	    fprintf (stderr, "Unknown tar flag '%c'\n"
+		    "Try `tar --help' for more information\n", 
+		    *options);
+	    exit (FALSE);
 	}
     }
 
     /* 
-     * Validate the options.
-     */
-    if (extractFlag + listFlag 
-#ifdef BB_FEATURE_TAR_CREATE
-	    + createFlag 
-#endif 
-	    != (TRUE+FALSE+FALSE)) {
-	fprintf (stderr,
-		 "Exactly one of 'c', 'x' or 't' must be specified\n");
-
-	exit (FALSE);
-    }
-
-    /* 
      * Do the correct type of action supplying the rest of the
      * command line arguments as the list of files to process.
      */
-#ifdef BB_FEATURE_TAR_CREATE
-    if (createFlag==TRUE)
+    if (createFlag==TRUE) {
+#ifndef BB_FEATURE_TAR_CREATE
+	fprintf (stderr, "This version of tar was not compiled with tar creation support.\n" );
+	exit (FALSE);
+#else
 	writeTarFile (argc, argv);
-    else
 #endif 
+    } else {
 	readTarFile (argc, argv);
-    if (errorFlag==TRUE)
+    }
+    if (errorFlag==TRUE) {
 	fprintf (stderr, "\n");
+    }
     exit (!errorFlag);
+
+flagError:
+    fprintf (stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
+    exit (FALSE);
 }