version 1.79, 2021/08/21 17:25:32 |
version 1.80, 2021/08/23 12:33:55 |
|
|
|
|
static enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmdq_item *); |
static enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmdq_item *); |
|
|
static void cmd_if_shell_callback(struct job *); |
static void cmd_if_shell_callback(struct job *); |
static void cmd_if_shell_free(void *); |
static void cmd_if_shell_free(void *); |
|
|
const struct cmd_entry cmd_if_shell_entry = { |
const struct cmd_entry cmd_if_shell_entry = { |
.name = "if-shell", |
.name = "if-shell", |
|
|
}; |
}; |
|
|
struct cmd_if_shell_data { |
struct cmd_if_shell_data { |
struct cmd_parse_input input; |
struct cmd_list *cmd_if; |
|
struct cmd_list *cmd_else; |
|
|
char *cmd_if; |
|
char *cmd_else; |
|
|
|
struct client *client; |
struct client *client; |
struct cmdq_item *item; |
struct cmdq_item *item; |
}; |
}; |
|
|
{ |
{ |
struct args *args = cmd_get_args(self); |
struct args *args = cmd_get_args(self); |
struct cmd_find_state *target = cmdq_get_target(item); |
struct cmd_find_state *target = cmdq_get_target(item); |
struct cmdq_state *state = cmdq_get_state(item); |
|
struct cmd_if_shell_data *cdata; |
struct cmd_if_shell_data *cdata; |
char *shellcmd, *error; |
struct cmdq_item *new_item; |
const char *cmd = NULL, *file; |
char *shellcmd; |
struct client *tc = cmdq_get_target_client(item); |
struct client *tc = cmdq_get_target_client(item); |
struct session *s = target->s; |
struct session *s = target->s; |
struct cmd_parse_input pi; |
struct cmd_list *cmdlist = NULL; |
enum cmd_parse_status status; |
|
u_int count = args_count(args); |
u_int count = args_count(args); |
|
|
shellcmd = format_single_from_target(item, args_string(args, 0)); |
shellcmd = format_single_from_target(item, args_string(args, 0)); |
if (args_has(args, 'F')) { |
if (args_has(args, 'F')) { |
if (*shellcmd != '0' && *shellcmd != '\0') |
if (*shellcmd != '0' && *shellcmd != '\0') |
cmd = args_string(args, 1); |
cmdlist = args_make_commands_now(self, item, 1); |
else if (count == 3) |
else if (count == 3) |
cmd = args_string(args, 2); |
cmdlist = args_make_commands_now(self, item, 2); |
free(shellcmd); |
else { |
if (cmd == NULL) |
free(shellcmd); |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
|
|
memset(&pi, 0, sizeof pi); |
|
cmd_get_source(self, &pi.file, &pi.line); |
|
pi.item = item; |
|
pi.c = tc; |
|
cmd_find_copy_state(&pi.fs, target); |
|
|
|
status = cmd_parse_and_insert(cmd, &pi, item, state, &error); |
|
if (status == CMD_PARSE_ERROR) { |
|
cmdq_error(item, "%s", error); |
|
free(error); |
|
return (CMD_RETURN_ERROR); |
|
} |
} |
|
free(shellcmd); |
|
if (cmdlist == NULL) |
|
return (CMD_RETURN_ERROR); |
|
new_item = cmdq_get_command(cmdlist, cmdq_get_state(item)); |
|
cmdq_insert_after(item, new_item); |
return (CMD_RETURN_NORMAL); |
return (CMD_RETURN_NORMAL); |
} |
} |
|
|
cdata = xcalloc(1, sizeof *cdata); |
cdata = xcalloc(1, sizeof *cdata); |
|
|
cdata->cmd_if = xstrdup(args_string(args, 1)); |
cdata->cmd_if = args_make_commands_now(self, item, 1); |
if (count == 3) |
if (cdata->cmd_if == NULL) |
cdata->cmd_else = xstrdup(args_string(args, 2)); |
return (CMD_RETURN_ERROR); |
|
if (count == 3) { |
|
cdata->cmd_else = args_make_commands_now(self, item, 2); |
|
if (cdata->cmd_else == NULL) |
|
return (CMD_RETURN_ERROR); |
|
} |
|
|
if (!args_has(args, 'b')) |
if (!args_has(args, 'b')) |
cdata->client = cmdq_get_client(item); |
cdata->client = cmdq_get_client(item); |
|
|
if (!args_has(args, 'b')) |
if (!args_has(args, 'b')) |
cdata->item = item; |
cdata->item = item; |
|
|
cmd_get_source(self, &file, &cdata->input.line); |
|
if (file != NULL) |
|
cdata->input.file = xstrdup(file); |
|
cdata->input.c = tc; |
|
if (cdata->input.c != NULL) |
|
cdata->input.c->references++; |
|
cmd_find_copy_state(&cdata->input.fs, target); |
|
|
|
if (job_run(shellcmd, 0, NULL, s, |
if (job_run(shellcmd, 0, NULL, s, |
server_client_get_cwd(cmdq_get_client(item), s), NULL, |
server_client_get_cwd(cmdq_get_client(item), s), NULL, |
cmd_if_shell_callback, cmd_if_shell_free, cdata, 0, -1, |
cmd_if_shell_callback, cmd_if_shell_free, cdata, 0, -1, |
|
|
{ |
{ |
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 cmdq_item *new_item = NULL; |
struct cmdq_item *item = cdata->item, *new_item; |
struct cmdq_state *new_state = NULL; |
struct cmd_list *cmdlist; |
char *cmd; |
|
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) |
cmd = cdata->cmd_else; |
cmdlist = cdata->cmd_else; |
else |
else |
cmd = cdata->cmd_if; |
cmdlist = cdata->cmd_if; |
if (cmd == NULL) |
if (cmdlist == NULL) |
goto out; |
goto out; |
|
|
pr = cmd_parse_from_string(cmd, &cdata->input); |
if (item == NULL) { |
switch (pr->status) { |
new_item = cmdq_get_command(cmdlist, NULL); |
case CMD_PARSE_ERROR: |
cmdq_append(c, new_item); |
if (cdata->item != NULL) |
} else { |
cmdq_error(cdata->item, "%s", pr->error); |
new_item = cmdq_get_command(cmdlist, cmdq_get_state(item)); |
free(pr->error); |
cmdq_insert_after(item, new_item); |
break; |
|
case CMD_PARSE_SUCCESS: |
|
if (cdata->item == NULL) |
|
new_state = cmdq_new_state(NULL, NULL, 0); |
|
else |
|
new_state = cmdq_get_state(cdata->item); |
|
new_item = cmdq_get_command(pr->cmdlist, new_state); |
|
if (cdata->item == NULL) |
|
cmdq_free_state(new_state); |
|
cmd_list_free(pr->cmdlist); |
|
break; |
|
} |
} |
if (new_item != NULL) { |
|
if (cdata->item == NULL) |
|
cmdq_append(c, new_item); |
|
else |
|
cmdq_insert_after(cdata->item, new_item); |
|
} |
|
|
|
out: |
out: |
if (cdata->item != NULL) |
if (cdata->item != NULL) |
|
|
if (cdata->client != NULL) |
if (cdata->client != NULL) |
server_client_unref(cdata->client); |
server_client_unref(cdata->client); |
|
|
free(cdata->cmd_else); |
if (cdata->cmd_else != NULL) |
free(cdata->cmd_if); |
cmd_list_free(cdata->cmd_else); |
|
cmd_list_free(cdata->cmd_if); |
if (cdata->input.c != NULL) |
|
server_client_unref(cdata->input.c); |
|
free((void *)cdata->input.file); |
|
|
|
free(cdata); |
free(cdata); |
} |
} |