diff options
author | Thomas Adam <thomas@xteddy.org> | 2019-05-23 13:02:27 +0100 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2019-05-23 13:02:27 +0100 |
commit | 75aeb733f292639f8332df11315ca8280e5631fd (patch) | |
tree | d459b4c2381ca737009613577deafe14196eceef /cmd-string.c | |
parent | 7ca2e2fe88cd282d3e8faea3f2000ad15972f71d (diff) | |
parent | 723010ba72e337832402f8e44981c02caa30b476 (diff) | |
download | rtmux-75aeb733f292639f8332df11315ca8280e5631fd.tar.gz rtmux-75aeb733f292639f8332df11315ca8280e5631fd.tar.bz2 rtmux-75aeb733f292639f8332df11315ca8280e5631fd.zip |
Merge branch 'obsd-master'
Diffstat (limited to 'cmd-string.c')
-rw-r--r-- | cmd-string.c | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/cmd-string.c b/cmd-string.c deleted file mode 100644 index 058f997c..00000000 --- a/cmd-string.c +++ /dev/null @@ -1,393 +0,0 @@ -/* $OpenBSD$ */ - -/* - * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> - -#include <errno.h> -#include <pwd.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include "tmux.h" - -/* - * Parse a command from a string. - */ - -static int cmd_string_getc(const char *, size_t *); -static void cmd_string_ungetc(size_t *); -static void cmd_string_copy(char **, char *, size_t *); -static char *cmd_string_string(const char *, size_t *, char, int); -static char *cmd_string_variable(const char *, size_t *); -static char *cmd_string_expand_tilde(const char *, size_t *); - -static int -cmd_string_getc(const char *s, size_t *p) -{ - const u_char *ucs = s; - - if (ucs[*p] == '\0') - return (EOF); - return (ucs[(*p)++]); -} - -static void -cmd_string_ungetc(size_t *p) -{ - (*p)--; -} - -static int -cmd_string_unicode(wchar_t *wc, const char *s, size_t *p, char ch) -{ - int size = (ch == 'u') ? 4 : 8; - u_int tmp; - - if (size == 4 && sscanf(s + *p, "%4x", &tmp) != 1) - return (-1); - if (size == 8 && sscanf(s + *p, "%8x", &tmp) != 1) - return (-1); - *p += size; - - *wc = (wchar_t)tmp; - return (0); -} - -int -cmd_string_split(const char *s, int *rargc, char ***rargv) -{ - size_t p = 0; - int ch, argc = 0, append = 0; - char **argv = NULL, *buf = NULL, *t; - const char *whitespace, *equals; - size_t len = 0; - - for (;;) { - ch = cmd_string_getc(s, &p); - switch (ch) { - case '\'': - if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL) - goto error; - cmd_string_copy(&buf, t, &len); - break; - case '"': - if ((t = cmd_string_string(s, &p, '"', 1)) == NULL) - goto error; - cmd_string_copy(&buf, t, &len); - break; - case '$': - if ((t = cmd_string_variable(s, &p)) == NULL) - goto error; - cmd_string_copy(&buf, t, &len); - break; - case '#': - /* Comment: discard rest of line. */ - while ((ch = cmd_string_getc(s, &p)) != EOF) - ; - /* FALLTHROUGH */ - case EOF: - case ' ': - case '\t': - if (buf != NULL) { - buf = xrealloc(buf, len + 1); - buf[len] = '\0'; - - argv = xreallocarray(argv, argc + 1, - sizeof *argv); - argv[argc++] = buf; - - buf = NULL; - len = 0; - } - - if (ch != EOF) - break; - - while (argc != 0) { - equals = strchr(argv[0], '='); - whitespace = argv[0] + strcspn(argv[0], " \t"); - if (equals == NULL || equals > whitespace) - break; - environ_put(global_environ, argv[0]); - argc--; - memmove(argv, argv + 1, argc * (sizeof *argv)); - } - goto done; - case '~': - if (buf != NULL) { - append = 1; - break; - } - t = cmd_string_expand_tilde(s, &p); - if (t == NULL) - goto error; - cmd_string_copy(&buf, t, &len); - break; - default: - append = 1; - break; - } - if (append) { - if (len >= SIZE_MAX - 2) - goto error; - buf = xrealloc(buf, len + 1); - buf[len++] = ch; - } - append = 0; - } - -done: - *rargc = argc; - *rargv = argv; - - free(buf); - return (0); - -error: - if (argv != NULL) - cmd_free_argv(argc, argv); - free(buf); - return (-1); -} - -struct cmd_list * -cmd_string_parse(const char *s, const char *file, u_int line, char **cause) -{ - struct cmd_list *cmdlist = NULL; - int argc; - char **argv; - - if (cause != NULL) - *cause = NULL; - log_debug ("%s: %s", __func__, s); - - if (cmd_string_split(s, &argc, &argv) != 0) { - xasprintf(cause, "invalid or unknown command: %s", s); - return (NULL); - } - if (argc != 0) { - cmdlist = cmd_list_parse(argc, argv, file, line, cause); - if (cmdlist == NULL) { - cmd_free_argv(argc, argv); - return (NULL); - } - } - cmd_free_argv(argc, argv); - return (cmdlist); -} - -static void -cmd_string_copy(char **dst, char *src, size_t *len) -{ - size_t srclen; - - srclen = strlen(src); - - *dst = xrealloc(*dst, *len + srclen + 1); - strlcpy(*dst + *len, src, srclen + 1); - - *len += srclen; - free(src); -} - -static char * -cmd_string_string(const char *s, size_t *p, char endch, int esc) -{ - int ch; - wchar_t wc; - struct utf8_data ud; - char *buf = NULL, *t; - size_t len = 0; - - while ((ch = cmd_string_getc(s, p)) != endch) { - switch (ch) { - case EOF: - goto error; - case '\\': - if (!esc) - break; - switch (ch = cmd_string_getc(s, p)) { - case EOF: - goto error; - case 'e': - ch = '\033'; - break; - case 'r': - ch = '\r'; - break; - case 'n': - ch = '\n'; - break; - case 't': - ch = '\t'; - break; - case 'u': - case 'U': - if (cmd_string_unicode(&wc, s, p, ch) != 0) - goto error; - if (utf8_split(wc, &ud) != UTF8_DONE) - goto error; - if (len >= SIZE_MAX - ud.size - 1) - goto error; - buf = xrealloc(buf, len + ud.size); - memcpy(buf + len, ud.data, ud.size); - len += ud.size; - continue; - } - break; - case '$': - if (!esc) - break; - if ((t = cmd_string_variable(s, p)) == NULL) - goto error; - cmd_string_copy(&buf, t, &len); - continue; - } - - if (len >= SIZE_MAX - 2) - goto error; - buf = xrealloc(buf, len + 1); - buf[len++] = ch; - } - - buf = xrealloc(buf, len + 1); - buf[len] = '\0'; - return (buf); - -error: - free(buf); - return (NULL); -} - -static char * -cmd_string_variable(const char *s, size_t *p) -{ - int ch, fch; - char *buf, *t; - size_t len; - struct environ_entry *envent; - -#define cmd_string_first(ch) ((ch) == '_' || \ - ((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z')) -#define cmd_string_other(ch) ((ch) == '_' || \ - ((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z') || \ - ((ch) >= '0' && (ch) <= '9')) - - buf = NULL; - len = 0; - - fch = EOF; - switch (ch = cmd_string_getc(s, p)) { - case EOF: - goto error; - case '{': - fch = '{'; - - ch = cmd_string_getc(s, p); - if (!cmd_string_first(ch)) - goto error; - /* FALLTHROUGH */ - default: - if (!cmd_string_first(ch)) { - xasprintf(&t, "$%c", ch); - return (t); - } - - buf = xrealloc(buf, len + 1); - buf[len++] = ch; - - for (;;) { - ch = cmd_string_getc(s, p); - if (ch == EOF || !cmd_string_other(ch)) - break; - else { - if (len >= SIZE_MAX - 3) - goto error; - buf = xrealloc(buf, len + 1); - buf[len++] = ch; - } - } - } - - if (fch == '{' && ch != '}') - goto error; - if (ch != EOF && fch != '{') - cmd_string_ungetc(p); /* ch */ - - buf = xrealloc(buf, len + 1); - buf[len] = '\0'; - - envent = environ_find(global_environ, buf); - free(buf); - if (envent == NULL) - return (xstrdup("")); - return (xstrdup(envent->value)); - -error: - free(buf); - return (NULL); -} - -static char * -cmd_string_expand_tilde(const char *s, size_t *p) -{ - struct passwd *pw; - struct environ_entry *envent; - char *home, *path, *user, *cp; - int last; - - home = NULL; - - last = cmd_string_getc(s, p); - if (last == EOF || last == '/' || last == ' '|| last == '\t') { - envent = environ_find(global_environ, "HOME"); - if (envent != NULL && *envent->value != '\0') - home = envent->value; - else if ((pw = getpwuid(getuid())) != NULL) - home = pw->pw_dir; - } else { - cmd_string_ungetc(p); - - cp = user = xmalloc(strlen(s)); - for (;;) { - last = cmd_string_getc(s, p); - if (last == EOF || - last == '/' || - last == ' '|| - last == '\t') - break; - *cp++ = last; - } - *cp = '\0'; - - if ((pw = getpwnam(user)) != NULL) - home = pw->pw_dir; - free(user); - } - - if (home == NULL) - return (NULL); - - if (last != EOF) - xasprintf(&path, "%s%c", home, last); - else - xasprintf(&path, "%s", home); - return (path); -} |