summaryrefslogtreecommitdiffstats
path: root/tmux.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmux.c')
-rw-r--r--tmux.c128
1 files changed, 84 insertions, 44 deletions
diff --git a/tmux.c b/tmux.c
index edc2a7c3..040d34b7 100644
--- a/tmux.c
+++ b/tmux.c
@@ -1,4 +1,4 @@
-/* $Id: tmux.c,v 1.149 2009-07-23 13:15:41 tcunha Exp $ */
+/* $Id: tmux.c,v 1.150 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -62,6 +62,8 @@ char *socket_path;
__dead void usage(void);
char *makesockpath(const char *);
+int prepare_unlock(enum hdrtype *, void **, size_t *, int);
+int prepare_cmd(enum hdrtype *, void **, size_t *, int, char **);
#ifndef HAVE_PROGNAME
char *__progname = (char *) "tmux";
@@ -210,18 +212,69 @@ makesockpath(const char *label)
}
int
+prepare_unlock(enum hdrtype *msg, void **buf, size_t *len, int argc)
+{
+ static struct msg_unlock_data unlockdata;
+ char *pass;
+
+ if (argc != 0) {
+ log_warnx("can't specify a command when unlocking");
+ return (-1);
+ }
+
+ if ((pass = getpass("Password: ")) == NULL)
+ return (-1);
+
+ if (strlen(pass) >= sizeof unlockdata.pass) {
+ log_warnx("password too long");
+ return (-1);
+ }
+
+ strlcpy(unlockdata.pass, pass, sizeof unlockdata.pass);
+ memset(pass, 0, strlen(pass));
+
+ *buf = &unlockdata;
+ *len = sizeof unlockdata;
+
+ *msg = MSG_UNLOCK;
+ return (0);
+}
+
+int
+prepare_cmd(enum hdrtype *msg, void **buf, size_t *len, int argc, char **argv)
+{
+ static struct msg_command_data cmddata;
+
+ client_fill_session(&cmddata);
+
+ cmddata.argc = argc;
+ if (cmd_pack_argv(argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
+ log_warnx("command too long");
+ return (-1);
+ }
+
+ *buf = &cmddata;
+ *len = sizeof cmddata;
+
+ *msg = MSG_COMMAND;
+ return (0);
+}
+
+int
main(int argc, char **argv)
{
struct client_ctx cctx;
- struct msg_command_data cmddata;
- struct buffer *b;
struct cmd_list *cmdlist;
struct cmd *cmd;
struct pollfd pfd;
+ enum hdrtype msg;
struct hdr hdr;
struct passwd *pw;
- char *s, *path, *label, *cause, *home, *pass = NULL;
+ struct msg_print_data printdata;
+ char *s, *path, *label, *home, *cause;
char cwd[MAXPATHLEN];
+ void *buf;
+ size_t len;
int retcode, opt, flags, unlock, cmdflags = 0;
unlock = flags = 0;
@@ -373,7 +426,7 @@ main(int argc, char **argv)
exit(1);
}
}
-
+
if (label == NULL)
label = xstrdup("default");
if (path == NULL && (path = makesockpath(label)) == NULL) {
@@ -392,36 +445,35 @@ main(int argc, char **argv)
options_set_string(&global_s_options, "default-path", "%s", cwd);
if (unlock) {
- if (argc != 0) {
- log_warnx("can't specify a command when unlocking");
+ if (prepare_unlock(&msg, &buf, &len, argc) != 0)
exit(1);
- }
- cmdlist = NULL;
- if ((pass = getpass("Password: ")) == NULL)
+ } else {
+ if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0)
exit(1);
+ }
+
+ if (unlock)
cmdflags &= ~CMD_STARTSERVER;
- } else {
- if (argc == 0) {
- cmd = xmalloc(sizeof *cmd);
- cmd->entry = &cmd_new_session_entry;
- cmd->entry->init(cmd, 0);
-
- cmdlist = xmalloc(sizeof *cmdlist);
- TAILQ_INIT(cmdlist);
- TAILQ_INSERT_HEAD(cmdlist, cmd, qentry);
- } else {
- cmdlist = cmd_list_parse(argc, argv, &cause);
- if (cmdlist == NULL) {
- log_warnx("%s", cause);
- exit(1);
- }
+ else if (argc == 0)
+ cmdflags |= CMD_STARTSERVER;
+ else {
+ /*
+ * It sucks parsing the command string twice (in client and
+ * later in server) but it is necessary to get the start server
+ * flag.
+ */
+ if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
+ log_warnx("%s", cause);
+ exit(1);
}
+ cmdflags &= ~CMD_STARTSERVER;
TAILQ_FOREACH(cmd, cmdlist, qentry) {
if (cmd->entry->flags & CMD_STARTSERVER) {
cmdflags |= CMD_STARTSERVER;
break;
}
}
+ cmd_list_free(cmdlist);
}
memset(&cctx, 0, sizeof cctx);
@@ -429,20 +481,8 @@ main(int argc, char **argv)
exit(1);
xfree(path);
- b = buffer_create(BUFSIZ);
- if (unlock) {
- cmd_send_string(b, pass);
- memset(pass, 0, strlen(pass));
- client_write_server(
- &cctx, MSG_UNLOCK, BUFFER_OUT(b), BUFFER_USED(b));
- } else {
- cmd_list_send(cmdlist, b);
- cmd_list_free(cmdlist);
- client_fill_session(&cmddata);
- client_write_server2(&cctx, MSG_COMMAND,
- &cmddata, sizeof cmddata, BUFFER_OUT(b), BUFFER_USED(b));
- }
- buffer_destroy(b);
+ client_write_server(&cctx, msg, buf, len);
+ memset(buf, 0, len);
retcode = 0;
for (;;) {
@@ -476,12 +516,12 @@ main(int argc, char **argv)
retcode = 1;
/* FALLTHROUGH */
case MSG_PRINT:
- if (hdr.size > INT_MAX - 1)
+ if (hdr.size < sizeof printdata)
fatalx("bad MSG_PRINT size");
- log_info("%.*s",
- (int) hdr.size, BUFFER_OUT(cctx.srv_in));
- if (hdr.size != 0)
- buffer_remove(cctx.srv_in, hdr.size);
+ buffer_read(cctx.srv_in, &printdata, sizeof printdata);
+
+ printdata.msg[(sizeof printdata.msg) - 1] = '\0';
+ log_info("%s", printdata.msg);
goto restart;
case MSG_READY:
retcode = client_main(&cctx);