version 1.79, 2013/03/24 09:27:20 |
version 1.80, 2013/03/24 09:54:10 |
|
|
struct window_pane *cmd_lookup_paneid(const char *); |
struct window_pane *cmd_lookup_paneid(const char *); |
struct winlink *cmd_lookup_winlink_windowid(struct session *, const char *); |
struct winlink *cmd_lookup_winlink_windowid(struct session *, const char *); |
struct window *cmd_lookup_windowid(const char *); |
struct window *cmd_lookup_windowid(const char *); |
struct session *cmd_window_session(struct cmd_ctx *, |
struct session *cmd_window_session(struct cmd_q *, struct window *, |
struct window *, struct winlink **); |
struct winlink **); |
struct winlink *cmd_find_window_offset(const char *, struct session *, int *); |
struct winlink *cmd_find_window_offset(const char *, struct session *, int *); |
int cmd_find_index_offset(const char *, struct session *, int *); |
int cmd_find_index_offset(const char *, struct session *, int *); |
struct window_pane *cmd_find_pane_offset(const char *, struct winlink *); |
struct window_pane *cmd_find_pane_offset(const char *, struct winlink *); |
|
|
struct cmd_ctx * |
|
cmd_get_ctx(struct client *cmdclient, struct client *curclient) |
|
{ |
|
struct cmd_ctx *ctx; |
|
|
|
ctx = xcalloc(1, sizeof *ctx); |
|
ctx->references = 0; |
|
|
|
ctx->cmdclient = cmdclient; |
|
ctx->curclient = curclient; |
|
|
|
cmd_ref_ctx(ctx); |
|
return (ctx); |
|
} |
|
|
|
void |
|
cmd_free_ctx(struct cmd_ctx *ctx) |
|
{ |
|
if (ctx->cmdclient != NULL) |
|
ctx->cmdclient->references--; |
|
if (ctx->curclient != NULL) |
|
ctx->curclient->references--; |
|
if (--ctx->references == 0) |
|
free(ctx); |
|
} |
|
|
|
void |
|
cmd_ref_ctx(struct cmd_ctx *ctx) |
|
{ |
|
ctx->references++; |
|
if (ctx->cmdclient != NULL) |
|
ctx->cmdclient->references++; |
|
if (ctx->curclient != NULL) |
|
ctx->curclient->references++; |
|
} |
|
|
|
int |
int |
cmd_pack_argv(int argc, char **argv, char *buf, size_t len) |
cmd_pack_argv(int argc, char **argv, char *buf, size_t len) |
{ |
{ |
|
|
} |
} |
|
|
struct cmd * |
struct cmd * |
cmd_parse(int argc, char **argv, char **cause) |
cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause) |
{ |
{ |
const struct cmd_entry **entryp, *entry; |
const struct cmd_entry **entryp, *entry; |
struct cmd *cmd; |
struct cmd *cmd; |
|
|
if (entry->check != NULL && entry->check(args) != 0) |
if (entry->check != NULL && entry->check(args) != 0) |
goto usage; |
goto usage; |
|
|
cmd = xmalloc(sizeof *cmd); |
cmd = xcalloc(1, sizeof *cmd); |
cmd->entry = entry; |
cmd->entry = entry; |
cmd->args = args; |
cmd->args = args; |
|
|
|
if (file != NULL) |
|
cmd->file = xstrdup(file); |
|
cmd->line = line; |
|
|
return (cmd); |
return (cmd); |
|
|
ambiguous: |
ambiguous: |
|
|
* session from all sessions. |
* session from all sessions. |
*/ |
*/ |
struct session * |
struct session * |
cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached) |
cmd_current_session(struct cmd_q *cmdq, int prefer_unattached) |
{ |
{ |
struct msg_command_data *data = ctx->msgdata; |
struct msg_command_data *data = cmdq->msgdata; |
struct client *c = ctx->cmdclient; |
struct client *c = cmdq->client; |
struct session *s; |
struct session *s; |
struct sessionslist ss; |
struct sessionslist ss; |
struct winlink *wl; |
struct winlink *wl; |
struct window_pane *wp; |
struct window_pane *wp; |
|
const char *path; |
int found; |
int found; |
|
|
if (ctx->curclient != NULL && ctx->curclient->session != NULL) |
if (c != NULL && c->session != NULL) |
return (ctx->curclient->session); |
return (c->session); |
|
|
/* |
/* |
* If the name of the calling client's pty is know, build a list of the |
* If the name of the calling client's pty is know, build a list of the |
* sessions that contain it and if any choose either the first or the |
* sessions that contain it and if any choose either the first or the |
* newest. |
* newest. |
*/ |
*/ |
if (c != NULL && c->tty.path != NULL) { |
path = c == NULL ? NULL : c->tty.path; |
|
if (path != NULL) { |
ARRAY_INIT(&ss); |
ARRAY_INIT(&ss); |
RB_FOREACH(s, sessions, &sessions) { |
RB_FOREACH(s, sessions, &sessions) { |
found = 0; |
found = 0; |
RB_FOREACH(wl, winlinks, &s->windows) { |
RB_FOREACH(wl, winlinks, &s->windows) { |
TAILQ_FOREACH(wp, &wl->window->panes, entry) { |
TAILQ_FOREACH(wp, &wl->window->panes, entry) { |
if (strcmp(wp->tty, c->tty.path) == 0) { |
if (strcmp(wp->tty, path) == 0) { |
found = 1; |
found = 1; |
break; |
break; |
} |
} |
|
|
* then of all clients. |
* then of all clients. |
*/ |
*/ |
struct client * |
struct client * |
cmd_current_client(struct cmd_ctx *ctx) |
cmd_current_client(struct cmd_q *cmdq) |
{ |
{ |
struct session *s; |
struct session *s; |
struct client *c; |
struct client *c; |
struct clients cc; |
struct clients cc; |
u_int i; |
u_int i; |
|
|
if (ctx->curclient != NULL) |
if (cmdq->client != NULL && cmdq->client->session != NULL) |
return (ctx->curclient); |
return (cmdq->client); |
|
|
/* |
/* |
* No current client set. Find the current session and return the |
* No current client set. Find the current session and return the |
* newest of its clients. |
* newest of its clients. |
*/ |
*/ |
s = cmd_current_session(ctx, 0); |
s = cmd_current_session(cmdq, 0); |
if (s != NULL && !(s->flags & SESSION_UNATTACHED)) { |
if (s != NULL && !(s->flags & SESSION_UNATTACHED)) { |
ARRAY_INIT(&cc); |
ARRAY_INIT(&cc); |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { |
|
|
|
|
/* Find the target client or report an error and return NULL. */ |
/* Find the target client or report an error and return NULL. */ |
struct client * |
struct client * |
cmd_find_client(struct cmd_ctx *ctx, const char *arg, int quiet) |
cmd_find_client(struct cmd_q *cmdq, const char *arg, int quiet) |
{ |
{ |
struct client *c; |
struct client *c; |
char *tmparg; |
char *tmparg; |
|
|
|
|
/* A NULL argument means the current client. */ |
/* A NULL argument means the current client. */ |
if (arg == NULL) { |
if (arg == NULL) { |
c = cmd_current_client(ctx); |
c = cmd_current_client(cmdq); |
if (c == NULL && !quiet) |
if (c == NULL && !quiet) |
ctx->error(ctx, "no clients"); |
cmdq_error(cmdq, "no clients"); |
return (c); |
return (c); |
} |
} |
tmparg = xstrdup(arg); |
tmparg = xstrdup(arg); |
|
|
|
|
/* If no client found, report an error. */ |
/* If no client found, report an error. */ |
if (c == NULL && !quiet) |
if (c == NULL && !quiet) |
ctx->error(ctx, "client not found: %s", tmparg); |
cmdq_error(cmdq, "client not found: %s", tmparg); |
|
|
free(tmparg); |
free(tmparg); |
return (c); |
return (c); |
|
|
|
|
/* Find session and winlink for window. */ |
/* Find session and winlink for window. */ |
struct session * |
struct session * |
cmd_window_session(struct cmd_ctx *ctx, struct window *w, struct winlink **wlp) |
cmd_window_session(struct cmd_q *cmdq, struct window *w, struct winlink **wlp) |
{ |
{ |
struct session *s; |
struct session *s; |
struct sessionslist ss; |
struct sessionslist ss; |
struct winlink *wl; |
struct winlink *wl; |
|
|
/* If this window is in the current session, return that winlink. */ |
/* If this window is in the current session, return that winlink. */ |
s = cmd_current_session(ctx, 0); |
s = cmd_current_session(cmdq, 0); |
if (s != NULL) { |
if (s != NULL) { |
wl = winlink_find_by_window(&s->windows, w); |
wl = winlink_find_by_window(&s->windows, w); |
if (wl != NULL) { |
if (wl != NULL) { |
|
|
|
|
/* Find the target session or report an error and return NULL. */ |
/* Find the target session or report an error and return NULL. */ |
struct session * |
struct session * |
cmd_find_session(struct cmd_ctx *ctx, const char *arg, int prefer_unattached) |
cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached) |
{ |
{ |
struct session *s; |
struct session *s; |
struct window_pane *wp; |
struct window_pane *wp; |
|
|
|
|
/* A NULL argument means the current session. */ |
/* A NULL argument means the current session. */ |
if (arg == NULL) |
if (arg == NULL) |
return (cmd_current_session(ctx, prefer_unattached)); |
return (cmd_current_session(cmdq, prefer_unattached)); |
|
|
/* Lookup as pane id or window id. */ |
/* Lookup as pane id or window id. */ |
if ((wp = cmd_lookup_paneid(arg)) != NULL) |
if ((wp = cmd_lookup_paneid(arg)) != NULL) |
return (cmd_window_session(ctx, wp->window, NULL)); |
return (cmd_window_session(cmdq, wp->window, NULL)); |
if ((w = cmd_lookup_windowid(arg)) != NULL) |
if ((w = cmd_lookup_windowid(arg)) != NULL) |
return (cmd_window_session(ctx, w, NULL)); |
return (cmd_window_session(cmdq, w, NULL)); |
|
|
/* Trim a single trailing colon if any. */ |
/* Trim a single trailing colon if any. */ |
tmparg = xstrdup(arg); |
tmparg = xstrdup(arg); |
|
|
/* An empty session name is the current session. */ |
/* An empty session name is the current session. */ |
if (*tmparg == '\0') { |
if (*tmparg == '\0') { |
free(tmparg); |
free(tmparg); |
return (cmd_current_session(ctx, prefer_unattached)); |
return (cmd_current_session(cmdq, prefer_unattached)); |
} |
} |
|
|
/* Find the session, if any. */ |
/* Find the session, if any. */ |
|
|
/* If no session found, report an error. */ |
/* If no session found, report an error. */ |
if (s == NULL) { |
if (s == NULL) { |
if (ambiguous) |
if (ambiguous) |
ctx->error(ctx, "more than one session: %s", tmparg); |
cmdq_error(cmdq, "more than one session: %s", tmparg); |
else |
else |
ctx->error(ctx, "session not found: %s", tmparg); |
cmdq_error(cmdq, "session not found: %s", tmparg); |
} |
} |
|
|
free(tmparg); |
free(tmparg); |
|
|
|
|
/* Find the target session and window or report an error and return NULL. */ |
/* Find the target session and window or report an error and return NULL. */ |
struct winlink * |
struct winlink * |
cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) |
cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp) |
{ |
{ |
struct session *s; |
struct session *s; |
struct winlink *wl; |
struct winlink *wl; |
|
|
* Find the current session. There must always be a current session, if |
* Find the current session. There must always be a current session, if |
* it can't be found, report an error. |
* it can't be found, report an error. |
*/ |
*/ |
if ((s = cmd_current_session(ctx, 0)) == NULL) { |
if ((s = cmd_current_session(cmdq, 0)) == NULL) { |
ctx->error(ctx, "can't establish current session"); |
cmdq_error(cmdq, "can't establish current session"); |
return (NULL); |
return (NULL); |
} |
} |
|
|
|
|
|
|
/* Lookup as pane id. */ |
/* Lookup as pane id. */ |
if ((wp = cmd_lookup_paneid(arg)) != NULL) { |
if ((wp = cmd_lookup_paneid(arg)) != NULL) { |
s = cmd_window_session(ctx, wp->window, &wl); |
s = cmd_window_session(cmdq, wp->window, &wl); |
if (sp != NULL) |
if (sp != NULL) |
*sp = s; |
*sp = s; |
return (wl); |
return (wl); |
|
|
|
|
no_session: |
no_session: |
if (ambiguous) |
if (ambiguous) |
ctx->error(ctx, "multiple sessions: %s", arg); |
cmdq_error(cmdq, "multiple sessions: %s", arg); |
else |
else |
ctx->error(ctx, "session not found: %s", arg); |
cmdq_error(cmdq, "session not found: %s", arg); |
free(sessptr); |
free(sessptr); |
return (NULL); |
return (NULL); |
|
|
not_found: |
not_found: |
if (ambiguous) |
if (ambiguous) |
ctx->error(ctx, "multiple windows: %s", arg); |
cmdq_error(cmdq, "multiple windows: %s", arg); |
else |
else |
ctx->error(ctx, "window not found: %s", arg); |
cmdq_error(cmdq, "window not found: %s", arg); |
free(sessptr); |
free(sessptr); |
return (NULL); |
return (NULL); |
} |
} |
|
|
* example if it is going to be created). |
* example if it is going to be created). |
*/ |
*/ |
int |
int |
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp) |
cmd_find_index(struct cmd_q *cmdq, const char *arg, struct session **sp) |
{ |
{ |
struct session *s; |
struct session *s; |
struct winlink *wl; |
struct winlink *wl; |
|
|
* Find the current session. There must always be a current session, if |
* Find the current session. There must always be a current session, if |
* it can't be found, report an error. |
* it can't be found, report an error. |
*/ |
*/ |
if ((s = cmd_current_session(ctx, 0)) == NULL) { |
if ((s = cmd_current_session(cmdq, 0)) == NULL) { |
ctx->error(ctx, "can't establish current session"); |
cmdq_error(cmdq, "can't establish current session"); |
return (-2); |
return (-2); |
} |
} |
|
|
|
|
|
|
no_session: |
no_session: |
if (ambiguous) |
if (ambiguous) |
ctx->error(ctx, "multiple sessions: %s", arg); |
cmdq_error(cmdq, "multiple sessions: %s", arg); |
else |
else |
ctx->error(ctx, "session not found: %s", arg); |
cmdq_error(cmdq, "session not found: %s", arg); |
free(sessptr); |
free(sessptr); |
return (-2); |
return (-2); |
|
|
invalid_index: |
invalid_index: |
if (ambiguous) |
if (ambiguous) |
goto not_found; |
goto not_found; |
ctx->error(ctx, "invalid index: %s", arg); |
cmdq_error(cmdq, "invalid index: %s", arg); |
|
|
free(sessptr); |
free(sessptr); |
return (-2); |
return (-2); |
|
|
not_found: |
not_found: |
if (ambiguous) |
if (ambiguous) |
ctx->error(ctx, "multiple windows: %s", arg); |
cmdq_error(cmdq, "multiple windows: %s", arg); |
else |
else |
ctx->error(ctx, "window not found: %s", arg); |
cmdq_error(cmdq, "window not found: %s", arg); |
free(sessptr); |
free(sessptr); |
return (-2); |
return (-2); |
} |
} |
|
|
* such as mysession:mywindow.0. |
* such as mysession:mywindow.0. |
*/ |
*/ |
struct winlink * |
struct winlink * |
cmd_find_pane(struct cmd_ctx *ctx, |
cmd_find_pane(struct cmd_q *cmdq, |
const char *arg, struct session **sp, struct window_pane **wpp) |
const char *arg, struct session **sp, struct window_pane **wpp) |
{ |
{ |
struct session *s; |
struct session *s; |
|
|
u_int idx; |
u_int idx; |
|
|
/* Get the current session. */ |
/* Get the current session. */ |
if ((s = cmd_current_session(ctx, 0)) == NULL) { |
if ((s = cmd_current_session(cmdq, 0)) == NULL) { |
ctx->error(ctx, "can't establish current session"); |
cmdq_error(cmdq, "can't establish current session"); |
return (NULL); |
return (NULL); |
} |
} |
if (sp != NULL) |
if (sp != NULL) |
|
|
|
|
/* Lookup as pane id. */ |
/* Lookup as pane id. */ |
if ((*wpp = cmd_lookup_paneid(arg)) != NULL) { |
if ((*wpp = cmd_lookup_paneid(arg)) != NULL) { |
s = cmd_window_session(ctx, (*wpp)->window, &wl); |
s = cmd_window_session(cmdq, (*wpp)->window, &wl); |
if (sp != NULL) |
if (sp != NULL) |
*sp = s; |
*sp = s; |
return (wl); |
return (wl); |
|
|
winptr[period - arg] = '\0'; |
winptr[period - arg] = '\0'; |
if (*winptr == '\0') |
if (*winptr == '\0') |
wl = s->curw; |
wl = s->curw; |
else if ((wl = cmd_find_window(ctx, winptr, sp)) == NULL) |
else if ((wl = cmd_find_window(cmdq, winptr, sp)) == NULL) |
goto error; |
goto error; |
|
|
/* Find the pane section and look it up. */ |
/* Find the pane section and look it up. */ |
|
|
lookup_string: |
lookup_string: |
/* Try pane string description. */ |
/* Try pane string description. */ |
if ((*wpp = window_find_string(wl->window, paneptr)) == NULL) { |
if ((*wpp = window_find_string(wl->window, paneptr)) == NULL) { |
ctx->error(ctx, "can't find pane: %s", paneptr); |
cmdq_error(cmdq, "can't find pane: %s", paneptr); |
goto error; |
goto error; |
} |
} |
|
|
|
|
return (s->curw); |
return (s->curw); |
|
|
/* Try as a window and use the active pane. */ |
/* Try as a window and use the active pane. */ |
if ((wl = cmd_find_window(ctx, arg, sp)) != NULL) |
if ((wl = cmd_find_window(cmdq, arg, sp)) != NULL) |
*wpp = wl->window->active; |
*wpp = wl->window->active; |
return (wl); |
return (wl); |
|
|
|
|
* directory. |
* directory. |
*/ |
*/ |
const char * |
const char * |
cmd_get_default_path(struct cmd_ctx *ctx, const char *cwd) |
cmd_get_default_path(struct cmd_q *cmdq, const char *cwd) |
{ |
{ |
|
struct client *c = cmdq->client; |
struct session *s; |
struct session *s; |
struct environ_entry *envent; |
struct environ_entry *envent; |
const char *root; |
const char *root; |
|
|
size_t skip; |
size_t skip; |
static char path[MAXPATHLEN]; |
static char path[MAXPATHLEN]; |
|
|
if ((s = cmd_current_session(ctx, 0)) == NULL) |
if ((s = cmd_current_session(cmdq, 0)) == NULL) |
return (NULL); |
return (NULL); |
|
|
if (cwd == NULL) |
if (cwd == NULL) |
|
|
return (cwd); |
return (cwd); |
} else { |
} else { |
/* Empty or relative path. */ |
/* Empty or relative path. */ |
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) |
if (c != NULL && c->session == NULL && c->cwd != NULL) |
root = ctx->cmdclient->cwd; |
root = c->cwd; |
else if (ctx->curclient != NULL && s->curw != NULL) |
else if (s->curw != NULL) |
root = get_proc_cwd(s->curw->window->active->fd); |
root = get_proc_cwd(s->curw->window->active->fd); |
else |
else |
return (s->cwd); |
return (s->cwd); |