Merge branch '4377_file_b'

* 4377_file_b:
  "file" utility: use -b option if available.
  Ticket #4377: file type check does not work with special character in filename.
This commit is contained in:
Andrew Borodin 2022-07-03 15:38:05 +03:00
commit ab63cd2a94
5 changed files with 52 additions and 21 deletions

View File

@ -126,7 +126,7 @@ fi
AC_SUBST(MANDOC) AC_SUBST(MANDOC)
AC_SUBST(MAN_FLAGS) AC_SUBST(MAN_FLAGS)
dnl Check for -z, -L, and -S options to file dnl Check for -z, -b, -L, and -S options to file
AC_CHECK_PROG(HAVE_FILECMD, file, true, false) AC_CHECK_PROG(HAVE_FILECMD, file, true, false)
if $HAVE_FILECMD; then if $HAVE_FILECMD; then
dnl Don't use the file command if it doesn't accept the -z option dnl Don't use the file command if it doesn't accept the -z option
@ -148,7 +148,22 @@ if $HAVE_FILECMD; then
fi fi
if test x$mc_cv_file_z = xyes; then if test x$mc_cv_file_z = xyes; then
dnl file is used; check -L and -S options dnl file is used; check -b, -L and -S options
AC_MSG_CHECKING([for -b option to file command])
AC_CACHE_VAL(mc_cv_file_b, [
file -b . > /dev/null 2>&1
if test $? = 0; then
mc_cv_file_b=yes
else
mc_cv_file_b=no
fi
])
AC_MSG_RESULT([$mc_cv_file_b])
if test x$mc_cv_file_b = xyes; then
AC_DEFINE(FILE_B, "-b ", [Define if the file command accepts the -b option])
fi
AC_MSG_CHECKING([for -L option to file command]) AC_MSG_CHECKING([for -L option to file command])
AC_CACHE_VAL(mc_cv_file_L, [ AC_CACHE_VAL(mc_cv_file_L, [

View File

@ -25,6 +25,8 @@
# #
# type (file matches this if `file %f` matches regular expression desc # type (file matches this if `file %f` matches regular expression desc
# (the filename: part from `file %f` is removed)) # (the filename: part from `file %f` is removed))
# Ignored if the "file" utility isn't used (not found in configure
step or disabled in ini file).
# #
# type/i (file matches this if `file %f` matches regular expression desc) # type/i (file matches this if `file %f` matches regular expression desc)
# The same as type but with case insensitive. # The same as type but with case insensitive.

View File

@ -50,7 +50,9 @@
#include "lib/charsets.h" /* get_codepage_index */ #include "lib/charsets.h" /* get_codepage_index */
#endif #endif
#ifdef USE_FILE_CMD
#include "src/setup.h" /* use_file_to_check_type */ #include "src/setup.h" /* use_file_to_check_type */
#endif
#include "src/execute.h" #include "src/execute.h"
#include "src/history.h" #include "src/history.h"
#include "src/usermenu.h" #include "src/usermenu.h"
@ -72,10 +74,11 @@
/*** file scope macro definitions ****************************************************************/ /*** file scope macro definitions ****************************************************************/
#ifdef USE_FILE_CMD #ifdef USE_FILE_CMD
#define FILE_CMD "file -z " FILE_S FILE_L #ifdef FILE_B
#define FILE_CMD "file -z " FILE_B FILE_S FILE_L
#else #else
/* actually file is unused, but define some reasonable command */ #define FILE_CMD "file -z " FILE_S FILE_L
#define FILE_CMD "file " #endif
#endif #endif
/*** file scope type declarations ****************************************************************/ /*** file scope type declarations ****************************************************************/
@ -540,6 +543,7 @@ exec_extension (WPanel * panel, void *target, const vfs_path_t * filename_vpath,
* NOTES: buf is null-terminated string. * NOTES: buf is null-terminated string.
*/ */
#ifdef USE_FILE_CMD
static int static int
get_popen_information (const char *cmd_file, const char *args, char *buf, int buflen) get_popen_information (const char *cmd_file, const char *args, char *buf, int buflen)
{ {
@ -643,13 +647,9 @@ regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, gboolean c
mc_return_val_if_error (mcerror, FALSE); mc_return_val_if_error (mcerror, FALSE);
if (!use_file_to_check_type)
return FALSE;
if (!*have_type) if (!*have_type)
{ {
vfs_path_t *localfile_vpath; vfs_path_t *localfile_vpath;
const char *realname; /* name used with "file" */
#ifdef HAVE_CHARSET #ifdef HAVE_CHARSET
static char encoding_id[21]; /* CSISO51INISCYRILLIC -- 20 */ static char encoding_id[21]; /* CSISO51INISCYRILLIC -- 20 */
@ -667,7 +667,6 @@ regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, gboolean c
return FALSE; return FALSE;
} }
realname = vfs_path_get_last_path_str (localfile_vpath);
#ifdef HAVE_CHARSET #ifdef HAVE_CHARSET
got_encoding_data = is_autodetect_codeset_enabled got_encoding_data = is_autodetect_codeset_enabled
@ -697,26 +696,32 @@ regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, gboolean c
if (got_data > 0) if (got_data > 0)
{ {
char *pp; char *pp;
size_t real_len;
pp = strchr (content_string, '\n'); pp = strchr (content_string, '\n');
if (pp != NULL) if (pp != NULL)
*pp = '\0'; *pp = '\0';
real_len = strlen (realname); #ifndef FILE_B
if (strncmp (content_string, realname, real_len) == 0)
{ {
/* Skip "realname: " */ const char *real_name; /* name used with "file" */
content_shift = real_len; size_t real_len;
if (content_string[content_shift] == ':')
real_name = vfs_path_get_last_path_str (localfile_vpath);
real_len = strlen (real_name);
if (strncmp (content_string, real_name, real_len) == 0)
{ {
/* Skip "real_name: " */
content_shift = real_len;
/* Solaris' file prints tab(s) after ':' */ /* Solaris' file prints tab(s) after ':' */
for (content_shift++; whitespace (content_string[content_shift]); if (content_string[content_shift] == ':')
content_shift++) for (content_shift++; whitespace (content_string[content_shift]);
; content_shift++)
;
} }
} }
#endif /* FILE_B */
} }
else else
{ {
@ -752,6 +757,7 @@ regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, gboolean c
return found; return found;
} }
#endif /* USE_FILE_CMD */
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/ /*** public functions ****************************************************************************/
@ -792,7 +798,9 @@ regex_command_for (void *target, const vfs_path_t * filename_vpath, const char *
int view_at_line_number = 0; int view_at_line_number = 0;
char *include_target = NULL; char *include_target = NULL;
size_t include_target_len = 0; size_t include_target_len = 0;
#ifdef USE_FILE_CMD
gboolean have_type = FALSE; /* Flag used by regex_check_type() */ gboolean have_type = FALSE; /* Flag used by regex_check_type() */
#endif
if (filename_vpath == NULL) if (filename_vpath == NULL)
return 0; return 0;
@ -961,7 +969,8 @@ regex_command_for (void *target, const vfs_path_t * filename_vpath, const char *
found = TRUE; found = TRUE;
} }
} }
else if (strncmp (p, "type/", 5) == 0) #ifdef USE_FILE_CMD
else if (use_file_to_check_type && strncmp (p, "type/", 5) == 0)
{ {
GError *mcerror = NULL; GError *mcerror = NULL;
@ -975,6 +984,7 @@ regex_command_for (void *target, const vfs_path_t * filename_vpath, const char *
if (mc_error_message (&mcerror, NULL)) if (mc_error_message (&mcerror, NULL))
error_flag = TRUE; /* leave it if file cannot be opened */ error_flag = TRUE; /* leave it if file cannot be opened */
} }
#endif /* USE_FILE_CMD */
else if (strncmp (p, "default/", 8) == 0) else if (strncmp (p, "default/", 8) == 0)
found = TRUE; found = TRUE;

View File

@ -164,8 +164,10 @@ gboolean auto_fill_mkdir_name = TRUE;
/* If set and you don't have subshell support, then C-o will give you a shell */ /* If set and you don't have subshell support, then C-o will give you a shell */
gboolean output_starts_shell = FALSE; gboolean output_starts_shell = FALSE;
#ifdef USE_FILE_CMD
/* If set, we execute the file command to check the file type */ /* If set, we execute the file command to check the file type */
gboolean use_file_to_check_type = TRUE; gboolean use_file_to_check_type = TRUE;
#endif
gboolean verbose = TRUE; gboolean verbose = TRUE;

View File

@ -96,7 +96,9 @@ extern gboolean only_leading_plus_minus;
extern int cd_symlinks; extern int cd_symlinks;
extern gboolean auto_fill_mkdir_name; extern gboolean auto_fill_mkdir_name;
extern gboolean output_starts_shell; extern gboolean output_starts_shell;
#ifdef USE_FILE_CMD
extern gboolean use_file_to_check_type; extern gboolean use_file_to_check_type;
#endif
extern gboolean file_op_compute_totals; extern gboolean file_op_compute_totals;
extern gboolean editor_ask_filename_before_edit; extern gboolean editor_ask_filename_before_edit;