4 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
28 * Asks for confirmation before executing a command.
31 static enum args_parse_type
cmd_confirm_before_args_parse(struct args
*,
33 static enum cmd_retval
cmd_confirm_before_exec(struct cmd
*,
36 static int cmd_confirm_before_callback(struct client
*, void *,
38 static void cmd_confirm_before_free(void *);
40 const struct cmd_entry cmd_confirm_before_entry
= {
41 .name
= "confirm-before",
44 .args
= { "bc:p:t:y", 1, 1, cmd_confirm_before_args_parse
},
45 .usage
= "[-by] [-c confirm_key] [-p prompt] " CMD_TARGET_CLIENT_USAGE
48 .flags
= CMD_CLIENT_TFLAG
,
49 .exec
= cmd_confirm_before_exec
52 struct cmd_confirm_before_data
{
53 struct cmdq_item
*item
;
54 struct cmd_list
*cmdlist
;
59 static enum args_parse_type
60 cmd_confirm_before_args_parse(__unused
struct args
*args
, __unused u_int idx
,
61 __unused
char **cause
)
63 return (ARGS_PARSE_COMMANDS_OR_STRING
);
66 static enum cmd_retval
67 cmd_confirm_before_exec(struct cmd
*self
, struct cmdq_item
*item
)
69 struct args
*args
= cmd_get_args(self
);
70 struct cmd_confirm_before_data
*cdata
;
71 struct client
*tc
= cmdq_get_target_client(item
);
72 struct cmd_find_state
*target
= cmdq_get_target(item
);
74 const char *confirm_key
, *prompt
, *cmd
;
75 int wait
= !args_has(args
, 'b');
77 cdata
= xcalloc(1, sizeof *cdata
);
78 cdata
->cmdlist
= args_make_commands_now(self
, item
, 0, 1);
79 if (cdata
->cmdlist
== NULL
)
80 return (CMD_RETURN_ERROR
);
85 cdata
->default_yes
= args_has(args
, 'y');
86 if ((confirm_key
= args_get(args
, 'c')) != NULL
) {
87 if (confirm_key
[1] == '\0' &&
88 confirm_key
[0] > 31 &&
90 cdata
->confirm_key
= confirm_key
[0];
92 cmdq_error(item
, "invalid confirm key");
93 return (CMD_RETURN_ERROR
);
97 cdata
->confirm_key
= 'y';
99 if ((prompt
= args_get(args
, 'p')) != NULL
)
100 xasprintf(&new_prompt
, "%s ", prompt
);
102 cmd
= cmd_get_entry(cmd_list_first(cdata
->cmdlist
))->name
;
103 xasprintf(&new_prompt
, "Confirm '%s'? (%c/n) ",
104 cmd
, cdata
->confirm_key
);
107 status_prompt_set(tc
, target
, new_prompt
, NULL
,
108 cmd_confirm_before_callback
, cmd_confirm_before_free
, cdata
,
109 PROMPT_SINGLE
, PROMPT_TYPE_COMMAND
);
113 return (CMD_RETURN_NORMAL
);
114 return (CMD_RETURN_WAIT
);
118 cmd_confirm_before_callback(struct client
*c
, void *data
, const char *s
,
121 struct cmd_confirm_before_data
*cdata
= data
;
122 struct cmdq_item
*item
= cdata
->item
, *new_item
;
125 if (c
->flags
& CLIENT_DEAD
)
130 if (s
[0] != cdata
->confirm_key
&& (s
[0] != '\0' || !cdata
->default_yes
))
135 new_item
= cmdq_get_command(cdata
->cmdlist
, NULL
);
136 cmdq_append(c
, new_item
);
138 new_item
= cmdq_get_command(cdata
->cmdlist
,
139 cmdq_get_state(item
));
140 cmdq_insert_after(item
, new_item
);
145 if (cmdq_get_client(item
) != NULL
&&
146 cmdq_get_client(item
)->session
== NULL
)
147 cmdq_get_client(item
)->retval
= retcode
;
154 cmd_confirm_before_free(void *data
)
156 struct cmd_confirm_before_data
*cdata
= data
;
158 cmd_list_free(cdata
->cmdlist
);