mirror of
https://github.com/weechat/weechat.git
synced 2026-07-01 15:26:37 +02:00
exec: add options "-pipe" and "-hsignal" in command /exec
This commit is contained in:
@@ -179,7 +179,7 @@ exec_command_parse_options (struct t_exec_cmd_options *cmd_options,
|
||||
int argc, char **argv, int start_arg,
|
||||
int set_command_index)
|
||||
{
|
||||
int i;
|
||||
int i, j, end, length, length_total;
|
||||
char *error;
|
||||
|
||||
for (i = start_arg; i < argc; i++)
|
||||
@@ -289,6 +289,62 @@ exec_command_parse_options (struct t_exec_cmd_options *cmd_options,
|
||||
i++;
|
||||
cmd_options->ptr_command_name = argv[i];
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[i], "-pipe") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
return 0;
|
||||
i++;
|
||||
if (cmd_options->pipe_command)
|
||||
{
|
||||
free (cmd_options->pipe_command);
|
||||
cmd_options->pipe_command = NULL;
|
||||
}
|
||||
if (argv[i][0] == '"')
|
||||
{
|
||||
/* search the ending double quote */
|
||||
length_total = 1;
|
||||
end = i;
|
||||
while (end < argc)
|
||||
{
|
||||
length = strlen (argv[end]);
|
||||
length_total += length + 1;
|
||||
if ((length > 0) && (argv[end][length - 1] == '"'))
|
||||
break;
|
||||
end++;
|
||||
}
|
||||
if (end == argc)
|
||||
return 0;
|
||||
cmd_options->pipe_command = malloc (length_total);
|
||||
if (!cmd_options->pipe_command)
|
||||
return 0;
|
||||
cmd_options->pipe_command[0] = '\0';
|
||||
for (j = i; j <= end; j++)
|
||||
{
|
||||
if (cmd_options->pipe_command[0])
|
||||
strcat (cmd_options->pipe_command, " ");
|
||||
strcat (cmd_options->pipe_command,
|
||||
(j == i) ? argv[j] + 1 : argv[j]);
|
||||
}
|
||||
length = strlen (cmd_options->pipe_command);
|
||||
if (length > 0)
|
||||
cmd_options->pipe_command[length - 1] = '\0';
|
||||
i = end;
|
||||
}
|
||||
else
|
||||
cmd_options->pipe_command = strdup (argv[i]);
|
||||
}
|
||||
else if (weechat_strcasecmp (argv[i], "-hsignal") == 0)
|
||||
{
|
||||
if (i + 1 >= argc)
|
||||
return 0;
|
||||
i++;
|
||||
if (cmd_options->hsignal)
|
||||
{
|
||||
free (cmd_options->hsignal);
|
||||
cmd_options->hsignal = NULL;
|
||||
}
|
||||
cmd_options->hsignal = strdup (argv[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (set_command_index)
|
||||
@@ -338,6 +394,8 @@ exec_command_run (struct t_gui_buffer *buffer,
|
||||
cmd_options.color = EXEC_COLOR_DECODE;
|
||||
cmd_options.display_rc = 1;
|
||||
cmd_options.ptr_command_name = NULL;
|
||||
cmd_options.pipe_command = NULL;
|
||||
cmd_options.hsignal = NULL;
|
||||
|
||||
/* parse default options */
|
||||
if (!exec_command_parse_options (&cmd_options,
|
||||
@@ -359,6 +417,12 @@ exec_command_run (struct t_gui_buffer *buffer,
|
||||
&& (cmd_options.output_to_buffer || cmd_options.new_buffer))
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
/* options "-pipe" and "-bg"/"-o"/"-n" are incompatible */
|
||||
if (cmd_options.pipe_command
|
||||
&& (cmd_options.detached || cmd_options.output_to_buffer
|
||||
|| cmd_options.new_buffer))
|
||||
return WEECHAT_RC_ERROR;
|
||||
|
||||
/* command not found? */
|
||||
if (cmd_options.command_index < 0)
|
||||
return WEECHAT_RC_ERROR;
|
||||
@@ -398,7 +462,9 @@ exec_command_run (struct t_gui_buffer *buffer,
|
||||
strdup (cmd_options.ptr_command_name) : NULL;
|
||||
new_exec_cmd->command = strdup (argv_eol[cmd_options.command_index]);
|
||||
new_exec_cmd->detached = cmd_options.detached;
|
||||
if (!cmd_options.detached)
|
||||
|
||||
if (!cmd_options.detached && !cmd_options.pipe_command
|
||||
&& !cmd_options.hsignal)
|
||||
{
|
||||
if (cmd_options.ptr_buffer_name && !cmd_options.ptr_buffer)
|
||||
{
|
||||
@@ -454,6 +520,8 @@ exec_command_run (struct t_gui_buffer *buffer,
|
||||
cmd_options.new_buffer : cmd_options.line_numbers;
|
||||
new_exec_cmd->color = cmd_options.color;
|
||||
new_exec_cmd->display_rc = cmd_options.display_rc;
|
||||
new_exec_cmd->pipe_command = cmd_options.pipe_command;
|
||||
new_exec_cmd->hsignal = cmd_options.hsignal;
|
||||
|
||||
/* execute the command */
|
||||
if (weechat_exec_plugin->debug >= 1)
|
||||
@@ -685,7 +753,8 @@ exec_command_init ()
|
||||
N_("-list"
|
||||
" || [-sh|-nosh] [-bg|-nobg] [-stdin|-nostdin] [-buffer <name>] "
|
||||
"[-l|-o|-n] |-sw|-nosw] [-ln|-noln] [-color off|decode|strip] "
|
||||
"[-rc|-norc] [-timeout <timeout>] [-name <name>] <command>"
|
||||
"[-rc|-norc] [-timeout <timeout>] [-name <name>] "
|
||||
"[-pipe <command>] [-hsignal <name>] <command>"
|
||||
" || -in <id> <text>"
|
||||
" || -inclose <id> [<text>]"
|
||||
" || -signal <id> <signal>"
|
||||
@@ -724,6 +793,13 @@ exec_command_init ()
|
||||
" -norc: don't display return code\n"
|
||||
"-timeout: set a timeout for the command (in seconds)\n"
|
||||
" -name: set a name for the command (to name it later with /exec)\n"
|
||||
" -pipe: send the output to a WeeChat/plugin command (line by "
|
||||
"line); if there are spaces in command/arguments, enclose them with "
|
||||
"double quotes; variable $line is replaced by the line (by default "
|
||||
"the line is added after the command, separated by a space) "
|
||||
"(not compatible with options -bg/-o/-n)\n"
|
||||
"-hsignal: send the output as a hsignal (to be used for example in "
|
||||
"a trigger) (not compatible with options -bg/-o/-n)\n"
|
||||
" command: the command to execute; if beginning with \"url:\", the "
|
||||
"shell is disabled and the content of URL is downloaded and sent as "
|
||||
"output\n"
|
||||
@@ -753,7 +829,7 @@ exec_command_init ()
|
||||
" /exec -o uptime"),
|
||||
"-list"
|
||||
" || -sh|-nosh|-bg|-nobg|-stdin|-nostdin|-buffer|-l|-o|-n|-sw|-nosw|"
|
||||
"-ln|-noln|-color|-timeout|-name|%*"
|
||||
"-ln|-noln|-color|-timeout|-name|-pipe|-hsignal|%*"
|
||||
" || -in|-inclose|-signal|-kill %(exec_commands_ids)"
|
||||
" || -killall"
|
||||
" || -set %(exec_commands_ids) stdin|stdin_close|signal"
|
||||
|
||||
@@ -36,6 +36,8 @@ struct t_exec_cmd_options
|
||||
int color; /* what to do with ANSI colors */
|
||||
int display_rc; /* 1 to display return code */
|
||||
const char *ptr_command_name; /* name of command */
|
||||
char *pipe_command; /* output piped to WeeChat/plugin cmd*/
|
||||
char *hsignal; /* send a hsignal with output */
|
||||
};
|
||||
|
||||
extern int exec_command_run (struct t_gui_buffer *buffer,
|
||||
|
||||
+127
-47
@@ -158,6 +158,8 @@ exec_add ()
|
||||
new_exec_cmd->err_size = 0;
|
||||
new_exec_cmd->err = NULL;
|
||||
new_exec_cmd->return_code = -1;
|
||||
new_exec_cmd->pipe_command = NULL;
|
||||
new_exec_cmd->hsignal = NULL;
|
||||
|
||||
exec_cmds_count++;
|
||||
|
||||
@@ -198,7 +200,7 @@ exec_timer_delete_cb (void *data, int remaining_calls)
|
||||
*/
|
||||
|
||||
void
|
||||
exec_command_concat_output (int *size, char **output, const char *text)
|
||||
exec_concat_output (int *size, char **output, const char *text)
|
||||
{
|
||||
int length, new_size;
|
||||
char *new_output;
|
||||
@@ -214,13 +216,35 @@ exec_command_concat_output (int *size, char **output, const char *text)
|
||||
*size = new_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decodes colors in a string (from stdout/stderr).
|
||||
*
|
||||
* Returns string with colors as-is, decoded or removed.
|
||||
*/
|
||||
|
||||
char *
|
||||
exec_decode_color (struct t_exec_cmd *exec_cmd, const char *string)
|
||||
{
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
if (exec_cmd->color == EXEC_COLOR_ANSI)
|
||||
return strdup (string);
|
||||
|
||||
return weechat_hook_modifier_exec (
|
||||
(exec_cmd->output_to_buffer || exec_cmd->pipe_command) ?
|
||||
"irc_color_decode_ansi" : "color_decode_ansi",
|
||||
(exec_cmd->color == EXEC_COLOR_DECODE) ? "1" : "0",
|
||||
string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Displays output of a command.
|
||||
*/
|
||||
|
||||
void
|
||||
exec_command_display_output (struct t_exec_cmd *exec_cmd,
|
||||
struct t_gui_buffer *buffer, int out)
|
||||
exec_display_output (struct t_exec_cmd *exec_cmd,
|
||||
struct t_gui_buffer *buffer, int out)
|
||||
{
|
||||
char *ptr_output, *ptr_line, *line, *line2, *pos;
|
||||
char str_number[32], str_tags[1024];
|
||||
@@ -234,7 +258,7 @@ exec_command_display_output (struct t_exec_cmd *exec_cmd,
|
||||
* if output is sent to the buffer, the buffer must exist
|
||||
* (we don't send output by default to core buffer)
|
||||
*/
|
||||
if (exec_cmd->output_to_buffer && !buffer)
|
||||
if (exec_cmd->output_to_buffer && !exec_cmd->pipe_command && !buffer)
|
||||
return;
|
||||
|
||||
ptr_line = ptr_output;
|
||||
@@ -252,20 +276,40 @@ exec_command_display_output (struct t_exec_cmd *exec_cmd,
|
||||
if (!line)
|
||||
break;
|
||||
|
||||
if (exec_cmd->color != EXEC_COLOR_ANSI)
|
||||
{
|
||||
line2 = weechat_hook_modifier_exec (
|
||||
(exec_cmd->output_to_buffer) ?
|
||||
"irc_color_decode_ansi" : "color_decode_ansi",
|
||||
(exec_cmd->color == EXEC_COLOR_DECODE) ? "1" : "0",
|
||||
line);
|
||||
free (line);
|
||||
if (!line2)
|
||||
break;
|
||||
line = line2;
|
||||
}
|
||||
/* decode colors */
|
||||
line2 = exec_decode_color (exec_cmd, line);
|
||||
free (line);
|
||||
if (!line2)
|
||||
break;
|
||||
line = line2;
|
||||
|
||||
if (exec_cmd->output_to_buffer)
|
||||
if (exec_cmd->pipe_command)
|
||||
{
|
||||
if (strstr (exec_cmd->pipe_command, "$line"))
|
||||
{
|
||||
/* replace $line by line content */
|
||||
line2 = weechat_string_replace (exec_cmd->pipe_command,
|
||||
"$line", line);
|
||||
if (line2)
|
||||
{
|
||||
weechat_command (buffer, line2);
|
||||
free (line2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add line at the end of command, after a space */
|
||||
length = strlen (exec_cmd->pipe_command) + 1 + strlen (line) + 1;
|
||||
line2 = malloc (length);
|
||||
if (line2)
|
||||
{
|
||||
snprintf (line2, length, "%s %s", exec_cmd->pipe_command, line);
|
||||
weechat_command (buffer, line2);
|
||||
free (line2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (exec_cmd->output_to_buffer)
|
||||
{
|
||||
if (exec_cmd->line_numbers)
|
||||
{
|
||||
@@ -310,35 +354,65 @@ void
|
||||
exec_end_command (struct t_exec_cmd *exec_cmd, int return_code)
|
||||
{
|
||||
struct t_gui_buffer *ptr_buffer;
|
||||
struct t_hashtable *hashtable;
|
||||
char str_number[32], *output;
|
||||
|
||||
ptr_buffer = weechat_buffer_search ("==", exec_cmd->buffer_full_name);
|
||||
|
||||
/* display stdout/stderr (if output to buffer, the buffer must exist) */
|
||||
exec_command_display_output (exec_cmd, ptr_buffer, 1);
|
||||
exec_command_display_output (exec_cmd, ptr_buffer, 0);
|
||||
|
||||
/*
|
||||
* display return code (only if command is not detached and if output is
|
||||
* NOT sent to buffer)
|
||||
*/
|
||||
if (!exec_cmd->detached && !exec_cmd->output_to_buffer
|
||||
&& exec_cmd->display_rc)
|
||||
if (exec_cmd->hsignal)
|
||||
{
|
||||
if (return_code >= 0)
|
||||
hashtable = weechat_hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL,
|
||||
NULL);
|
||||
if (hashtable)
|
||||
{
|
||||
weechat_printf_tags (ptr_buffer, "exec_rc",
|
||||
_("%s: end of command %d (\"%s\"), "
|
||||
"return code: %d"),
|
||||
EXEC_PLUGIN_NAME, exec_cmd->number,
|
||||
exec_cmd->command, return_code);
|
||||
weechat_hashtable_set (hashtable, "command", exec_cmd->command);
|
||||
snprintf (str_number, sizeof (str_number), "%d", exec_cmd->number);
|
||||
weechat_hashtable_set (hashtable, "number", str_number);
|
||||
weechat_hashtable_set (hashtable, "name", exec_cmd->name);
|
||||
output = exec_decode_color (exec_cmd, exec_cmd->out);
|
||||
weechat_hashtable_set (hashtable, "out", output);
|
||||
if (output)
|
||||
free (output);
|
||||
output = exec_decode_color (exec_cmd, exec_cmd->err);
|
||||
weechat_hashtable_set (hashtable, "err", output);
|
||||
if (output)
|
||||
free (output);
|
||||
weechat_hook_hsignal_send (exec_cmd->hsignal, hashtable);
|
||||
weechat_hashtable_free (hashtable);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_buffer = weechat_buffer_search ("==", exec_cmd->buffer_full_name);
|
||||
|
||||
exec_display_output (exec_cmd, ptr_buffer, 1);
|
||||
exec_display_output (exec_cmd, ptr_buffer, 0);
|
||||
|
||||
/*
|
||||
* display return code (only if command is not detached, if output is
|
||||
* NOT sent to buffer, and if command is not piped)
|
||||
*/
|
||||
if (exec_cmd->display_rc
|
||||
&& !exec_cmd->detached && !exec_cmd->output_to_buffer
|
||||
&& !exec_cmd->pipe_command)
|
||||
{
|
||||
weechat_printf_tags (ptr_buffer, "exec_rc",
|
||||
_("%s: unexpected end of command %d "
|
||||
"(\"%s\")"),
|
||||
EXEC_PLUGIN_NAME, exec_cmd->number,
|
||||
exec_cmd->command);
|
||||
if (return_code >= 0)
|
||||
{
|
||||
weechat_printf_tags (ptr_buffer, "exec_rc",
|
||||
_("%s: end of command %d (\"%s\"), "
|
||||
"return code: %d"),
|
||||
EXEC_PLUGIN_NAME, exec_cmd->number,
|
||||
exec_cmd->command, return_code);
|
||||
}
|
||||
else
|
||||
{
|
||||
weechat_printf_tags (ptr_buffer, "exec_rc",
|
||||
_("%s: unexpected end of command %d "
|
||||
"(\"%s\")"),
|
||||
EXEC_PLUGIN_NAME, exec_cmd->number,
|
||||
exec_cmd->command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,15 +468,15 @@ exec_process_cb (void *data, const char *command, int return_code,
|
||||
|
||||
if (out)
|
||||
{
|
||||
exec_command_concat_output (&ptr_exec_cmd->out_size,
|
||||
&ptr_exec_cmd->out,
|
||||
out);
|
||||
exec_concat_output (&ptr_exec_cmd->out_size,
|
||||
&ptr_exec_cmd->out,
|
||||
out);
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
exec_command_concat_output (&ptr_exec_cmd->err_size,
|
||||
&ptr_exec_cmd->err,
|
||||
err);
|
||||
exec_concat_output (&ptr_exec_cmd->err_size,
|
||||
&ptr_exec_cmd->err,
|
||||
err);
|
||||
}
|
||||
|
||||
if (return_code >= 0)
|
||||
@@ -444,6 +518,10 @@ exec_free (struct t_exec_cmd *exec_cmd)
|
||||
free (exec_cmd->out);
|
||||
if (exec_cmd->err)
|
||||
free (exec_cmd->err);
|
||||
if (exec_cmd->pipe_command)
|
||||
free (exec_cmd->pipe_command);
|
||||
if (exec_cmd->hsignal)
|
||||
free (exec_cmd->hsignal);
|
||||
|
||||
free (exec_cmd);
|
||||
|
||||
@@ -494,6 +572,8 @@ exec_print_log ()
|
||||
weechat_log_printf (" err_size. . . . . . . . : %d", ptr_exec_cmd->err_size);
|
||||
weechat_log_printf (" err . . . . . . . . . . : '%s'", ptr_exec_cmd->err);
|
||||
weechat_log_printf (" return_code . . . . . . : %d", ptr_exec_cmd->return_code);
|
||||
weechat_log_printf (" pipe_command. . . . . . : '%s'", ptr_exec_cmd->pipe_command);
|
||||
weechat_log_printf (" hsignal . . . . . . . . : '%s'", ptr_exec_cmd->hsignal);
|
||||
weechat_log_printf (" prev_cmd. . . . . . . . : 0x%lx", ptr_exec_cmd->prev_cmd);
|
||||
weechat_log_printf (" next_cmd. . . . . . . . : 0x%lx", ptr_exec_cmd->next_cmd);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,10 @@ struct t_exec_cmd
|
||||
char *err; /* stderr of command */
|
||||
int return_code; /* command return code */
|
||||
|
||||
/* pipe/hsignal */
|
||||
char *pipe_command; /* output piped to WeeChat/plugin cmd*/
|
||||
char *hsignal; /* send a hsignal with output */
|
||||
|
||||
struct t_exec_cmd *prev_cmd; /* link to previous command */
|
||||
struct t_exec_cmd *next_cmd; /* link to next command */
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user