enum cmd_retval cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; struct environ *env; struct environ_entry *envent; if (args_has(self->args, 'g')) env = global_environ; else { s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); env = s->environ; } if (args->argc != 0) { envent = environ_find(env, args->argv[0]); if (envent == NULL) { cmdq_error(cmdq, "unknown variable: %s", args->argv[0]); return (CMD_RETURN_ERROR); } cmd_show_environment_print(self, cmdq, envent); return (CMD_RETURN_NORMAL); } envent = environ_first(env); while (envent != NULL) { cmd_show_environment_print(self, cmdq, envent); envent = environ_next(envent); } return (CMD_RETURN_NORMAL); }
int cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; u_int limit; char *pdata; size_t psize; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); limit = options_get_number(&s->options, "buffer-limit"); pdata = xstrdup(data->arg); psize = strlen(pdata); if (data->buffer == -1) { paste_add(&s->buffers, pdata, psize, limit); return (0); } if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) { ctx->error(ctx, "no buffer %d", data->buffer); xfree(pdata); return (-1); } return (0); }
int cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct client *c; struct session *s; enum msgtype msgtype; u_int i; if (args_has(args, 'P')) msgtype = MSG_DETACHKILL; else msgtype = MSG_DETACH; if (args_has(args, 's')) { s = cmd_find_session(ctx, args_get(args, 's'), 0); if (s == NULL) return (-1); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); if (c != NULL && c->session == s) server_write_client(c, msgtype, NULL, 0); } } else { c = cmd_find_client(ctx, args_get(args, 't')); if (c == NULL) return (-1); server_write_client(c, msgtype, NULL, 0); } return (0); }
enum cmd_retval cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; const char *newname; newname = args->argv[0]; if (!session_check_name(newname)) { cmdq_error(cmdq, "bad session name: %s", newname); return (CMD_RETURN_ERROR); } if (session_find(newname) != NULL) { cmdq_error(cmdq, "duplicate session: %s", newname); return (CMD_RETURN_ERROR); } if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) return (CMD_RETURN_ERROR); RB_REMOVE(sessions, &sessions, s); free(s->name); s->name = xstrdup(newname); RB_INSERT(sessions, &sessions, s); server_status_session(s); notify_session_renamed(s); return (CMD_RETURN_NORMAL); }
int cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct session *s; const char *newname; newname = args->argv[0]; if (!session_check_name(newname)) { ctx->error(ctx, "bad session name: %s", newname); return (-1); } if (session_find(newname) != NULL) { ctx->error(ctx, "duplicate session: %s", newname); return (-1); } if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) return (-1); RB_REMOVE(sessions, &sessions, s); xfree(s->name); s->name = xstrdup(newname); RB_INSERT(sessions, &sessions, s); server_status_session(s); control_notify_session_renamed(s); return (0); }
int cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_switch_client_data *data = self->data; struct client *c; struct session *s; if (data == NULL) return (0); if ((c = cmd_find_client(ctx, data->name)) == NULL) return (-1); if (data->flag_next) { if ((s = session_next_session(c->session)) == NULL) { ctx->error(ctx, "can't find next session"); return (-1); } } else if (data->flag_previous) { if ((s = session_previous_session(c->session)) == NULL) { ctx->error(ctx, "can't find previous session"); return (-1); } } else s = cmd_find_session(ctx, data->target); if (s == NULL) return (-1); c->session = s; recalculate_sizes(); server_redraw_client(c); return (0); }
/* ARGSUSED */ int cmd_list_clients_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct client *c; struct session *s; u_int i; const char *s_utf8; if (args_has(args, 't')) { s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (-1); } else s = NULL; for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); if (c == NULL || c->session == NULL) continue; if (c->tty.flags & TTY_UTF8) s_utf8 = " (utf8)"; else s_utf8 = ""; if (s != NULL && s != c->session) continue; ctx->print(ctx, "%s: %s [%ux%u %s]%s", c->tty.path, c->session->name, c->tty.sx, c->tty.sy, c->tty.termname, s_utf8); } return (0); }
int cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; FILE *f; char *pdata, *new_pdata; size_t psize; u_int limit; int ch; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); if ((f = fopen(data->arg, "rb")) == NULL) { ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); return (-1); } pdata = NULL; psize = 0; while ((ch = getc(f)) != EOF) { /* Do not let the server die due to memory exhaustion. */ if ((new_pdata = realloc(pdata, psize + 2)) == NULL) { ctx->error(ctx, "realloc error: %s", strerror(errno)); goto error; } pdata = new_pdata; pdata[psize++] = ch; } if (ferror(f)) { ctx->error(ctx, "%s: read error", data->arg); goto error; } if (pdata != NULL) pdata[psize] = '\0'; fclose(f); limit = options_get_number(&s->options, "buffer-limit"); if (data->buffer == -1) { paste_add(&s->buffers, pdata, psize, limit); return (0); } if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) { ctx->error(ctx, "no buffer %d", data->buffer); goto error; } return (0); error: if (pdata != NULL) xfree(pdata); fclose(f); return (-1); }
int cmd_has_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; if (cmd_find_session(ctx, args_get(args, 't'), 0) == NULL) return (-1); return (0); }
int cmd_has_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; if (cmd_find_session(ctx, data->target) == NULL) return (-1); return (0); }
enum cmd_retval cmd_has_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; if (cmd_find_session(ctx, args_get(args, 't'), 0) == NULL) return (CMD_RETURN_ERROR); return (CMD_RETURN_NORMAL); }
int cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct client *c; struct session *s; if ((c = cmd_find_client(ctx, args_get(args, 'c'))) == NULL) return (-1); if (args_has(args, 'r')) { if (c->flags & CLIENT_READONLY) { c->flags &= ~CLIENT_READONLY; ctx->info(ctx, "made client writable"); } else { c->flags |= CLIENT_READONLY; ctx->info(ctx, "made client read-only"); } } s = NULL; if (args_has(args, 'n')) { if ((s = session_next_session(c->session)) == NULL) { ctx->error(ctx, "can't find next session"); return (-1); } } else if (args_has(args, 'p')) { if ((s = session_previous_session(c->session)) == NULL) { ctx->error(ctx, "can't find previous session"); return (-1); } } else if (args_has(args, 'l')) { if (c->last_session != NULL && session_alive(c->last_session)) s = c->last_session; if (s == NULL) { ctx->error(ctx, "can't find last session"); return (-1); } } else s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (-1); if (c->session != NULL) c->last_session = c->session; c->session = s; session_update_activity(s); recalculate_sizes(); server_check_unattached(); server_redraw_client(c); s->curw->flags &= ~WINLINK_ALERTFLAGS; return (0); }
int cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_copy_buffer_data *data = self->data; struct paste_buffer *pb; struct paste_stack *dst_ps, *src_ps; u_char *pdata; struct session *dst_session, *src_session; u_int limit; if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL || (src_session = cmd_find_session(ctx, data->src_session)) == NULL) return (-1); dst_ps = &dst_session->buffers; src_ps = &src_session->buffers; if (data->src_idx == -1) { if ((pb = paste_get_top(src_ps)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) { ctx->error(ctx, "no buffer %d", data->src_idx); return (-1); } } limit = options_get_number(&dst_session->options, "buffer-limit"); pdata = xmalloc(pb->size); memcpy(pdata, pb->data, pb->size); if (data->dst_idx == -1) paste_add(dst_ps, pdata, pb->size, limit); else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) { ctx->error(ctx, "no buffer %d", data->dst_idx); xfree(pdata); return (-1); } return (0); }
/* Set user option. */ enum cmd_retval cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr, const char *valstr) { struct args *args = self->args; struct session *s; struct winlink *wl; struct options *oo; if (args_has(args, 's')) oo = &global_options; else if (args_has(self->args, 'w') || self->entry == &cmd_set_window_option_entry) { if (args_has(self->args, 'g')) oo = &global_w_options; else { wl = cmd_find_window(ctx, args_get(args, 't'), NULL); if (wl == NULL) return (CMD_RETURN_ERROR); oo = &wl->window->options; } } else { if (args_has(self->args, 'g')) oo = &global_s_options; else { s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); oo = &s->options; } } if (args_has(args, 'u')) { if (options_find1(oo, optstr) == NULL) { ctx->error(ctx, "unknown option: %s", optstr); return (CMD_RETURN_ERROR); } if (valstr != NULL) { ctx->error(ctx, "value passed to unset option: %s", optstr); return (CMD_RETURN_ERROR); } options_remove(oo, optstr); } else { if (valstr == NULL) { ctx->error(ctx, "empty value"); return (CMD_RETURN_ERROR); } options_set_string(oo, optstr, "%s", valstr); if (!args_has(args, 'q')) ctx->info(ctx, "set option: %s -> %s", optstr, valstr); } return (CMD_RETURN_NORMAL); }
int cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct winlink *wl; struct session *s; int next, previous, last, activity; next = self->entry == &cmd_next_window_entry; if (args_has(self->args, 'n')) next = 1; previous = self->entry == &cmd_previous_window_entry; if (args_has(self->args, 'p')) previous = 1; last = self->entry == &cmd_last_window_entry; if (args_has(self->args, 'l')) last = 1; if (next || previous || last) { s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (-1); activity = args_has(self->args, 'a'); if (next) { if (session_next(s, activity) != 0) { ctx->error(ctx, "no next window"); return (-1); } } else if (previous) { if (session_previous(s, activity) != 0) { ctx->error(ctx, "no previous window"); return (-1); } } else { if (session_last(s) != 0) { ctx->error(ctx, "no last window"); return (-1); } } server_redraw_session(s); } else { wl = cmd_find_window(ctx, args_get(args, 't'), &s); if (wl == NULL) return (-1); if (session_select(s, wl->idx) == 0) server_redraw_session(s); } recalculate_sizes(); return (0); }
int cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct session *s; struct environ *env; const char *name, *value; name = args->argv[0]; if (*name == '\0') { ctx->error(ctx, "empty variable name"); return (-1); } if (strchr(name, '=') != NULL) { ctx->error(ctx, "variable name contains ="); return (-1); } if (args->argc < 1) value = NULL; else value = args->argv[1]; if (args_has(self->args, 'g')) env = &global_environ; else { if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) return (-1); env = &s->environ; } if (args_has(self->args, 'u')) { if (value != NULL) { ctx->error(ctx, "can't specify a value with -u"); return (-1); } environ_unset(env, name); } else if (args_has(self->args, 'r')) { if (value != NULL) { ctx->error(ctx, "can't specify a value with -r"); return (-1); } environ_set(env, name, NULL); } else { if (value == NULL) { ctx->error(ctx, "no value specified"); return (-1); } environ_set(env, name, value); } return (0); }
int cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct session *s; if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL) return (-1); server_destroy_session(s); session_destroy(s); return (0); }
int cmd_lock_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct session *s; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); server_lock_session(s); recalculate_sizes(); return (0); }
int cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct session *s; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); xfree(s->name); s->name = xstrdup(data->arg); server_status_session(s); return (0); }
int cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_switch_client_data *data = self->data; struct client *c; struct session *s; if (data == NULL) return (0); if ((c = cmd_find_client(ctx, data->name)) == NULL) return (-1); s = NULL; if (data->flag_next) { if ((s = session_next_session(c->session)) == NULL) { ctx->error(ctx, "can't find next session"); return (-1); } } else if (data->flag_previous) { if ((s = session_previous_session(c->session)) == NULL) { ctx->error(ctx, "can't find previous session"); return (-1); } } else if (data->flag_last) { if (c->last_session != NULL && session_alive(c->last_session)) s = c->last_session; if (s == NULL) { ctx->error(ctx, "can't find last session"); return (-1); } } else s = cmd_find_session(ctx, data->target); if (s == NULL) return (-1); if (c->session != NULL) c->last_session = c->session; c->session = s; session_update_activity(s); recalculate_sizes(); server_check_unattached(); server_redraw_client(c); return (0); }
/* ARGSUSED */ int cmd_list_clients_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct client *c; struct session *s; struct format_tree *ft; const char *template; u_int i; char *line; if (args_has(args, 't')) { s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (-1); } else s = NULL;
int cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; const struct options_table_entry *table, *oe; struct session *s; struct winlink *wl; struct options *oo; struct options_entry *o; const char *optval; if (args_has(self->args, 's')) { oo = &global_options; table = server_options_table; } else if (args_has(self->args, 'w') || self->entry == &cmd_show_window_options_entry) { table = window_options_table; if (args_has(self->args, 'g')) oo = &global_w_options; else { wl = cmd_find_window(ctx, args_get(args, 't'), NULL); if (wl == NULL) return (-1); oo = &wl->window->options; } } else { table = session_options_table; if (args_has(self->args, 'g')) oo = &global_s_options; else { s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (-1); oo = &s->options; } } for (oe = table; oe->name != NULL; oe++) { if ((o = options_find1(oo, oe->name)) == NULL) continue; optval = options_table_print_entry(oe, o); ctx->print(ctx, "%s %s", oe->name, optval); } return (0); }
enum cmd_retval cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; if (args_has(args, 'a')) cmd_list_windows_server(self, cmdq); else { s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); cmd_list_windows_session(self, s, cmdq, 0); } return (CMD_RETURN_NORMAL); }
int cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct session *s; if (args_has(args, 'a')) cmd_list_windows_server(self, ctx); else { s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (-1); cmd_list_windows_session(self, s, ctx, 0); } return (0); }
int cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; struct paste_buffer *pb; mode_t mask; FILE *f; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); if (data->buffer == -1) { if ((pb = paste_get_top(&s->buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) { ctx->error(ctx, "no buffer %d", data->buffer); return (-1); } } mask = umask(S_IRWXG | S_IRWXO); if (data->chflags & CMD_CHFLAG('a')) f = fopen(data->arg, "ab"); else f = fopen(data->arg, "wb"); umask(mask); if (f == NULL) { ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); return (-1); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { ctx->error(ctx, "%s: fwrite error", data->arg); fclose(f); return (-1); } fclose(f); return (0); }
int cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); if (data->buffer == -1) paste_free_top(&s->buffers); else if (paste_free_index(&s->buffers, data->buffer) != 0) { ctx->error(ctx, "no buffer %d", data->buffer); return (-1); } return (0); }
int cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct client *c; struct session *s; if ((c = cmd_find_client(ctx, args_get(args, 'c'))) == NULL) return (-1); s = NULL; if (args_has(args, 'n')) { if ((s = session_next_session(c->session)) == NULL) { ctx->error(ctx, "can't find next session"); return (-1); } } else if (args_has(args, 'p')) { if ((s = session_previous_session(c->session)) == NULL) { ctx->error(ctx, "can't find previous session"); return (-1); } } else if (args_has(args, 'l')) { if (c->last_session != NULL && session_alive(c->last_session)) s = c->last_session; if (s == NULL) { ctx->error(ctx, "can't find last session"); return (-1); } } else s = cmd_find_session(ctx, args_get(args, 't'), 0); if (s == NULL) return (-1); if (c->session != NULL) c->last_session = c->session; c->session = s; session_update_activity(s); recalculate_sizes(); server_check_unattached(); server_redraw_client(c); return (0); }
enum cmd_retval cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; struct session *s; struct format_tree *ft; const char *template; u_int i; char *line; if (args_has(args, 't')) { s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); } else s = NULL; if ((template = args_get(args, 'F')) == NULL)
enum cmd_retval cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c, *c2; struct session *s; enum msgtype msgtype; u_int i; if (args_has(args, 'P')) msgtype = MSG_DETACHKILL; else msgtype = MSG_DETACH; if (args_has(args, 's')) { s = cmd_find_session(cmdq, args_get(args, 's'), 0); if (s == NULL) return (CMD_RETURN_ERROR); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); if (c != NULL && c->session == s) server_write_client(c, msgtype, NULL, 0); } } else { c = cmd_find_client(cmdq, args_get(args, 't'), 0); if (c == NULL) return (CMD_RETURN_ERROR); if (args_has(args, 'a')) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c2 = ARRAY_ITEM(&clients, i); if (c2 == NULL || c == c2) continue; server_write_client(c2, msgtype, NULL, 0); } } else server_write_client(c, msgtype, NULL, 0); } return (CMD_RETURN_STOP); }
enum cmd_retval cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct session *s; struct winlink *wl; const struct options_table_entry *table; struct options *oo; int quiet; if (args_has(self->args, 's')) { oo = global_options; table = server_options_table; } else if (args_has(self->args, 'w') || self->entry == &cmd_show_window_options_entry) { table = window_options_table; if (args_has(self->args, 'g')) oo = global_w_options; else { wl = cmd_find_window(cmdq, args_get(args, 't'), NULL); if (wl == NULL) return (CMD_RETURN_ERROR); oo = wl->window->options; } } else { table = session_options_table; if (args_has(self->args, 'g')) oo = global_s_options; else { s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); oo = s->options; } } quiet = args_has(self->args, 'q'); if (args->argc == 0) return (cmd_show_options_all(self, cmdq, table, oo)); else return (cmd_show_options_one(self, cmdq, oo, quiet)); }