]> git.mdlowis.com Git - proto/labwc.git/commitdiff
action: expand shell variables before execvp()
authorJohan Malm <jgm323@gmail.com>
Wed, 30 Jun 2021 18:56:31 +0000 (19:56 +0100)
committerJohan Malm <jgm323@gmail.com>
Wed, 30 Jun 2021 18:56:31 +0000 (19:56 +0100)
Expanding shell variables, including tilde, enables the following type
of keybind:

<keyboard>
    <keybind key="XF86AudioMute">
      <action name="Execute">
        <command>bash ~/mute-script.sh</command>
      </action>
    </keybind>
</keyboard>

Fixes issue #32

include/common/buf.h
src/action.c
src/common/buf.c

index 98be625d39b2179f819166ae717202acbc1fe472..bb18624d0e5df2cdc058b78af9770742343ab2a0 100644 (file)
@@ -17,17 +17,24 @@ struct buf {
        int len;
 };
 
+/**
+ * buf_expand_shell_variables - expand $foo and ~ in buffer
+ * @s: buffer
+ * Note: ${foo} and $$ are not handled
+ */
+void buf_expand_shell_variables(struct buf *s);
+
 /**
  * buf_init - allocate NULL-terminated C string buffer
- * @s - buffer
+ * @s: buffer
  * Note: use free(s->buf) to free it.
  */
 void buf_init(struct buf *s);
 
 /**
  * buf_add - add data to C string buffer
- * @s - buffer
- * @data - data to be added
+ * @s: buffer
+ * @data: data to be added
  */
 void buf_add(struct buf *s, const char *data);
 
index 5510dc85730c54e717c7b606efdbc675eeae9ef3..3ac0633d383a65424c3c3c3bd628cc421e6bf827 100644 (file)
@@ -26,7 +26,12 @@ action(struct server *server, const char *action, const char *command)
        if (!strcasecmp(action, "Debug")) {
                /* nothing */
        } else if (!strcasecmp(action, "Execute")) {
-               spawn_async_no_shell(command);
+               struct buf cmd;
+               buf_init(&cmd);
+               buf_add(&cmd, command);
+               buf_expand_shell_variables(&cmd);
+               spawn_async_no_shell(cmd.buf);
+               free(cmd.buf);
        } else if (!strcasecmp(action, "Exit")) {
                wl_display_terminate(server->wl_display);
        } else if (!strcasecmp(action, "NextWindow")) {
index 27081f01e4fe2a01e19d3ea253a62445b3dc47fc..abc2b877ecf31fd5ca232776ab5da4440c6a9545 100644 (file)
@@ -1,5 +1,49 @@
+#include <ctype.h>
 #include "common/buf.h"
 
+void
+buf_expand_shell_variables(struct buf *s)
+{
+       struct buf new;
+       struct buf environment_variable;
+       buf_init(&new);
+       buf_init(&environment_variable);
+
+       for (int i = 0 ; i < s->len ; i++) {
+               if (s->buf[i] == '$') {
+                       /* expand environment variable */
+                       environment_variable.len = 0;
+                       buf_add(&environment_variable, s->buf + i + 1);
+                       char *p = environment_variable.buf;
+                       while (isalnum(*p)) {
+                               ++p;
+                       }
+                       *p = '\0';
+                       p = getenv(environment_variable.buf);
+                       if (!p) {
+                               goto out;
+                       }
+                       buf_add(&new, p);
+                       i += strlen(environment_variable.buf);
+               } else if (s->buf[i] == '~') {
+                       /* expand tilde */
+                       buf_add(&new, getenv("HOME"));
+               } else {
+                       /* just add one character at a time */
+                       if (new.alloc <= new.len + 1) {
+                               new.alloc = new.alloc * 3/2 + 16;
+                               new.buf = realloc(new.buf, new.alloc);
+                       }
+                       new.buf[new.len++] = s->buf[i];
+                       new.buf[new.len] = '\0';
+               }
+       }
+out:
+       free(environment_variable.buf);
+       free(s->buf);
+       s->buf = new.buf;
+}
+
 void
 buf_init(struct buf *s)
 {