extlinux: fix handling of /etc/mtab syslinux-3.71-pre3
authorH. Peter Anvin <hpa@zytor.com>
Thu, 3 Jul 2008 02:53:58 +0000 (19:53 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Thu, 3 Jul 2008 02:53:58 +0000 (19:53 -0700)
When we didn't find the filesystem in /proc/mounts, we would go
through /etc/mtab, but then completely botch the parsing thereof.
Move the parsing to a common function to avoid this problem.

NEWS
extlinux/main.c

diff --git a/NEWS b/NEWS
index 81ab3fa..0e910e6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ Changes in 3.71:
          calls(!!)
        * Simple menu: fix navigation around disabled entries
          (or at least try to...)
+       * EXTLINUX: proper error message when confused about mount point.
 
 Changes in 3.70:
        * PXELINUX: Support enhanced capabilities when running on top
index 0edce5a..819f74b 100644 (file)
@@ -801,6 +801,32 @@ static int validate_device(const char *path, int devfd)
   return (pst.st_dev == dst.st_rdev) ? 0 : -1;
 }
 
+#ifndef __KLIBC__
+static const char *find_device(const char *mtab_file, dev_t dev)
+{
+  struct mntent *mnt;
+  struct stat dst;
+  FILE *mtab;
+  const char *devname = NULL;
+
+  mtab = setmntent(mtab_file, "r");
+  if (!mtab)
+    return NULL;
+  
+  while ( (mnt = getmntent(mtab)) ) {
+    if ( (!strcmp(mnt->mnt_type, "ext2") ||
+         !strcmp(mnt->mnt_type, "ext3")) &&
+        !stat(mnt->mnt_fsname, &dst) && dst.st_rdev == dev ) {
+      devname = strdup(mnt->mnt_fsname);
+      break;
+    }
+  }
+  endmntent(mtab);
+
+  return devname;
+}
+#endif
+
 int
 install_loader(const char *path, int update_only)
 {
@@ -808,11 +834,6 @@ install_loader(const char *path, int update_only)
   int devfd, rv;
   const char *devname = NULL;
   struct statfs sfs;
-#ifndef __KLIBC__
-  struct mntent *mnt = NULL;
-  struct stat dst;
-  FILE *mtab;
-#endif
 
   if ( stat(path, &st) || !S_ISDIR(st.st_mode) ) {
     fprintf(stderr, "%s: Not a directory: %s\n", program, path);
@@ -848,35 +869,17 @@ install_loader(const char *path, int update_only)
 
 #else
 
-  if ( (mtab = setmntent("/proc/mounts", "r")) ) {
-    while ( (mnt = getmntent(mtab)) ) {
-      if ( (!strcmp(mnt->mnt_type, "ext2") ||
-           !strcmp(mnt->mnt_type, "ext3")) &&
-          !stat(mnt->mnt_fsname, &dst) &&
-          dst.st_rdev == st.st_dev ) {
-       devname = mnt->mnt_fsname;
-       break;
-      }
-    }
-  }
-
-  if ( !devname ) {
+  devname = find_device("/proc/mounts", st.st_dev);
+  if (!devname) {
     /* Didn't find it in /proc/mounts, try /etc/mtab */
-    if ( (mtab = setmntent("/etc/mtab", "r")) ) {
-      while ( (mnt = getmntent(mtab)) ) {
-       devname = mnt->mnt_fsname;
-       break;
-      }
-    }
+    devname = find_device("/etc/mtab", st.st_dev);
   }
-
-  if ( !devname ) {
+  if (!devname) {
     fprintf(stderr, "%s: cannot find device for path %s\n", program, path);
     return 1;
   }
 
   fprintf(stderr, "%s is device %s\n", path, devname);
-
 #endif
 
   if ( (devfd = open(devname, O_RDWR|O_SYNC)) < 0 ) {