Fixed ln, df, and removed redundant stuff from mtab.
diff --git a/Changelog b/Changelog
index 8a22e49..3923cf8 100644
--- a/Changelog
+++ b/Changelog
@@ -1,5 +1,12 @@
 0.33
 	* Fixed a bug where init could hang instead of rebooting.
+	* Removed some debugging noise from init.c
+	* Fixed ln so it works now (it was very broken).
+	* Fixed df so it won't segfault when there is no /etc/fstab,
+	* If BB_MTAB is not defined, df and mount will whine if /etc/fstab
+	    is not installed (since they cannot fixup "/dev/root" to 
+	    state the real root device name)
+	* merged some redundant code from mtab.c/df.c into utility.c
 
 0.32
 	* More changes -- many thanks to Lineo for paying me to work on
diff --git a/coreutils/df.c b/coreutils/df.c
index 94b6b82..a84a330 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -38,6 +38,7 @@
     struct statfs s;
     long blocks_used;
     long blocks_percent_used;
+    struct fstab* fstabItem;
 
     if (statfs(mountPoint, &s) != 0) {
 	perror(mountPoint);
@@ -48,9 +49,12 @@
 	blocks_used = s.f_blocks - s.f_bfree;
 	blocks_percent_used = (long)
 	    (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
-	if (strcmp(device, "/dev/root") == 0)
-	    device = (getfsfile("/"))->fs_spec;
-
+	/* Note that if /etc/fstab is missing, libc can't fix up /dev/root for us */
+	if (strcmp (device, "/dev/root") == 0) {
+	    fstabItem = getfsfile ("/");
+	    if (fstabItem != NULL)
+		device = fstabItem->fs_spec;
+	}
 	printf("%-20s %9ld %9ld %9ld %3ld%% %s\n",
 	       device,
 	       (long) (s.f_blocks * (s.f_bsize / 1024.0)),
@@ -63,52 +67,14 @@
     return 0;
 }
 
-/*
- * Given a block device, find the mount table entry if that block device
- * is mounted.
- *
- * Given any other file (or directory), find the mount table entry for its
- * filesystem.
- */
-extern struct mntent *findMountPoint(const char *name, const char *table)
-{
-    struct stat s;
-    dev_t mountDevice;
-    FILE *mountTable;
-    struct mntent *mountEntry;
-
-    if (stat(name, &s) != 0)
-	return 0;
-
-    if ((s.st_mode & S_IFMT) == S_IFBLK)
-	mountDevice = s.st_rdev;
-    else
-	mountDevice = s.st_dev;
-
-
-    if ((mountTable = setmntent(table, "r")) == 0)
-	return 0;
-
-    while ((mountEntry = getmntent(mountTable)) != 0) {
-	if (strcmp(name, mountEntry->mnt_dir) == 0
-	    || strcmp(name, mountEntry->mnt_fsname) == 0)	/* String match. */
-	    break;
-	if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice)	/* Match the device. */
-	    break;
-	if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice)	/* Match the directory's mount point. */
-	    break;
-    }
-    endmntent(mountTable);
-    return mountEntry;
-}
-
-
-
 extern int df_main(int argc, char **argv)
 {
     printf("%-20s %-14s %s %s %s %s\n", "Filesystem",
 	   "1k-blocks", "Used", "Available", "Use%", "Mounted on");
 
+    /* Only compiled in if BB_MTAB is not defined */
+    whine_if_fstab_is_missing();
+
     if (argc > 1) {
 	struct mntent *mountEntry;
 	int status;
diff --git a/coreutils/ln.c b/coreutils/ln.c
index 1e30e2b..62496fb 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -27,23 +27,21 @@
 #include <errno.h>
 
 
-static const char ln_usage[] = "ln [-s] [-f] original-name additional-name\n"
-"\n"
-"\tAdd a new name that refers to the same file as \"original-name\"\n"
-"\n"
-"\t-s:\tUse a \"symbolic\" link, instead of a \"hard\" link.\n"
-"\t-f:\tRemove existing destination files.\n";
+static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n"
+"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n"
+"\nOptions:\n"
+"\t-s\tmake symbolic links instead of hard links\n"
+"\t-f\tremove existing destination files\n";
 
 
 static int symlinkFlag = FALSE;
 static int removeoldFlag = FALSE;
-static const char *destName;
 
 
 extern int ln_main(int argc, char **argv)
 {
     int status;
-    char newdestName[NAME_MAX];
+    static char* linkName;
 
     if (argc < 3) {
 	usage (ln_usage);
@@ -69,30 +67,27 @@
     }
 
 
-    destName = argv[argc - 1];
+    linkName = argv[argc - 1];
 
-    if ((argc > 3) && !(isDirectory(destName))) {
-	fprintf(stderr, "%s: not a directory\n", destName);
+    if ((argc > 3) && !(isDirectory(linkName))) {
+	fprintf(stderr, "%s: not a directory\n", linkName);
 	exit (FALSE);
     }
 
     while (argc-- >= 2) {
-	strcpy(newdestName, destName);
-	strcat(newdestName, (*argv)+(strlen(*(++argv))));
-	
 	if (removeoldFlag==TRUE ) {
-	    status = ( unlink(newdestName) && errno != ENOENT );
+	    status = ( unlink(linkName) && errno != ENOENT );
 	    if ( status != 0 ) {
-		perror(newdestName);
+		perror(linkName);
 		exit( FALSE);
 	    }
 	}
 	if ( symlinkFlag==TRUE)
-		status = symlink(*argv, newdestName);
+		status = symlink(*argv, linkName);
 	else
-		status = link(*argv, newdestName);
+		status = link(*argv, linkName);
 	if ( status != 0 ) {
-	    perror(newdestName);
+	    perror(linkName);
 	    exit( FALSE);
 	}
     }
diff --git a/df.c b/df.c
index 94b6b82..a84a330 100644
--- a/df.c
+++ b/df.c
@@ -38,6 +38,7 @@
     struct statfs s;
     long blocks_used;
     long blocks_percent_used;
+    struct fstab* fstabItem;
 
     if (statfs(mountPoint, &s) != 0) {
 	perror(mountPoint);
@@ -48,9 +49,12 @@
 	blocks_used = s.f_blocks - s.f_bfree;
 	blocks_percent_used = (long)
 	    (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
-	if (strcmp(device, "/dev/root") == 0)
-	    device = (getfsfile("/"))->fs_spec;
-
+	/* Note that if /etc/fstab is missing, libc can't fix up /dev/root for us */
+	if (strcmp (device, "/dev/root") == 0) {
+	    fstabItem = getfsfile ("/");
+	    if (fstabItem != NULL)
+		device = fstabItem->fs_spec;
+	}
 	printf("%-20s %9ld %9ld %9ld %3ld%% %s\n",
 	       device,
 	       (long) (s.f_blocks * (s.f_bsize / 1024.0)),
@@ -63,52 +67,14 @@
     return 0;
 }
 
-/*
- * Given a block device, find the mount table entry if that block device
- * is mounted.
- *
- * Given any other file (or directory), find the mount table entry for its
- * filesystem.
- */
-extern struct mntent *findMountPoint(const char *name, const char *table)
-{
-    struct stat s;
-    dev_t mountDevice;
-    FILE *mountTable;
-    struct mntent *mountEntry;
-
-    if (stat(name, &s) != 0)
-	return 0;
-
-    if ((s.st_mode & S_IFMT) == S_IFBLK)
-	mountDevice = s.st_rdev;
-    else
-	mountDevice = s.st_dev;
-
-
-    if ((mountTable = setmntent(table, "r")) == 0)
-	return 0;
-
-    while ((mountEntry = getmntent(mountTable)) != 0) {
-	if (strcmp(name, mountEntry->mnt_dir) == 0
-	    || strcmp(name, mountEntry->mnt_fsname) == 0)	/* String match. */
-	    break;
-	if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice)	/* Match the device. */
-	    break;
-	if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice)	/* Match the directory's mount point. */
-	    break;
-    }
-    endmntent(mountTable);
-    return mountEntry;
-}
-
-
-
 extern int df_main(int argc, char **argv)
 {
     printf("%-20s %-14s %s %s %s %s\n", "Filesystem",
 	   "1k-blocks", "Used", "Available", "Use%", "Mounted on");
 
+    /* Only compiled in if BB_MTAB is not defined */
+    whine_if_fstab_is_missing();
+
     if (argc > 1) {
 	struct mntent *mountEntry;
 	int status;
diff --git a/internal.h b/internal.h
index c66c9f1..8d111a6 100644
--- a/internal.h
+++ b/internal.h
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <mntent.h>
 
 
 /* Some useful definitions */
@@ -145,12 +146,19 @@
 extern void my_getgrgid(char* group, gid_t gid);
 extern int get_kernel_revision();
 extern int get_console_fd(char* tty_name);
-
+extern struct mntent *findMountPoint(const char *name, const char *table);
 extern void write_mtab(char* blockDevice, char* directory, 
 	char* filesystemType, long flags, char* string_flags);
 extern void erase_mtab(const char * name);
 
 
+#if defined BB_MTAB
+#define whine_if_fstab_is_missing() {} 
+#else
+extern void whine_if_fstab_is_missing();
+#endif
+
+
 #if defined (BB_FSCK_MINIX) || defined (BB_MKFS_MINIX)
 
 static inline int bit(char * addr,unsigned int nr) 
diff --git a/ln.c b/ln.c
index 1e30e2b..62496fb 100644
--- a/ln.c
+++ b/ln.c
@@ -27,23 +27,21 @@
 #include <errno.h>
 
 
-static const char ln_usage[] = "ln [-s] [-f] original-name additional-name\n"
-"\n"
-"\tAdd a new name that refers to the same file as \"original-name\"\n"
-"\n"
-"\t-s:\tUse a \"symbolic\" link, instead of a \"hard\" link.\n"
-"\t-f:\tRemove existing destination files.\n";
+static const char ln_usage[] = "ln [OPTION] TARGET... LINK_NAME|DIRECTORY\n"
+"Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n"
+"\nOptions:\n"
+"\t-s\tmake symbolic links instead of hard links\n"
+"\t-f\tremove existing destination files\n";
 
 
 static int symlinkFlag = FALSE;
 static int removeoldFlag = FALSE;
-static const char *destName;
 
 
 extern int ln_main(int argc, char **argv)
 {
     int status;
-    char newdestName[NAME_MAX];
+    static char* linkName;
 
     if (argc < 3) {
 	usage (ln_usage);
@@ -69,30 +67,27 @@
     }
 
 
-    destName = argv[argc - 1];
+    linkName = argv[argc - 1];
 
-    if ((argc > 3) && !(isDirectory(destName))) {
-	fprintf(stderr, "%s: not a directory\n", destName);
+    if ((argc > 3) && !(isDirectory(linkName))) {
+	fprintf(stderr, "%s: not a directory\n", linkName);
 	exit (FALSE);
     }
 
     while (argc-- >= 2) {
-	strcpy(newdestName, destName);
-	strcat(newdestName, (*argv)+(strlen(*(++argv))));
-	
 	if (removeoldFlag==TRUE ) {
-	    status = ( unlink(newdestName) && errno != ENOENT );
+	    status = ( unlink(linkName) && errno != ENOENT );
 	    if ( status != 0 ) {
-		perror(newdestName);
+		perror(linkName);
 		exit( FALSE);
 	    }
 	}
 	if ( symlinkFlag==TRUE)
-		status = symlink(*argv, newdestName);
+		status = symlink(*argv, linkName);
 	else
-		status = link(*argv, newdestName);
+		status = link(*argv, linkName);
 	if ( status != 0 ) {
-	    perror(newdestName);
+	    perror(linkName);
 	    exit( FALSE);
 	}
     }
diff --git a/mount.c b/mount.c
index 8b5efe1..4c085d0 100644
--- a/mount.c
+++ b/mount.c
@@ -208,14 +208,13 @@
     char *filesystemType = "auto";
     char *device = NULL;
     char *directory = NULL;
-    struct stat statBuf;
     int all = FALSE;
     int fakeIt = FALSE;
     int useMtab = TRUE;
     int i;
 
-    if (stat("/etc/fstab", &statBuf) < 0) 
-	fprintf(stderr, "/etc/fstab file missing -- Please install one.\n\n");
+    /* Only compiled in if BB_MTAB is not defined */
+    whine_if_fstab_is_missing();
 
     if (argc == 1) {
 	FILE *mountTable = setmntent (mtab_file, "r");
diff --git a/mtab.c b/mtab.c
index b6304a1..e855717 100644
--- a/mtab.c
+++ b/mtab.c
@@ -59,48 +59,6 @@
 		perror(mtab_file);
 }
 
-/*
- * Given a block device, find the mount table entry if that block device
- * is mounted.
- *
- * Given any other file (or directory), find the mount table entry for its
- * filesystem.
- */
-static struct mntent *
-findMountPoint(const char * name, const char * table)
-{
-    struct stat	s;
-    dev_t mountDevice;
-    FILE* mountTable;
-    struct mntent* mountEntry;
-
-    if ( stat(name, &s) != 0 )
-	return 0;
-
-    if ( (s.st_mode & S_IFMT) == S_IFBLK )
-	mountDevice = s.st_rdev;
-    else
-	mountDevice = s.st_dev;
-
-    
-    if ( (mountTable = setmntent(table, "r")) == 0 )
-	return 0;
-
-    while ( (mountEntry = getmntent(mountTable)) != 0 ) {
-	if ( strcmp(name, mountEntry->mnt_dir) == 0 || 
-		strcmp(name, mountEntry->mnt_fsname) == 0 )	/* String match. */
-	    break;
-	if ( stat(mountEntry->mnt_fsname, &s) == 0 && 
-		s.st_rdev == mountDevice )	/* Match the device. */
-	    break;
-	if ( stat(mountEntry->mnt_dir, &s) == 0 && 
-		s.st_dev == mountDevice )	/* Match the directory's mount point. */
-	    break;
-    }
-    endmntent(mountTable);
-    return mountEntry;
-}
-
 extern void 
 write_mtab(char* blockDevice, char* directory, 
 	char* filesystemType, long flags, char* string_flags)
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 8b5efe1..4c085d0 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -208,14 +208,13 @@
     char *filesystemType = "auto";
     char *device = NULL;
     char *directory = NULL;
-    struct stat statBuf;
     int all = FALSE;
     int fakeIt = FALSE;
     int useMtab = TRUE;
     int i;
 
-    if (stat("/etc/fstab", &statBuf) < 0) 
-	fprintf(stderr, "/etc/fstab file missing -- Please install one.\n\n");
+    /* Only compiled in if BB_MTAB is not defined */
+    whine_if_fstab_is_missing();
 
     if (argc == 1) {
 	FILE *mountTable = setmntent (mtab_file, "r");
diff --git a/utility.c b/utility.c
index 50d0192..97c597e 100644
--- a/utility.c
+++ b/utility.c
@@ -868,5 +868,64 @@
 
 
 #endif
+
+
+
+
+#if defined BB_DF | defined BB_MTAB
+/*
+ * Given a block device, find the mount table entry if that block device
+ * is mounted.
+ *
+ * Given any other file (or directory), find the mount table entry for its
+ * filesystem.
+ */
+extern struct mntent *findMountPoint(const char *name, const char *table)
+{
+    struct stat s;
+    dev_t mountDevice;
+    FILE *mountTable;
+    struct mntent *mountEntry;
+
+    if (stat(name, &s) != 0)
+	return 0;
+
+    if ((s.st_mode & S_IFMT) == S_IFBLK)
+	mountDevice = s.st_rdev;
+    else
+	mountDevice = s.st_dev;
+
+
+    if ((mountTable = setmntent(table, "r")) == 0)
+	return 0;
+
+    while ((mountEntry = getmntent(mountTable)) != 0) {
+	if (strcmp(name, mountEntry->mnt_dir) == 0
+	    || strcmp(name, mountEntry->mnt_fsname) == 0)	/* String match. */
+	    break;
+	if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice)	/* Match the device. */
+	    break;
+	if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice)	/* Match the directory's mount point. */
+	    break;
+    }
+    endmntent(mountTable);
+    return mountEntry;
+}
+
+#endif
+
+
+
+#if !defined BB_MTAB && (defined BB_MOUNT || defined BB_DF )
+extern void whine_if_fstab_is_missing()
+{
+    struct stat statBuf;
+    if (stat("/etc/fstab", &statBuf) < 0) 
+	fprintf(stderr, "/etc/fstab file missing -- install one to name /dev/root.\n\n");
+}
+#endif
+
+
 /* END CODE */
 
+