File e2fsprogs-libvolume_id-support.patch of Package e2fsprogs

--- misc/Makefile.in
+++ misc/Makefile.in
@@ -36,7 +36,7 @@
 DUMPE2FS_OBJS=	dumpe2fs.o
 BADBLOCKS_OBJS=	badblocks.o
 E2IMAGE_OBJS=	e2image.o
-FSCK_OBJS=	fsck.o base_device.o
+FSCK_OBJS=	fsck.o base_device.o fsck_udev.o
 BLKID_OBJS=	blkid.o
 FILEFRAG_OBJS=	filefrag.o
 
@@ -57,6 +57,9 @@
 LIBS_BLKID= $(LIBBLKID) $(LIBUUID)
 DEPLIBS_BLKID= $(LIBBLKID) $(DEPLIBUUID)
 
+LIBS_VOLID= -lvolume_id
+DEPLIBS_VOLID=
+
 LIBS_E2P= $(LIBE2P) $(LIBCOM_ERR) 
 DEPLIBS_E2P= $(LIBE2P) $(LIBCOM_ERR) 
 
@@ -98,10 +101,6 @@
 	@$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(srcdir)/base_device.c \
 		-DDEBUG -o base_device
 
-check:: base_device
-	./base_device < $(srcdir)/base_device.tst > base_device.out
-	cmp $(srcdir)/base_device.tst base_device.out
-
 mklost+found: $(MKLPF_OBJS)
 	@echo "	LD $@"
 	@$(CC) $(ALL_LDFLAGS) -o mklost+found $(MKLPF_OBJS) $(LIBINTL)
@@ -138,9 +137,9 @@
 	@$(CC) $(ALL_LDFLAGS) -o dumpe2fs $(DUMPE2FS_OBJS) $(LIBS) \
 		$(LIBS_E2P) $(LIBUUID) $(LIBINTL)
 
-fsck: $(FSCK_OBJS) $(DEBLIBS_BLKID)
+fsck: $(FSCK_OBJS) $(DEBLIBS_VOLID)
 	@echo "	LD $@"
-	@$(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBS_BLKID) $(LIBINTL)
+	@$(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBS_VOLID) $(LIBINTL)
 
 badblocks: $(BADBLOCKS_OBJS) $(DEPLIBS)
 	@echo "	LD $@"
--- misc/base_device.c
+++ misc/base_device.c
@@ -27,6 +27,8 @@
 #endif
 #include <ctype.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
 
 #include "fsck.h"
 
--- misc/fsck.8.in
+++ misc/fsck.8.in
@@ -8,7 +8,7 @@
 .SH SYNOPSIS
 .B fsck
 [
-.B \-sAVRTNP
+.B \-sAVRTMNP
 ]
 [
 .B \-C
@@ -236,6 +236,14 @@
 .B \-N
 Don't execute, just show what would be done.
 .TP
+.B \-M
+Emulate
+.BR mount (1)
+behaviour; do not check the filesystem if it's not listed in
+/etc/fstab or if
+.I fs_pass_no
+of the corresponding entry is zero.
+.TP
 .B \-P
 When the 
 .B \-A
--- misc/fsck.c
+++ misc/fsck.c
@@ -59,7 +59,6 @@
 #include "../version.h"
 #include "nls-enable.h"
 #include "fsck.h"
-#include "blkid/blkid.h"
 
 #ifndef _PATH_MNTTAB
 #define	_PATH_MNTTAB	"/etc/fstab"
@@ -118,7 +117,6 @@
 struct fsck_instance *instance_list;
 const char *fsck_prefix_path = "/sbin:/sbin/fs.d:/sbin/fs:/etc/fs:/etc";
 char *fsck_path = 0;
-blkid_cache cache = NULL;
 
 static char *string_copy(const char *s)
 {
@@ -297,7 +295,7 @@
 	parse_escape(freq);
 	parse_escape(passno);
 
-	dev = blkid_get_devname(cache, device, NULL);
+	dev = fsck_get_devname(device);
 	if (dev)
 		device = dev;
 
@@ -322,7 +320,7 @@
 	
 	if (strcmp(fs->type, "auto") != 0)
 		return;
-	t = blkid_get_tag_value(cache, "TYPE", fs->device);
+	t = fsck_get_fstype(fs->device);
 	if (t) {
 		free(fs->type);
 		fs->type = t;
@@ -1048,7 +1046,7 @@
 
 static void usage(NOARGS)
 {
-	fputs(_("Usage: fsck [-ANPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr);
+	fputs(_("Usage: fsck [-AMNPRTV] [ -C [ fd ] ] [-t fstype] [fs-options] [filesys ...]\n"), stderr);
 	exit(EXIT_USAGE);
 }
 
@@ -1094,7 +1092,7 @@
 					progname);
 				exit(EXIT_ERROR);
 			}
-			dev = blkid_get_devname(cache, arg, NULL);
+			dev = fsck_get_devname(arg);
 			if (!dev && strchr(arg, '=')) {
 				/*
 				 * Check to see if we failed because
@@ -1240,7 +1238,7 @@
 	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
 	textdomain(NLS_CAT_NAME);
 #endif
-	blkid_get_cache(&cache, getenv("BLKID_FILE"));
+	fsck_get_cache(getenv("BLKID_FILE"));
 	PRS(argc, argv);
 
 	if (!notitle)
@@ -1287,6 +1285,16 @@
 			break;
 		}
 		fs = lookup(devices[i]);
+		if (like_mount) {
+			/*
+			 * Emulate mount behaviour:
+			 * Do not check device if not found
+			 * in /etc/fstab or if the passno
+			 * is set to '0'
+			 */
+			if (!fs || ignore(fs))
+				continue;
+		}
 		if (!fs) {
 			fs = create_fs_device(devices[i], 0, "auto",
 					      0, -1, -1);
@@ -1309,6 +1317,6 @@
 	}
 	status |= wait_many(FLAG_WAIT_ALL);
 	free(fsck_path);
-	blkid_put_cache(cache);
+	fsck_put_cache();
 	return status;
 }
--- misc/fsck.h
+++ misc/fsck.h
@@ -68,3 +68,9 @@
 
 extern dev_t base_devt(const char *device);
 extern int match_device(const char *dev1, const char *dev2);
+
+extern int fsck_get_cache(const char *filename);
+extern void fsck_put_cache(void);
+extern char *fsck_get_devname(const char *device);
+extern char *fsck_get_fstype(const char *device);
+
--- misc/fsck_blkid.c
+++ misc/fsck_blkid.c
@@ -0,0 +1,29 @@
+/*
+ * Wrapper for libblkid
+ */
+
+#include <stdio.h>
+#include "blkid/blkid.h"
+
+static blkid_cache cache = NULL;
+
+int fsck_get_cache(const char *filename)
+{
+	return blkid_get_cache(&cache, name);
+}
+
+void fsck_put_cache(void)
+{
+	blkid_put_cache(cache);
+}
+
+char *fsck_get_devname(const char *device)
+{
+	return blkid_get_devname(cache, device, NULL);
+}
+
+char *fsck_get_fstype(const char *device)
+{
+	return blkid_get_tag_value(cache, "TYPE", device);
+}
+
--- misc/fsck_udev.c
+++ misc/fsck_udev.c
@@ -0,0 +1,188 @@
+/*
+ * Wrapper for libvolume_id
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/ioctl.h>
+#include <stddef.h>
+#include <libvolume_id.h>
+
+#include "fsck.h"
+
+int fsck_get_cache(const char *filename)
+{
+	return 0;
+}
+
+void fsck_put_cache(void)
+{
+}
+
+char *fsck_get_devname_by_uuid(const char *uuid)
+{
+	char *dev = NULL;
+
+	if (!uuid)
+		return NULL;
+
+	dev = malloc(19 + strlen(uuid));
+	if (dev) {
+		strcpy(dev,"/dev/disk/by-uuid/");
+		strcat(dev,uuid);
+	}
+
+	return dev;
+}
+
+char *fsck_get_devname_by_label(const char *label)
+{
+	char *dev = NULL;
+
+	if (!label)
+		return NULL;
+
+	dev = malloc(20 + strlen(label));
+	if (dev) {
+		strcpy(dev,"/dev/disk/by-label/");
+		strcat(dev,label);
+	}
+
+	return dev;
+}
+
+char *fsck_get_devname(const char *spec)
+{
+	char *token, *cp, *value;
+	char *nspec = NULL;
+
+	if (!spec)
+		return NULL;
+
+	token = strdup(spec);
+	if (!token)
+		return NULL;
+
+	/* We have to return an allocated string */
+	if (!(cp = strchr(token, '=')))
+		return token;
+
+	value = token + (cp - token);
+	*value++ = '\0';
+
+	if (*value == '"' || *value == '\'') {
+		char c = *value++;
+		if (!(cp = strrchr(value, c)))
+			goto errout; /* missing closing quote */
+		*cp = '\0';
+	}
+	
+	if (!strcmp(token,"LABEL")) {
+		nspec = fsck_get_devname_by_label(value);
+	} else if (!strcmp(token,"UUID")) {
+		nspec = fsck_get_devname_by_uuid(value);
+	}
+
+	free(token);
+
+ errout:
+	return nspec;
+}       
+
+struct volume_id_types_t {
+	int id;
+	char *token;
+	char *env;
+};
+
+enum {
+	VOLUME_ID_NONE=0,
+	VOLUME_ID_TYPE,
+	VOLUME_ID_LABEL,
+	VOLUME_ID_UUID
+};
+
+#define volume_id_offset(member) (unsigned long)offsetof(struct volume_id,member)
+
+struct volume_id_types_t volume_id_types[] = {
+	{ VOLUME_ID_TYPE, "TYPE", "ID_FS_TYPE" },
+	{ VOLUME_ID_LABEL, "LABEL", "ID_FS_LABEL" },
+	{ VOLUME_ID_UUID, "UUID",  "ID_FS_UUID" },
+	{ VOLUME_ID_NONE, NULL, NULL },
+};
+
+char *volume_id_get_tag(const char *spec, const char *token)
+{
+	struct volume_id *vid;
+	uint64_t size;
+	struct volume_id_types_t *volume_id_ptr = volume_id_types;
+	char *var, *value;
+
+	value = malloc(VOLUME_ID_LABEL_SIZE);
+	if (!value)
+		return NULL;
+
+	if (!spec)
+		return NULL;
+
+	while (volume_id_ptr->token && strcmp(volume_id_ptr->token,token))
+		volume_id_ptr++;
+
+	if (!volume_id_ptr->token) {
+		free(value);
+		value = NULL;
+		goto out;
+	}
+
+	/* Quick exit if ID_FS_* variables are set */
+	if ((var = getenv(volume_id_ptr->env))) {
+		strcpy(value,var);
+		goto out;
+	}
+
+	vid = volume_id_open_node(spec);
+	if (!vid) {
+		free(value);
+		value = NULL;
+		goto out;
+	}
+
+	if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
+		size = 0;
+
+	if (volume_id_probe_all(vid, 0, size) == 0) {
+		switch(volume_id_ptr->id) {
+		case VOLUME_ID_TYPE:
+			strcpy(value, vid->type);
+			break;
+		case VOLUME_ID_LABEL:
+			strcpy(value, vid->label);
+			break;
+		case VOLUME_ID_UUID:
+			strcpy(value, vid->uuid);
+			break;
+		default:
+			free(value);
+			value = NULL;
+			break;
+		}
+	} else {
+		free(value);
+		volume_id_close(vid);
+		return NULL;
+	}
+
+	volume_id_close(vid);
+
+ out:
+	return value;
+}
+
+char *fsck_get_fstype(const char *device)
+{
+	return volume_id_get_tag(device, "TYPE");
+}
+
openSUSE Build Service is sponsored by