reiserfsprogs: use com_err in reiserfs_open

We dump failure messages to the terminal regardless of whether the caller
wants them or not.  This can be annoying when used as part of a general
tool that tests to see which file system is on a device by calling
its open routine.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
diff --git a/configure.ac b/configure.ac
index 82a686d..44db257 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,10 @@
 UUID_LIBS="$LIBS"
 AC_SUBST(UUID_LIBS)
 
+AC_CHECK_LIB(com_err, _et_list, , AC_MSG_WARN(libcom_err could not be found))
+COM_ERR_LIBS="$LIBS"
+AC_SUBST(COM_ERR_LIBS)
+
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/ioctl.h unistd.h uuid/uuid.h)
diff --git a/debugreiserfs/debugreiserfs.c b/debugreiserfs/debugreiserfs.c
index 139a3a1..5ee9d48 100644
--- a/debugreiserfs/debugreiserfs.c
+++ b/debugreiserfs/debugreiserfs.c
@@ -4,6 +4,7 @@
  */
 
 #include "debugreiserfs.h"
+#include <com_err.h>
 
 reiserfs_filsys_t fs;
 
@@ -683,7 +684,7 @@
 int main(int argc, char *argv[])
 {
 	char *file_name;
-	int error;
+	long error;
 	struct debugreiserfs_data *data;
 	FILE *log;
 
@@ -701,7 +702,7 @@
 	if (no_reiserfs_found(fs)) {
 		reiserfs_exit(1, "\n\ndebugreiserfs: can not open reiserfs on "
 			      "\"%s\": %s\n\n", file_name,
-			      error ? strerror(error)
+			      error ? error_message(error)
 			      : "no filesystem found");
 		exit(1);
 	}
diff --git a/fsck/main.c b/fsck/main.c
index 26551e1..5063504 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -1318,7 +1318,7 @@
 	struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
 	char *width;
 	int retval;
-	int error;
+	long error;
 
 	width = getenv("COLUMNS");
 	if (width)
@@ -1391,7 +1391,7 @@
 		if (error) {
 			reiserfs_exit(EXIT_OPER, "Failed to open the device "
 				      "'%s': %s\n\n", file_name,
-				      strerror(error));
+				      error_message(error));
 		}
 
 		if (data->mode != FSCK_SB) {
diff --git a/fsck/super.c b/fsck/super.c
index 4fc7762..5769fee 100644
--- a/fsck/super.c
+++ b/fsck/super.c
@@ -190,6 +190,7 @@
 	size_t n = 0;
 	struct stat stat_buf;
 	int retval, exit_code = EXIT_OK;
+	long error;
 
 	if (!no_reiserfs_found(fs)) {
 		sb = getmem(sizeof(*sb));
@@ -381,24 +382,31 @@
 		switch (version) {
 		case 1:
 			fs = reiserfs_create(filename, REISERFS_FORMAT_3_6,
-					     block_count, retval, 1, 1);
+					     block_count, retval, 1, 1,
+					     &error);
 			break;
 		case 2:
 			fs = reiserfs_create(filename, REISERFS_FORMAT_3_5,
-					     block_count, retval, 1, 1);
+					     block_count, retval, 1, 1,
+					     &error);
 			break;
 		case 3:
 			fs = reiserfs_create(filename, REISERFS_FORMAT_3_6,
-					     block_count, retval, 1, 0);
+					     block_count, retval, 1, 0,
+					     &error);
 			break;
 		case 4:
 			fs = reiserfs_create(filename, REISERFS_FORMAT_3_5,
-					     block_count, retval, 1, 0);
+					     block_count, retval, 1, 0,
+					     &error);
 			break;
 		}
 
-		if (fs == NULL)
+		if (fs == NULL) {
+			fprintf(stderr, "reiserfs_create failed: %s\n",
+				error_message(error));
 			return;
+		}
 
 		sb = fs->fs_ondisk_sb;
 		fs->fs_vp = data;
diff --git a/include/reiserfs_lib.h b/include/reiserfs_lib.h
index f66d46a..2156380 100644
--- a/include/reiserfs_lib.h
+++ b/include/reiserfs_lib.h
@@ -11,6 +11,7 @@
 
 typedef struct reiserfs_filsys * reiserfs_filsys_t;
 
+#include <com_err.h>
 #include "reiserfs_fs.h"
 
 struct _bitmap {
@@ -75,11 +76,12 @@
 void init_tb_struct(struct tree_balance *tb, reiserfs_filsys_t ,
 		    struct reiserfs_path *path, int size);
 
-reiserfs_filsys_t reiserfs_open(const char *filename, int flags, int *error,
+reiserfs_filsys_t reiserfs_open(const char *filename, int flags, long *error,
 				 void *vp, int skip_check);
 reiserfs_filsys_t reiserfs_create(const char *filename, int version,
 				   unsigned long block_count, int block_size,
-				   int default_journal, int new_format);
+				   int default_journal, int new_format,
+				   long *error);
 void reiserfs_flush(reiserfs_filsys_t );
 void reiserfs_free(reiserfs_filsys_t );
 void reiserfs_close(reiserfs_filsys_t );
diff --git a/mkreiserfs/mkreiserfs.c b/mkreiserfs/mkreiserfs.c
index 889cda5..463eb8e 100644
--- a/mkreiserfs/mkreiserfs.c
+++ b/mkreiserfs/mkreiserfs.c
@@ -576,6 +576,7 @@
 	__u64 fs_size = 0;
 	int c;
 	static int flag;
+	long error;
 
 	program_name = strrchr(argv[0], '/');
 
@@ -751,9 +752,11 @@
 			return 1;
 
 	fs = reiserfs_create(device_name, select_format(), fs_size, Block_size,
-			     Create_default_journal, 1);
+			     Create_default_journal, 1, &error);
 
 	if (!fs) {
+		reiserfs_warning(stderr, "reiserfs_create failed: %s %ld\n",
+				 error_message(error), error);
 		return 1;
 	}
 
diff --git a/reiserfscore/Makefile.am b/reiserfscore/Makefile.am
index a140a23..ce0a691 100644
--- a/reiserfscore/Makefile.am
+++ b/reiserfscore/Makefile.am
@@ -1,9 +1,21 @@
 lib_LTLIBRARIES = libreiserfscore.la
 
+reiserfsdir = $(includedir)/reiserfs
+reiserfs_HEADERS = reiserfs_err.h
+
+reiserfs_err.c reiserfs_err.h: reiserfs_err.et
+	$(RM) -f reisefs_err.c reiserfs_err.h
+	compile_et reiserfs_err.et
+reiserfs_err.h: reiserfs_err.c
+
+BUILT_SOURCES = reiserfs_err.h reiserfs_err.c
+CLEANFILES = reiserfs_err.h reiserfs_err.c
+
 libreiserfscore_la_SOURCES = do_balan.c fix_node.c hashes.c ibalance.c \
 			     lbalance.c prints.c stree.c node_formats.c \
-			     reiserfslib.c bitmap.c journal.c xattr.c includes.h
-libreiserfscore_la_LIBADD = ../lib/libmisc.la
+			     reiserfslib.c bitmap.c journal.c xattr.c \
+			     includes.h reiserfs_err.c
+libreiserfscore_la_LIBADD = ../lib/libmisc.la -lcom_err
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = reiserfscore.pc
diff --git a/reiserfscore/includes.h b/reiserfscore/includes.h
index f8a9098..31fad42 100644
--- a/reiserfscore/includes.h
+++ b/reiserfscore/includes.h
@@ -10,6 +10,7 @@
 #include "io.h"
 #include "misc.h"
 #include "reiserfs_lib.h"
+#include "reiserfs_err.h"
 
 #include <string.h>
 #include <stdlib.h>
diff --git a/reiserfscore/reiserfs_err.et b/reiserfscore/reiserfs_err.et
new file mode 100644
index 0000000..f84a9b5
--- /dev/null
+++ b/reiserfscore/reiserfs_err.et
@@ -0,0 +1,27 @@
+# reiserfs_err.et - Error codes for reiserfscore
+#
+# Copyright (C) 2016 SUSE
+#
+	error_table reiserfs
+ec	REISERFS_ET_BREAD_FAILED,
+	"bread failed to read block"
+
+ec	REISERFS_ET_BAD_MAGIC,
+	"the reiserfs superblock cannot be found"
+
+ec	REISERFS_ET_BAD_SUPER,
+	"a superblock with wrong parameters was found in the block"
+
+ec	REISERFS_ET_SMALL_PARTITION,
+	"Your partition is not big enough to contain the filesystem"
+
+ec	REISERFS_ET_NOT_ENOUGH_BLOCKS,
+	"not enough blocks on device"
+
+ec	REISERFS_ET_TOO_SMALL,
+	"cannot create a file system that small"
+
+ec	REISERFS_ET_GETBLK_FAILED,
+	"getblk failed"
+
+	end
diff --git a/reiserfscore/reiserfslib.c b/reiserfscore/reiserfslib.c
index 2ee2e49..6535379 100644
--- a/reiserfscore/reiserfslib.c
+++ b/reiserfscore/reiserfslib.c
@@ -56,7 +56,7 @@
    is refused. Journal and bitmap are to be opened separately.
    skip_check is set to 1 if checks of openned SB should be omitted.*/
 reiserfs_filsys_t reiserfs_open(const char *filename, int flags,
-				 int *error, void *vp, int check)
+				 long *error, void *vp, int check)
 {
 	reiserfs_filsys_t fs;
 	struct buffer_head *bh;
@@ -67,8 +67,7 @@
 	/* convert root dir key and parent root dir key to little endian format */
 	make_const_keys();
 
-	if (error)
-		*error = 0;
+	*error = 0;
 
 	fd = open(filename, flags
 #if defined(O_LARGEFILE)
@@ -76,8 +75,7 @@
 #endif
 	    );
 	if (fd == -1) {
-		if (error)
-			*error = errno;
+		*error = errno;
 		return NULL;
 	}
 
@@ -91,9 +89,7 @@
 	for (i = 2; i < 17; i += 14) {
 		bh = bread(fd, i, 4096);
 		if (!bh) {
-			reiserfs_warning(stderr,
-					 "reiserfs_open: bread failed reading block %d\n",
-					 i);
+			*error = REISERFS_ET_BREAD_FAILED;
 		} else {
 			sb = (struct reiserfs_super_block *)bh->b_data;
 
@@ -105,9 +101,7 @@
 		}
 	}
 
-	reiserfs_warning(stderr,
-			 "\nreiserfs_open: the reiserfs superblock cannot be found on %s.\n",
-			 filename);
+	*error = REISERFS_ET_BAD_MAGIC;
 
 	freemem(fs);
 	close(fd);
@@ -117,9 +111,7 @@
 found:
 
 	if (!is_blocksize_correct(get_sb_block_size(sb))) {
-		reiserfs_warning(stderr,
-				 "reiserfs_open: a superblock with wrong parameters "
-				 "was found in the block (%d).\n", i);
+		*error = REISERFS_ET_BAD_SUPER;
 		freemem(fs);
 		close(fd);
 		brelse(bh);
@@ -135,12 +127,7 @@
 			  get_sb_block_size(sb));
 
 		if (!tmp_bh) {
-			reiserfs_warning(stderr,
-					 "\n%s: Your partition is not big enough to contain the \n"
-					 "filesystem of (%lu) blocks as was specified in the found super block.\n",
-					 __FUNCTION__,
-					 get_sb_block_count(sb) - 1);
-
+			*error = REISERFS_ET_SMALL_PARTITION;
 			freemem(fs);
 			close(fd);
 			brelse(bh);
@@ -158,9 +145,7 @@
 		brelse(bh);
 		bh = bread(fd, i, fs->fs_blocksize);
 		if (!bh) {
-			reiserfs_warning(stderr,
-					 "reiserfs_open: bread failed reading block %d, size %d\n",
-					 i, fs->fs_blocksize);
+			*error = REISERFS_ET_BREAD_FAILED;
 			freemem(fs);
 			return NULL;
 		}
@@ -189,32 +174,32 @@
 				   int version,
 				   unsigned long block_count,
 				   int block_size,
-				   int default_journal, int new_format)
+				   int default_journal, int new_format,
+				   long *error)
 {
 	reiserfs_filsys_t fs;
 	time_t now;
 	unsigned int bmap_nr = reiserfs_bmap_nr(block_count, block_size);;
 
+	*error = 0;
+
 	/* convert root dir key and parent root dir key to little endian format */
 	make_const_keys();
 
 	if (count_blocks(filename, block_size) < block_count) {
-		reiserfs_warning(stderr,
-				 "reiserfs_create: no enough blocks on device\n");
+		*error = REISERFS_ET_NOT_ENOUGH_BLOCKS;
 		return NULL;
 	}
 
 	if (!is_block_count_correct(REISERFS_DISK_OFFSET_IN_BYTES / block_size,
 				    block_size, block_count, 0)) {
-		reiserfs_warning(stderr,
-				 "reiserfs_create: can not create that small "
-				 "(%u blocks) filesystem\n", block_count);
+		*error = REISERFS_ET_TOO_SMALL;
 		return NULL;
 	}
 
 	fs = getmem(sizeof(*fs));
 	if (!fs) {
-		reiserfs_warning(stderr, "reiserfs_create: getmem failed\n");
+		*error = errno;
 		return NULL;
 	}
 
@@ -224,9 +209,7 @@
 #endif
 	    );
 	if (fs->fs_dev == -1) {
-		reiserfs_warning(stderr,
-				 "reiserfs_create: could not open %s: %s\n",
-				 filename, strerror(errno));
+		*error = errno;
 		freemem(fs);
 		return NULL;
 	}
@@ -245,7 +228,7 @@
 					 block_size, block_size);
 
 	if (!fs->fs_super_bh) {
-		reiserfs_warning(stderr, "reiserfs_create: getblk failed\n");
+		*error = REISERFS_ET_GETBLK_FAILED;
 		return NULL;
 	}
 
@@ -1647,3 +1630,8 @@
 	pathrelse(&path);
 	return ret;
 }
+
+void __attribute__ ((constructor)) init(void)
+{
+	initialize_reiserfs_error_table();
+}
diff --git a/resize_reiserfs/resize_reiserfs.c b/resize_reiserfs/resize_reiserfs.c
index 3f513a6..54ec06a 100644
--- a/resize_reiserfs/resize_reiserfs.c
+++ b/resize_reiserfs/resize_reiserfs.c
@@ -191,7 +191,7 @@
 	struct reiserfs_super_block *sb;
 
 	int c;
-	int error;
+	long error;
 
 	struct reiserfs_super_block *sb_old;
 
@@ -253,7 +253,7 @@
 	if (!fs) {
 		if (error) {
 			reiserfs_exit(1, "cannot open '%s': %s",
-				      devname, strerror(error));
+				      devname, error_message(error));
 		} else {
 			exit(1);
 		}
diff --git a/tune/tune.c b/tune/tune.c
index eed16ec..e860910 100644
--- a/tune/tune.c
+++ b/tune/tune.c
@@ -398,6 +398,7 @@
 	struct reiserfs_journal_header *j_head;
 	reiserfs_trans_t old, new;
 	int Is_journal_or_maxtrans_size_specified = 0;
+	long error;
 
 	program_name = strrchr(argv[0], '/');
 
@@ -560,9 +561,10 @@
 	/* device to be formatted */
 	device_name = argv[optind];
 
-	fs = reiserfs_open(device_name, O_RDONLY, NULL, NULL, 1);
+	fs = reiserfs_open(device_name, O_RDONLY, &error, NULL, 1);
 	if (no_reiserfs_found(fs)) {
-		message("Cannot open reiserfs on %s", device_name);
+		message("Cannot open reiserfs on %s: %s", device_name,
+			error_message(error));
 		return 1;
 	}