📄 ext.c
字号:
/* Extension dependent execution.
Copyright (C) 1994, 1995 The Free Software Foundation
Written by: 1995 Jakub Jelinek
1994 Miguel de Icaza
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <config.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#ifdef __os2__
# include <io.h>
#endif
#include "tty.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include <malloc.h>
#include <string.h>
#include <errno.h>
#include "mad.h"
#include "user.h"
#include "main.h"
#include "fs.h"
#include "util.h"
#include "dialog.h"
#include "global.h"
#include "ext.h"
#include "view.h"
#include "main.h"
#include "../vfs/vfs.h"
#include "x.h"
#include "cons.saver.h"
#include "layout.h"
#ifdef SCO_FLAVOR
#include <sys/wait.h>
#endif /* SCO_FLAVOR */
/* "$Id: ext.c 15091 2005-05-07 21:24:31Z sedwards $" */
/* If set, we execute the file command to check the file type */
int use_file_to_check_type = 1;
/* This variable points to a copy of the mc.ext file in memory
* With this we avoid loading/parsing the file each time we
* need it
*/
static char *data = NULL;
#ifdef OS2_NT
__declspec(dllimport) __stdcall unsigned GetTempPathA(unsigned,char*);
static char tmpcmdfilename[255];
char *gettmpcmdname(){
int i,fd;
char TmpPath[255];
memset(TmpPath,0,255);
memset(tmpcmdfilename,0,255);
GetTempPathA(255,TmpPath);
for(i=0;i<32000;++i){
sprintf(tmpcmdfilename,"%stmp%d.bat",TmpPath,i);
if((fd=_open(tmpcmdfilename,_O_RDONLY)) != -1)
_close(fd);
else if (errno == ENOENT)
break;
}
return tmpcmdfilename;
}
#endif
void
flush_extension_file (void)
{
if (data){
free (data);
data = NULL;
}
}
typedef char *(*quote_func_t)(const char *name, int i);
static char *
quote_block (quote_func_t quote_func, char **quoting_block)
{
char **p = quoting_block;
char *result = 0;
char *tail = 0;
int current_len = 0;
for (p = quoting_block; *p; p++){
int temp_len;
char *temp = quote_func (*p, 0);
temp_len = strlen (temp);
current_len += temp_len + 2;
result = realloc (result, current_len);
if (!tail)
tail = result;
strcpy (tail, temp);
strcat (tail, " ");
tail += temp_len + 1;
free (temp);
}
return result;
}
static void
exec_extension (char *filename, char *data, char **drops, int *move_dir, int start_line)
{
char *file_name;
int cmd_file_fd;
FILE *cmd_file;
int expand_prefix_found = 0;
int parameter_found = 0;
char prompt [80];
int run_view = 0;
int def_hex_mode = default_hex_mode, changed_hex_mode = 0;
int def_nroff_flag = default_nroff_flag, changed_nroff_flag = 0;
int written_nonspace = 0;
int is_cd = 0;
char buffer [1024];
char *p = 0;
char *localcopy = NULL;
int do_local_copy;
time_t localmtime = 0;
struct stat mystat;
quote_func_t quote_func = name_quote;
/* Avoid making a local copy if we are doing a cd */
if (!vfs_file_is_local(filename))
do_local_copy = 1;
else
do_local_copy = 0;
/* Note: this has to be done after the getlocalcopy call,
* since it uses tmpnam as well
*/
#ifdef OS2_NT
file_name = strdup (gettmpcmdname ());
#else
file_name = strdup (tmpnam (NULL));
#endif
if ((cmd_file_fd = open (file_name, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600)) == -1){
message (1, MSG_ERROR, _(" Can't create temporary command file \n %s "),
unix_error_string (errno));
return;
}
cmd_file = fdopen (cmd_file_fd, "w");
#ifdef OS2_NT
fprintf (cmd_file, "REM #!%s\n", shell);
#else
fprintf (cmd_file, "#!%s\n", shell);
#endif
prompt [0] = 0;
for (;*data && *data != '\n'; data++){
if (parameter_found){
if (*data == '}'){
char *parameter;
parameter_found = 0;
parameter = input_dialog (_(" Parameter "), prompt, "");
if (!parameter){
/* User canceled */
fclose (cmd_file);
unlink (file_name);
if (localcopy) {
mc_ungetlocalcopy (filename, localcopy, 0);
}
free (file_name);
return;
}
fputs (parameter, cmd_file);
written_nonspace = 1;
free (parameter);
} else {
int len = strlen (prompt);
if (len < sizeof (prompt) - 1){
prompt [len] = *data;
prompt [len+1] = 0;
}
}
} else if (expand_prefix_found){
expand_prefix_found = 0;
if (*data == '{')
parameter_found = 1;
else {
int i = check_format_view (data);
char *v;
if (i){
data += i - 1;
run_view = 1;
} else if ((i = check_format_cd (data)) > 0) {
is_cd = 1;
quote_func = fake_name_quote;
do_local_copy = 0;
p = buffer;
data += i - 1;
} else if ((i = check_format_var (data, &v)) > 0 && v){
fputs (v, cmd_file);
free (v);
data += i;
} else {
char *text;
if (*data == 'f'){
if (do_local_copy){
localcopy = mc_getlocalcopy (filename);
if (localcopy == NULL) {
fclose(cmd_file);
unlink(file_name);
free(file_name);
return;
}
mc_stat (localcopy, &mystat);
localmtime = mystat.st_mtime;
text = (*quote_func) (localcopy, 0);
} else {
text = (*quote_func) (filename, 0);
}
} else if (*data == 'q') {
text = quote_block (quote_func, drops);
} else
text = expand_format (*data, !is_cd);
if (!is_cd)
fputs (text, cmd_file);
else {
strcpy (p, text);
p = strchr (p, 0);
}
free (text);
written_nonspace = 1;
}
}
} else {
if (*data == '%')
expand_prefix_found = 1;
else {
if (*data != ' ' && *data != '\t')
written_nonspace = 1;
if (is_cd)
*(p++) = *data;
else
fputc (*data, cmd_file);
}
}
} /* for */
fputc ('\n', cmd_file);
fclose (cmd_file);
chmod (file_name, S_IRWXU);
if (run_view){
altered_hex_mode = 0;
altered_nroff_flag = 0;
if (def_hex_mode != default_hex_mode)
changed_hex_mode = 1;
if (def_nroff_flag != default_nroff_flag)
changed_nroff_flag = 1;
/* If we've written whitespace only, then just load filename
* into view
*/
if (written_nonspace)
view (file_name, filename, move_dir, start_line);
else
view (0, filename, move_dir, start_line);
if (changed_hex_mode && !altered_hex_mode)
default_hex_mode = def_hex_mode;
if (changed_nroff_flag && !altered_nroff_flag)
default_nroff_flag = def_nroff_flag;
repaint_screen ();
} else if (is_cd) {
char *q;
*p = 0;
p = buffer;
while (*p == ' ' && *p == '\t')
p++;
/* Search last non-space character. Start search at the end in order
not to short filenames containing spaces. */
q = p + strlen (p) - 1;
while (q >= p && (*q == ' ' || *q == '\t'))
q--;
q[1] = 0;
do_cd (p, cd_parse_command);
} else {
shell_execute (file_name, EXECUTE_INTERNAL | EXECUTE_TEMPFILE);
if (console_flag)
{
handle_console (CONSOLE_SAVE);
if (output_lines && keybar_visible)
{
show_console_contents (output_start_y,
LINES-keybar_visible-output_lines-1,
LINES-keybar_visible-1);
}
}
#ifdef OLD_CODE
if (vfs_current_is_local ())
shell_execute (file_name, EXECUTE_INTERNAL);
else
message (1, _(" Warning "), _(" Can't execute commands on a Virtual File System directory "));
#endif
}
#ifndef PORT_DOES_BACKGROUND_EXEC
unlink (file_name);
#endif
if (localcopy) {
mc_stat (localcopy, &mystat);
mc_ungetlocalcopy (filename, localcopy, localmtime != mystat.st_mtime);
}
free (file_name);
}
#ifdef FILE_L
# define FILE_CMD "file -L "
#else
# define FILE_CMD "file "
#endif
/* The second argument is action, i.e. Open, View, Edit, Drop, or NULL if
* we want regex_command to return a list of all user defined actions.
* Third argument is space separated list of dropped files (for actions
* other then Drop it should be NULL);
*
* This function returns:
*
* If action != NULL, then it returns "Success" (not allocated) if it ran
* some command or NULL if not.
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -