cmd-confirm-before.c revision 1.9
1/* $OpenBSD: cmd-confirm-before.c,v 1.9 2009/11/13 19:53:29 nicm Exp $ */ 2 3/* 4 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> 5 * 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. 9 * 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. 17 */ 18 19#include <ctype.h> 20#include <string.h> 21 22#include "tmux.h" 23 24/* 25 * Asks for confirmation before executing a command. 26 */ 27 28int cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *); 29void cmd_confirm_before_init(struct cmd *, int); 30 31int cmd_confirm_before_callback(void *, const char *); 32void cmd_confirm_before_free(void *); 33 34const struct cmd_entry cmd_confirm_before_entry = { 35 "confirm-before", "confirm", 36 CMD_TARGET_CLIENT_USAGE " command", 37 CMD_ARG1, "", 38 cmd_confirm_before_init, 39 cmd_target_parse, 40 cmd_confirm_before_exec, 41 cmd_target_free, 42 cmd_target_print 43}; 44 45struct cmd_confirm_before_data { 46 struct client *c; 47 char *cmd; 48}; 49 50void 51cmd_confirm_before_init(struct cmd *self, int key) 52{ 53 struct cmd_target_data *data; 54 55 cmd_target_init(self, key); 56 data = self->data; 57 58 switch (key) { 59 case '&': 60 data->arg = xstrdup("kill-window"); 61 break; 62 case 'x': 63 data->arg = xstrdup("kill-pane"); 64 break; 65 } 66} 67 68int 69cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx) 70{ 71 struct cmd_target_data *data = self->data; 72 struct cmd_confirm_before_data *cdata; 73 struct client *c; 74 char *buf, *cmd, *ptr; 75 76 if (ctx->curclient == NULL) { 77 ctx->error(ctx, "must be run interactively"); 78 return (-1); 79 } 80 81 if ((c = cmd_find_client(ctx, data->target)) == NULL) 82 return (-1); 83 84 ptr = xstrdup(data->arg); 85 if ((cmd = strtok(ptr, " \t")) == NULL) 86 cmd = ptr; 87 xasprintf(&buf, "Confirm '%s'? (y/n) ", cmd); 88 xfree(ptr); 89 90 cdata = xmalloc(sizeof *cdata); 91 cdata->cmd = xstrdup(data->arg); 92 cdata->c = c; 93 status_prompt_set(cdata->c, buf, 94 cmd_confirm_before_callback, cmd_confirm_before_free, cdata, 95 PROMPT_SINGLE); 96 97 xfree(buf); 98 return (1); 99} 100 101int 102cmd_confirm_before_callback(void *data, const char *s) 103{ 104 struct cmd_confirm_before_data *cdata = data; 105 struct client *c = cdata->c; 106 struct cmd_list *cmdlist; 107 struct cmd_ctx ctx; 108 char *cause; 109 110 if (s == NULL || *s == '\0') 111 return (0); 112 if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') 113 return (0); 114 115 if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) { 116 if (cause != NULL) { 117 *cause = toupper((u_char) *cause); 118 status_message_set(c, "%s", cause); 119 xfree(cause); 120 } 121 return (0); 122 } 123 124 ctx.msgdata = NULL; 125 ctx.curclient = c; 126 127 ctx.error = key_bindings_error; 128 ctx.print = key_bindings_print; 129 ctx.info = key_bindings_info; 130 131 ctx.cmdclient = NULL; 132 133 cmd_list_exec(cmdlist, &ctx); 134 cmd_list_free(cmdlist); 135 136 return (0); 137} 138 139void 140cmd_confirm_before_free(void *data) 141{ 142 struct cmd_confirm_before_data *cdata = data; 143 144 if (cdata->cmd != NULL) 145 xfree(cdata->cmd); 146 xfree(cdata); 147} 148