util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sami Kerola <kerolasa@iki.fi>
To: util-linux@vger.kernel.org
Cc: Sami Kerola <kerolasa@iki.fi>
Subject: [PATCH 1/2] more: use libmagic to identify binary files
Date: Wed,  6 May 2020 20:19:22 +0100	[thread overview]
Message-ID: <20200506191923.5272-2-kerolasa@iki.fi> (raw)
In-Reply-To: <20200506191923.5272-1-kerolasa@iki.fi>

As the old commend said: 'This code would best be shared with the file(1)
program or, perhaps, more should not try to be so smart'.  Now at configure
time one can choose whether more(1) is sharing code with file(1), or not.

Addresses: http://bugs.debian.org/139205
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 configure.ac             | 12 ++++++++++
 text-utils/Makemodule.am |  2 +-
 text-utils/more.c        | 52 +++++++++++++++++++++++++---------------
 3 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/configure.ac b/configure.ac
index 1428dc893..8f50e8102 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1501,6 +1501,18 @@ AS_IF([test "x$with_libz" = xno], [have_z=no], [
   AC_CHECK_LIB([z], [crc32], [have_z=yes], [have_z=no])
 ])
 
+AC_ARG_WITH([libmagic],
+  AS_HELP_STRING([--without-libmagic], [compile without libmagic]),
+  [], [with_libmagic=auto]
+)
+AS_IF([test "x$with_libmagic" = xno], [have_magic=no], [
+  AC_CHECK_LIB([magic], [magic_open], [
+    AC_DEFINE([HAVE_MAGIC], [1], [Define to 1 if you have the libmagic present.])
+    MAGIC_LIBS="-lmagic"
+  ])
+])
+AC_SUBST([MAGIC_LIBS])
+
 
 AC_ARG_ENABLE([cramfs],
   AS_HELP_STRING([--disable-cramfs], [do not build fsck.cramfs, mkfs.cramfs]),
diff --git a/text-utils/Makemodule.am b/text-utils/Makemodule.am
index 3f10934e9..6c4b52082 100644
--- a/text-utils/Makemodule.am
+++ b/text-utils/Makemodule.am
@@ -80,7 +80,7 @@ bin_PROGRAMS += more
 dist_man_MANS += text-utils/more.1
 more_SOURCES = text-utils/more.c
 more_CFLAGS = $(AM_CFLAGS) $(BSD_WARN_CFLAGS)
-more_LDADD = $(LDADD) libcommon.la
+more_LDADD = $(LDADD) $(MAGIC_LIBS) libcommon.la
 if HAVE_TINFO
 more_LDADD += $(TINFO_LIBS)
 more_LDADD += $(TINFO_CFLAGS)
diff --git a/text-utils/more.c b/text-utils/more.c
index 69a0b89f6..014b40a6c 100644
--- a/text-utils/more.c
+++ b/text-utils/more.c
@@ -74,13 +74,17 @@
 # include <term.h>
 #endif
 
-#include "env.h"
+#ifdef HAVE_MAGIC
+# include <magic.h>
+#endif
+
 #include "strutils.h"
 #include "nls.h"
 #include "xalloc.h"
 #include "widechar.h"
 #include "closestream.h"
 #include "rpmatch.h"
+#include "env.h"
 
 #ifdef TEST_PROGRAM
 # define NON_INTERACTIVE_MORE 1
@@ -157,6 +161,9 @@ struct more_control {
 	int last_key_arg;		/* previous key command argument */
 	int last_colon_command;		/* is a colon-prefixed key command */
 	char *shell_line;		/* line to execute in subshell */
+#ifdef HAVE_MAGIC
+	magic_t magic;			/* libmagic database entries */
+#endif
 	unsigned int
 		bad_stdout:1,		/* true if overwriting does not turn off standout */
 		catch_suspend:1,	/* we should catch the SIGTSTP signal */
@@ -350,19 +357,24 @@ static void print_separator(const int c, int n)
 	putchar('\n');
 }
 
-/* magic --
- *	check for file magic numbers.  This code would best be shared
- *	with the file(1) program or, perhaps, more should not try to be
- *	so smart. */
-static int check_magic(FILE *f, char *fs)
+/* check_magic -- check for file magic numbers. */
+static int check_magic(struct more_control *ctl, char *fs)
 {
+#ifdef HAVE_MAGIC
+	const char *mime_encoding = magic_descriptor(ctl->magic, fileno(ctl->current_file));
+
+	if (!mime_encoding || !(strcmp("binary", mime_encoding))) {
+		printf(_("\n******** %s: Not a text file ********\n\n"), fs);
+		return 1;
+	}
+#else
 	signed char twobytes[2];
 
 	/* don't try to look ahead if the input is unseekable */
-	if (fseek(f, 0L, SEEK_SET))
+	if (fseek(ctl->current_file, 0L, SEEK_SET))
 		return 0;
 
-	if (fread(twobytes, 2, 1, f) == 1) {
+	if (fread(twobytes, 2, 1, ctl->current_file) == 1) {
 		switch (twobytes[0] + (twobytes[1] << 8)) {
 		case 0407:	/* a.out obj */
 		case 0410:	/* a.out exec */
@@ -376,7 +388,8 @@ static int check_magic(FILE *f, char *fs)
 			return 1;
 		}
 	}
-	fseek(f, 0L, SEEK_SET);	/* rewind() not necessary */
+	fseek(ctl->current_file, 0L, SEEK_SET);	/* rewind() not necessary */
+#endif
 	return 0;
 }
 
@@ -394,23 +407,17 @@ static void checkf(struct more_control *ctl, char *fs)
 	    (fstat(fileno(ctl->current_file), &st) != 0)) {
 		if (ctl->clear_line_ends)
 			putp(ctl->erase_line);
-		warn(_("stat of %s failed"), fs);
-		ctl->current_file = NULL;
+		warn(_("cannot open %s"), fs);
 		return;
 	}
+#ifndef HAVE_MAGIC
 	if ((st.st_mode & S_IFMT) == S_IFDIR) {
 		printf(_("\n*** %s: directory ***\n\n"), fs);
 		ctl->current_file = NULL;
 		return;
 	}
-	ctl->current_line = 0;
-	ctl->file_position = 0;
-	if ((ctl->current_file = fopen(fs, "r")) == NULL) {
-		fflush(stdout);
-		warn(_("cannot open %s"), fs);
-		return;
-	}
-	if (check_magic(ctl->current_file, fs)) {
+#endif
+	if (check_magic(ctl, fs)) {
 		fclose(ctl->current_file);
 		ctl->current_file = NULL;
 		return;
@@ -704,6 +711,9 @@ static void reset_tty(struct more_control *ctl)
 /* Clean up terminal state and exit. Also come here if interrupt signal received */
 static void __attribute__((__noreturn__)) more_exit(struct more_control *ctl)
 {
+#ifdef HAVE_MAGIC
+	magic_close(ctl->magic);
+#endif
 	reset_tty(ctl);
 	if (ctl->clear_line_ends) {
 		putchar('\r');
@@ -1906,6 +1916,10 @@ int main(int argc, char **argv)
 
 	initterm(&ctl);
 
+#ifdef HAVE_MAGIC
+	ctl.magic = magic_open(MAGIC_MIME_ENCODING | MAGIC_SYMLINK);
+	magic_load(ctl.magic, NULL);
+#endif
 	prepare_line_buffer(&ctl);
 
 	ctl.d_scroll_len = ctl.lines_per_page / 2 - 1;
-- 
2.26.2


  reply	other threads:[~2020-05-06 19:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-06 19:19 [PATCH 0/2] more(1) use libmagic and make page up/down and arrow keys work Sami Kerola
2020-05-06 19:19 ` Sami Kerola [this message]
2020-05-06 19:19 ` [PATCH 2/2] more: make page and arrow up/down to update view Sami Kerola
2020-05-12  8:53 ` [PATCH 0/2] more(1) use libmagic and make page up/down and arrow keys work Karel Zak
2020-05-12 13:45   ` Sami Kerola

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200506191923.5272-2-kerolasa@iki.fi \
    --to=kerolasa@iki.fi \
    --cc=util-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).