version 1.60, 2018/08/27 11:03:34 |
version 1.61, 2019/05/23 11:13:30 |
|
|
}; |
}; |
|
|
struct cmd_if_shell_data { |
struct cmd_if_shell_data { |
char *file; |
struct cmd_parse_input input; |
u_int line; |
|
|
|
char *cmd_if; |
char *cmd_if; |
char *cmd_else; |
char *cmd_else; |
|
|
cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) |
cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) |
{ |
{ |
struct args *args = self->args; |
struct args *args = self->args; |
struct cmdq_shared *shared = item->shared; |
struct mouse_event *m = &item->shared->mouse; |
struct cmd_if_shell_data *cdata; |
struct cmd_if_shell_data *cdata; |
char *shellcmd, *cmd, *cause; |
char *shellcmd, *cmd; |
struct cmd_list *cmdlist; |
|
struct cmdq_item *new_item; |
struct cmdq_item *new_item; |
struct client *c = cmd_find_client(item, NULL, 1); |
struct client *c = cmd_find_client(item, NULL, 1); |
struct session *s = item->target.s; |
struct session *s = item->target.s; |
struct winlink *wl = item->target.wl; |
struct winlink *wl = item->target.wl; |
struct window_pane *wp = item->target.wp; |
struct window_pane *wp = item->target.wp; |
|
struct cmd_parse_input pi; |
|
struct cmd_parse_result *pr; |
|
|
shellcmd = format_single(item, args->argv[0], c, s, wl, wp); |
shellcmd = format_single(item, args->argv[0], c, s, wl, wp); |
if (args_has(args, 'F')) { |
if (args_has(args, 'F')) { |
cmd = NULL; |
|
if (*shellcmd != '0' && *shellcmd != '\0') |
if (*shellcmd != '0' && *shellcmd != '\0') |
cmd = args->argv[1]; |
cmd = args->argv[1]; |
else if (args->argc == 3) |
else if (args->argc == 3) |
cmd = args->argv[2]; |
cmd = args->argv[2]; |
|
else |
|
cmd = NULL; |
free(shellcmd); |
free(shellcmd); |
if (cmd == NULL) |
if (cmd == NULL) |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
cmdlist = cmd_string_parse(cmd, NULL, 0, &cause); |
|
if (cmdlist == NULL) { |
memset(&pi, 0, sizeof pi); |
if (cause != NULL) { |
if (self->file != NULL) |
cmdq_error(item, "%s", cause); |
pi.file = self->file; |
free(cause); |
pi.line = self->line; |
} |
pi.item = item; |
|
pi.c = c; |
|
cmd_find_copy_state(&pi.fs, &item->target); |
|
|
|
pr = cmd_parse_from_string(cmd, &pi); |
|
switch (pr->status) { |
|
case CMD_PARSE_EMPTY: |
|
break; |
|
case CMD_PARSE_ERROR: |
|
cmdq_error(item, "%s", pr->error); |
|
free(pr->error); |
return (CMD_RETURN_ERROR); |
return (CMD_RETURN_ERROR); |
|
case CMD_PARSE_SUCCESS: |
|
new_item = cmdq_get_command(pr->cmdlist, NULL, m, 0); |
|
cmdq_insert_after(item, new_item); |
|
cmd_list_free(pr->cmdlist); |
|
break; |
} |
} |
new_item = cmdq_get_command(cmdlist, NULL, &shared->mouse, 0); |
|
cmdq_insert_after(item, new_item); |
|
cmd_list_free(cmdlist); |
|
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
} |
} |
|
|
cdata = xcalloc(1, sizeof *cdata); |
cdata = xcalloc(1, sizeof *cdata); |
if (self->file != NULL) { |
|
cdata->file = xstrdup(self->file); |
|
cdata->line = self->line; |
|
} |
|
|
|
cdata->cmd_if = xstrdup(args->argv[1]); |
cdata->cmd_if = xstrdup(args->argv[1]); |
if (args->argc == 3) |
if (args->argc == 3) |
cdata->cmd_else = xstrdup(args->argv[2]); |
cdata->cmd_else = xstrdup(args->argv[2]); |
else |
else |
cdata->cmd_else = NULL; |
cdata->cmd_else = NULL; |
|
memcpy(&cdata->mouse, m, sizeof cdata->mouse); |
|
|
cdata->client = item->client; |
cdata->client = item->client; |
if (cdata->client != NULL) |
if (cdata->client != NULL) |
|
|
cdata->item = item; |
cdata->item = item; |
else |
else |
cdata->item = NULL; |
cdata->item = NULL; |
memcpy(&cdata->mouse, &shared->mouse, sizeof cdata->mouse); |
|
|
|
|
memset(&cdata->input, 0, sizeof cdata->input); |
|
if (self->file != NULL) |
|
cdata->input.file = xstrdup(self->file); |
|
cdata->input.line = self->line; |
|
cdata->input.item = cdata->item; |
|
cdata->input.c = c; |
|
if (cdata->input.c != NULL) |
|
cdata->input.c->references++; |
|
cmd_find_copy_state(&cdata->input.fs, &item->target); |
|
|
if (job_run(shellcmd, s, server_client_get_cwd(item->client, s), NULL, |
if (job_run(shellcmd, s, server_client_get_cwd(item->client, s), NULL, |
cmd_if_shell_callback, cmd_if_shell_free, cdata, 0) == NULL) { |
cmd_if_shell_callback, cmd_if_shell_free, cdata, 0) == NULL) { |
cmdq_error(item, "failed to run command: %s", shellcmd); |
cmdq_error(item, "failed to run command: %s", shellcmd); |
|
|
{ |
{ |
struct cmd_if_shell_data *cdata = job_get_data(job); |
struct cmd_if_shell_data *cdata = job_get_data(job); |
struct client *c = cdata->client; |
struct client *c = cdata->client; |
struct cmd_list *cmdlist; |
struct mouse_event *m = &cdata->mouse; |
struct cmdq_item *new_item; |
struct cmdq_item *new_item; |
char *cause, *cmd, *file = cdata->file; |
char *cmd; |
u_int line = cdata->line; |
|
int status; |
int status; |
|
struct cmd_parse_result *pr; |
|
|
status = job_get_status(job); |
status = job_get_status(job); |
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) |
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) |
|
|
if (cmd == NULL) |
if (cmd == NULL) |
goto out; |
goto out; |
|
|
cmdlist = cmd_string_parse(cmd, file, line, &cause); |
pr = cmd_parse_from_string(cmd, &cdata->input); |
if (cmdlist == NULL) { |
switch (pr->status) { |
if (cause != NULL && cdata->item != NULL) |
case CMD_PARSE_EMPTY: |
cmdq_error(cdata->item, "%s", cause); |
|
free(cause); |
|
new_item = NULL; |
new_item = NULL; |
} else { |
break; |
new_item = cmdq_get_command(cmdlist, NULL, &cdata->mouse, 0); |
case CMD_PARSE_ERROR: |
cmd_list_free(cmdlist); |
new_item = cmdq_get_error(pr->error); |
|
free(pr->error); |
|
break; |
|
case CMD_PARSE_SUCCESS: |
|
new_item = cmdq_get_command(pr->cmdlist, NULL, m, 0); |
|
cmd_list_free(pr->cmdlist); |
|
break; |
} |
} |
|
|
if (new_item != NULL) { |
if (new_item != NULL) { |
if (cdata->item == NULL) |
if (cdata->item == NULL) |
cmdq_append(c, new_item); |
cmdq_append(c, new_item); |
|
|
free(cdata->cmd_else); |
free(cdata->cmd_else); |
free(cdata->cmd_if); |
free(cdata->cmd_if); |
|
|
free(cdata->file); |
if (cdata->input.c != NULL) |
|
server_client_unref(cdata->input.c); |
|
free((void *)cdata->input.file); |
|
|
free(cdata); |
free(cdata); |
} |
} |