1 Commits
1.0 ... 0.9

Author SHA1 Message Date
no_author
dc2b811476 This commit was manufactured by cvs2svn to create tag 'TMUX_0_9'. 2009-07-02 18:26:56 +00:00
153 changed files with 6879 additions and 11920 deletions

38
CHANGES
View File

@@ -1,39 +1,3 @@
CHANGES FROM 0.9 TO 1.0, 20 Sept 2009
* Option to alter the format of the window title set by tmux.
* Backoff for a while after multiple incorrect password attempts.
* Quick display of pane numbers (C-b q).
* Better choose-window, choose-session commands and a new choose-client command.
* Option to request multiple responses when using command-prompt.
* Improved environment handling.
* Combine wrapped lines when pasting.
* Option to override terminal settings (terminal-overrides).
* Use the full range of ACS characters for drawing pane separator lines.
* Customisable mode keys.
* Status line colour options, with embedded colours in status-left/right, and
an option to centre the window list.
* Much improved layouts, including both horizontal and vertical splitting.
* Optional visual bell, activity and content indications.
* Set the utf8 and status-utf8 options when the server is started with -u.
* display-message command to show a message in the status line, by default some
information about the current window.
* Improved current process detection on NetBSD.
* unlink-window -k is now the same as kill-window.
* attach-session now works from inside tmux.
* A system-wide configuration file, /etc/tmux.conf.
* A number of new commands in copy mode, including searching.
* Panes are now specified using the target (-t) notation.
* -t now accepts fnmatch(3) patterns and looks for prefixes.
* Translate \r into \n when pasting.
* Support for binding commands to keys without the prefix key
* Support for alternate screen (terminfo smcup/rmcup).
* Maintain data that goes off screen after reducing the window size, so it can
be restored when the size is increased again.
* New if-shell command to test a shell command before running a tmux command.
* tmux now works as the shell.
* Man page reorganisation.
* Many minor additions, much code tidying and several bug fixes.
CHANGES FROM 0.8 TO 0.9, 01 July 2009 CHANGES FROM 0.8 TO 0.9, 01 July 2009
* Major changes to build infrastructure: cleanup of makefiles and addition * Major changes to build infrastructure: cleanup of makefiles and addition
@@ -1358,7 +1322,7 @@ The list of older changes is below.
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.300 2009-09-20 18:54:21 nicm Exp $ $Id: CHANGES,v 1.299 2009-07-01 22:15:16 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms

61
FAQ
View File

@@ -42,17 +42,16 @@ include as much of the following information as possible:
Please send feature requests by email to nicm@users.sourceforge.net. Please send feature requests by email to nicm@users.sourceforge.net.
* Why do you use the screen terminal description inside tmux? It sucks. * Why do you use the screen termcap inside tmux? It sucks.
It is already widely available. It is planned to change to something else such It is already widely available. It is planned to change to something else
as xterm-xfree86 at some point, if possible. such as xterm-color at some point, if possible.
* I don't see any colour in my terminal! Help! * I don't see any colour in my terminal! Help!
On some platforms, common terminal descriptions such as xterm do not include On some platforms, common termcaps such as xterm do not include colour. screen
colour. screen ignores this, tmux does not. If the terminal emulator in use ignores this, tmux does not. If the terminal emulator in use supports colour,
supports colour, use a value for TERM which correctly lists this, such as use a termcap which correctly lists this, such as xterm-color.
xterm-color.
* tmux freezes my terminal when I attach to a session. I even have to kill -9 * tmux freezes my terminal when I attach to a session. I even have to kill -9
the shell it was started from to recover! the shell it was started from to recover!
@@ -93,22 +92,13 @@ checking the LC_ALL, LC_CTYPE and LANG environment variables. list-clients may
be used to check if this is detected correctly; if not, the -u command-line be used to check if this is detected correctly; if not, the -u command-line
flag may be specified when creating or attaching a client to a tmux session: flag may be specified when creating or attaching a client to a tmux session:
$ tmux -u new $ tmux -u new
* How do I use a 256 colour terminal? * How do I use a 256 colour terminal?
Provided the underlying terminal supports 256 colours, it is usually sufficient tmux will attempt to detect a 256 colour terminal both by looking at the Co
to add the following to ~/.tmux.conf: termcap entry and, as this is broken for some terminals such as xterm-256color,
by looking for the string "256col" in the termcap name.
set -g default-terminal "screen-256color"
Note that some platforms do not support "screen-256color" ("infocmp
screen-256color" will return an error) - in this case see the next entry in
this FAQ.
tmux attempts to detect a 256 colour terminal both by looking at the colors
terminfo entry and by looking for the string "256col" in the TERM environment
variable.
If both these methods fail, the -2 flag may be passed to tmux when attaching If both these methods fail, the -2 flag may be passed to tmux when attaching
to a session to indicate the terminal supports 256 colours. to a session to indicate the terminal supports 256 colours.
@@ -116,18 +106,22 @@ to a session to indicate the terminal supports 256 colours.
* vim or $otherprogram doesn't display 256 colours. What's up? * vim or $otherprogram doesn't display 256 colours. What's up?
Some programs attempt to detect the number of colours a terminal is capable of Some programs attempt to detect the number of colours a terminal is capable of
by checking the colors terminfo or Co termcap entry. However, this is not by checking the Co termcap entry. However, this is not reliable, and in any
reliable, and in any case is missing from the "screen" terminal description case is missing from the "screen" termcap used inside tmux.
used inside tmux.
There are two options (aside from using "screen-256color") to allow programs to There are three options to allow programs to recognise they are running on
recognise they are running on a 256-colour terminal inside tmux: a 256-colour terminal inside tmux:
- Manually force the application to use 256 colours always or if TERM is set to - Manually force the application to use 256 colours always or if TERM is set to
screen. For vim, you can do this by overriding the t_Co option, see screen. For vim, you can do this by overriding the t_Co option, see
http://vim.wikia.com/wiki/256_colors_in_vim. http://vim.wikia.com/wiki/256_colors_in_vim.
- Creating a custom terminfo file that includes colors#256 in ~/.terminfo and - If the platform includes it, using the "screen-256color" termcap (set
using it instead. These may be compiled with tic(1). TERM=screen-256color). "infocmp screen-256color" can be used to check if this
is supported. It is not currently possible to set this globally inside tmux
but it may be done in a shell startup script by checking if TERM is screen
and exporting TERM=screen-256color instead.
- Creating a custom terminfo file that includes Co#256 in ~/.terminfo and using
it instead. These may be compiled with tic(1).
* How do I make Ctrl-PgUp and Ctrl-PgDn work in vim? * How do I make Ctrl-PgUp and Ctrl-PgDn work in vim?
@@ -193,12 +187,11 @@ Automatic window renaming may use a lot of CPU, particularly on slow computers:
if this is a problem, turn it off with "setw -g automatic-rename off". If this if this is a problem, turn it off with "setw -g automatic-rename off". If this
doesn't fix it, please report the problem. doesn't fix it, please report the problem.
* I use PuTTY and my tmux window pane separators are all qqqqqqqqq's! * How do I prevent tmux from resizing my PuTTY window?
PuTTY is using a character set translation that doesn't support ACS line This isn't tmux's fault, but happens because the initialisation strings for the
drawing. With a Unicode font, try setting PuTTY to use a different translation terminal in use (set through TERM) request it. PuTTY can be told to ignore such
on the Window -> Translation configuration page. For example, change UTF-8 to requests: in the configuration window under Terminal -> Features, check the
ISO-8859-1 or CP437. It may also be necessary to adjust the way PuTTY treats "Disable remote-controlled terminal resizing" box.
line drawing characters in the lower part of the same configuration page.
$Id: FAQ,v 1.29 2009-08-08 20:46:26 nicm Exp $ $Id: FAQ,v 1.23 2009-07-01 19:49:56 nicm Exp $

View File

@@ -1,15 +1,23 @@
# $Id: GNUmakefile,v 1.114 2009-09-20 18:54:21 nicm Exp $ # $Id: GNUmakefile,v 1.107 2009-07-01 22:10:06 nicm Exp $
.PHONY: clean .PHONY: clean
VERSION= 1.0 VERSION= 0.9
#FDEBUG= 1 #FDEBUG= 1
CC?= gcc CC?= gcc
CFLAGS+= -DBUILD="\"$(VERSION)\"" CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib LDFLAGS+= -L/usr/local/lib
LIBS+= LIBS+= -lncurses
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
ifeq ($(shell (LC_ALL=C $(CC) -v 2>&1|awk '/gcc version 4/') || true), )
CPPFLAGS:= -I. -I- $(CPPFLAGS)
else
CPPFLAGS:= -iquote. $(CPPFLAGS)
endif
ifdef FDEBUG ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG CFLAGS+= -g -ggdb -DDEBUG
@@ -19,17 +27,6 @@ CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
endif endif
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
ifeq ($(shell (LC_ALL=C $(CC) -v 2>&1|awk '/gcc version 4|clang/') || true), )
CPPFLAGS:= -I. -I- $(CPPFLAGS)
else
CPPFLAGS:= -iquote. $(CPPFLAGS)
ifdef FDEBUG
CFLAGS+= -Wno-pointer-sign
endif
endif
PREFIX?= /usr/local PREFIX?= /usr/local
INSTALLDIR= install -d INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555 INSTALLBIN= install -g bin -o root -m 555
@@ -48,12 +45,9 @@ depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend $(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
clean: clean:
rm -f tmux *.o *~ *.core *.log compat/*.o rm -f tmux *.o .depend *~ *.core *.log compat/*.o
clean-depend: clean-all: clean
rm -f .depend
clean-all: clean clean-depend
rm -f config.h config.mk rm -f config.h config.mk
install: all install: all
@@ -61,5 +55,3 @@ install: all
$(INSTALLBIN) tmux $(DESTDIR)$(PREFIX)/bin/tmux $(INSTALLBIN) tmux $(DESTDIR)$(PREFIX)/bin/tmux
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1 $(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) tmux.1 $(DESTDIR)$(PREFIX)/man/man1/tmux.1 $(INSTALLMAN) tmux.1 $(DESTDIR)$(PREFIX)/man/man1/tmux.1
-include .depend

View File

@@ -1,16 +1,25 @@
# $Id: Makefile,v 1.149 2009-09-20 18:54:21 nicm Exp $ # $Id: Makefile,v 1.142 2009-07-01 22:10:06 nicm Exp $
.SUFFIXES: .c .o .SUFFIXES: .c .o
.PHONY: clean .PHONY: clean
VERSION= 1.0 VERSION= 0.9
#FDEBUG= 1 #FDEBUG= 1
CC?= cc CC?= cc
CFLAGS+= -DBUILD="\"$(VERSION)\"" CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib LDFLAGS+= -L/usr/local/lib
LIBS+= LIBS+= -lncurses
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
CCV!= (LC_ALL=C ${CC} -v 2>&1|awk '/gcc version 4/') || true
.if empty(CCV)
CPPFLAGS:= -I. -I- -I/usr/local/include ${CPPFLAGS}
.else
CPPFLAGS:= -iquote. -I/usr/local/include ${CPPFLAGS}
.endif
.ifdef FDEBUG .ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG CFLAGS+= -g -ggdb -DDEBUG
@@ -20,18 +29,6 @@ CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
.endif .endif
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
CCV!= (LC_ALL=C ${CC} -v 2>&1|awk '/gcc version 4|clang/') || true
.if empty(CCV)
CPPFLAGS:= -I. -I- -I/usr/local/include ${CPPFLAGS}
.else
CPPFLAGS:= -iquote. -I/usr/local/include ${CPPFLAGS}
.ifdef FDEBUG
CFLAGS+= -Wno-pointer-sign
.endif
.endif
PREFIX?= /usr/local PREFIX?= /usr/local
INSTALLDIR= install -d INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555 INSTALLBIN= install -g bin -o root -m 555
@@ -53,12 +50,9 @@ depend:
mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c} mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
clean: clean:
rm -f tmux *.o *~ *.core *.log compat/*.o rm -f tmux *.o .depend *~ *.core *.log compat/*.o
clean-depend: clean-all: clean
rm -f .depend
clean-all: clean clean-depend
rm -f config.h config.mk rm -f config.h config.mk
install: all install: all

6
NOTES
View File

@@ -41,6 +41,10 @@ The following is a summary of major features implemented in this version:
- A configuration file. - A configuration file.
- UTF-8 support. - UTF-8 support.
And major missing features:
- No support for programs changing termios(4) settings or other tty(4) ioctls.
A more extensive, but rough, todo list is included in the TODO file. A more extensive, but rough, todo list is included in the TODO file.
tmux also depends on several features of the client terminal (TERM), if these tmux also depends on several features of the client terminal (TERM), if these
@@ -83,4 +87,4 @@ welcome. Please send by email to:
-- Nicholas Marriott <nicm@users.sf.net> -- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.49 2009-07-06 18:53:24 nicm Exp $ $Id: NOTES,v 1.48 2009-07-01 19:49:56 nicm Exp $

98
TODO
View File

@@ -1,4 +1,5 @@
- window creation/idle time - window creation/idle time
- could use bsearch all over the place or get rid of smaller tables (clientmsg)
- better errors when creating new windows/sessions (how?) - better errors when creating new windows/sessions (how?)
- implicitly add exec to the commands for new windows (switch to disable it)? - implicitly add exec to the commands for new windows (switch to disable it)?
- it would be nice to have multichar commands eg C-b K K - it would be nice to have multichar commands eg C-b K K
@@ -6,16 +7,21 @@
extend list-clients to list clients attached to a session (-a for all?) extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session? bring back detach-session to detach all clients on a session?
- allow fnmatch for -c, so that you can, eg, detach all clients - allow fnmatch for -c, so that you can, eg, detach all clients
- bind non prefix keys
- garbage collect window history (100 lines at a time?) if it hasn't been used - garbage collect window history (100 lines at a time?) if it hasn't been used
in $x time (need window creation/use times) in $x time (need window creation/use times)
- lift SHRT_MAX limits for history? - lift SHRT_MAX limits for history?
- better mode features: search - audit copy/scroll and other modes for problems with very small windows
- better mode features: search, back word, forward word, etc
- flags to centre screen in window - flags to centre screen in window
- better terminal emulation - better terminal emulation (identify, insert mode, some other bits)
- audit for leftover/unused code
- activity/bell should be per-window not per-link? what if it is cur win in - activity/bell should be per-window not per-link? what if it is cur win in
session not being watched? session not being watched?
- tidy up window modes
- next prev word etc in command prompt; also ^K - next prev word etc in command prompt; also ^K
- many more info() displays for various things - many more info() displays for various things
- vi half page scroll
- backspace should perhaps wrap backwards over newlines which were not moved - backspace should perhaps wrap backwards over newlines which were not moved
down by a newline: screen and the OS X terminal does this but xterm and most down by a newline: screen and the OS X terminal does this but xterm and most
others do not. this might be hard: a flag for each grid line (top bit of size others do not. this might be hard: a flag for each grid line (top bit of size
@@ -25,10 +31,17 @@
- use a better termcap internally instead of screen, perhaps xterm - use a better termcap internally instead of screen, perhaps xterm
- kill all but current pane - kill all but current pane
- fix rxvt cursor fg issue (text under cursor can have non-white fg) - fix rxvt cursor fg issue (text under cursor can have non-white fg)
- key handling sucks a bit and may need to be reworked
- some people find first window being 0 rather than 1 is awkward on the
keyboard
- client sx/sy should be in tty, then can let the terminal wrap at edge - client sx/sy should be in tty, then can let the terminal wrap at edge
to allow xterm to pick up it should be one line for its c/p to allow xterm to pick up it should be one line for its c/p
- should be able to move to a hidden pane and it would be moved into view. pane - should be able to move to a hidden pane and it would be moved into view. pane
number in status line/top-right would be cool for this number in status line/top-right would be cool for this
- command to run something without a window at all - output to
window-more. what for? isnt this the same as doing it w/ splitw/neww now?
- would be nice if tmux could be the shell (tmux attach, but hard link to tmux
binary as "tmuxsh" or wrapper script?) problems with tty dev permissions
- support other mouse modes (highlight etc) and use it in copy mode - support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically? - set-remain-on-exit is a bit of a hack, some way to do it generically?
- set-option should be set-session-option and should be overall global options - set-option should be set-session-option and should be overall global options
@@ -36,71 +49,44 @@
also quiet, utf8 and maybe other flags? also quiet, utf8 and maybe other flags?
-g is a bit unexpected in conf file -g is a bit unexpected in conf file
- clear window title on exit - clear window title on exit
- refer to windows by name etc (duplicates? fnmatch?)
- the output code (tty.c) could do with optimisation depending on term - the output code (tty.c) could do with optimisation depending on term
capibilities capibilities
- would be nice to be able to use "--" to mark start of command w/ neww etc - would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting to avoid quoting
- goto line and search history in copy/scroll modes - goto line and search history in copy/scroll modes
- a command to display the status line briefly when it is turned off
- clone session command - clone session command
- make command sequences more usable: don't require space after ;, handle - make command sequences more usable: don't require space after ;, handle
errors better errors better
- might be nice if attach-session behaved like switch-client inside an
existing client
- key to switch to copy mode from scroll mode - key to switch to copy mode from scroll mode
- attach should have a flag to create session if it doesn't exist - attach should have a flag to create session if it doesn't exist
- rename split-window -> split-pane?? - layout/split stuff:
** NEW layout design:
1. finish rewrite manual with tree of layout_cell
2. convert automatic layout modes to produce a tree and make
them one-off operations
3. move any size/position details from window_pane to layout_cell
3.5. fix -p/-l on split
4. a way to address panes by name ("top-left") and position ("0,0")
TO TEST: force-width/height OK, respawn-window, rotate-window OK, break-pane??
** rename split-window -> split-pane
- fix UTF-8 guesswork on sparc64, improve tty checks - fix UTF-8 guesswork on sparc64, improve tty checks
- choice and more mode would be better per client than per window? - choice and more mode would be better per client than per window?
- hooks to which commands may be attached, for example: tmux add-hook
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
$HOME/.tmux-session.conf
- get it passing all the vttest tests that don't require resizing the terminal
- esc seq to set window title should be documented and should set
automatic-rename
- way to set socket path from config file
- XXX once env stuff is in, default-path and VISUAL/EDITOR should be picked up
when session is started
- what about utmp etc? can tmux update it like screen? setgid?
- H/M/L commands in copy mode with vi-keys, for jumping to the top/middle/last
line on the screen
- split list-windows into separate list-windows and list-panes
- warts on current naming:
- display-time but message-fg/bg/attr
- list-* vs show-*
- server-info
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-*
- pcvt25 doesn't work properly, why? (bce?)
- tidy up and prioritise todo list ;-)
- it is only possible to specify 8 colours to fg/bg options; should be able to
set 256 as well
- neww and attach can create a session if none exists?
would work fine with config file since
- a way for force-width/height to apply to only one pane (how?)
- **** a command to run something without a window and send any output to the
window-more. if no output, info() a line saying "'%s' returned %d". so i can
bind mpc control commands to function keys ;-)
- command to list what is actually running in each window with command line,
pid (need some adaption of the osdep code)
- string option to change/remove the symbols (*-+ etc) in status line
- support for bce
- it would be nice if the start/end line keys in copy mode were aware of
wrapped lines
- per session locking
- some way to force a screen to use the entire terminal even if it is forced - some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F) to be smaller by other clients. pan smaller terminal? (like screen F)
-- idea of a "view" onto a window, need base x/y offsets - close/redirect stderr when popen to child proc for #() in status line
for redraw - if-shell-command command to run a tmux command if a shell command returns true
- a window option which means data is echoed to all panes in a window - hooks to which commands may be attached, for example:
- support running tmux from inside tmux [#(), if-shell] -- tmux add-hook "new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file $HOME/.tmux-session.conf
generic system-like function which may take a callback - get it passing all the vttest tests that don't require resizing the terminal
also sets up environment (TMUX) and has a timeout - does tmux require a exmple conf? where does it go?
for #(): command schedular, status line queues it with a time, run in - there are an awful lot of commands. maybe separate man page for conf
main loop, and uses most recent result -- can also be used for persistent file/commands -similar to ssh/ssh_config?
commands which never exit just continually output - esc seq to set window title should be documented and should set automatic-rename
for if-shell, callback?? - *** get rid of PANE_HIDDEN -- initially just check for outside window
- handle resize better in copy mode - way to set socket path from config file
- way to copy stuff that is off screen due to resize - the "window with one pane" vs window distinction is weird, eg you can't kill-pane the last pane
- fix line wrapping c&p problems in xterm etc
- a way to address panes by name ("top-left") and position ("0,0")
- ability to specify multiple prefix keys
- commands should be able to succeed or fail and have || or && for command
lists
- support the mouse wheel to scroll through history

194
arg.c Normal file
View File

@@ -0,0 +1,194 @@
/* $Id: arg.c,v 1.6 2009-06-25 15:25:45 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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 <fnmatch.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
struct client *arg_lookup_client(const char *);
struct session *arg_lookup_session(const char *);
struct client *
arg_lookup_client(const char *name)
{
struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && strcmp(name, c->tty.path) == 0)
return (c);
}
return (NULL);
}
struct session *
arg_lookup_session(const char *name)
{
struct session *s, *newest = NULL;
struct timeval *tv;
u_int i;
tv = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL || fnmatch(name, s->name, 0) != 0)
continue;
if (tv == NULL || timercmp(&s->tv, tv, >)) {
newest = s;
tv = &s->tv;
}
}
return (newest);
}
struct client *
arg_parse_client(const char *arg)
{
struct client *c;
char *arg2;
size_t n;
if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (n && arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* Try and look up the client name. */
c = arg_lookup_client(arg2);
xfree(arg2);
return (c);
}
return (NULL);
}
struct session *
arg_parse_session(const char *arg)
{
struct session *s;
struct client *c;
char *arg2;
size_t n;
if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (n && arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* See if the argument matches a session. */
if ((s = arg_lookup_session(arg2)) != NULL) {
xfree(arg2);
return (s);
}
/* If not try a client. */
if ((c = arg_lookup_client(arg2)) != NULL) {
xfree(arg2);
return (c->session);
}
xfree(arg2);
}
return (NULL);
}
int
arg_parse_window(const char *arg, struct session **s, int *idx)
{
char *arg2, *ptr;
const char *errstr;
*idx = -1;
/* Handle no argument or a single :. */
if (arg == NULL || (arg[0] == ':' && arg[1] == '\0')) {
*s = arg_parse_session(NULL);
return (0);
}
/* Find the separator if any. */
arg2 = xstrdup(arg);
ptr = strrchr(arg2, ':');
/*
* If it is first, this means no session name, so use current session
* and try to convert the rest as index.
*/
if (ptr == arg2) {
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}
xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}
/* If missing, try as an index, else look up immediately. */
if (ptr == NULL) {
*idx = strtonum(arg2, 0, INT_MAX, &errstr);
if (errstr == NULL) {
/* This is good as an index; use current session. */
xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}
*idx = -1;
goto lookup;
}
/* If last, strip it and look up as a session. */
if (ptr[1] == '\0') {
*ptr = '\0';
goto lookup;
}
/* Present but not first and not last. Break and convert both. */
*ptr = '\0';
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}
lookup:
/* Look up as session. */
*s = arg_parse_session(arg2);
xfree(arg2);
if (*s == NULL)
return (1);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: buffer-poll.c,v 1.16 2009-08-19 09:28:10 nicm Exp $ */ /* $Id: buffer-poll.c,v 1.14 2009-06-25 16:22:36 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,8 +29,10 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
{ {
ssize_t n; ssize_t n;
#ifdef HAVE_POLL
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP)) if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
return (-1); return (-1);
#endif
if (pfd->revents & POLLIN) { if (pfd->revents & POLLIN) {
buffer_ensure(in, BUFSIZ); buffer_ensure(in, BUFSIZ);
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in)); n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));

View File

@@ -1,4 +1,4 @@
/* $Id: buffer.c,v 1.8 2009-08-21 21:09:13 tcunha Exp $ */ /* $Id: buffer.c,v 1.7 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -100,6 +100,9 @@ buffer_remove(struct buffer *b, size_t size)
void void
buffer_write(struct buffer *b, const void *data, size_t size) buffer_write(struct buffer *b, const void *data, size_t size)
{ {
if (size == 0)
fatalx("zero size");
buffer_ensure(b, size); buffer_ensure(b, size);
memcpy(BUFFER_IN(b), data, size); memcpy(BUFFER_IN(b), data, size);
buffer_add(b, size); buffer_add(b, size);
@@ -124,7 +127,7 @@ buffer_write8(struct buffer *b, uint8_t n)
{ {
buffer_ensure(b, 1); buffer_ensure(b, 1);
BUFFER_IN(b)[0] = n; BUFFER_IN(b)[0] = n;
b->size++; buffer_add(b, 1);
} }
/* Extract an 8-bit value. */ /* Extract an 8-bit value. */

30
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.22 2009-08-24 16:27:03 tcunha Exp $ */ /* $Id: cfg.c,v 1.18 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -51,15 +51,25 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
} }
int int
load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause) load_cfg(const char *path, char **cause)
{ {
FILE *f; FILE *f;
u_int n; u_int n;
struct stat sb;
char *buf, *line, *ptr; char *buf, *line, *ptr;
size_t len; size_t len;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd_ctx ctx; struct cmd_ctx ctx;
if (stat(path, &sb) != 0) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (-1);
}
if (!S_ISREG(sb.st_mode)) {
xasprintf(cause, "%s: not a regular file", path);
return (-1);
}
if ((f = fopen(path, "rb")) == NULL) { if ((f = fopen(path, "rb")) == NULL) {
xasprintf(cause, "%s: %s", path, strerror(errno)); xasprintf(cause, "%s: %s", path, strerror(errno));
return (1); return (1);
@@ -87,20 +97,16 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
continue; continue;
cfg_cause = NULL; cfg_cause = NULL;
if (ctxin == NULL) { ctx.msgdata = NULL;
ctx.msgdata = NULL; ctx.cursession = NULL;
ctx.curclient = NULL; ctx.curclient = NULL;
ctx.cmdclient = NULL;
} else {
ctx.msgdata = ctxin->msgdata;
ctx.curclient = ctxin->curclient;
ctx.cmdclient = ctxin->cmdclient;
}
ctx.error = cfg_error; ctx.error = cfg_error;
ctx.print = cfg_print; ctx.print = cfg_print;
ctx.info = cfg_print; ctx.info = cfg_print;
ctx.cmdclient = NULL;
cfg_cause = NULL; cfg_cause = NULL;
cmd_list_exec(cmdlist, &ctx); cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
@@ -116,8 +122,6 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
return (0); return (0);
error: error:
if (line != NULL)
xfree(line);
fclose(f); fclose(f);
xasprintf(&ptr, "%s: %s at line %u", path, *cause, n); xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);

View File

@@ -1,4 +1,4 @@
/* $Id: client-fn.c,v 1.10 2009-08-14 21:04:04 tcunha Exp $ */ /* $Id: client-fn.c,v 1.6 2009-03-04 17:24:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,7 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -64,27 +63,30 @@ client_fill_session(struct msg_command_data *data)
void void
client_write_server( client_write_server(
struct client_ctx *cctx, enum msgtype type, void *buf, size_t len) struct client_ctx *cctx, enum hdrtype type, void *buf, size_t len)
{ {
imsg_compose(&cctx->ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len); struct hdr hdr;
hdr.type = type;
hdr.size = len;
buffer_write(cctx->srv_out, &hdr, sizeof hdr);
if (buf != NULL && len > 0)
buffer_write(cctx->srv_out, buf, len);
} }
void void
client_suspend(void) client_write_server2(struct client_ctx *cctx,
enum hdrtype type, void *buf1, size_t len1, void *buf2, size_t len2)
{ {
struct sigaction act; struct hdr hdr;
memset(&act, 0, sizeof act); hdr.type = type;
sigemptyset(&act.sa_mask); hdr.size = len1 + len2;
act.sa_flags = SA_RESTART; buffer_write(cctx->srv_out, &hdr, sizeof hdr);
act.sa_handler = SIG_DFL; if (buf1 != NULL && len1 > 0)
if (sigaction(SIGTSTP, &act, NULL) != 0) buffer_write(cctx->srv_out, buf1, len1);
fatal("sigaction failed"); if (buf2 != NULL && len2 > 0)
buffer_write(cctx->srv_out, buf2, len2);
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
} }

159
client-msg.c Normal file
View File

@@ -0,0 +1,159 @@
/* $Id: client-msg.c,v 1.19 2009-06-25 15:25:45 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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 <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_shutdown(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exited(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **);
struct client_msg {
enum hdrtype type;
int (*fn)(struct hdr *, struct client_ctx *, char **);
};
struct client_msg client_msg_table[] = {
{ MSG_DETACH, client_msg_fn_detach },
{ MSG_ERROR, client_msg_fn_error },
{ MSG_EXIT, client_msg_fn_exit },
{ MSG_EXITED, client_msg_fn_exited },
{ MSG_SHUTDOWN, client_msg_fn_shutdown },
{ MSG_SUSPEND, client_msg_fn_suspend },
};
int
client_msg_dispatch(struct client_ctx *cctx, char **error)
{
struct hdr hdr;
struct client_msg *msg;
u_int i;
if (BUFFER_USED(cctx->srv_in) < sizeof hdr)
return (1);
memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr);
if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size)
return (1);
buffer_remove(cctx->srv_in, sizeof hdr);
for (i = 0; i < nitems(client_msg_table); i++) {
msg = client_msg_table + i;
if (msg->type == hdr.type) {
if (msg->fn(&hdr, cctx, error) != 0)
return (-1);
return (0);
}
}
fatalx("unexpected message");
}
int
client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
{
if (hdr->size == SIZE_MAX)
fatalx("bad MSG_ERROR size");
*error = xmalloc(hdr->size + 1);
buffer_read(cctx->srv_in, *error, hdr->size);
(*error)[hdr->size] = '\0';
return (-1);
}
int
client_msg_fn_detach(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_DETACH size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_DETACH;
return (0);
}
int
client_msg_fn_shutdown(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_SHUTDOWN;
return (0);
}
int
client_msg_fn_exit(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_EXIT size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_EXIT;
return (0);
}
int
client_msg_fn_exited(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_EXITED size");
return (-1);
}
int
client_msg_fn_suspend(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
struct sigaction act;
if (hdr->size != 0)
fatalx("bad MSG_SUSPEND size");
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
act.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &act, NULL) != 0)
fatal("sigaction failed");
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
return (0);
}

217
client.c
View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.70 2009-09-03 21:06:30 tcunha Exp $ */ /* $Id: client.c,v 1.53 2009-07-01 23:06:32 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,19 +33,19 @@
#include "tmux.h" #include "tmux.h"
void client_send_environ(struct client_ctx *);
void client_handle_winch(struct client_ctx *); void client_handle_winch(struct client_ctx *);
int int
client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags) client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
{ {
struct sockaddr_un sa; struct sockaddr_un sa;
struct stat sb; struct stat sb;
struct msg_identify_data data; struct msg_identify_data data;
struct winsize ws; struct winsize ws;
size_t size; size_t size;
int fd, fd2, mode; int mode;
char *name, *term; struct buffer *b;
char *name;
#ifdef HAVE_SETPROCTITLE #ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN]; char rpathbuf[MAXPATHLEN];
#endif #endif
@@ -57,8 +57,8 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
#endif #endif
if (lstat(path, &sb) != 0) { if (lstat(path, &sb) != 0) {
if (cmdflags & CMD_STARTSERVER && errno == ENOENT) { if (start_server && errno == ENOENT) {
if ((fd = server_start(path)) == -1) if ((cctx->srv_fd = server_start(path)) == -1)
goto start_failed; goto start_failed;
goto server_started; goto server_started;
} }
@@ -77,14 +77,15 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
goto not_found; goto not_found;
} }
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket"); fatal("socket");
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) { if (connect(
cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
if (errno == ECONNREFUSED) { if (errno == ECONNREFUSED) {
if (unlink(path) != 0 || !(cmdflags & CMD_STARTSERVER)) if (unlink(path) != 0 || !start_server)
goto not_found; goto not_found;
if ((fd = server_start(path)) == -1) if ((cctx->srv_fd = server_start(path)) == -1)
goto start_failed; goto start_failed;
goto server_started; goto server_started;
} }
@@ -92,40 +93,34 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
} }
server_started: server_started:
if ((mode = fcntl(fd, F_GETFL)) == -1) if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
fatal("fcntl failed"); fatal("fcntl failed");
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed"); fatal("fcntl failed");
imsg_init(&cctx->ibuf, fd); cctx->srv_in = buffer_create(BUFSIZ);
cctx->srv_out = buffer_create(BUFSIZ);
if (cmdflags & CMD_SENDENVIRON)
client_send_environ(cctx);
if (isatty(STDIN_FILENO)) { if (isatty(STDIN_FILENO)) {
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)"); fatal("ioctl(TIOCGWINSZ)");
data.version = PROTOCOL_VERSION;
data.flags = flags; data.flags = flags;
data.sx = ws.ws_col; data.sx = ws.ws_col;
data.sy = ws.ws_row; data.sy = ws.ws_row;
*data.tty = '\0';
if (getcwd(data.cwd, sizeof data.cwd) == NULL) if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0'; *data.cwd = '\0';
*data.term = '\0';
if ((term = getenv("TERM")) != NULL) {
if (strlcpy(data.term,
term, sizeof data.term) >= sizeof data.term)
*data.term = '\0';
}
*data.tty = '\0';
if ((name = ttyname(STDIN_FILENO)) == NULL) if ((name = ttyname(STDIN_FILENO)) == NULL)
fatal("ttyname failed"); fatal("ttyname failed");
if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty) if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty)
fatalx("ttyname failed"); fatalx("ttyname failed");
fd2 = dup(STDIN_FILENO); b = buffer_create(BUFSIZ);
imsg_compose(&cctx->ibuf, MSG_IDENTIFY, cmd_send_string(b, getenv("TERM"));
PROTOCOL_VERSION, -1, fd2, &data, sizeof data); client_write_server2(cctx, MSG_IDENTIFY,
&data, sizeof data, BUFFER_OUT(b), BUFFER_USED(b));
buffer_destroy(b);
} }
return (0); return (0);
@@ -139,41 +134,19 @@ not_found:
return (1); return (1);
} }
void
client_send_environ(struct client_ctx *cctx)
{
char **var;
struct msg_environ_data data;
for (var = environ; *var != NULL; var++) {
if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
continue;
client_write_server(cctx, MSG_ENVIRON, &data, sizeof data);
}
}
int int
client_main(struct client_ctx *cctx) client_main(struct client_ctx *cctx)
{ {
struct pollfd pfd; struct pollfd pfd;
int n, nfds; char *error;
int xtimeout; /* Yay for ncurses namespace! */
siginit(); siginit();
logfile("client"); logfile("client");
/* error = NULL;
* imsg_read in the first client poll loop (before the terminal has while (!sigterm) {
* been initialiased) may have read messages into the buffer after the
* MSG_READY switched to here. Process anything outstanding now so poll
* doesn't hang waiting for messages that have already arrived.
*/
if (client_msg_dispatch(cctx) != 0)
goto out;
for (;;) {
if (sigterm)
client_write_server(cctx, MSG_EXITING, NULL, 0);
if (sigchld) { if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG); waitpid(WAIT_ANY, NULL, WNOHANG);
sigchld = 0; sigchld = 0;
@@ -186,37 +159,32 @@ client_main(struct client_ctx *cctx)
sigcont = 0; sigcont = 0;
} }
pfd.fd = cctx->ibuf.fd; switch (client_msg_dispatch(cctx, &error)) {
case -1:
goto out;
case 0:
/* May be more in buffer, don't let poll block. */
xtimeout = 0;
break;
default:
/* Out of data, poll may block. */
xtimeout = INFTIM;
break;
}
pfd.fd = cctx->srv_fd;
pfd.events = POLLIN; pfd.events = POLLIN;
if (cctx->ibuf.w.queued > 0) if (BUFFER_USED(cctx->srv_out) > 0)
pfd.events |= POLLOUT; pfd.events |= POLLOUT;
if ((nfds = poll(&pfd, 1, INFTIM)) == -1) { if (poll(&pfd, 1, xtimeout) == -1) {
if (errno == EAGAIN || errno == EINTR) if (errno == EAGAIN || errno == EINTR)
continue; continue;
fatal("poll failed"); fatal("poll failed");
} }
if (nfds == 0)
continue;
if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL)) if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
fatalx("socket error"); goto server_dead;
if (pfd.revents & POLLIN) {
if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) {
cctx->exittype = CCTX_DIED;
break;
}
if (client_msg_dispatch(cctx) != 0)
break;
}
if (pfd.revents & POLLOUT) {
if (msgbuf_write(&cctx->ibuf.w) < 0) {
cctx->exittype = CCTX_DIED;
break;
}
}
} }
out: out:
@@ -224,27 +192,28 @@ out:
printf("[terminated]\n"); printf("[terminated]\n");
return (1); return (1);
} }
switch (cctx->exittype) {
case CCTX_DIED: if (cctx->flags & CCTX_SHUTDOWN) {
printf("[lost server]\n");
return (0);
case CCTX_SHUTDOWN:
printf("[server exited]\n"); printf("[server exited]\n");
return (0); return (0);
case CCTX_EXIT: }
if (cctx->errstr != NULL) {
printf("[error: %s]\n", cctx->errstr); if (cctx->flags & CCTX_EXIT) {
return (1);
}
printf("[exited]\n"); printf("[exited]\n");
return (0); return (0);
case CCTX_DETACH: }
if (cctx->flags & CCTX_DETACH) {
printf("[detached]\n"); printf("[detached]\n");
return (0); return (0);
default:
printf("[unknown error]\n");
return (1);
} }
printf("[error: %s]\n", error);
return (1);
server_dead:
printf("[lost server]\n");
return (0);
} }
void void
@@ -262,69 +231,3 @@ client_handle_winch(struct client_ctx *cctx)
sigwinch = 0; sigwinch = 0;
} }
int
client_msg_dispatch(struct client_ctx *cctx)
{
struct imsg imsg;
struct msg_print_data printdata;
ssize_t n, datalen;
for (;;) {
if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1)
fatalx("imsg_get failed");
if (n == 0)
return (0);
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
switch (imsg.hdr.type) {
case MSG_DETACH:
if (datalen != 0)
fatalx("bad MSG_DETACH size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_DETACH;
break;
case MSG_ERROR:
if (datalen != sizeof printdata)
fatalx("bad MSG_ERROR size");
memcpy(&printdata, imsg.data, sizeof printdata);
printdata.msg[(sizeof printdata.msg) - 1] = '\0';
/* Error string used after exit message from server. */
cctx->errstr = xstrdup(printdata.msg);
imsg_free(&imsg);
return (-1);
case MSG_EXIT:
if (datalen != 0)
fatalx("bad MSG_EXIT size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_EXIT;
break;
case MSG_EXITED:
if (datalen != 0)
fatalx("bad MSG_EXITED size");
imsg_free(&imsg);
return (-1);
case MSG_SHUTDOWN:
if (datalen != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_SHUTDOWN;
break;
case MSG_SUSPEND:
if (datalen != 0)
fatalx("bad MSG_SUSPEND size");
client_suspend();
break;
default:
fatalx("unexpected message");
}
imsg_free(&imsg);
}
}

16
clock.c
View File

@@ -1,4 +1,4 @@
/* $Id: clock.c,v 1.7 2009-09-11 14:13:52 tcunha Exp $ */ /* $Id: clock.c,v 1.4 2009-05-04 17:58:25 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -112,6 +112,8 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
strftime(tim, sizeof tim, "%H:%M", localtime(&t)); strftime(tim, sizeof tim, "%H:%M", localtime(&t));
screen_write_clearscreen(ctx); screen_write_clearscreen(ctx);
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = colour;
if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) { if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) {
if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) { if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) {
@@ -119,8 +121,7 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
y = screen_size_y(s) / 2; y = screen_size_y(s) / 2;
screen_write_cursormove(ctx, x, y); screen_write_cursormove(ctx, x, y);
memcpy(&gc, &grid_default_cell, sizeof gc); gc.fg = colour;
colour_set_fg(&gc, colour);
screen_write_puts(ctx, &gc, "%s", tim); screen_write_puts(ctx, &gc, "%s", tim);
} }
return; return;
@@ -129,8 +130,6 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
x = (screen_size_x(s) / 2) - 3 * strlen(tim); x = (screen_size_x(s) / 2) - 3 * strlen(tim);
y = (screen_size_y(s) / 2) - 3; y = (screen_size_y(s) / 2) - 3;
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_bg(&gc, colour);
for (ptr = tim; *ptr != '\0'; ptr++) { for (ptr = tim; *ptr != '\0'; ptr++) {
if (*ptr >= '0' && *ptr <= '9') if (*ptr >= '0' && *ptr <= '9')
idx = *ptr - '0'; idx = *ptr - '0';
@@ -148,10 +147,13 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
} }
for (j = 0; j < 5; j++) { for (j = 0; j < 5; j++) {
screen_write_cursormove(ctx, x, y + j);
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
screen_write_cursormove(ctx, x + i, y + j);
if (clock_table[idx][j][i]) if (clock_table[idx][j][i])
screen_write_putc(ctx, &gc, ' '); gc.attr |= GRID_ATTR_REVERSE;
else
gc.attr &= ~GRID_ATTR_REVERSE;
screen_write_putc(ctx, &gc, ' ');
} }
} }
x += 6; x += 6;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-attach-session.c,v 1.32 2009-08-09 17:48:55 tcunha Exp $ */ /* $Id: cmd-attach-session.c,v 1.26 2009-06-25 16:34:50 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_attach_session_entry = { const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach", "attach-session", "attach",
"[-d] " CMD_TARGET_SESSION_USAGE, "[-d] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, CMD_CHFLAG('d'), CMD_DFLAG|CMD_CANTNEST|CMD_STARTSERVER,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_attach_session_exec, cmd_attach_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -42,10 +44,10 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct session *s; struct session *s;
struct client *c; char *cause;
const char *update;
char *overrides, *cause; if (ctx->curclient != NULL)
u_int i; return (0);
if (ARRAY_LENGTH(&sessions) == 0) { if (ARRAY_LENGTH(&sessions) == 0) {
ctx->error(ctx, "no sessions"); ctx->error(ctx, "no sessions");
@@ -54,53 +56,24 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
if (ctx->cmdclient == NULL && ctx->curclient == NULL) if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
return (0); ctx->error(ctx, "not a terminal");
return (-1);
if (ctx->cmdclient == NULL) {
if (data->chflags & CMD_CHFLAG('d')) {
/*
* Can't use server_write_session in case attaching to
* the same session as currently attached to.
*/
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (c == ctx->curclient)
continue;
server_write_client(c, MSG_DETACH, NULL, 0);
}
}
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
} else {
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
overrides =
options_get_string(&s->options, "terminal-overrides");
if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "terminal open failed: %s", cause);
xfree(cause);
return (-1);
}
if (data->chflags & CMD_CHFLAG('d'))
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
update = options_get_string(&s->options, "update-environment");
environ_update(update, &ctx->cmdclient->environ, &s->environ);
server_redraw_client(ctx->cmdclient);
} }
recalculate_sizes();
return (1); /* 1 means don't tell command client to exit */ if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
ctx->error(ctx, "terminal open failed: %s", cause);
xfree(cause);
return (-1);
}
if (data->flags & CMD_DFLAG)
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
recalculate_sizes();
server_redraw_client(ctx->cmdclient);
return (1);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-bind-key.c,v 1.25 2009-07-28 23:19:06 tcunha Exp $ */ /* $Id: cmd-bind-key.c,v 1.21 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -28,28 +26,26 @@
int cmd_bind_key_parse(struct cmd *, int, char **, char **); int cmd_bind_key_parse(struct cmd *, int, char **, char **);
int cmd_bind_key_exec(struct cmd *, struct cmd_ctx *); int cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
void cmd_bind_key_send(struct cmd *, struct buffer *);
void cmd_bind_key_recv(struct cmd *, struct buffer *);
void cmd_bind_key_free(struct cmd *); void cmd_bind_key_free(struct cmd *);
size_t cmd_bind_key_print(struct cmd *, char *, size_t); size_t cmd_bind_key_print(struct cmd *, char *, size_t);
int cmd_bind_key_table(struct cmd *, struct cmd_ctx *);
struct cmd_bind_key_data { struct cmd_bind_key_data {
int key; int key;
int can_repeat; int can_repeat;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
int command_key;
char *tablename;
char *modecmd;
}; };
const struct cmd_entry cmd_bind_key_entry = { const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind", "bind-key", "bind",
"[-cnr] [-t key-table] key command [arguments]", "[-r] key command [arguments]",
0, 0, 0,
NULL, NULL,
cmd_bind_key_parse, cmd_bind_key_parse,
cmd_bind_key_exec, cmd_bind_key_exec,
cmd_bind_key_send,
cmd_bind_key_recv,
cmd_bind_key_free, cmd_bind_key_free,
cmd_bind_key_print cmd_bind_key_print
}; };
@@ -58,29 +54,17 @@ int
cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause) cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
{ {
struct cmd_bind_key_data *data; struct cmd_bind_key_data *data;
int opt, no_prefix = 0; int opt;
self->data = data = xmalloc(sizeof *data); self->data = data = xmalloc(sizeof *data);
data->can_repeat = 0; data->can_repeat = 0;
data->cmdlist = NULL; data->cmdlist = NULL;
data->command_key = 0;
data->tablename = NULL;
data->modecmd = NULL;
while ((opt = getopt(argc, argv, "cnrt:")) != -1) { while ((opt = getopt(argc, argv, "r")) != -1) {
switch (opt) { switch (opt) {
case 'c':
data->command_key = 1;
break;
case 'n':
no_prefix = 1;
break;
case 'r': case 'r':
data->can_repeat = 1; data->can_repeat = 1;
break; break;
case 't':
data->tablename = xstrdup(optarg);
break;
default: default:
goto usage; goto usage;
} }
@@ -94,19 +78,11 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
xasprintf(cause, "unknown key: %s", argv[0]); xasprintf(cause, "unknown key: %s", argv[0]);
goto error; goto error;
} }
if (!no_prefix)
data->key |= KEYC_PREFIX;
argc--; argc--;
argv++; argv++;
if (data->tablename != NULL) { if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
if (argc != 1) goto error;
goto usage;
data->modecmd = xstrdup(argv[0]);
} else {
if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
goto error;
}
return (0); return (0);
@@ -125,8 +101,6 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
if (data == NULL) if (data == NULL)
return (0); return (0);
if (data->tablename != NULL)
return (cmd_bind_key_table(self, ctx));
key_bindings_add(data->key, data->can_repeat, data->cmdlist); key_bindings_add(data->key, data->can_repeat, data->cmdlist);
data->cmdlist = NULL; /* avoid free */ data->cmdlist = NULL; /* avoid free */
@@ -134,37 +108,23 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
return (0); return (0);
} }
int void
cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx) cmd_bind_key_send(struct cmd *self, struct buffer *b)
{ {
struct cmd_bind_key_data *data = self->data; struct cmd_bind_key_data *data = self->data;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
enum mode_key_cmd cmd;
if ((mtab = mode_key_findtable(data->tablename)) == NULL) { buffer_write(b, data, sizeof *data);
ctx->error(ctx, "unknown key table: %s", data->tablename); cmd_list_send(data->cmdlist, b);
return (-1); }
}
cmd = mode_key_fromstring(mtab->cmdstr, data->modecmd); void
if (cmd == MODEKEY_NONE) { cmd_bind_key_recv(struct cmd *self, struct buffer *b)
ctx->error(ctx, "unknown command: %s", data->modecmd); {
return (-1); struct cmd_bind_key_data *data;
}
self->data = data = xmalloc(sizeof *data);
mtmp.key = data->key & ~KEYC_PREFIX; buffer_read(b, data, sizeof *data);
mtmp.mode = data->command_key ? 1 : 0; data->cmdlist = cmd_list_recv(b);
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
mbind->cmd = cmd;
return (0);
}
mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key;
mbind->mode = mtmp.mode;
mbind->cmd = cmd;
SPLAY_INSERT(mode_key_tree, mtab->tree, mbind);
return (0);
} }
void void
@@ -174,10 +134,6 @@ cmd_bind_key_free(struct cmd *self)
if (data->cmdlist != NULL) if (data->cmdlist != NULL)
cmd_list_free(data->cmdlist); cmd_list_free(data->cmdlist);
if (data->tablename != NULL)
xfree(data->tablename);
if (data->modecmd != NULL)
xfree(data->modecmd);
xfree(data); xfree(data);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.8 2009-08-16 19:16:27 tcunha Exp $ */ /* $Id: cmd-break-pane.c,v 1.3 2009-05-18 21:01:38 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,31 +30,41 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_break_pane_entry = { const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp", "break-pane", "breakp",
CMD_TARGET_PANE_USAGE " [-d]", CMD_PANE_WINDOW_USAGE " [-d]",
0, CMD_CHFLAG('d'), CMD_DFLAG,
cmd_target_init, cmd_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_break_pane_exec, cmd_break_pane_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
int int
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct session *s; struct session *s;
struct window_pane *wp; struct window_pane *wp;
struct window *w; struct window *w;
char *cause; char *cause;
int base_idx;
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (window_count_panes(wl->window) == 1) { if (window_count_panes(wl->window) == 1) {
ctx->error(ctx, "can't break with only one pane"); ctx->error(ctx, "can't break pane: %d", data->pane);
return (-1); return (-1);
} }
@@ -64,18 +74,17 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl->window->active == NULL) if (wl->window->active == NULL)
wl->window->active = TAILQ_NEXT(wp, entry); wl->window->active = TAILQ_NEXT(wp, entry);
} }
layout_close_pane(wp); layout_refresh(wl->window, 0);
w = wp->window = window_create1(s->sx, s->sy); w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp; w->active = wp;
w->name = default_window_name(w); w->name = default_window_name(w);
layout_init(w);
base_idx = options_get_number(&s->options, "base-index"); wl = session_attach(s, w, -1, &cause); /* can't fail */
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */ if (!(data->flags & CMD_DFLAG))
if (!(data->chflags & CMD_CHFLAG('d')))
session_select(s, wl->idx); session_select(s, wl->idx);
layout_refresh(w, 0);
server_redraw_session(s); server_redraw_session(s);

View File

@@ -1,152 +0,0 @@
/* $Id: cmd-choose-client.c,v 1.3 2009-09-07 23:59:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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 <ctype.h>
#include "tmux.h"
/*
* Enter choice mode to choose a client.
*/
int cmd_choose_client_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_client_callback(void *, int);
void cmd_choose_client_free(void *);
const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_choose_client_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_choose_client_data {
struct client *client;
char *template;
};
int
cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_choose_client_data *cdata;
struct winlink *wl;
struct client *c;
u_int i, idx, cur;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c == ctx->curclient)
cur = idx;
idx++;
window_choose_add(wl->window->active, i,
"%s: %s [%ux%u %s]%s", c->tty.path,
c->session->name, c->tty.sx, c->tty.sy,
c->tty.termname, c->tty.flags & TTY_UTF8 ? " (utf8)" : "");
}
cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL)
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("detach-client -t '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
cur, cmd_choose_client_callback, cmd_choose_client_free, cdata);
return (0);
}
void
cmd_choose_client_callback(void *data, int idx)
{
struct cmd_choose_client_data *cdata = data;
struct client *c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause;
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
if ((u_int) idx > ARRAY_LENGTH(&clients) - 1)
return;
c = ARRAY_ITEM(&clients, idx);
if (c == NULL || c->session == NULL)
return;
template = cmd_template_replace(cdata->template, c->tty.path, 1);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, "%s", cause);
xfree(cause);
}
xfree(template);
return;
}
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_client_free(void *data)
{
struct cmd_choose_client_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-session.c,v 1.13 2009-09-07 23:59:19 tcunha Exp $ */ /* $Id: cmd-choose-session.c,v 1.7 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -29,22 +27,22 @@
int cmd_choose_session_exec(struct cmd *, struct cmd_ctx *); int cmd_choose_session_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_session_callback(void *, int); void cmd_choose_session_callback(void *, int);
void cmd_choose_session_free(void *);
const struct cmd_entry cmd_choose_session_entry = { const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL, "choose-session", NULL,
CMD_TARGET_WINDOW_USAGE " [template]", CMD_TARGET_WINDOW_USAGE,
CMD_ARG01, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_choose_session_exec, cmd_choose_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
struct cmd_choose_session_data { struct cmd_choose_session_data {
struct client *client; u_int client;
char *template;
}; };
int int
@@ -83,15 +81,10 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL) cdata->client = server_client_index(ctx->curclient);
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("switch-client -t '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active, window_choose_ready(
cur, cmd_choose_session_callback, cmd_choose_session_free, cdata); wl->window->active, cur, cmd_choose_session_callback, cdata);
return (0); return (0);
} }
@@ -100,53 +93,15 @@ void
cmd_choose_session_callback(void *data, int idx) cmd_choose_session_callback(void *data, int idx)
{ {
struct cmd_choose_session_data *cdata = data; struct cmd_choose_session_data *cdata = data;
struct session *s; struct client *c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause;
if (idx == -1) if (idx != -1 && cdata->client <= ARRAY_LENGTH(&clients) - 1) {
return; c = ARRAY_ITEM(&clients, cdata->client);
if (cdata->client->flags & CLIENT_DEAD) if (c != NULL && (u_int) idx <= ARRAY_LENGTH(&sessions) - 1) {
return; c->session = ARRAY_ITEM(&sessions, idx);
recalculate_sizes();
if ((u_int) idx > ARRAY_LENGTH(&sessions) - 1) server_redraw_client(c);
return;
s = ARRAY_ITEM(&sessions, idx);
if (s == NULL)
return;
template = cmd_template_replace(cdata->template, s->name, 1);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(cdata->client, "%s", cause);
xfree(cause);
} }
xfree(template);
return;
} }
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_session_free(void *data)
{
struct cmd_choose_session_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata); xfree(cdata);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-window.c,v 1.17 2009-09-07 23:59:19 tcunha Exp $ */ /* $Id: cmd-choose-window.c,v 1.9 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -29,23 +27,22 @@
int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *); int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_window_callback(void *, int); void cmd_choose_window_callback(void *, int);
void cmd_choose_window_free(void *);
const struct cmd_entry cmd_choose_window_entry = { const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL, "choose-window", NULL,
CMD_TARGET_WINDOW_USAGE " [template]", CMD_TARGET_WINDOW_USAGE,
CMD_ARG01, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_choose_window_exec, cmd_choose_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
struct cmd_choose_window_data { struct cmd_choose_window_data {
struct client *client; u_int session;
struct session *session;
char *template;
}; };
int int
@@ -57,8 +54,6 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl, *wm; struct winlink *wl, *wm;
struct window *w; struct window *w;
u_int idx, cur; u_int idx, cur;
char flag, *title;
const char *left, *right;
if (ctx->curclient == NULL) { if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively"); ctx->error(ctx, "must be run interactively");
@@ -80,44 +75,17 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx; cur = idx;
idx++; idx++;
flag = ' ';
if (session_alert_has(s, wm, WINDOW_ACTIVITY))
flag = '#';
else if (session_alert_has(s, wm, WINDOW_BELL))
flag = '!';
else if (session_alert_has(s, wm, WINDOW_CONTENT))
flag = '+';
else if (wm == s->curw)
flag = '*';
else if (wm == SLIST_FIRST(&s->lastw))
flag = '-';
title = w->active->screen->title;
if (wm == wl)
title = w->active->base.title;
left = " \"";
right = "\"";
if (*title == '\0')
left = right = "";
window_choose_add(wl->window->active, window_choose_add(wl->window->active,
wm->idx, "%3d: %s%c [%ux%u] (%u panes)%s%s%s", wm->idx, "%3d: %s [%ux%u %s] (%u panes)", wm->idx, w->name,
wm->idx, w->name, flag, w->sx, w->sy, window_count_panes(w), w->sx, w->sy, layout_name(w), window_count_panes(w));
left, title, right);
} }
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL) if (session_index(s, &cdata->session) != 0)
cdata->template = xstrdup(data->arg); fatalx("session not found");
else
cdata->template = xstrdup("select-window -t '%%'");
cdata->session = s;
cdata->session->references++;
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active, window_choose_ready(
cur, cmd_choose_window_callback, cmd_choose_window_free, cdata); wl->window->active, cur, cmd_choose_window_callback, cdata);
return (0); return (0);
} }
@@ -126,54 +94,13 @@ void
cmd_choose_window_callback(void *data, int idx) cmd_choose_window_callback(void *data, int idx)
{ {
struct cmd_choose_window_data *cdata = data; struct cmd_choose_window_data *cdata = data;
struct cmd_list *cmdlist; struct session *s;
struct cmd_ctx ctx;
char *target, *template, *cause;
if (idx == -1) if (idx != -1 && cdata->session <= ARRAY_LENGTH(&sessions) - 1) {
return; s = ARRAY_ITEM(&sessions, cdata->session);
if (cdata->client->flags & CLIENT_DEAD) if (s != NULL && session_select(s, idx) == 0)
return; server_redraw_session(s);
if (cdata->session->flags & SESSION_DEAD) recalculate_sizes();
return;
if (cdata->client->session != cdata->session)
return;
xasprintf(&target, "%s:%d", cdata->session->name, idx);
template = cmd_template_replace(cdata->template, target, 1);
xfree(target);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(cdata->client, "%s", cause);
xfree(cause);
}
xfree(template);
return;
} }
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_window_free(void *data)
{
struct cmd_choose_window_data *cdata = data;
cdata->session->references--;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata); xfree(cdata);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clear-history.c,v 1.7 2009-07-30 21:04:40 tcunha Exp $ */ /* $Id: cmd-clear-history.c,v 1.3 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,24 +28,36 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = { const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist", "clear-history", "clearhist",
CMD_TARGET_PANE_USAGE, CMD_PANE_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_clear_history_exec, cmd_clear_history_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
int int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
struct grid *gd; struct grid *gd;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
gd = wp->base.grid; gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy); grid_move_lines(gd, 0, gd->hsize, gd->sy);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clock-mode.c,v 1.6 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-clock-mode.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,11 +28,13 @@ int cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clock_mode_entry = { const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL, "clock-mode", NULL,
CMD_TARGET_PANE_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_clock_mode_exec, cmd_clock_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -41,12 +43,12 @@ int
cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct window_pane *wp; struct winlink *wl;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
window_pane_set_mode(wp, &window_clock_mode); window_pane_set_mode(wl->window->active, &window_clock_mode);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-command-prompt.c,v 1.25 2009-08-25 13:53:39 tcunha Exp $ */ /* $Id: cmd-command-prompt.c,v 1.16 2009-02-16 18:58:14 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,111 +27,57 @@
* Prompt for command in client. * Prompt for command in client.
*/ */
void cmd_command_prompt_init(struct cmd *, int); void cmd_command_prompt_init(struct cmd *, int);
int cmd_command_prompt_parse(struct cmd *, int, char **, char **); int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
void cmd_command_prompt_free(struct cmd *);
size_t cmd_command_prompt_print(struct cmd *, char *, size_t);
int cmd_command_prompt_callback(void *, const char *); int cmd_command_prompt_callback(void *, const char *);
void cmd_command_prompt_cfree(void *);
const struct cmd_entry cmd_command_prompt_entry = { const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL, "command-prompt", NULL,
CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]", CMD_TARGET_CLIENT_USAGE " [template]",
0, 0, CMD_ARG01,
cmd_command_prompt_init, cmd_command_prompt_init,
cmd_command_prompt_parse, cmd_target_parse,
cmd_command_prompt_exec, cmd_command_prompt_exec,
cmd_command_prompt_free, cmd_target_send,
cmd_command_prompt_print cmd_target_recv,
cmd_target_free,
cmd_target_print
}; };
struct cmd_command_prompt_data { struct cmd_command_prompt_data {
char *prompts;
char *target;
char *template;
};
struct cmd_command_prompt_cdata {
struct client *c; struct client *c;
char *next_prompt;
char *prompts;
char *template; char *template;
int idx;
}; };
void void
cmd_command_prompt_init(struct cmd *self, int key) cmd_command_prompt_init(struct cmd *self, int key)
{ {
struct cmd_command_prompt_data *data; struct cmd_target_data *data;
self->data = data = xmalloc(sizeof *data); cmd_target_init(self, key);
data->prompts = NULL; data = self->data;
data->target = NULL;
data->template = NULL;
switch (key) { switch (key) {
case ',': case ',':
data->template = xstrdup("rename-window '%%'"); data->arg = xstrdup("rename-window '%%'");
break; break;
case '.': case '.':
data->template = xstrdup("move-window -t '%%'"); data->arg = xstrdup("move-window -t '%%'");
break; break;
case 'f': case 'f':
data->template = xstrdup("find-window '%%'"); data->arg = xstrdup("find-window '%%'");
break; break;
} }
} }
int
cmd_command_prompt_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_command_prompt_data *data;
int opt;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "p:t:")) != -1) {
switch (opt) {
case 'p':
if (data->prompts == NULL)
data->prompts = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 0 && argc != 1)
goto usage;
if (argc == 1)
data->template = xstrdup(argv[0]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int int
cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_command_prompt_data *data = self->data; struct cmd_target_data *data = self->data;
struct cmd_command_prompt_cdata *cdata; struct cmd_command_prompt_data *cdata;
struct client *c; struct client *c;
char *prompt, *ptr; char *hdr, *ptr;
size_t n;
if ((c = cmd_find_client(ctx, data->target)) == NULL) if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1); return (-1);
@@ -141,102 +87,80 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->c = c; cdata->c = c;
cdata->idx = 1; if (data->arg != NULL) {
cdata->next_prompt = NULL; cdata->template = xstrdup(data->arg);
cdata->prompts = NULL; if ((ptr = strchr(data->arg, ' ')) == NULL)
cdata->template = NULL; ptr = strchr(data->arg, '\0');
xasprintf(&hdr, "(%.*s) ", (int) (ptr - data->arg), data->arg);
if (data->template != NULL) } else {
cdata->template = xstrdup(data->template); cdata->template = NULL;
else hdr = xstrdup(":");
cdata->template = xstrdup("%1"); }
if (data->prompts != NULL) status_prompt_set(c, hdr, cmd_command_prompt_callback, cdata, 0);
cdata->prompts = xstrdup(data->prompts); xfree(hdr);
else if (data->template != NULL) {
n = strcspn(data->template, " ,");
xasprintf(&cdata->prompts, "(%.*s) ", (int) n, data->template);
} else
cdata->prompts = xstrdup(":");
cdata->next_prompt = cdata->prompts;
ptr = strsep(&cdata->next_prompt, ",");
if (data->prompts == NULL)
prompt = xstrdup(ptr);
else
xasprintf(&prompt, "%s ", ptr);
status_prompt_set(c, prompt, cmd_command_prompt_callback,
cmd_command_prompt_cfree, cdata, 0);
xfree(prompt);
return (0); return (0);
} }
void
cmd_command_prompt_free(struct cmd *self)
{
struct cmd_command_prompt_data *data = self->data;
if (data->prompts != NULL)
xfree(data->prompts);
if (data->target != NULL)
xfree(data->target);
if (data->template != NULL)
xfree(data->template);
xfree(data);
}
size_t
cmd_command_prompt_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_command_prompt_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->prompts != NULL)
off += cmd_prarg(buf + off, len - off, " -p ", data->prompts);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->template != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->template);
return (off);
}
int int
cmd_command_prompt_callback(void *data, const char *s) cmd_command_prompt_callback(void *data, const char *s)
{ {
struct cmd_command_prompt_cdata *cdata = data; struct cmd_command_prompt_data *cdata = data;
struct client *c = cdata->c; struct client *c = cdata->c;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd_ctx ctx; struct cmd_ctx ctx;
char *cause, *newtempl, *prompt, *ptr; char *cause, *ptr, *buf, ch;
size_t len, slen;
if (s == NULL) if (s == NULL) {
xfree(cdata);
return (0); return (0);
newtempl = cmd_template_replace(cdata->template, s, cdata->idx);
xfree(cdata->template);
cdata->template = newtempl;
if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
xasprintf(&prompt, "%s ", ptr);
status_prompt_update(c, prompt);
xfree(prompt);
cdata->idx++;
return (1);
} }
slen = strlen(s);
if (cmd_string_parse(newtempl, &cmdlist, &cause) != 0) { len = 0;
if (cause != NULL) { buf = NULL;
*cause = toupper((u_char) *cause); if (cdata->template != NULL) {
status_message_set(c, "%s", cause); ptr = cdata->template;
xfree(cause); while (*ptr != '\0') {
switch (ch = *ptr++) {
case '%':
if (*ptr != '%')
break;
ptr++;
buf = xrealloc(buf, 1, len + slen + 1);
memcpy(buf + len, s, slen);
len += slen;
break;
default:
buf = xrealloc(buf, 1, len + 2);
buf[len++] = ch;
break;
}
} }
return (0); xfree(cdata->template);
buf[len] = '\0';
s = buf;
} }
xfree(cdata);
if (cmd_string_parse(s, &cmdlist, &cause) != 0) {
if (cause == NULL)
return (0);
*cause = toupper((u_char) *cause);
status_message_set(c, cause);
xfree(cause);
cmdlist = NULL;
}
if (buf != NULL)
xfree(buf);
if (cmdlist == NULL)
return (0);
ctx.msgdata = NULL; ctx.msgdata = NULL;
ctx.cursession = c->session;
ctx.curclient = c; ctx.curclient = c;
ctx.error = key_bindings_error; ctx.error = key_bindings_error;
@@ -248,19 +172,7 @@ cmd_command_prompt_callback(void *data, const char *s)
cmd_list_exec(cmdlist, &ctx); cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback) if (c->prompt_callback != (void *) &cmd_command_prompt_callback)
return (1); return (1);
return (0); return (0);
} }
void
cmd_command_prompt_cfree(void *data)
{
struct cmd_command_prompt_cdata *cdata = data;
if (cdata->prompts != NULL)
xfree(cdata->prompts);
if (cdata->template != NULL)
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-confirm-before.c,v 1.11 2009-08-24 16:24:18 tcunha Exp $ */ /* $Id: cmd-confirm-before.c,v 1.4 2009-04-28 18:29:44 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -29,24 +29,25 @@ int cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *);
void cmd_confirm_before_init(struct cmd *, int); void cmd_confirm_before_init(struct cmd *, int);
int cmd_confirm_before_callback(void *, const char *); int cmd_confirm_before_callback(void *, const char *);
void cmd_confirm_before_free(void *);
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
CMD_TARGET_CLIENT_USAGE " command",
CMD_ARG1, 0,
cmd_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_confirm_before_data { struct cmd_confirm_before_data {
struct client *c; struct client *c;
char *cmd; char *cmd;
}; };
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
CMD_TARGET_CLIENT_USAGE " command",
CMD_ARG1,
cmd_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
void void
cmd_confirm_before_init(struct cmd *self, int key) cmd_confirm_before_init(struct cmd *self, int key)
{ {
@@ -66,7 +67,7 @@ cmd_confirm_before_init(struct cmd *self, int key)
} }
int int
cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_confirm_before_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct cmd_confirm_before_data *cdata; struct cmd_confirm_before_data *cdata;
@@ -90,9 +91,8 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg); cdata->cmd = xstrdup(data->arg);
cdata->c = c; cdata->c = c;
status_prompt_set(cdata->c, buf, status_prompt_set(
cmd_confirm_before_callback, cmd_confirm_before_free, cdata, cdata->c, buf, cmd_confirm_before_callback, cdata, PROMPT_SINGLE);
PROMPT_SINGLE);
xfree(buf); xfree(buf);
return (1); return (1);
@@ -107,21 +107,20 @@ cmd_confirm_before_callback(void *data, const char *s)
struct cmd_ctx ctx; struct cmd_ctx ctx;
char *cause; char *cause;
if (s == NULL || *s == '\0') if (s == NULL || tolower((u_char) s[0]) != 'y' || s[1] != '\0')
return (0); goto out;
if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
return (0);
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) { if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) { if (cause != NULL) {
*cause = toupper((u_char) *cause); *cause = toupper((u_char) *cause);
status_message_set(c, "%s", cause); status_message_set(c, cause);
xfree(cause); xfree(cause);
} }
return (0); goto out;
} }
ctx.msgdata = NULL; ctx.msgdata = NULL;
ctx.cursession = c->session;
ctx.curclient = c; ctx.curclient = c;
ctx.error = key_bindings_error; ctx.error = key_bindings_error;
@@ -133,15 +132,10 @@ cmd_confirm_before_callback(void *data, const char *s)
cmd_list_exec(cmdlist, &ctx); cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
return (0); out:
}
void
cmd_confirm_before_free(void *data)
{
struct cmd_confirm_before_data *cdata = data;
if (cdata->cmd != NULL) if (cdata->cmd != NULL)
xfree(cdata->cmd); xfree(cdata->cmd);
xfree(cdata); xfree(cdata);
return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-buffer.c,v 1.4 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-copy-buffer.c,v 1.1 2009-02-03 17:21:19 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -16,10 +16,7 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/types.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
@@ -29,6 +26,8 @@
int cmd_copy_buffer_parse(struct cmd *, int, char **, char **); int cmd_copy_buffer_parse(struct cmd *, int, char **, char **);
int cmd_copy_buffer_exec(struct cmd *, struct cmd_ctx *); int cmd_copy_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_copy_buffer_send(struct cmd *, struct buffer *);
void cmd_copy_buffer_recv(struct cmd *, struct buffer *);
void cmd_copy_buffer_free(struct cmd *); void cmd_copy_buffer_free(struct cmd *);
void cmd_copy_buffer_init(struct cmd *, int); void cmd_copy_buffer_init(struct cmd *, int);
size_t cmd_copy_buffer_print(struct cmd *, char *, size_t); size_t cmd_copy_buffer_print(struct cmd *, char *, size_t);
@@ -43,10 +42,12 @@ struct cmd_copy_buffer_data {
const struct cmd_entry cmd_copy_buffer_entry = { const struct cmd_entry cmd_copy_buffer_entry = {
"copy-buffer", "copyb", "copy-buffer", "copyb",
"[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]", "[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
0, 0, 0,
cmd_copy_buffer_init, cmd_copy_buffer_init,
cmd_copy_buffer_parse, cmd_copy_buffer_parse,
cmd_copy_buffer_exec, cmd_copy_buffer_exec,
cmd_copy_buffer_send,
cmd_copy_buffer_recv,
cmd_copy_buffer_free, cmd_copy_buffer_free,
cmd_copy_buffer_print cmd_copy_buffer_print
}; };
@@ -125,44 +126,61 @@ cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_copy_buffer_data *data = self->data; struct cmd_copy_buffer_data *data = self->data;
struct paste_buffer *pb; struct paste_buffer *pb;
struct paste_stack *dst_ps, *src_ps;
u_char *pdata;
struct session *dst_session, *src_session; struct session *dst_session, *src_session;
u_int limit; u_int limit;
if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL || if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL ||
(src_session = cmd_find_session(ctx, data->src_session)) == NULL) (src_session = cmd_find_session(ctx, data->src_session)) == NULL)
return (-1); return (-1);
dst_ps = &dst_session->buffers;
src_ps = &src_session->buffers;
if (data->src_idx == -1) { if (data->src_idx == -1) {
if ((pb = paste_get_top(src_ps)) == NULL) { if ((pb = paste_get_top(&src_session->buffers)) == NULL) {
ctx->error(ctx, "no buffers"); ctx->error(ctx, "no buffers");
return (-1); return (-1);
} }
} else { } else {
if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) { if ((pb = paste_get_index(&src_session->buffers,
data->src_idx)) == NULL) {
ctx->error(ctx, "no buffer %d", data->src_idx); ctx->error(ctx, "no buffer %d", data->src_idx);
return (-1); return (-1);
} }
} }
limit = options_get_number(&dst_session->options, "buffer-limit"); limit = options_get_number(&dst_session->options, "buffer-limit");
if (data->dst_idx == -1) {
pdata = xmalloc(pb->size); paste_add(&dst_session->buffers, xstrdup(pb->data), limit);
memcpy(pdata, pb->data, pb->size); return (0);
}
if (data->dst_idx == -1) if (paste_replace(&dst_session->buffers, data->dst_idx,
paste_add(dst_ps, pdata, pb->size, limit); xstrdup(pb->data)) != 0) {
else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) {
ctx->error(ctx, "no buffer %d", data->dst_idx); ctx->error(ctx, "no buffer %d", data->dst_idx);
xfree(pdata);
return (-1); return (-1);
} }
return (0); return (0);
} }
void
cmd_copy_buffer_send(struct cmd *self, struct buffer *b)
{
struct cmd_copy_buffer_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->dst_session);
cmd_send_string(b, data->src_session);
}
void
cmd_copy_buffer_recv(struct cmd *self, struct buffer *b)
{
struct cmd_copy_buffer_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->dst_session = cmd_recv_string(b);
data->src_session = cmd_recv_string(b);
}
void void
cmd_copy_buffer_free(struct cmd *self) cmd_copy_buffer_free(struct cmd *self)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-copy-mode.c,v 1.19 2009-07-01 23:06:32 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,11 +28,13 @@ int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = { const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL, "copy-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE, CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('u'), CMD_UFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_copy_mode_exec, cmd_copy_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
NULL NULL
}; };
@@ -41,13 +43,15 @@ int
cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
wp = wl->window->active;
window_pane_set_mode(wp, &window_copy_mode); window_pane_set_mode(wp, &window_copy_mode);
if (wp->mode == &window_copy_mode && data->chflags & CMD_CHFLAG('u')) if (wp->mode == &window_copy_mode && data->flags & CMD_UFLAG)
window_copy_pageup(wp); window_copy_pageup(wp);
return (0); return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-delete-buffer.c,v 1.7 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-delete-buffer.c,v 1.5 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_delete_buffer_entry = { const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb", "delete-buffer", "deleteb",
CMD_BUFFER_SESSION_USAGE, CMD_BUFFER_SESSION_USAGE,
0, 0, 0,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_delete_buffer_exec, cmd_delete_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-detach-client.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-detach-client.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_detach_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_detach_client_entry = { const struct cmd_entry cmd_detach_client_entry = {
"detach-client", "detach", "detach-client", "detach",
CMD_TARGET_CLIENT_USAGE, CMD_TARGET_CLIENT_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_detach_client_exec, cmd_detach_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,63 +0,0 @@
/* $Id: cmd-display-message.c,v 1.2 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
*
* 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 <time.h>
#include "tmux.h"
/*
* Displays a message in the status line.
*/
int cmd_display_message_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_message_entry = {
"display-message", "display",
CMD_TARGET_CLIENT_USAGE " [message]",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_display_message_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
const char *template;
char *msg;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
if (data->arg == NULL)
template = "[#S] #I:#W, current pane #P - (%H:%M %d-%b-%y)";
else
template = data->arg;
msg = status_replace(c->session, template, time(NULL));
status_message_set(c, "%s", msg);
xfree(msg);
return (0);
}

View File

@@ -1,52 +0,0 @@
/* $Id: cmd-display-panes.c,v 1.1 2009-08-31 22:30:15 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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 "tmux.h"
/*
* Display panes on a client.
*/
int cmd_display_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
CMD_TARGET_CLIENT_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_display_panes_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_display_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
server_set_identify(c);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-down-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-down-pane.c,v 1.7 2009-04-01 21:10:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_down_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_down_pane_entry = { const struct cmd_entry cmd_down_pane_entry = {
"down-pane", "downp", "down-pane", "downp",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_down_pane_exec, cmd_down_pane_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -52,8 +54,8 @@ cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_NEXT(w->active, entry); w->active = TAILQ_NEXT(w->active, entry);
if (w->active == NULL) if (w->active == NULL)
w->active = TAILQ_FIRST(&w->panes); w->active = TAILQ_FIRST(&w->panes);
} while (!window_pane_visible(w->active)); layout_refresh(w, 1);
server_status_window(wl->window); } while (w->active->flags & PANE_HIDDEN);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-find-window.c,v 1.13 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-find-window.c,v 1.10 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,10 +34,12 @@ void cmd_find_window_callback(void *, int);
const struct cmd_entry cmd_find_window_entry = { const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw", "find-window", "findw",
CMD_TARGET_WINDOW_USAGE " match-string", CMD_TARGET_WINDOW_USAGE " match-string",
CMD_ARG1, 0, CMD_ARG1,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_find_window_exec, cmd_find_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -138,7 +140,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
fatalx("session not found"); fatalx("session not found");
window_choose_ready( window_choose_ready(
wl->window->active, 0, cmd_find_window_callback, xfree, cdata); wl->window->active, 0, cmd_find_window_callback, cdata);
out: out:
ARRAY_FREE(&list_idx); ARRAY_FREE(&list_idx);
@@ -159,4 +161,5 @@ cmd_find_window_callback(void *data, int idx)
server_redraw_session(s); server_redraw_session(s);
recalculate_sizes(); recalculate_sizes();
} }
xfree(cdata);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.34 2009-08-26 22:13:52 tcunha Exp $ */ /* $Id: cmd-generic.c,v 1.28 2009-05-21 19:47:57 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,10 +23,13 @@
#include "tmux.h" #include "tmux.h"
int cmd_getopt(int, char **, const char *, uint64_t); #define CMD_FLAGS "adDgkuU"
int cmd_flags(int, uint64_t, uint64_t *); #define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_BIGDFLAG|CMD_GFLAG|CMD_KFLAG| \
size_t cmd_print_flags(char *, size_t, size_t, uint64_t); CMD_UFLAG|CMD_BIGUFLAG)
int cmd_fill_argument(int, char **, char **, int, char **);
int cmd_do_flags(int, int, int *);
size_t cmd_print_flags(char *, size_t, size_t, int);
int cmd_fill_argument(int, char **, int, char **);
size_t size_t
cmd_prarg(char *buf, size_t len, const char *prefix, char *arg) cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
@@ -36,78 +39,85 @@ cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
return (xsnprintf(buf, len, "%s%s", prefix, arg)); return (xsnprintf(buf, len, "%s%s", prefix, arg));
} }
/* Prepend flags from chflags onto flagstr and call getopt. */
int int
cmd_getopt(int argc, char **argv, const char *flagstr, uint64_t chflags) cmd_do_flags(int opt, int iflags, int *oflags)
{ {
u_char ch; switch (opt) {
char buf[128]; case 'a':
size_t len, off; if (iflags & CMD_AFLAG) {
(*oflags) |= CMD_AFLAG;
*buf = '\0';
len = sizeof buf;
off = 0;
for (ch = 0; ch < 26; ch++) {
if (chflags & CMD_CHFLAG('a' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'a' + ch);
if (chflags & CMD_CHFLAG('A' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'A' + ch);
}
strlcat(buf, flagstr, sizeof buf);
return (getopt(argc, argv, buf));
}
/*
* If this option is expected (in ichflags), set it in ochflags, otherwise
* return -1.
*/
int
cmd_flags(int opt, uint64_t ichflags, uint64_t *ochflags)
{
u_char ch;
for (ch = 0; ch < 26; ch++) {
if (opt == 'a' + ch && ichflags & CMD_CHFLAG(opt)) {
(*ochflags) |= CMD_CHFLAG(opt);
return (0); return (0);
} }
if (opt == 'A' + ch && ichflags & CMD_CHFLAG(opt)) { return (-1);
(*ochflags) |= CMD_CHFLAG(opt); case 'd':
if (iflags & CMD_DFLAG) {
(*oflags) |= CMD_DFLAG;
return (0); return (0);
} }
return (-1);
case 'D':
if (iflags & CMD_BIGDFLAG) {
(*oflags) |= CMD_BIGDFLAG;
return (0);
}
return (-1);
case 'g':
if (iflags & CMD_GFLAG) {
(*oflags) |= CMD_GFLAG;
return (0);
}
return (-1);
case 'k':
if (iflags & CMD_KFLAG) {
(*oflags) |= CMD_KFLAG;
return (0);
}
return (-1);
case 'u':
if (iflags & CMD_UFLAG) {
(*oflags) |= CMD_UFLAG;
return (0);
}
return (-1);
case 'U':
if (iflags & CMD_BIGUFLAG) {
(*oflags) |= CMD_BIGUFLAG;
return (0);
}
return (-1);
} }
return (-1); return (1);
} }
/* Print the flags supported in chflags. */
size_t size_t
cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags) cmd_print_flags(char *buf, size_t len, size_t off, int flags)
{ {
u_char ch;
size_t boff = off; size_t boff = off;
if (chflags == 0) if ((flags & CMD_FLAGMASK) == 0)
return (0); return (0);
off += xsnprintf(buf + off, len - off, " -"); off += xsnprintf(buf + off, len - off, " -");
if (off < len && flags & CMD_AFLAG)
for (ch = 0; ch < 26; ch++) { off += xsnprintf(buf + off, len - off, "a");
if (chflags & CMD_CHFLAG('a' + ch)) if (off < len && flags & CMD_BIGDFLAG)
off += xsnprintf(buf + off, len - off, "%c", 'a' + ch); off += xsnprintf(buf + off, len - off, "D");
if (chflags & CMD_CHFLAG('A' + ch)) if (off < len && flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, "%c", 'A' + ch); off += xsnprintf(buf + off, len - off, "d");
} if (off < len && flags & CMD_GFLAG)
off += xsnprintf(buf + off, len - off, "g");
if (off < len && flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, "k");
if (off < len && flags & CMD_UFLAG)
off += xsnprintf(buf + off, len - off, "u");
if (off < len && flags & CMD_BIGUFLAG)
off += xsnprintf(buf + off, len - off, "U");
return (off - boff); return (off - boff);
} }
int int
cmd_fill_argument(int flags, char **arg, char **arg2, int argc, char **argv) cmd_fill_argument(int flags, char **arg, int argc, char **argv)
{ {
*arg = NULL; *arg = NULL;
*arg2 = NULL;
if (flags & CMD_ARG1) { if (flags & CMD_ARG1) {
if (argc != 1) if (argc != 1)
@@ -124,23 +134,6 @@ cmd_fill_argument(int flags, char **arg, char **arg2, int argc, char **argv)
return (0); return (0);
} }
if (flags & CMD_ARG2) {
if (argc != 2)
return (-1);
*arg = xstrdup(argv[0]);
*arg2 = xstrdup(argv[1]);
return (0);
}
if (flags & CMD_ARG12) {
if (argc != 1 && argc != 2)
return (-1);
*arg = xstrdup(argv[0]);
if (argc == 2)
*arg2 = xstrdup(argv[1]);
return (0);
}
if (argc != 0) if (argc != 0)
return (-1); return (-1);
return (0); return (0);
@@ -152,26 +145,28 @@ cmd_target_init(struct cmd *self, unused int key)
struct cmd_target_data *data; struct cmd_target_data *data;
self->data = data = xmalloc(sizeof *data); self->data = data = xmalloc(sizeof *data);
data->chflags = 0; data->flags = 0;
data->target = NULL; data->target = NULL;
data->arg = NULL; data->arg = NULL;
data->arg2 = NULL;
} }
int int
cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause) cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
{ {
struct cmd_target_data *data; struct cmd_target_data *data;
const struct cmd_entry *entry = self->entry;
int opt; int opt;
/* Don't use the entry version since it may be dependent on key. */ /* Don't use the entry version since it may be dependent on key. */
cmd_target_init(self, 0); cmd_target_init(self, 0);
data = self->data; data = self->data;
while ((opt = cmd_getopt(argc, argv, "t:", entry->chflags)) != -1) { while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0) switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
continue; continue;
}
switch (opt) { switch (opt) {
case 't': case 't':
if (data->target == NULL) if (data->target == NULL)
@@ -184,8 +179,7 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (cmd_fill_argument( if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
goto usage; goto usage;
return (0); return (0);
@@ -196,6 +190,27 @@ usage:
return (-1); return (-1);
} }
void
cmd_target_send(struct cmd *self, struct buffer *b)
{
struct cmd_target_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->arg);
}
void
cmd_target_recv(struct cmd *self, struct buffer *b)
{
struct cmd_target_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void void
cmd_target_free(struct cmd *self) cmd_target_free(struct cmd *self)
{ {
@@ -205,8 +220,6 @@ cmd_target_free(struct cmd *self)
xfree(data->target); xfree(data->target);
if (data->arg != NULL) if (data->arg != NULL)
xfree(data->arg); xfree(data->arg);
if (data->arg2 != NULL)
xfree(data->arg2);
xfree(data); xfree(data);
} }
@@ -219,13 +232,11 @@ cmd_target_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name); off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL) if (data == NULL)
return (off); return (off);
off += cmd_print_flags(buf, len, off, data->chflags); off += cmd_print_flags(buf, len, off, data->flags);
if (off < len && data->target != NULL) if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target); off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL) if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg); off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off); return (off);
} }
@@ -235,26 +246,28 @@ cmd_srcdst_init(struct cmd *self, unused int key)
struct cmd_srcdst_data *data; struct cmd_srcdst_data *data;
self->data = data = xmalloc(sizeof *data); self->data = data = xmalloc(sizeof *data);
data->chflags = 0; data->flags = 0;
data->src = NULL; data->src = NULL;
data->dst = NULL; data->dst = NULL;
data->arg = NULL; data->arg = NULL;
data->arg2 = NULL;
} }
int int
cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause) cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
{ {
struct cmd_srcdst_data *data; struct cmd_srcdst_data *data;
const struct cmd_entry *entry = self->entry;
int opt; int opt;
cmd_srcdst_init(self, 0); cmd_srcdst_init(self, 0);
data = self->data; data = self->data;
while ((opt = cmd_getopt(argc, argv, "s:t:", entry->chflags)) != -1) { while ((opt = getopt(argc, argv, CMD_FLAGS "s:t:")) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0) switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
continue; continue;
}
switch (opt) { switch (opt) {
case 's': case 's':
if (data->src == NULL) if (data->src == NULL)
@@ -271,8 +284,7 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (cmd_fill_argument( if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
goto usage; goto usage;
return (0); return (0);
@@ -283,6 +295,29 @@ usage:
return (-1); return (-1);
} }
void
cmd_srcdst_send(struct cmd *self, struct buffer *b)
{
struct cmd_srcdst_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->src);
cmd_send_string(b, data->dst);
cmd_send_string(b, data->arg);
}
void
cmd_srcdst_recv(struct cmd *self, struct buffer *b)
{
struct cmd_srcdst_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->src = cmd_recv_string(b);
data->dst = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void void
cmd_srcdst_free(struct cmd *self) cmd_srcdst_free(struct cmd *self)
{ {
@@ -294,8 +329,6 @@ cmd_srcdst_free(struct cmd *self)
xfree(data->dst); xfree(data->dst);
if (data->arg != NULL) if (data->arg != NULL)
xfree(data->arg); xfree(data->arg);
if (data->arg2 != NULL)
xfree(data->arg2);
xfree(data); xfree(data);
} }
@@ -308,15 +341,13 @@ cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name); off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL) if (data == NULL)
return (off); return (off);
off += cmd_print_flags(buf, len, off, data->chflags); off += cmd_print_flags(buf, len, off, data->flags);
if (off < len && data->src != NULL) if (off < len && data->src != NULL)
off += xsnprintf(buf + off, len - off, " -s %s", data->src); off += xsnprintf(buf + off, len - off, " -s %s", data->src);
if (off < len && data->dst != NULL) if (off < len && data->dst != NULL)
off += xsnprintf(buf + off, len - off, " -t %s", data->dst); off += xsnprintf(buf + off, len - off, " -t %s", data->dst);
if (off < len && data->arg != NULL) if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg); off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off); return (off);
} }
@@ -326,27 +357,29 @@ cmd_buffer_init(struct cmd *self, unused int key)
struct cmd_buffer_data *data; struct cmd_buffer_data *data;
self->data = data = xmalloc(sizeof *data); self->data = data = xmalloc(sizeof *data);
data->chflags = 0; data->flags = 0;
data->target = NULL; data->target = NULL;
data->buffer = -1; data->buffer = -1;
data->arg = NULL; data->arg = NULL;
data->arg2 = NULL;
} }
int int
cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause) cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
{ {
struct cmd_buffer_data *data; struct cmd_buffer_data *data;
const struct cmd_entry *entry = self->entry;
int opt, n; int opt, n;
const char *errstr; const char *errstr;
cmd_buffer_init(self, 0); cmd_buffer_init(self, 0);
data = self->data; data = self->data;
while ((opt = cmd_getopt(argc, argv, "b:t:", entry->chflags)) != -1) { while ((opt = getopt(argc, argv, CMD_FLAGS "b:t:")) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0) switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
continue; continue;
}
switch (opt) { switch (opt) {
case 'b': case 'b':
if (data->buffer == -1) { if (data->buffer == -1) {
@@ -369,8 +402,7 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if (cmd_fill_argument( if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
goto usage; goto usage;
return (0); return (0);
@@ -382,6 +414,27 @@ error:
return (-1); return (-1);
} }
void
cmd_buffer_send(struct cmd *self, struct buffer *b)
{
struct cmd_buffer_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->arg);
}
void
cmd_buffer_recv(struct cmd *self, struct buffer *b)
{
struct cmd_buffer_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void void
cmd_buffer_free(struct cmd *self) cmd_buffer_free(struct cmd *self)
{ {
@@ -391,8 +444,6 @@ cmd_buffer_free(struct cmd *self)
xfree(data->target); xfree(data->target);
if (data->arg != NULL) if (data->arg != NULL)
xfree(data->arg); xfree(data->arg);
if (data->arg2 != NULL)
xfree(data->arg2);
xfree(data); xfree(data);
} }
@@ -405,14 +456,239 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name); off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL) if (data == NULL)
return (off); return (off);
off += cmd_print_flags(buf, len, off, data->chflags); off += cmd_print_flags(buf, len, off, data->flags);
if (off < len && data->buffer != -1) if (off < len && data->buffer != -1)
off += xsnprintf(buf + off, len - off, " -b %d", data->buffer); off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
if (off < len && data->target != NULL) if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target); off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL) if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg); off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL) return (off);
off += cmd_prarg(buf + off, len - off, " ", data->arg2); }
void
cmd_option_init(struct cmd *self, unused int key)
{
struct cmd_option_data *data;
self->data = data = xmalloc(sizeof *data);
data->flags = 0;
data->target = NULL;
data->option = NULL;
data->value = NULL;
}
int
cmd_option_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_option_data *data;
int opt;
/* Don't use the entry version since it may be dependent on key. */
cmd_option_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
continue;
}
switch (opt) {
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc == 2) {
data->option = xstrdup(argv[0]);
data->value = xstrdup(argv[1]);
} else if (argc == 1)
data->option = xstrdup(argv[0]);
else
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
void
cmd_option_send(struct cmd *self, struct buffer *b)
{
struct cmd_option_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->option);
cmd_send_string(b, data->value);
}
void
cmd_option_recv(struct cmd *self, struct buffer *b)
{
struct cmd_option_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->option = cmd_recv_string(b);
data->value = cmd_recv_string(b);
}
void
cmd_option_free(struct cmd *self)
{
struct cmd_option_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
if (data->option != NULL)
xfree(data->option);
if (data->value != NULL)
xfree(data->value);
xfree(data);
}
size_t
cmd_option_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_option_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
off += cmd_print_flags(buf, len, off, data->flags);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->option != NULL)
off += xsnprintf(buf + off, len - off, " %s", data->option);
if (off < len && data->value != NULL)
off += xsnprintf(buf + off, len - off, " %s", data->value);
return (off);
}
void
cmd_pane_init(struct cmd *self, unused int key)
{
struct cmd_pane_data *data;
self->data = data = xmalloc(sizeof *data);
data->flags = 0;
data->target = NULL;
data->arg = NULL;
data->pane = -1;
}
int
cmd_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_pane_data *data;
int opt, n;
const char *errstr;
/* Don't use the entry version since it may be dependent on key. */
cmd_pane_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, CMD_FLAGS "p:t:")) != -1) {
switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
continue;
}
switch (opt) {
case 'p':
if (data->pane == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "pane %s", errstr);
goto error;
}
data->pane = n;
}
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
}
void
cmd_pane_send(struct cmd *self, struct buffer *b)
{
struct cmd_pane_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->arg);
}
void
cmd_pane_recv(struct cmd *self, struct buffer *b)
{
struct cmd_pane_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void
cmd_pane_free(struct cmd *self)
{
struct cmd_pane_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
if (data->arg != NULL)
xfree(data->arg);
xfree(data);
}
size_t
cmd_pane_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_pane_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
off += cmd_print_flags(buf, len, off, data->flags);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
return (off); return (off);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-has-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-has-session.c,v 1.12 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_has_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_has_session_entry = { const struct cmd_entry cmd_has_session_entry = {
"has-session", "has", "has-session", "has",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_has_session_exec, cmd_has_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,151 +0,0 @@
/* $Id: cmd-if-shell.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
*
* 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 <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Executes a tmux command if a shell command returns true.
*/
int cmd_if_shell_parse(struct cmd *, int, char **, char **);
int cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_if_shell_free(struct cmd *);
void cmd_if_shell_init(struct cmd *, int);
size_t cmd_if_shell_print(struct cmd *, char *, size_t);
struct cmd_if_shell_data {
char *cmd;
char *sh_cmd;
};
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"shell-command command",
0, 0,
cmd_if_shell_init,
cmd_if_shell_parse,
cmd_if_shell_exec,
cmd_if_shell_free,
cmd_if_shell_print
};
void
cmd_if_shell_init(struct cmd *self, unused int arg)
{
struct cmd_if_shell_data *data;
self->data = data = xmalloc(sizeof *data);
data->cmd = NULL;
data->sh_cmd = NULL;
}
int
cmd_if_shell_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_if_shell_data *data;
int opt;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "")) != -1) {
switch (opt) {
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 2)
goto usage;
data->sh_cmd = xstrdup(argv[0]);
data->cmd = xstrdup(argv[1]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_if_shell_data *data = self->data;
struct cmd_list *cmdlist;
char *cause;
int ret;
if ((ret = system(data->sh_cmd)) < 0) {
ctx->error(ctx, "system error: %s", strerror(errno));
return (-1);
} else if (ret != 0)
return (0);
if (cmd_string_parse(data->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
ctx->error(ctx, "%s", cause);
xfree(cause);
}
return (-1);
}
if (cmd_list_exec(cmdlist, ctx) < 0) {
cmd_list_free(cmdlist);
return (-1);
}
cmd_list_free(cmdlist);
return (0);
}
void
cmd_if_shell_free(struct cmd *self)
{
struct cmd_if_shell_data *data = self->data;
if (data->cmd != NULL)
xfree(data->cmd);
if (data->sh_cmd != NULL)
xfree(data->sh_cmd);
xfree(data);
}
size_t
cmd_if_shell_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_if_shell_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->sh_cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->sh_cmd);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */ /* $Id: cmd-kill-pane.c,v 1.7 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,33 +30,43 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = { const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp", "kill-pane", "killp",
CMD_TARGET_PANE_USAGE, CMD_PANE_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_kill_pane_exec, cmd_kill_pane_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
int int
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (window_count_panes(wl->window) == 1) {
ctx->error(ctx, "can't kill pane: %d", data->pane);
return (-1); return (-1);
if (window_count_panes(wl->window) == 1) {
/* Only one pane, kill the window. */
server_kill_window(wl->window);
return (0);
} }
layout_close_pane(wp);
window_remove_pane(wl->window, wp); window_remove_pane(wl->window, wp);
server_redraw_window(wl->window); server_redraw_window(wl->window);
layout_refresh(wl->window, 0);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-kill-server.c,v 1.6 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,11 +32,13 @@ int cmd_kill_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_server_entry = { const struct cmd_entry cmd_kill_server_entry = {
"kill-server", NULL, "kill-server", NULL,
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_kill_server_exec, cmd_kill_server_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-kill-session.c,v 1.12 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_kill_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_session_entry = { const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL, "kill-session", NULL,
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_kill_session_exec, cmd_kill_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.19 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-kill-window.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_kill_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_window_entry = { const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw", "kill-window", "killw",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_kill_window_exec, cmd_kill_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -42,11 +44,26 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct session *s;
struct client *c;
u_int i;
int destroyed;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
server_kill_window(wl->window); destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
recalculate_sizes();
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-last-window.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-last-window.c,v 1.16 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_last_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_last_window_entry = { const struct cmd_entry cmd_last_window_entry = {
"last-window", "last", "last-window", "last",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_last_window_exec, cmd_last_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-link-window.c,v 1.32 2009-08-16 19:16:27 tcunha Exp $ */ /* $Id: cmd-link-window.c,v 1.28 2009-01-23 16:59:14 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_link_window_entry = { const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw", "link-window", "linkw",
"[-dk] " CMD_SRCDST_WINDOW_USAGE, "[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'), CMD_DFLAG|CMD_KFLAG,
cmd_srcdst_init, cmd_srcdst_init,
cmd_srcdst_parse, cmd_srcdst_parse,
cmd_link_window_exec, cmd_link_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free, cmd_srcdst_free,
cmd_srcdst_print cmd_srcdst_print
}; };
@@ -50,8 +52,19 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL) if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL)
return (-1); return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
if (arg_parse_window(data->dst, &dst, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->dst);
return (-1); return (-1);
}
if (dst == NULL)
dst = ctx->cursession;
if (dst == NULL)
dst = cmd_current_session(ctx);
if (dst == NULL) {
ctx->error(ctx, "session not found: %s", data->dst);
return (-1);
}
wl_dst = NULL; wl_dst = NULL;
if (idx != -1) if (idx != -1)
@@ -60,7 +73,7 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl_dst->window == wl_src->window) if (wl_dst->window == wl_src->window)
return (0); return (0);
if (data->chflags & CMD_CHFLAG('k')) { if (data->flags & CMD_KFLAG) {
/* /*
* Can't use session_detach as it will destroy session * Can't use session_detach as it will destroy session
* if this makes it empty. * if this makes it empty.
@@ -71,14 +84,12 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Force select/redraw if current. */ /* Force select/redraw if current. */
if (wl_dst == dst->curw) { if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d'); data->flags &= ~CMD_DFLAG;
dst->curw = NULL; dst->curw = NULL;
} }
} }
} }
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause); wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) { if (wl_dst == NULL) {
ctx->error(ctx, "create session failed: %s", cause); ctx->error(ctx, "create session failed: %s", cause);
@@ -86,7 +97,7 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
} }
if (data->chflags & CMD_CHFLAG('d')) if (data->flags & CMD_DFLAG)
server_status_session(dst); server_status_session(dst);
else { else {
session_select(dst, wl_dst->idx); session_select(dst, wl_dst->idx);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-buffers.c,v 1.12 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-list-buffers.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_buffers_entry = { const struct cmd_entry cmd_list_buffers_entry = {
"list-buffers", "lsb", "list-buffers", "lsb",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_list_buffers_exec, cmd_list_buffers_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,33 +48,44 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s; struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
u_int idx; u_int idx;
char tmp[51 * 4 + 1]; char *tmp;
size_t size, len; size_t size, in, out;
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
if (s->sx > 35) { /* leave three for ... */
size = s->sx - 32;
tmp = xmalloc(size + 1);
} else {
size = 0;
tmp = NULL;
}
idx = 0; idx = 0;
while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) { while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
size = pb->size; if (tmp != NULL) {
in = out = 0;
while (out < size && pb->data[in] != '\0') {
if (pb->data[in] > 31 && pb->data[in] != 127)
tmp[out++] = pb->data[in];
in++;
}
tmp[out] = '\0';
if (out == size) {
tmp[out - 1] = '.';
tmp[out - 2] = '.';
tmp[out - 3] = '.';
}
/* Translate the first 50 characters. */ ctx->print(ctx, "%d: %zu bytes: \"%s\"",
len = size; idx - 1, strlen(pb->data), tmp);
if (len > 50) } else
len = 50; ctx->print(ctx, "%d: %zu bytes", idx, strlen(pb->data));
strvisx(tmp, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL);
/*
* If the first 50 characterswere encoded as a longer string,
* or there is definitely more data, add "...".
*/
if (size > 50 || strlen(tmp) > 50) {
tmp[50 - 3] = '\0';
strlcat(tmp, "...", sizeof tmp);
}
ctx->print(ctx, "%u: %zu bytes: \"%s\"", idx - 1, size, tmp);
} }
if (tmp != NULL)
xfree(tmp);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-clients.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-list-clients.c,v 1.16 2009-06-25 16:34:50 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,11 +32,13 @@ int cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_clients_entry = { const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc", "list-clients", "lsc",
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_list_clients_exec, cmd_list_clients_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-commands.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-list-commands.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_list_commands_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_commands_entry = { const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm", "list-commands", "lscm",
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_list_commands_exec, cmd_list_commands_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-keys.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */ /* $Id: cmd-list-keys.c,v 1.14 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -28,97 +26,33 @@
int cmd_list_keys_exec(struct cmd *, struct cmd_ctx *); int cmd_list_keys_exec(struct cmd *, struct cmd_ctx *);
int cmd_list_keys_table(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_keys_entry = { const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk", "list-keys", "lsk",
"[-t key-table]", "",
0, 0, 0,
cmd_target_init, NULL,
cmd_target_parse, NULL,
cmd_list_keys_exec, cmd_list_keys_exec,
cmd_target_free, NULL,
cmd_target_print NULL,
NULL,
NULL
}; };
int int
cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_list_keys_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data;
struct key_binding *bd; struct key_binding *bd;
const char *key; const char *key;
char tmp[BUFSIZ], keytmp[64]; char tmp[BUFSIZ];
int width, keywidth;
if (data->target != NULL)
return (cmd_list_keys_table(self, ctx));
width = 0;
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
keywidth = strlen(key) + 1;
if (!(bd->key & KEYC_PREFIX))
keywidth += 2;
if (keywidth > width)
width = keywidth;
}
SPLAY_FOREACH(bd, key_bindings, &key_bindings) { SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX); if ((key = key_string_lookup_key(bd->key)) == NULL)
if (key == NULL)
continue; continue;
*tmp = '\0'; *tmp = '\0';
cmd_list_print(bd->cmdlist, tmp, sizeof tmp); cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
if (!(bd->key & KEYC_PREFIX)) { ctx->print(ctx, "%11s: %s", key, tmp);
xsnprintf(keytmp, sizeof keytmp, "[%s]", key);
key = keytmp;
}
ctx->print(ctx, "%*s: %s", width, key, tmp);
}
return (0);
}
int
cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind;
const char *key, *cmdstr, *mode;
int width, keywidth;
if ((mtab = mode_key_findtable(data->target)) == NULL) {
ctx->error(ctx, "unknown key table: %s", data->target);
return (-1);
}
width = 0;
SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
if (key == NULL)
continue;
keywidth = strlen(key) + 1;
if (keywidth > width)
width = keywidth;
}
SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
if (key == NULL)
continue;
mode = "";
if (mbind->mode != 0)
mode = "(command mode) ";
cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
if (cmdstr != NULL)
ctx->print(ctx, "%*s: %s%s", width, key, mode, cmdstr);
} }
return (0); return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-sessions.c,v 1.21 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-list-sessions.c,v 1.19 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,11 +31,13 @@ int cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = { const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", "", "list-sessions", "ls", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_list_sessions_exec, cmd_list_sessions_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.40 2009-08-09 17:28:23 tcunha Exp $ */ /* $Id: cmd-list-windows.c,v 1.35 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_windows_entry = { const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw", "list-windows", "lsw",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_list_windows_exec, cmd_list_windows_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -48,7 +50,6 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
struct grid *gd; struct grid *gd;
struct grid_line *gl;
u_int i; u_int i;
unsigned long long size; unsigned long long size;
const char *name; const char *name;
@@ -66,20 +67,20 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
size = 0; size = 0;
for (i = 0; i < gd->hsize; i++) { for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i]; size += gd->size[i] * sizeof **gd->data;
size += gl->cellsize * sizeof *gl->celldata; size += gd->usize[i] * sizeof **gd->udata;
size += gl->utf8size * sizeof *gl->utf8data;
} }
size += gd->hsize * sizeof *gd->linedata; size += gd->hsize * (sizeof *gd->data);
size += gd->hsize * (sizeof *gd->size);
name = NULL;
if (wp->fd != -1) if (wp->fd != -1)
name = ttyname(wp->fd); name = ttyname(wp->fd);
if (name == NULL) else
name = "unknown"; name = "unknown";
ctx->print(ctx, ctx->print(ctx,
" %s [%ux%u] [history %u/%u, %llu bytes]", " %s [%ux%u %s] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, gd->hsize, gd->hlimit, size); name, wp->sx, wp->sy, layout_name(w), gd->hsize,
gd->hlimit, size);
} }
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-list.c,v 1.5 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -86,6 +86,41 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
return (0); return (0);
} }
void
cmd_list_send(struct cmd_list *cmdlist, struct buffer *b)
{
struct cmd *cmd;
u_int n;
n = 0;
TAILQ_FOREACH(cmd, cmdlist, qentry)
n++;
buffer_write(b, &n, sizeof n);
TAILQ_FOREACH(cmd, cmdlist, qentry)
cmd_send(cmd, b);
}
struct cmd_list *
cmd_list_recv(struct buffer *b)
{
struct cmd_list *cmdlist;
struct cmd *cmd;
u_int n;
buffer_read(b, &n, sizeof n);
cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist);
while (n-- > 0) {
cmd = cmd_recv(b);
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
}
return (cmdlist);
}
void void
cmd_list_free(struct cmd_list *cmdlist) cmd_list_free(struct cmd_list *cmdlist)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-load-buffer.c,v 1.4 2009-05-21 19:38:51 nicm Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -35,10 +35,12 @@ int cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_load_buffer_entry = { const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb", "load-buffer", "loadb",
CMD_BUFFER_SESSION_USAGE " path", CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, 0, CMD_ARG1,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_load_buffer_exec, cmd_load_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -48,18 +50,22 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_buffer_data *data = self->data; struct cmd_buffer_data *data = self->data;
struct session *s; struct session *s;
struct stat sb; struct stat statbuf;
FILE *f; FILE *f;
u_char *buf; char *buf;
u_int limit; u_int limit;
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
if (stat(data->arg, &sb) < 0) { if (stat(data->arg, &statbuf) < 0) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1); return (-1);
} }
if (!S_ISREG(statbuf.st_mode)) {
ctx->error(ctx, "%s: not a regular file", data->arg);
return (-1);
}
if ((f = fopen(data->arg, "rb")) == NULL) { if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
@@ -70,27 +76,27 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
* We don't want to die due to memory exhaustion, hence xmalloc can't * We don't want to die due to memory exhaustion, hence xmalloc can't
* be used here. * be used here.
*/ */
if ((buf = malloc(sb.st_size + 1)) == NULL) { if ((buf = malloc(statbuf.st_size + 1)) == NULL) {
ctx->error(ctx, "malloc error: %s", strerror(errno)); ctx->error(ctx, "malloc error: %s", strerror(errno));
fclose(f);
return (-1); return (-1);
} }
if (fread(buf, 1, sb.st_size, f) != (size_t) sb.st_size) { if (fread(buf, 1, statbuf.st_size, f) != (size_t) statbuf.st_size) {
ctx->error(ctx, "%s: fread error", data->arg); ctx->error(ctx, "%s: fread error", data->arg);
xfree(buf); xfree(buf);
fclose(f); fclose(f);
return (-1); return (-1);
} }
buf[statbuf.st_size] = '\0';
fclose(f); fclose(f);
limit = options_get_number(&s->options, "buffer-limit"); limit = options_get_number(&s->options, "buffer-limit");
if (data->buffer == -1) { if (data->buffer == -1) {
paste_add(&s->buffers, buf, sb.st_size, limit); paste_add(&s->buffers, buf, limit);
return (0); return (0);
} }
if (paste_replace(&s->buffers, data->buffer, buf, sb.st_size) != 0) { if (paste_replace(&s->buffers, data->buffer, buf) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer); ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf); xfree(buf);
return (-1); return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-server.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-lock-server.c,v 1.4 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,12 +33,14 @@ int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_server_entry = { const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock", "lock-server", "lock",
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_lock_server_exec, cmd_lock_server_exec,
NULL, NULL,
NULL, NULL,
NULL,
NULL,
}; };
int int

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-move-window.c,v 1.9 2009-08-16 19:16:27 tcunha Exp $ */ /* $Id: cmd-move-window.c,v 1.5 2009-01-23 16:59:14 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_move_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_move_window_entry = { const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew", "move-window", "movew",
"[-dk] " CMD_SRCDST_WINDOW_USAGE, "[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'), CMD_DFLAG|CMD_KFLAG,
cmd_srcdst_init, cmd_srcdst_init,
cmd_srcdst_parse, cmd_srcdst_parse,
cmd_move_window_exec, cmd_move_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free, cmd_srcdst_free,
cmd_srcdst_print cmd_srcdst_print
}; };
@@ -52,8 +54,19 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL) if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
return (-1); return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
if (arg_parse_window(data->dst, &dst, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->dst);
return (-1); return (-1);
}
if (dst == NULL)
dst = ctx->cursession;
if (dst == NULL)
dst = cmd_current_session(ctx);
if (dst == NULL) {
ctx->error(ctx, "session not found: %s", data->dst);
return (-1);
}
wl_dst = NULL; wl_dst = NULL;
if (idx != -1) if (idx != -1)
@@ -62,7 +75,7 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl_dst->window == wl_src->window) if (wl_dst->window == wl_src->window)
return (0); return (0);
if (data->chflags & CMD_CHFLAG('k')) { if (data->flags & CMD_KFLAG) {
/* /*
* Can't use session_detach as it will destroy session * Can't use session_detach as it will destroy session
* if this makes it empty. * if this makes it empty.
@@ -73,14 +86,12 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Force select/redraw if current. */ /* Force select/redraw if current. */
if (wl_dst == dst->curw) { if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d'); data->flags &= ~CMD_DFLAG;
dst->curw = NULL; dst->curw = NULL;
} }
} }
} }
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause); wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) { if (wl_dst == NULL) {
ctx->error(ctx, "attach window failed: %s", cause); ctx->error(ctx, "attach window failed: %s", cause);
@@ -100,7 +111,7 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_client(c); server_redraw_client(c);
} }
if (data->chflags & CMD_CHFLAG('d')) if (data->flags & CMD_DFLAG)
server_status_session(dst); server_status_session(dst);
else { else {
session_select(dst, wl_dst->idx); session_select(dst, wl_dst->idx);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.66 2009-09-16 12:36:27 nicm Exp $ */ /* $Id: cmd-new-session.c,v 1.41 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,10 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -30,6 +26,8 @@
int cmd_new_session_parse(struct cmd *, int, char **, char **); int cmd_new_session_parse(struct cmd *, int, char **, char **);
int cmd_new_session_exec(struct cmd *, struct cmd_ctx *); int cmd_new_session_exec(struct cmd *, struct cmd_ctx *);
void cmd_new_session_send(struct cmd *, struct buffer *);
void cmd_new_session_recv(struct cmd *, struct buffer *);
void cmd_new_session_free(struct cmd *); void cmd_new_session_free(struct cmd *);
void cmd_new_session_init(struct cmd *, int); void cmd_new_session_init(struct cmd *, int);
size_t cmd_new_session_print(struct cmd *, char *, size_t); size_t cmd_new_session_print(struct cmd *, char *, size_t);
@@ -44,10 +42,12 @@ struct cmd_new_session_data {
const struct cmd_entry cmd_new_session_entry = { const struct cmd_entry cmd_new_session_entry = {
"new-session", "new", "new-session", "new",
"[-d] [-n window-name] [-s session-name] [command]", "[-d] [-n window-name] [-s session-name] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, 0, CMD_STARTSERVER|CMD_CANTNEST,
cmd_new_session_init, cmd_new_session_init,
cmd_new_session_parse, cmd_new_session_parse,
cmd_new_session_exec, cmd_new_session_exec,
cmd_new_session_send,
cmd_new_session_recv,
cmd_new_session_free, cmd_new_session_free,
cmd_new_session_print cmd_new_session_print
}; };
@@ -111,149 +111,106 @@ int
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_new_session_data *data = self->data; struct cmd_new_session_data *data = self->data;
struct client *c = ctx->cmdclient;
struct session *s; struct session *s;
struct window *w; char *cmd, *cwd, *cause;
struct environ env;
struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
int detached, idx;
u_int sx, sy; u_int sx, sy;
if (ctx->curclient != NULL)
return (0);
if (!data->flag_detached) {
if (c == NULL) {
ctx->error(ctx, "no client to attach to");
return (-1);
}
if (!(c->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
}
if (data->newname != NULL && session_find(data->newname) != NULL) { if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname); ctx->error(ctx, "duplicate session: %s", data->newname);
return (-1); return (-1);
} }
/* cmd = data->cmd;
* There are three cases: if (cmd == NULL)
* cmd = options_get_string(&global_options, "default-command");
* 1. If cmdclient is non-NULL, new-session has been called from the if (c == NULL || c->cwd == NULL)
* command-line - cmdclient is to become a new attached, interactive cwd = options_get_string(&global_options, "default-path");
* client. Unless -d is given, the terminal must be opened and then else
* the client sent MSG_READY. cwd = c->cwd;
*
* 2. If cmdclient is NULL, new-session has been called from an
* existing client (such as a key binding).
*
* 3. Both are NULL, the command was in the configuration file. Treat
* this as if -d was given even if it was not.
*
* In all cases, a new additional session needs to be created and
* (unless -d) set as the current session for the client.
*/
/* Set -d if no client. */ sx = 80;
detached = data->flag_detached; sy = 25;
if (ctx->cmdclient == NULL && ctx->curclient == NULL) if (!data->flag_detached) {
detached = 1; sx = c->tty.sx;
sy = c->tty.sy;
/*
* Save the termios settings, part of which is used for new windows in
* this session.
*
* This is read again with tcgetattr() rather than using tty.tio as if
* detached, tty_open won't be called. Because of this, it must be done
* before opening the terminal as that calls tcsetattr() to prepare for
* tmux taking over.
*/
if (ctx->cmdclient != NULL && ctx->cmdclient->tty.fd != -1) {
if (tcgetattr(ctx->cmdclient->tty.fd, &tio) != 0)
fatal("tcgetattr failed");
tiop = &tio;
} else
tiop = NULL;
/* Open the terminal if necessary. */
if (!detached && ctx->cmdclient != NULL) {
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
overrides =
options_get_string(&global_s_options, "terminal-overrides");
if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause);
xfree(cause);
return (-1);
}
} }
/* Get the new session working directory. */ if (options_get_number(&global_options, "status")) {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) if (sy == 0)
cwd = ctx->cmdclient->cwd; sy = 1;
else else
cwd = options_get_string(&global_s_options, "default-path"); sy--;
/* Find new session size. */
if (detached) {
sx = 80;
sy = 24;
} else if (ctx->cmdclient != NULL) {
sx = ctx->cmdclient->tty.sx;
sy = ctx->cmdclient->tty.sy;
} else {
sx = ctx->curclient->tty.sx;
sy = ctx->curclient->tty.sy;
} }
if (sy > 0 && options_get_number(&global_s_options, "status"))
sy--;
if (sx == 0)
sx = 1;
if (sy == 0)
sy = 1;
/* Figure out the command for the new window. */ if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
if (data->cmd != NULL) ctx->error(ctx, "open terminal failed: %s", cause);
cmd = data->cmd; xfree(cause);
else return (-1);
cmd = options_get_string(&global_s_options, "default-command"); }
/* Construct the environment. */
environ_init(&env);
update = options_get_string(&global_s_options, "update-environment");
if (ctx->cmdclient != NULL)
environ_update(update, &ctx->cmdclient->environ, &env);
/* Create the new session. */ s = session_create(data->newname, cmd, cwd, sx, sy, &cause);
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(
data->newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
if (s == NULL) { if (s == NULL) {
ctx->error(ctx, "create session failed: %s", cause); ctx->error(ctx, "create session failed: %s", cause);
xfree(cause); xfree(cause);
return (-1); return (-1);
} }
environ_free(&env);
/* Set the initial window name if one given. */
if (data->winname != NULL) { if (data->winname != NULL) {
w = s->curw->window; xfree(s->curw->window->name);
s->curw->window->name = xstrdup(data->winname);
xfree(w->name); options_set_number(
w->name = xstrdup(data->winname); &s->curw->window->options, "automatic-rename", 0);
options_set_number(&w->options, "automatic-rename", 0);
} }
/* if (data->flag_detached) {
* Set the client to the new session. If a command client exists, it is if (c != NULL)
* taking this session and needs to get MSG_READY and stay around. server_write_client(c, MSG_EXIT, NULL, 0);
*/ } else {
if (!detached) { c->session = s;
if (ctx->cmdclient != NULL) { server_write_client(c, MSG_READY, NULL, 0);
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0); server_redraw_client(c);
ctx->cmdclient->session = s;
server_redraw_client(ctx->cmdclient);
} else {
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
}
} }
recalculate_sizes(); recalculate_sizes();
return (!detached); /* 1 means don't tell command client to exit */ return (1);
}
void
cmd_new_session_send(struct cmd *self, struct buffer *b)
{
struct cmd_new_session_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->newname);
cmd_send_string(b, data->winname);
cmd_send_string(b, data->cmd);
}
void
cmd_new_session_recv(struct cmd *self, struct buffer *b)
{
struct cmd_new_session_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->newname = cmd_recv_string(b);
data->winname = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
} }
void void

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-window.c,v 1.37 2009-08-16 19:16:27 tcunha Exp $ */ /* $Id: cmd-new-window.c,v 1.31 2009-01-23 16:59:14 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,6 +28,8 @@
int cmd_new_window_parse(struct cmd *, int, char **, char **); int cmd_new_window_parse(struct cmd *, int, char **, char **);
int cmd_new_window_exec(struct cmd *, struct cmd_ctx *); int cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_new_window_send(struct cmd *, struct buffer *);
void cmd_new_window_recv(struct cmd *, struct buffer *);
void cmd_new_window_free(struct cmd *); void cmd_new_window_free(struct cmd *);
void cmd_new_window_init(struct cmd *, int); void cmd_new_window_init(struct cmd *, int);
size_t cmd_new_window_print(struct cmd *, char *, size_t); size_t cmd_new_window_print(struct cmd *, char *, size_t);
@@ -43,10 +45,12 @@ struct cmd_new_window_data {
const struct cmd_entry cmd_new_window_entry = { const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww", "new-window", "neww",
"[-dk] [-n window-name] [-t target-window] [command]", "[-dk] [-n window-name] [-t target-window] [command]",
0, 0, 0,
cmd_new_window_init, cmd_new_window_init,
cmd_new_window_parse, cmd_new_window_parse,
cmd_new_window_exec, cmd_new_window_exec,
cmd_new_window_send,
cmd_new_window_recv,
cmd_new_window_free, cmd_new_window_free,
cmd_new_window_print cmd_new_window_print
}; };
@@ -122,8 +126,18 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (data == NULL) if (data == NULL)
return (0); return (0);
if ((idx = cmd_find_index(ctx, data->target, &s)) == -2) if (arg_parse_window(data->target, &s, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->target);
return (-1); return (-1);
}
if (s == NULL)
s = ctx->cursession;
if (s == NULL)
s = cmd_current_session(ctx);
if (s == NULL) {
ctx->error(ctx, "session not found: %s", data->target);
return (-1);
}
wl = NULL; wl = NULL;
if (idx != -1) if (idx != -1)
@@ -150,12 +164,10 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (cmd == NULL) if (cmd == NULL)
cmd = options_get_string(&s->options, "default-command"); cmd = options_get_string(&s->options, "default-command");
if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL) if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
cwd = options_get_string(&s->options, "default-path"); cwd = options_get_string(&global_options, "default-path");
else else
cwd = ctx->cmdclient->cwd; cwd = ctx->cmdclient->cwd;
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, data->name, cmd, cwd, idx, &cause); wl = session_new(s, data->name, cmd, cwd, idx, &cause);
if (wl == NULL) { if (wl == NULL) {
ctx->error(ctx, "create window failed: %s", cause); ctx->error(ctx, "create window failed: %s", cause);
@@ -171,6 +183,29 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0); return (0);
} }
void
cmd_new_window_send(struct cmd *self, struct buffer *b)
{
struct cmd_new_window_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->name);
cmd_send_string(b, data->cmd);
}
void
cmd_new_window_recv(struct cmd *self, struct buffer *b)
{
struct cmd_new_window_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->name = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
}
void void
cmd_new_window_free(struct cmd *self) cmd_new_window_free(struct cmd *self)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-layout.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-next-layout.c,v 1.2 2009-04-30 21:17:06 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_next_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_layout_entry = { const struct cmd_entry cmd_next_layout_entry = {
"next-layout", "nextl", "next-layout", "nextl",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_next_layout_exec, cmd_next_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -42,13 +44,12 @@ cmd_next_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
u_int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
layout = layout_set_next(wl->window); layout_next(wl->window);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout)); ctx->info(ctx, "layout now: %s", layout_name(wl->window));
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-next-window.c,v 1.17 2009-06-25 15:29:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,10 +30,12 @@ int cmd_next_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_window_entry = { const struct cmd_entry cmd_next_window_entry = {
"next-window", "next", "next-window", "next",
"[-a] " CMD_TARGET_SESSION_USAGE, "[-a] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('a'), CMD_AFLAG,
cmd_next_window_init, cmd_next_window_init,
cmd_target_parse, cmd_target_parse,
cmd_next_window_exec, cmd_next_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,8 +48,8 @@ cmd_next_window_init(struct cmd *self, int key)
cmd_target_init(self, key); cmd_target_init(self, key);
data = self->data; data = self->data;
if (key == ('n' | KEYC_ESCAPE)) if (key == KEYC_ADDESC('n'))
data->chflags |= CMD_CHFLAG('a'); data->flags |= CMD_AFLAG;
} }
int int
@@ -61,7 +63,7 @@ cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
activity = 0; activity = 0;
if (data->chflags & CMD_CHFLAG('a')) if (data->flags & CMD_AFLAG)
activity = 1; activity = 1;
if (session_next(s, activity) == 0) if (session_next(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-paste-buffer.c,v 1.20 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-paste-buffer.c,v 1.16 2009-07-02 16:23:54 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,15 +27,16 @@
*/ */
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *); int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_paste_buffer_lf2cr(struct buffer *, const char *, size_t);
const struct cmd_entry cmd_paste_buffer_entry = { const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb", "paste-buffer", "pasteb",
"[-dr] " CMD_BUFFER_WINDOW_USAGE, "[-d] " CMD_BUFFER_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('r'), CMD_DFLAG,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_paste_buffer_exec, cmd_paste_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -45,13 +46,13 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_buffer_data *data = self->data; struct cmd_buffer_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp; struct window *w;
struct session *s; struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
wp = wl->window->active; w = wl->window;
if (data->buffer == -1) if (data->buffer == -1)
pb = paste_get_top(&s->buffers); pb = paste_get_top(&s->buffers);
@@ -62,16 +63,11 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
} }
if (pb != NULL && *pb->data != '\0') { if (pb != NULL && *pb->data != '\0')
/* -r means raw data without LF->CR conversion. */ buffer_write(w->active->out, pb->data, strlen(pb->data));
if (data->chflags & CMD_CHFLAG('r'))
buffer_write(wp->out, pb->data, pb->size);
else
cmd_paste_buffer_lf2cr(wp->out, pb->data, pb->size);
}
/* Delete the buffer if -d. */ /* Delete the buffer if -d. */
if (data->chflags & CMD_CHFLAG('d')) { if (data->flags & CMD_DFLAG) {
if (data->buffer == -1) if (data->buffer == -1)
paste_free_top(&s->buffers); paste_free_top(&s->buffers);
else else
@@ -80,21 +76,3 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0); return (0);
} }
/* Add bytes to a buffer but change every '\n' to '\r'. */
void
cmd_paste_buffer_lf2cr(struct buffer *b, const char *data, size_t size)
{
const char *end = data + size;
const char *lf;
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
buffer_write(b, data, lf - data);
buffer_write8(b, '\r');
data = lf + 1;
}
if (end != data)
buffer_write(b, data, end - data);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-layout.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-previous-layout.c,v 1.1 2009-04-30 21:17:06 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_previous_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_layout_entry = { const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl", "previous-layout", "prevl",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_previous_layout_exec, cmd_previous_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -42,13 +44,12 @@ cmd_previous_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
u_int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
layout = layout_set_previous(wl->window); layout_previous(wl->window);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout)); ctx->info(ctx, "layout now: %s", layout_name(wl->window));
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-previous-window.c,v 1.17 2009-06-25 15:29:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,10 +30,12 @@ int cmd_previous_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_window_entry = { const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev", "previous-window", "prev",
"[-a] " CMD_TARGET_SESSION_USAGE, "[-a] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('a'), CMD_AFLAG,
cmd_previous_window_init, cmd_previous_window_init,
cmd_target_parse, cmd_target_parse,
cmd_previous_window_exec, cmd_previous_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,8 +48,8 @@ cmd_previous_window_init(struct cmd *self, int key)
cmd_target_init(self, key); cmd_target_init(self, key);
data = self->data; data = self->data;
if (key == ('p' | KEYC_ESCAPE)) if (key == KEYC_ADDESC('p'))
data->chflags |= CMD_CHFLAG('a'); data->flags |= CMD_AFLAG;
} }
int int
@@ -61,7 +63,7 @@ cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
activity = 0; activity = 0;
if (data->chflags & CMD_CHFLAG('a')) if (data->flags & CMD_AFLAG)
activity = 1; activity = 1;
if (session_previous(s, activity) == 0) if (session_previous(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-refresh-client.c,v 1.10 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-refresh-client.c,v 1.8 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_refresh_client_entry = { const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh", "refresh-client", "refresh",
CMD_TARGET_CLIENT_USAGE, CMD_TARGET_CLIENT_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_refresh_client_exec, cmd_refresh_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-session.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-rename-session.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_rename_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_session_entry = { const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename", "rename-session", "rename",
CMD_TARGET_SESSION_USAGE " new-name", CMD_TARGET_SESSION_USAGE " new-name",
CMD_ARG1, 0, CMD_ARG1,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_rename_session_exec, cmd_rename_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -51,7 +53,5 @@ cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx)
xfree(s->name); xfree(s->name);
s->name = xstrdup(data->arg); s->name = xstrdup(data->arg);
server_status_session(s);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.29 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-rename-window.c,v 1.27 2009-05-04 17:58:26 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_rename_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_window_entry = { const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew", "rename-window", "renamew",
CMD_TARGET_WINDOW_USAGE " new-name", CMD_TARGET_WINDOW_USAGE " new-name",
CMD_ARG1, 0, CMD_ARG1,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_rename_window_exec, cmd_rename_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-resize-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */ /* $Id: cmd-resize-pane.c,v 1.7 2009-05-21 19:46:00 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,47 +31,32 @@ int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = { const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep", "resize-pane", "resizep",
"[-DU] " CMD_TARGET_PANE_USAGE " [adjustment]", CMD_PANE_WINDOW_USAGE "[-DU] [adjustment]",
CMD_ARG01, CMD_ARG01|CMD_BIGUFLAG|CMD_BIGDFLAG,
CMD_CHFLAG('D')|CMD_CHFLAG('L')|CMD_CHFLAG('R')|CMD_CHFLAG('U'),
cmd_resize_pane_init, cmd_resize_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_resize_pane_exec, cmd_resize_pane_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
void void
cmd_resize_pane_init(struct cmd *self, int key) cmd_resize_pane_init(struct cmd *self, int key)
{ {
struct cmd_target_data *data; struct cmd_pane_data *data;
cmd_target_init(self, key); cmd_pane_init(self, key);
data = self->data; data = self->data;
if (key == (KEYC_UP | KEYC_CTRL)) if (key == KEYC_ADDCTL(KEYC_DOWN))
data->chflags |= CMD_CHFLAG('U'); data->flags |= CMD_BIGDFLAG;
if (key == (KEYC_DOWN | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('D'); if (key == KEYC_ADDESC(KEYC_UP))
if (key == (KEYC_LEFT | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('L');
if (key == (KEYC_RIGHT | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('R');
if (key == (KEYC_UP | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('U');
data->arg = xstrdup("5"); data->arg = xstrdup("5");
} if (key == KEYC_ADDESC(KEYC_DOWN)) {
if (key == (KEYC_DOWN | KEYC_ESCAPE)) { data->flags |= CMD_BIGDFLAG;
data->chflags |= CMD_CHFLAG('D');
data->arg = xstrdup("5");
}
if (key == (KEYC_LEFT | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('L');
data->arg = xstrdup("5");
}
if (key == (KEYC_RIGHT | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('R');
data->arg = xstrdup("5"); data->arg = xstrdup("5");
} }
} }
@@ -79,14 +64,23 @@ cmd_resize_pane_init(struct cmd *self, int key)
int int
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
const char *errstr; const char *errstr;
struct window_pane *wp; struct window_pane *wp;
u_int adjust; u_int adjust;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (data->arg == NULL) if (data->arg == NULL)
adjust = 1; adjust = 1;
@@ -98,14 +92,12 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
} }
if (data->chflags & (CMD_CHFLAG('L')|CMD_CHFLAG('R'))) { if (!(data->flags & CMD_BIGDFLAG))
if (data->chflags & CMD_CHFLAG('L')) adjust = -adjust;
adjust = -adjust; if (layout_resize(wp, adjust) != 0) {
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust); ctx->error(ctx, "layout %s "
} else { "does not support resizing", layout_name(wp->window));
if (data->chflags & CMD_CHFLAG('U')) return (-1);
adjust = -adjust;
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
} }
server_redraw_window(wl->window); server_redraw_window(wl->window);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-respawn-window.c,v 1.22 2009-09-16 12:36:27 nicm Exp $ */ /* $Id: cmd-respawn-window.c,v 1.14 2009-03-04 17:24:07 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_respawn_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_respawn_window_entry = { const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw", "respawn-window", "respawnw",
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]", "[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
CMD_ARG01, CMD_CHFLAG('k'), CMD_ARG01|CMD_KFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_respawn_window_exec, cmd_respawn_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -47,14 +49,14 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
struct session *s; struct session *s;
struct environ env; const char **env;
char *cause; char *cause;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
w = wl->window; w = wl->window;
if (!(data->chflags & CMD_CHFLAG('k'))) { if (!(data->flags & CMD_KFLAG)) {
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1) if (wp->fd == -1)
continue; continue;
@@ -64,31 +66,22 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
} }
environ_init(&env); env = server_fill_environ(s);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
layout_free(w);
window_destroy_panes(w); window_destroy_panes(w);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy); window_pane_resize(wp, w->sx, w->sy);
if (window_pane_spawn( if (window_pane_spawn(wp, data->arg, NULL, env, &cause) != 0) {
wp, data->arg, NULL, NULL, &env, s->tio, &cause) != 0) {
ctx->error(ctx, "respawn window failed: %s", cause); ctx->error(ctx, "respawn window failed: %s", cause);
xfree(cause); xfree(cause);
environ_free(&env);
return (-1); return (-1);
} }
layout_init(w);
screen_reinit(&wp->base); screen_reinit(&wp->base);
window_set_active_pane(w, wp);
recalculate_sizes(); recalculate_sizes();
server_redraw_window(w); server_redraw_window(w);
environ_free(&env);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rotate-window.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-rotate-window.c,v 1.4 2009-06-25 15:28:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,10 +30,12 @@ int cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rotate_window_entry = { const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew", "rotate-window", "rotatew",
"[-DU] " CMD_TARGET_WINDOW_USAGE, "[-DU] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('D')|CMD_CHFLAG('U'), CMD_BIGUFLAG|CMD_BIGDFLAG,
cmd_rotate_window_init, cmd_rotate_window_init,
cmd_target_parse, cmd_target_parse,
cmd_rotate_window_exec, cmd_rotate_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,8 +48,8 @@ cmd_rotate_window_init(struct cmd *self, int key)
cmd_target_init(self, key); cmd_target_init(self, key);
data = self->data; data = self->data;
if (key == ('o' | KEYC_ESCAPE)) if (key == KEYC_ADDESC('o'))
data->chflags |= CMD_CHFLAG('D'); data->flags |= CMD_BIGDFLAG;
} }
int int
@@ -57,68 +59,64 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl; struct winlink *wl;
struct window *w; struct window *w;
struct window_pane *wp, *wp2; struct window_pane *wp, *wp2;
struct layout_cell *lc;
u_int sx, sy, xoff, yoff; u_int sx, sy, xoff, yoff;
int flags;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
w = wl->window; w = wl->window;
if (data->chflags & CMD_CHFLAG('D')) { if (data->flags & CMD_BIGDFLAG) {
wp = TAILQ_LAST(&w->panes, window_panes); wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
lc = wp->layout_cell;
xoff = wp->xoff; yoff = wp->yoff; xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy; sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL) if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL)
break; break;
wp->layout_cell = wp2->layout_cell;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy); window_pane_resize(wp, wp2->sx, wp2->sy);
} }
wp->layout_cell = lc;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = xoff; wp->yoff = yoff; wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy); window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL) if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
wp = TAILQ_LAST(&w->panes, window_panes); wp = TAILQ_LAST(&w->panes, window_panes);
window_set_active_pane(w, wp); window_set_active_pane(w, wp);
server_redraw_window(w);
} else { } else {
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_TAIL(&w->panes, wp, entry); TAILQ_INSERT_TAIL(&w->panes, wp, entry);
lc = wp->layout_cell;
xoff = wp->xoff; yoff = wp->yoff; xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy; sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) { TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) {
if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL) if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL)
break; break;
wp->layout_cell = wp2->layout_cell;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy); window_pane_resize(wp, wp2->sx, wp2->sy);
} }
wp->layout_cell = lc;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = xoff; wp->yoff = yoff; wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy); window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_NEXT(w->active, entry)) == NULL) if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
window_set_active_pane(w, wp); window_set_active_pane(w, wp);
server_redraw_window(w);
} }
layout_refresh(w, 0);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-save-buffer.c,v 1.8 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-save-buffer.c,v 1.5 2009-05-18 16:22:30 nicm Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -33,10 +33,12 @@ int cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_save_buffer_entry = { const struct cmd_entry cmd_save_buffer_entry = {
"save-buffer", "saveb", "save-buffer", "saveb",
"[-a] " CMD_BUFFER_SESSION_USAGE " path", "[-a] " CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, CMD_CHFLAG('a'), CMD_AFLAG|CMD_ARG1,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_save_buffer_exec, cmd_save_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -66,7 +68,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
mask = umask(S_IRWXG | S_IRWXO); mask = umask(S_IRWXG | S_IRWXO);
if (data->chflags & CMD_CHFLAG('a')) if (data->flags & CMD_AFLAG)
f = fopen(data->arg, "ab"); f = fopen(data->arg, "ab");
else else
f = fopen(data->arg, "wb"); f = fopen(data->arg, "wb");
@@ -75,7 +77,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
} }
if (fwrite(pb->data, 1, pb->size, f) != pb->size) { if (fwrite(pb->data, 1, strlen(pb->data), f) != strlen(pb->data)) {
ctx->error(ctx, "%s: fwrite error", data->arg); ctx->error(ctx, "%s: fwrite error", data->arg);
fclose(f); fclose(f);
return (-1); return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-scroll-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-scroll-mode.c,v 1.19 2009-07-01 23:06:32 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_scroll_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_scroll_mode_entry = { const struct cmd_entry cmd_scroll_mode_entry = {
"scroll-mode", NULL, "scroll-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE, CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('u'), CMD_UFLAG,
cmd_scroll_mode_init, cmd_scroll_mode_init,
cmd_target_parse, cmd_target_parse,
cmd_scroll_mode_exec, cmd_scroll_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -48,7 +50,7 @@ cmd_scroll_mode_init(struct cmd *self, int key)
switch (key) { switch (key) {
case KEYC_PPAGE: case KEYC_PPAGE:
data->chflags |= CMD_CHFLAG('u'); data->flags |= CMD_UFLAG;
break; break;
} }
} }
@@ -57,13 +59,15 @@ int
cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
wp = wl->window->active;
window_pane_set_mode(wp, &window_scroll_mode); window_pane_set_mode(wp, &window_scroll_mode);
if (wp->mode == &window_scroll_mode && data->chflags & CMD_CHFLAG('u')) if (wp->mode == &window_scroll_mode && data->flags & CMD_UFLAG)
window_scroll_pageup(wp); window_scroll_pageup(wp);
return (0); return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-layout.c,v 1.8 2009-07-28 23:04:29 tcunha Exp $ */ /* $Id: cmd-select-layout.c,v 1.3 2009-06-25 16:34:50 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = { const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl", "select-layout", "selectl",
CMD_TARGET_WINDOW_USAGE " [layout-name]", CMD_TARGET_WINDOW_USAGE " layout-name",
CMD_ARG01, 0, CMD_ARG1,
cmd_select_layout_init, cmd_select_layout_init,
cmd_target_parse, cmd_target_parse,
cmd_select_layout_exec, cmd_select_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -47,17 +49,17 @@ cmd_select_layout_init(struct cmd *self, int key)
data = self->data; data = self->data;
switch (key) { switch (key) {
case ('1' | KEYC_ESCAPE): case KEYC_ADDESC('0'):
data->arg = xstrdup("manual-vertical");
break;
case KEYC_ADDESC('1'):
data->arg = xstrdup("even-horizontal"); data->arg = xstrdup("even-horizontal");
break; break;
case ('2' | KEYC_ESCAPE): case KEYC_ADDESC('2'):
data->arg = xstrdup("even-vertical"); data->arg = xstrdup("even-vertical");
break;
case ('3' | KEYC_ESCAPE):
data->arg = xstrdup("main-horizontal");
break; break;
case ('4' | KEYC_ESCAPE): case KEYC_ADDESC('9'):
data->arg = xstrdup("main-vertical"); data->arg = xstrdup("active-only");
break; break;
} }
} }
@@ -72,17 +74,13 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (data->arg == NULL) { if ((layout = layout_lookup(data->arg)) == -1) {
layout = wl->window->lastlayout; ctx->error(ctx, "unknown or ambiguous layout: %s", data->arg);
if (layout == -1)
return (0);
} else if ((layout = layout_set_lookup(data->arg)) == -1) {
ctx->error(ctx, "unknown layout or ambiguous: %s", data->arg);
return (-1); return (-1);
} }
layout = layout_set_select(wl->window, layout); if (layout_select(wl->window, layout) == 0)
ctx->info(ctx, "arranging in: %s", layout_set_name(layout)); ctx->info(ctx, "layout now: %s", layout_name(wl->window));
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-pane.c,v 1.10 2009-07-30 20:45:20 tcunha Exp $ */ /* $Id: cmd-select-pane.c,v 1.4 2009-04-01 21:10:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,31 +28,42 @@ int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = { const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp", "select-pane", "selectp",
CMD_TARGET_PANE_USAGE, CMD_PANE_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_select_pane_exec, cmd_select_pane_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
int int
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (!window_pane_visible(wp)) { if (wp->flags & PANE_HIDDEN) {
ctx->error(ctx, "pane not visible: %s", data->target); ctx->error(ctx, "pane %d is hidden", data->pane);
return (-1); return (-1);
} }
window_set_active_pane(wl->window, wp); window_set_active_pane(wl->window, wp);
server_status_window(wl->window); layout_refresh(wl->window, 1);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-prompt.c,v 1.12 2009-08-16 19:29:24 tcunha Exp $ */ /* $Id: cmd-select-prompt.c,v 1.7 2009-02-13 18:57:55 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,10 +33,12 @@ int cmd_select_prompt_callback(void *, const char *);
const struct cmd_entry cmd_select_prompt_entry = { const struct cmd_entry cmd_select_prompt_entry = {
"select-prompt", NULL, "select-prompt", NULL,
CMD_TARGET_CLIENT_USAGE, CMD_TARGET_CLIENT_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_select_prompt_exec, cmd_select_prompt_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -53,7 +55,7 @@ cmd_select_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
if (c->prompt_string != NULL) if (c->prompt_string != NULL)
return (0); return (0);
status_prompt_set(c, "index ", cmd_select_prompt_callback, NULL, c, 0); status_prompt_set(c, "index ", cmd_select_prompt_callback, c, 0);
return (0); return (0);
} }
@@ -66,20 +68,20 @@ cmd_select_prompt_callback(void *data, const char *s)
char msg[128]; char msg[128];
u_int idx; u_int idx;
if (s == NULL || *s == '\0') if (s == NULL)
return (0); return (0);
idx = strtonum(s, 0, UINT_MAX, &errstr); idx = strtonum(s, 0, UINT_MAX, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
xsnprintf(msg, sizeof msg, "Index %s: %s", errstr, s); xsnprintf(msg, sizeof msg, "Index %s: %s", errstr, s);
status_message_set(c, "%s", msg); status_message_set(c, msg);
return (0); return (0);
} }
if (winlink_find_by_index(&c->session->windows, idx) == NULL) { if (winlink_find_by_index(&c->session->windows, idx) == NULL) {
xsnprintf(msg, sizeof msg, xsnprintf(msg, sizeof msg,
"Window not found: %s:%d", c->session->name, idx); "Window not found: %s:%d", c->session->name, idx);
status_message_set(c, "%s", msg); status_message_set(c, msg);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-window.c,v 1.23 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-select-window.c,v 1.21 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_select_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_window_entry = { const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw", "select-window", "selectw",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_select_window_init, cmd_select_window_init,
cmd_target_parse, cmd_target_parse,
cmd_select_window_exec, cmd_select_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-keys.c,v 1.21 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-send-keys.c,v 1.18 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,6 +28,8 @@
int cmd_send_keys_parse(struct cmd *, int, char **, char **); int cmd_send_keys_parse(struct cmd *, int, char **, char **);
int cmd_send_keys_exec(struct cmd *, struct cmd_ctx *); int cmd_send_keys_exec(struct cmd *, struct cmd_ctx *);
void cmd_send_keys_send(struct cmd *, struct buffer *);
void cmd_send_keys_recv(struct cmd *, struct buffer *);
void cmd_send_keys_free(struct cmd *); void cmd_send_keys_free(struct cmd *);
size_t cmd_send_keys_print(struct cmd *, char *, size_t); size_t cmd_send_keys_print(struct cmd *, char *, size_t);
@@ -40,11 +42,13 @@ struct cmd_send_keys_data {
const struct cmd_entry cmd_send_keys_entry = { const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send", "send-keys", "send",
"[-t target-pane] key ...", "[-t target-window] key ...",
0, 0, 0,
NULL, NULL,
cmd_send_keys_parse, cmd_send_keys_parse,
cmd_send_keys_exec, cmd_send_keys_exec,
cmd_send_keys_send,
cmd_send_keys_recv,
cmd_send_keys_free, cmd_send_keys_free,
cmd_send_keys_print cmd_send_keys_print
}; };
@@ -106,21 +110,45 @@ int
cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_send_keys_data *data = self->data; struct cmd_send_keys_data *data = self->data;
struct window_pane *wp; struct winlink *wl;
u_int i; u_int i;
if (data == NULL) if (data == NULL)
return (-1); return (-1);
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
for (i = 0; i < data->nkeys; i++) for (i = 0; i < data->nkeys; i++) {
window_pane_key(wp, ctx->curclient, data->keys[i]); window_pane_key(
wl->window->active, ctx->curclient, data->keys[i]);
}
return (0); return (0);
} }
void
cmd_send_keys_send(struct cmd *self, struct buffer *b)
{
struct cmd_send_keys_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
buffer_write(b, data->keys, data->nkeys * sizeof *data->keys);
}
void
cmd_send_keys_recv(struct cmd *self, struct buffer *b)
{
struct cmd_send_keys_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->keys = xcalloc(data->nkeys, sizeof *data->keys);
buffer_read(b, data->keys, data->nkeys * sizeof *data->keys);
}
void void
cmd_send_keys_free(struct cmd *self) cmd_send_keys_free(struct cmd *self)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-prefix.c,v 1.26 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-send-prefix.c,v 1.23 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,11 +28,13 @@ int cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = { const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL, "send-prefix", NULL,
CMD_TARGET_PANE_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_send_prefix_exec, cmd_send_prefix_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -42,14 +44,14 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct session *s; struct session *s;
struct window_pane *wp; struct winlink *wl;
int key; int key;
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
key = options_get_number(&s->options, "prefix"); key = options_get_number(&s->options, "prefix");
window_pane_key(wp, ctx->curclient, key); window_pane_key(wl->window->active, ctx->curclient, key);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.28 2009-09-07 23:59:19 tcunha Exp $ */ /* $Id: cmd-server-info.c,v 1.20 2009-06-25 20:27:31 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,11 +35,13 @@ int cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = { const struct cmd_entry cmd_server_info_entry = {
"server-info", "info", "server-info", "info",
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_server_info_exec, cmd_server_info_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };
@@ -56,7 +58,6 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct tty_term_code_entry *ent; struct tty_term_code_entry *ent;
struct utsname un; struct utsname un;
struct grid *gd; struct grid *gd;
struct grid_line *gl;
u_int i, j, k; u_int i, j, k;
char out[80]; char out[80];
char *tim; char *tim;
@@ -68,9 +69,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
*strchr(tim, '\n') = '\0'; *strchr(tim, '\n') = '\0';
ctx->print(ctx, ctx->print(ctx,
"tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim); "tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(ctx, "socket path %s, debug level %d%s%s", ctx->print(ctx, "socket path %s, debug level %d%s",
socket_path, debug_level, be_quiet ? ", quiet" : "", socket_path, debug_level, be_quiet ? ", quiet" : "");
login_shell ? ", login shell" : "");
if (uname(&un) == 0) { if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s", ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine); un.sysname, un.release, un.version, un.machine);
@@ -82,7 +82,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION); ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION);
ctx->print(ctx, "%u clients, %u sessions", ctx->print(ctx, "%u clients, %u sessions",
ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions)); ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions));
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
ctx->print(ctx, "Clients:"); ctx->print(ctx, "Clients:");
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -91,12 +91,11 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
continue; continue;
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] " ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x, references=%u]", i, c->tty.path, "[flags=0x%x/0x%x]", i, c->tty.path, c->fd, c->tty.fd,
c->ibuf.fd, c->tty.fd, c->session->name, c->session->name, c->tty.sx, c->tty.sy, c->tty.termname,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags, c->flags, c->tty.flags);
c->tty.flags, c->references);
} }
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
ctx->print(ctx, "Sessions: [%zu/%zu]", ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8)); sizeof (struct grid_cell), sizeof (struct grid_utf8));
@@ -110,30 +109,28 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
*strchr(tim, '\n') = '\0'; *strchr(tim, '\n') = '\0';
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] " ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x, references=%u]", i, s->name, "[flags=0x%x]", i, s->name, winlink_count(&s->windows),
winlink_count(&s->windows), tim, s->sx, s->sy, s->flags, tim, s->sx, s->sy, s->flags);
s->references);
RB_FOREACH(wl, winlinks, &s->windows) { RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window; w = wl->window;
ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, " ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, "
"references=%u, last layout=%d]", wl->idx, w->name, "references=%u, layout=%u]", wl->idx, w->name,
w->sx, w->sy, w->flags, w->references, w->sx, w->sy, w->flags, w->references,
w->lastlayout); w->layout);
j = 0; j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0; lines = ulines = size = usize = 0;
gd = wp->base.grid; gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) { for (k = 0; k < gd->hsize + gd->sy; k++) {
gl = &gd->linedata[k]; if (gd->data[k] != NULL) {
if (gl->celldata != NULL) {
lines++; lines++;
size += gl->cellsize * size += gd->size[k] *
sizeof *gl->celldata; sizeof (**gd->data);
} }
if (gl->utf8data != NULL) { if (gd->udata[k] != NULL) {
ulines++; ulines++;
usize += gl->utf8size * usize += gd->usize[k] *
sizeof *gl->utf8data; sizeof (**gd->udata);
} }
} }
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu " ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
@@ -145,7 +142,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
} }
} }
} }
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
ctx->print(ctx, "Terminals:"); ctx->print(ctx, "Terminals:");
SLIST_FOREACH(term, &tty_terms, entry) { SLIST_FOREACH(term, &tty_terms, entry) {
@@ -177,7 +174,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
} }
} }
} }
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-set-buffer.c,v 1.7 2009-01-25 18:51:28 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,7 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <stdlib.h>
#include "tmux.h" #include "tmux.h"
@@ -31,10 +31,12 @@ int cmd_set_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_buffer_entry = { const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb", "set-buffer", "setb",
CMD_BUFFER_SESSION_USAGE " data", CMD_BUFFER_SESSION_USAGE " data",
CMD_ARG1, 0, CMD_ARG1,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_set_buffer_exec, cmd_set_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -45,23 +47,17 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_buffer_data *data = self->data; struct cmd_buffer_data *data = self->data;
struct session *s; struct session *s;
u_int limit; u_int limit;
u_char *pdata;
size_t psize;
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
limit = options_get_number(&s->options, "buffer-limit"); limit = options_get_number(&s->options, "buffer-limit");
pdata = xstrdup(data->arg);
psize = strlen(pdata);
if (data->buffer == -1) { if (data->buffer == -1) {
paste_add(&s->buffers, pdata, psize, limit); paste_add(&s->buffers, xstrdup(data->arg), limit);
return (0); return (0);
} }
if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) { if (paste_replace(&s->buffers, data->buffer, xstrdup(data->arg)) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer); ctx->error(ctx, "no buffer %d", data->buffer);
xfree(pdata);
return (-1); return (-1);
} }
return (0); return (0);

View File

@@ -1,88 +0,0 @@
/* $Id: cmd-set-environment.c,v 1.2 2009-08-11 14:42:59 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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 <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Set an environment variable.
*/
int cmd_set_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv",
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
CMD_ARG12, CMD_CHFLAG('g')|CMD_CHFLAG('r')|CMD_CHFLAG('u'),
NULL,
cmd_target_parse,
cmd_set_environment_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct environ *env;
if (*data->arg == '\0') {
ctx->error(ctx, "empty variable name");
return (-1);
}
if (strchr(data->arg, '=') != NULL) {
ctx->error(ctx, "variable name contains =");
return (-1);
}
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
env = &s->environ;
}
if (data->chflags & CMD_CHFLAG('u')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -u");
return (-1);
}
environ_unset(env, data->arg);
} else if (data->chflags & CMD_CHFLAG('r')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -r");
return (-1);
}
environ_set(env, data->arg, NULL);
} else {
if (data->arg2 == NULL) {
ctx->error(ctx, "no value specified");
return (-1);
}
environ_set(env, data->arg, data->arg2);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.79 2009-09-19 18:53:01 tcunha Exp $ */ /* $Id: cmd-set-option.c,v 1.62 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,34 +31,28 @@ int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_option_entry = { const struct cmd_entry cmd_set_option_entry = {
"set-option", "set", "set-option", "set",
"[-agu] " CMD_TARGET_SESSION_USAGE " option [value]", CMD_OPTION_SESSION_USAGE,
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'), CMD_GFLAG|CMD_UFLAG,
NULL, NULL,
cmd_target_parse, cmd_option_parse,
cmd_set_option_exec, cmd_set_option_exec,
cmd_target_free, cmd_option_send,
cmd_target_print cmd_option_recv,
cmd_option_free,
cmd_option_print
}; };
const char *set_option_status_keys_list[] = { const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL "emacs", "vi", NULL
}; };
const char *set_option_status_justify_list[] = {
"left", "centre", "right", NULL
};
const char *set_option_bell_action_list[] = { const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL "none", "any", "current", NULL
}; };
const struct set_option_entry set_option_table[] = { const struct set_option_entry set_option_table[NSETOPTION] = {
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list }, { "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "default-command", SET_OPTION_STRING, 0, 0, NULL }, { "default-command", SET_OPTION_STRING, 0, 0, NULL },
{ "default-path", SET_OPTION_STRING, 0, 0, NULL }, { "default-path", SET_OPTION_STRING, 0, 0, NULL },
{ "default-shell", SET_OPTION_STRING, 0, 0, NULL },
{ "default-terminal", SET_OPTION_STRING, 0, 0, NULL },
{ "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
@@ -69,83 +63,69 @@ const struct set_option_entry set_option_table[] = {
{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, { "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL }, { "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles-string", SET_OPTION_STRING, 0, 0, NULL },
{ "status", SET_OPTION_FLAG, 0, 0, NULL }, { "status", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "status-justify",
SET_OPTION_CHOICE, 0, 0, set_option_status_justify_list },
{ "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list }, { "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list },
{ "status-left", SET_OPTION_STRING, 0, 0, NULL }, { "status-left", SET_OPTION_STRING, 0, 0, NULL },
{ "status-left-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-left-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-left-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, NULL }, { "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-right-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL }, { "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL },
{ "update-environment", SET_OPTION_STRING, 0, 0, NULL },
{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
}; };
int int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_option_data *data = self->data;
struct session *s; struct session *s;
struct client *c; struct client *c;
struct options *oo; struct options *oo;
const struct set_option_entry *entry, *opt; const struct set_option_entry *entry;
u_int i; u_int i;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_s_options; oo = &global_options;
else { else {
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
oo = &s->options; oo = &s->options;
} }
if (*data->arg == '\0') { if (*data->option == '\0') {
ctx->error(ctx, "invalid option"); ctx->error(ctx, "invalid option");
return (-1); return (-1);
} }
entry = NULL; entry = NULL;
for (opt = set_option_table; opt->name != NULL; opt++) { for (i = 0; i < NSETOPTION; i++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0) if (strncmp(set_option_table[i].name,
data->option, strlen(data->option)) != 0)
continue; continue;
if (entry != NULL) { if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg); ctx->error(ctx, "ambiguous option: %s", data->option);
return (-1); return (-1);
} }
entry = opt; entry = &set_option_table[i];
/* Bail now if an exact match. */ /* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0) if (strcmp(entry->name, data->option) == 0)
break; break;
} }
if (entry == NULL) { if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg); ctx->error(ctx, "unknown option: %s", data->option);
return (-1); return (-1);
} }
if (data->chflags & CMD_CHFLAG('u')) { if (data->flags & CMD_UFLAG) {
if (data->chflags & CMD_CHFLAG('g')) { if (data->flags & CMD_GFLAG) {
ctx->error(ctx, ctx->error(ctx,
"can't unset global option: %s", entry->name); "can't unset global option: %s", entry->name);
return (-1); return (-1);
} }
if (data->arg2 != NULL) { if (data->value != NULL) {
ctx->error(ctx, ctx->error(ctx,
"value passed to unset option: %s", entry->name); "value passed to unset option: %s", entry->name);
return (-1); return (-1);
@@ -156,26 +136,25 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else { } else {
switch (entry->type) { switch (entry->type) {
case SET_OPTION_STRING: case SET_OPTION_STRING:
set_option_string(ctx, oo, entry, set_option_string(ctx, oo, entry, data->value);
data->arg2, data->chflags & CMD_CHFLAG('a'));
break; break;
case SET_OPTION_NUMBER: case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2); set_option_number(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_KEY: case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->arg2); set_option_key(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_COLOUR: case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2); set_option_colour(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_ATTRIBUTES: case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2); set_option_attributes(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_FLAG: case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2); set_option_flag(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_CHOICE: case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2); set_option_choice(ctx, oo, entry, data->value);
break; break;
} }
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-password.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-set-password.c,v 1.5 2009-06-25 16:47:00 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,6 +29,8 @@
int cmd_set_password_parse(struct cmd *, int, char **, char **); int cmd_set_password_parse(struct cmd *, int, char **, char **);
int cmd_set_password_exec(struct cmd *, struct cmd_ctx *); int cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_password_send(struct cmd *, struct buffer *);
void cmd_set_password_recv(struct cmd *, struct buffer *);
void cmd_set_password_free(struct cmd *); void cmd_set_password_free(struct cmd *);
void cmd_set_password_init(struct cmd *, int); void cmd_set_password_init(struct cmd *, int);
size_t cmd_set_password_print(struct cmd *, char *, size_t); size_t cmd_set_password_print(struct cmd *, char *, size_t);
@@ -41,10 +43,12 @@ struct cmd_set_password_data {
const struct cmd_entry cmd_set_password_entry = { const struct cmd_entry cmd_set_password_entry = {
"set-password", "pass", "set-password", "pass",
"[-c] password", "[-c] password",
0, 0, 0,
cmd_set_password_init, cmd_set_password_init,
cmd_set_password_parse, cmd_set_password_parse,
cmd_set_password_exec, cmd_set_password_exec,
cmd_set_password_send,
cmd_set_password_recv,
cmd_set_password_free, cmd_set_password_free,
cmd_set_password_print cmd_set_password_print
}; };
@@ -114,10 +118,30 @@ cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
server_password = NULL; server_password = NULL;
else else
server_password = xstrdup(data->password); server_password = xstrdup(data->password);
log_debug("pw now %s", server_password);
return (0); return (0);
} }
void
cmd_set_password_send(struct cmd *self, struct buffer *b)
{
struct cmd_set_password_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->password);
}
void
cmd_set_password_recv(struct cmd *self, struct buffer *b)
{
struct cmd_set_password_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->password = cmd_recv_string(b);
}
void void
cmd_set_password_free(struct cmd *self) cmd_set_password_free(struct cmd *self)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.38 2009-08-11 14:42:59 nicm Exp $ */ /* $Id: cmd-set-window-option.c,v 1.28 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,13 +31,15 @@ int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_window_option_entry = { const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw", "set-window-option", "setw",
"[-agu] " CMD_TARGET_WINDOW_USAGE " option [value]", CMD_OPTION_WINDOW_USAGE,
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'), CMD_GFLAG|CMD_UFLAG,
NULL, NULL,
cmd_target_parse, cmd_option_parse,
cmd_set_window_option_exec, cmd_set_window_option_exec,
cmd_target_free, cmd_option_send,
cmd_target_print cmd_option_recv,
cmd_option_free,
cmd_option_print
}; };
const char *set_option_mode_keys_list[] = { const char *set_option_mode_keys_list[] = {
@@ -46,7 +48,7 @@ const char *set_option_mode_keys_list[] = {
const char *set_option_clock_mode_style_list[] = { const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL "12", "24", NULL
}; };
const struct set_option_entry set_window_option_table[] = { const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL }, { "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL }, { "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL }, { "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
@@ -54,76 +56,71 @@ const struct set_option_entry set_window_option_table[] = {
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list }, SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list }, { "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL }, { "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL }, { "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, { "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL }, { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL }, { "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
}; };
int int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_option_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct client *c; struct client *c;
struct options *oo; struct options *oo;
const struct set_option_entry *entry, *opt; const struct set_option_entry *entry;
u_int i; u_int i;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_w_options; oo = &global_window_options;
else { else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
oo = &wl->window->options; oo = &wl->window->options;
} }
if (*data->arg == '\0') { if (*data->option == '\0') {
ctx->error(ctx, "invalid option"); ctx->error(ctx, "invalid option");
return (-1); return (-1);
} }
entry = NULL; entry = NULL;
for (opt = set_window_option_table; opt->name != NULL; opt++) { for (i = 0; i < NSETWINDOWOPTION; i++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0) if (strncmp(set_window_option_table[i].name,
data->option, strlen(data->option)) != 0)
continue; continue;
if (entry != NULL) { if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg); ctx->error(ctx, "ambiguous option: %s", data->option);
return (-1); return (-1);
} }
entry = opt; entry = &set_window_option_table[i];
/* Bail now if an exact match. */ /* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0) if (strcmp(entry->name, data->option) == 0)
break; break;
} }
if (entry == NULL) { if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg); ctx->error(ctx, "unknown option: %s", data->option);
return (-1); return (-1);
} }
if (data->chflags & CMD_CHFLAG('u')) { if (data->flags & CMD_UFLAG) {
if (data->chflags & CMD_CHFLAG('g')) { if (data->flags & CMD_GFLAG) {
ctx->error(ctx, ctx->error(ctx,
"can't unset global option: %s", entry->name); "can't unset global option: %s", entry->name);
return (-1); return (-1);
} }
if (data->arg2 != NULL) { if (data->value != NULL) {
ctx->error(ctx, ctx->error(ctx,
"value passed to unset option: %s", entry->name); "value passed to unset option: %s", entry->name);
return (-1); return (-1);
@@ -134,26 +131,25 @@ cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else { } else {
switch (entry->type) { switch (entry->type) {
case SET_OPTION_STRING: case SET_OPTION_STRING:
set_option_string(ctx, oo, entry, set_option_string(ctx, oo, entry, data->value);
data->arg2, data->chflags & CMD_CHFLAG('a'));
break; break;
case SET_OPTION_NUMBER: case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2); set_option_number(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_KEY: case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->arg2); set_option_key(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_COLOUR: case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2); set_option_colour(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_ATTRIBUTES: case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2); set_option_attributes(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_FLAG: case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2); set_option_flag(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_CHOICE: case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2); set_option_choice(ctx, oo, entry, data->value);
break; break;
} }
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-show-buffer.c,v 1.4 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -29,10 +31,12 @@ int cmd_show_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_buffer_entry = { const struct cmd_entry cmd_show_buffer_entry = {
"show-buffer", "showb", "show-buffer", "showb",
CMD_BUFFER_SESSION_USAGE, CMD_BUFFER_SESSION_USAGE,
0, 0, 0,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_show_buffer_exec, cmd_show_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -43,9 +47,9 @@ cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_buffer_data *data = self->data; struct cmd_buffer_data *data = self->data;
struct session *s; struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
char *in, *buf, *ptr; u_int size;
size_t size, len; char *buf, *ptr;
u_int width; size_t len;
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
@@ -59,43 +63,27 @@ cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "no buffer %d", data->buffer); ctx->error(ctx, "no buffer %d", data->buffer);
return (-1); return (-1);
} }
if (pb == NULL)
return (0);
size = pb->size; if (pb != NULL) {
if (size > SIZE_MAX / 4 - 1) size = s->sx;
size = SIZE_MAX / 4 - 1;
in = xmalloc(size * 4 + 1);
strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB);
width = s->sx; buf = xmalloc(size + 1);
if (ctx->cmdclient != NULL) len = 0;
width = ctx->cmdclient->tty.sx;
buf = xmalloc(width + 1);
len = 0;
ptr = in;
do {
buf[len++] = *ptr++;
if (len == width || buf[len - 1] == '\n') {
if (buf[len - 1] == '\n')
len--;
buf[len] = '\0';
ctx->print(ctx, "%s", buf); ptr = pb->data;
len = 0; do {
} buf[len++] = *ptr++;
} while (*ptr != '\0');
if (len == size) {
if (len != 0) { buf[len] = '\0';
ctx->print(ctx, buf);
len = 0;
}
} while (*ptr != '\0');
buf[len] = '\0'; buf[len] = '\0';
ctx->print(ctx, "%s", buf); ctx->print(ctx, buf);
} }
xfree(buf);
xfree(in);
return (0); return (0);
} }

View File

@@ -1,67 +0,0 @@
/* $Id: cmd-show-environment.c,v 1.1 2009-08-09 17:48:55 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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 <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Show environment.
*/
int cmd_show_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv",
"[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'),
cmd_target_init,
cmd_target_parse,
cmd_show_environment_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct environ *env;
struct environ_entry *envent;
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
env = &s->environ;
}
RB_FOREACH(envent, environ, env) {
if (envent->value != NULL)
ctx->print(ctx, "%s=%s", envent->name, envent->value);
else
ctx->print(ctx, "-%s", envent->name);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.16 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-show-options.c,v 1.11 2009-01-27 20:22:33 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_options_entry = { const struct cmd_entry cmd_show_options_entry = {
"show-options", "show", "show-options", "show",
"[-g] " CMD_TARGET_SESSION_USAGE, "[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'), CMD_GFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_show_options_exec, cmd_show_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -47,18 +49,21 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s; struct session *s;
struct options *oo; struct options *oo;
const struct set_option_entry *entry; const struct set_option_entry *entry;
u_int i;
char *vs; char *vs;
long long vn; long long vn;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_s_options; oo = &global_options;
else { else {
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
oo = &s->options; oo = &s->options;
} }
for (entry = set_option_table; entry->name != NULL; entry++) { for (i = 0; i < NSETOPTION; i++) {
entry = &set_option_table[i];
if (options_find1(oo, entry->name) == NULL) if (options_find1(oo, entry->name) == NULL)
continue; continue;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-window-options.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-show-window-options.c,v 1.7 2009-01-27 20:22:33 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_window_options_entry = { const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw", "show-window-options", "showw",
"[-g] " CMD_TARGET_WINDOW_USAGE, "[-g] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('g'), CMD_GFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_show_window_options_exec, cmd_show_window_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -47,18 +49,21 @@ cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl; struct winlink *wl;
struct options *oo; struct options *oo;
const struct set_option_entry *entry; const struct set_option_entry *entry;
u_int i;
char *vs; char *vs;
long long vn; long long vn;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_w_options; oo = &global_window_options;
else { else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
oo = &wl->window->options; oo = &wl->window->options;
} }
for (entry = set_window_option_table; entry->name != NULL; entry++) { for (i = 0; i < NSETWINDOWOPTION; i++) {
entry = &set_window_option_table[i];
if (options_find1(oo, entry->name) == NULL) if (options_find1(oo, entry->name) == NULL)
continue; continue;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-source-file.c,v 1.8 2009-08-24 16:27:03 tcunha Exp $ */ /* $Id: cmd-source-file.c,v 1.5 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -26,6 +26,8 @@
int cmd_source_file_parse(struct cmd *, int, char **, char **); int cmd_source_file_parse(struct cmd *, int, char **, char **);
int cmd_source_file_exec(struct cmd *, struct cmd_ctx *); int cmd_source_file_exec(struct cmd *, struct cmd_ctx *);
void cmd_source_file_send(struct cmd *, struct buffer *);
void cmd_source_file_recv(struct cmd *, struct buffer *);
void cmd_source_file_free(struct cmd *); void cmd_source_file_free(struct cmd *);
void cmd_source_file_init(struct cmd *, int); void cmd_source_file_init(struct cmd *, int);
size_t cmd_source_file_print(struct cmd *, char *, size_t); size_t cmd_source_file_print(struct cmd *, char *, size_t);
@@ -37,10 +39,12 @@ struct cmd_source_file_data {
const struct cmd_entry cmd_source_file_entry = { const struct cmd_entry cmd_source_file_entry = {
"source-file", "source", "source-file", "source",
"path", "path",
0, 0, 0,
cmd_source_file_init, cmd_source_file_init,
cmd_source_file_parse, cmd_source_file_parse,
cmd_source_file_exec, cmd_source_file_exec,
cmd_source_file_send,
cmd_source_file_recv,
cmd_source_file_free, cmd_source_file_free,
cmd_source_file_print cmd_source_file_print
}; };
@@ -90,7 +94,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_source_file_data *data = self->data; struct cmd_source_file_data *data = self->data;
char *cause; char *cause;
if (load_cfg(data->path, ctx, &cause) != 0) { if (load_cfg(data->path, &cause) != 0) {
ctx->error(ctx, "%s", cause); ctx->error(ctx, "%s", cause);
xfree(cause); xfree(cause);
return (-1); return (-1);
@@ -99,6 +103,25 @@ cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0); return (0);
} }
void
cmd_source_file_send(struct cmd *self, struct buffer *b)
{
struct cmd_source_file_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->path);
}
void
cmd_source_file_recv(struct cmd *self, struct buffer *b)
{
struct cmd_source_file_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->path = cmd_recv_string(b);
}
void void
cmd_source_file_free(struct cmd *self) cmd_source_file_free(struct cmd *self)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-split-window.c,v 1.27 2009-09-16 12:36:27 nicm Exp $ */ /* $Id: cmd-split-window.c,v 1.15 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,6 +29,8 @@
int cmd_split_window_parse(struct cmd *, int, char **, char **); int cmd_split_window_parse(struct cmd *, int, char **, char **);
int cmd_split_window_exec(struct cmd *, struct cmd_ctx *); int cmd_split_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_split_window_send(struct cmd *, struct buffer *);
void cmd_split_window_recv(struct cmd *, struct buffer *);
void cmd_split_window_free(struct cmd *); void cmd_split_window_free(struct cmd *);
void cmd_split_window_init(struct cmd *, int); void cmd_split_window_init(struct cmd *, int);
size_t cmd_split_window_print(struct cmd *, char *, size_t); size_t cmd_split_window_print(struct cmd *, char *, size_t);
@@ -37,24 +39,25 @@ struct cmd_split_window_data {
char *target; char *target;
char *cmd; char *cmd;
int flag_detached; int flag_detached;
int flag_horizontal;
int percentage; int percentage;
int size; int lines;
}; };
const struct cmd_entry cmd_split_window_entry = { const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw", "split-window", "splitw",
"[-dhv] [-p percentage|-l size] [-t target-window] [command]", "[-d] [-p percentage|-l lines] [-t target-window] [command]",
0, 0, 0,
cmd_split_window_init, cmd_split_window_init,
cmd_split_window_parse, cmd_split_window_parse,
cmd_split_window_exec, cmd_split_window_exec,
cmd_split_window_send,
cmd_split_window_recv,
cmd_split_window_free, cmd_split_window_free,
cmd_split_window_print cmd_split_window_print
}; };
void void
cmd_split_window_init(struct cmd *self, int key) cmd_split_window_init(struct cmd *self, unused int arg)
{ {
struct cmd_split_window_data *data; struct cmd_split_window_data *data;
@@ -62,63 +65,50 @@ cmd_split_window_init(struct cmd *self, int key)
data->target = NULL; data->target = NULL;
data->cmd = NULL; data->cmd = NULL;
data->flag_detached = 0; data->flag_detached = 0;
data->flag_horizontal = 0;
data->percentage = -1; data->percentage = -1;
data->size = -1; data->lines = -1;
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
case '"':
data->flag_horizontal = 0;
break;
}
} }
int int
cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause) cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
{ {
struct cmd_split_window_data *data; struct cmd_split_window_data *data;
int opt; int opt, n;
const char *errstr; const char *errstr;
self->entry->init(self, 0); self->entry->init(self, 0);
data = self->data; data = self->data;
while ((opt = getopt(argc, argv, "dhl:p:t:v")) != -1) { while ((opt = getopt(argc, argv, "dl:p:t:")) != -1) {
switch (opt) { switch (opt) {
case 'd': case 'd':
data->flag_detached = 1; data->flag_detached = 1;
break; break;
case 'h':
data->flag_horizontal = 1;
break;
case 't': case 't':
if (data->target == NULL) if (data->target == NULL)
data->target = xstrdup(optarg); data->target = xstrdup(optarg);
break; break;
case 'l': case 'l':
if (data->percentage != -1 || data->size != -1) if (data->percentage == -1 && data->lines == -1) {
break; n = strtonum(optarg, 1, INT_MAX, &errstr);
data->size = strtonum(optarg, 1, INT_MAX, &errstr); if (errstr != NULL) {
if (errstr != NULL) { xasprintf(cause, "lines %s", errstr);
xasprintf(cause, "size %s", errstr); goto error;
goto error; }
data->lines = n;
} }
break; break;
case 'p': case 'p':
if (data->size != -1 || data->percentage != -1) if (data->lines == -1 && data->percentage == -1) {
break; n = strtonum(optarg, 1, 100, &errstr);
data->percentage = strtonum(optarg, 1, 100, &errstr); if (errstr != NULL) {
if (errstr != NULL) { xasprintf(
xasprintf(cause, "percentage %s", errstr); cause, "percentage %s", errstr);
goto error; goto error;
}
data->percentage = n;
} }
break; break;
case 'v':
data->flag_horizontal = 0;
break;
default: default:
goto usage; goto usage;
} }
@@ -149,53 +139,38 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl; struct winlink *wl;
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
struct environ env; const char **env;
char *cmd, *cwd, *cause; char *cmd, *cwd, *cause;
const char *shell;
u_int hlimit; u_int hlimit;
int size; int lines;
enum layout_type type;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
w = wl->window; w = wl->window;
environ_init(&env); env = server_fill_environ(s);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
cmd = data->cmd; cmd = data->cmd;
if (cmd == NULL) if (cmd == NULL)
cmd = options_get_string(&s->options, "default-command"); cmd = options_get_string(&s->options, "default-command");
if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL) if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
cwd = options_get_string(&s->options, "default-path"); cwd = options_get_string(&global_options, "default-path");
else else
cwd = ctx->cmdclient->cwd; cwd = ctx->cmdclient->cwd;
size = -1; lines = -1;
if (data->size != -1) if (data->lines != -1)
size = data->size; lines = data->lines;
else if (data->percentage != -1) else if (data->percentage != -1)
size = (w->active->sy * data->percentage) / 100; lines = (w->active->sy * data->percentage) / 100;
hlimit = options_get_number(&s->options, "history-limit"); hlimit = options_get_number(&s->options, "history-limit");
wp = window_add_pane(w, lines, cmd, cwd, env, hlimit, &cause);
type = LAYOUT_TOPBOTTOM; if (wp == NULL) {
if (data->flag_horizontal) ctx->error(ctx, "create pane failed: %s", cause);
type = LAYOUT_LEFTRIGHT; xfree(cause);
return (-1);
shell = options_get_string(&s->options, "default-shell");
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
wp = window_add_pane(w, hlimit);
if (window_pane_spawn(wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
if (layout_split_pane(w->active, type, size, wp) != 0) {
cause = xstrdup("pane too small");
goto error;
} }
server_redraw_window(w); server_redraw_window(w);
if (!data->flag_detached) { if (!data->flag_detached) {
@@ -204,17 +179,30 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_session(s); server_redraw_session(s);
} else } else
server_status_session(s); server_status_session(s);
layout_refresh(w, 0);
environ_free(&env);
return (0); return (0);
}
error: void
environ_free(&env); cmd_split_window_send(struct cmd *self, struct buffer *b)
if (wp != NULL) {
window_remove_pane(w, wp); struct cmd_split_window_data *data = self->data;
ctx->error(ctx, "create pane failed: %s", cause);
xfree(cause); buffer_write(b, data, sizeof *data);
return (-1); cmd_send_string(b, data->target);
cmd_send_string(b, data->cmd);
}
void
cmd_split_window_recv(struct cmd *self, struct buffer *b)
{
struct cmd_split_window_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
} }
void void
@@ -240,14 +228,6 @@ cmd_split_window_print(struct cmd *self, char *buf, size_t len)
return (off); return (off);
if (off < len && data->flag_detached) if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d"); off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->flag_horizontal)
off += xsnprintf(buf + off, len - off, " -h");
if (off < len && data->size > 0)
off += xsnprintf(buf + off, len - off, " -l %d", data->size);
if (off < len && data->percentage > 0) {
off += xsnprintf(
buf + off, len - off, " -p %d", data->percentage);
}
if (off < len && data->target != NULL) if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target); off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->cmd != NULL) if (off < len && data->cmd != NULL)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-start-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-start-server.c,v 1.6 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_start_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_start_server_entry = { const struct cmd_entry cmd_start_server_entry = {
"start-server", "start", "start-server", "start",
"", "",
CMD_STARTSERVER, 0, CMD_STARTSERVER,
NULL, NULL,
NULL, NULL,
cmd_start_server_exec, cmd_start_server_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.23 2009-08-09 17:48:55 tcunha Exp $ */ /* $Id: cmd-string.c,v 1.17 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,11 +19,9 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -35,7 +33,6 @@ int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(const char *, size_t *); void cmd_string_ungetc(const char *, size_t *);
char *cmd_string_string(const char *, size_t *, char, int); char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *); char *cmd_string_variable(const char *, size_t *);
char *cmd_string_expand_tilde(const char *, size_t *);
int int
cmd_string_getc(const char *s, size_t *p) cmd_string_getc(const char *s, size_t *p)
@@ -59,11 +56,21 @@ int
cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause) cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
{ {
size_t p; size_t p;
int ch, i, argc, rval, have_arg; int ch, argc, rval, have_arg;
char **argv, *buf, *t; char **argv, *buf, *t, *u;
const char *whitespace, *equals;
size_t len; size_t len;
if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL)
t = strchr(s, '\0');
if ((u = strchr(s, '=')) != NULL && u < t) {
if (putenv(xstrdup(s)) != 0) {
xasprintf(cause, "assignment failed: %s", s);
return (-1);
}
*cmdlist = NULL;
return (0);
}
argv = NULL; argv = NULL;
argc = 0; argc = 0;
@@ -107,7 +114,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = xrealloc(buf, 1, len + strlen(t) + 1); buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1); strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t); len += strlen(t);
xfree(t);
have_arg = 1; have_arg = 1;
break; break;
@@ -137,18 +143,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
if (argc == 0) if (argc == 0)
goto out; goto out;
for (i = 0; i < argc; i++) {
equals = strchr(argv[i], '=');
whitespace = argv[i] + strcspn(argv[i], " \t");
if (equals == NULL || equals > whitespace)
break;
environ_put(&global_environ, argv[i]);
memmove(&argv[i], &argv[i + 1], argc - i - 1);
argc--;
}
if (argc == 0)
goto out;
*cmdlist = cmd_list_parse(argc, argv, cause); *cmdlist = cmd_list_parse(argc, argv, cause);
if (*cmdlist == NULL) if (*cmdlist == NULL)
goto out; goto out;
@@ -159,17 +153,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
rval = 0; rval = 0;
goto out; goto out;
case '~':
if (have_arg == 0) {
if ((t = cmd_string_expand_tilde(s, &p)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
break;
}
/* FALLTHROUGH */
default: default:
if (len >= SIZE_MAX - 2) if (len >= SIZE_MAX - 2)
goto error; goto error;
@@ -217,9 +200,6 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
switch (ch = cmd_string_getc(s, p)) { switch (ch = cmd_string_getc(s, p)) {
case EOF: case EOF:
goto error; goto error;
case 'e':
ch = '\033';
break;
case 'r': case 'r':
ch = '\r'; ch = '\r';
break; break;
@@ -239,7 +219,6 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
buf = xrealloc(buf, 1, len + strlen(t) + 1); buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1); strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t); len += strlen(t);
xfree(t);
continue; continue;
} }
@@ -328,31 +307,3 @@ error:
xfree(buf); xfree(buf);
return (NULL); return (NULL);
} }
char *
cmd_string_expand_tilde(const char *s, size_t *p)
{
struct passwd *pw;
char *home, *path, *username;
home = NULL;
if (cmd_string_getc(s, p) == '/') {
if ((home = getenv("HOME")) == NULL) {
if ((pw = getpwuid(getuid())) != NULL)
home = pw->pw_dir;
}
} else {
cmd_string_ungetc(s, p);
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
return (NULL);
if ((pw = getpwnam(username)) != NULL)
home = pw->pw_dir;
if (username != NULL)
xfree(username);
}
if (home == NULL)
return (NULL);
xasprintf(&path, "%s/", home);
return (path);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-suspend-client.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-suspend-client.c,v 1.2 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -37,10 +37,12 @@ struct cmd_suspend_client_data {
const struct cmd_entry cmd_suspend_client_entry = { const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc", "suspend-client", "suspendc",
"[-c target-client]", "[-c target-client]",
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_suspend_client_exec, cmd_suspend_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-pane.c,v 1.13 2009-07-30 21:04:40 tcunha Exp $ */ /* $Id: cmd-swap-pane.c,v 1.6 2009-06-25 15:28:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,118 +26,269 @@
* Swap two panes. * Swap two panes.
*/ */
void cmd_swap_pane_init(struct cmd *, int); int cmd_swap_pane_parse(struct cmd *, int, char **, char **);
int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *); int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_swap_pane_send(struct cmd *, struct buffer *);
void cmd_swap_pane_recv(struct cmd *, struct buffer *);
void cmd_swap_pane_free(struct cmd *);
void cmd_swap_pane_init(struct cmd *, int);
size_t cmd_swap_pane_print(struct cmd *, char *, size_t);
struct cmd_swap_pane_data {
char *target;
int src;
int dst;
int flag_detached;
int flag_up;
int flag_down;
};
const struct cmd_entry cmd_swap_pane_entry = { const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp", "swap-pane", "swapp",
"[-dDU] " CMD_SRCDST_PANE_USAGE, "[-dDU] [-t target-window] [-p src-index] [-q dst-index]",
0, CMD_CHFLAG('d')|CMD_CHFLAG('D')|CMD_CHFLAG('U'), 0,
cmd_swap_pane_init, cmd_swap_pane_init,
cmd_srcdst_parse, cmd_swap_pane_parse,
cmd_swap_pane_exec, cmd_swap_pane_exec,
cmd_srcdst_free, cmd_swap_pane_send,
cmd_srcdst_print cmd_swap_pane_recv,
cmd_swap_pane_free,
cmd_swap_pane_print
}; };
void void
cmd_swap_pane_init(struct cmd *self, int key) cmd_swap_pane_init(struct cmd *self, int key)
{ {
struct cmd_target_data *data; struct cmd_swap_pane_data *data;
cmd_srcdst_init(self, key); self->data = data = xmalloc(sizeof *data);
data->target = NULL;
data->src = -1;
data->dst = -1;
data->flag_detached = 0;
data->flag_up = 0;
data->flag_down = 0;
switch (key) {
case '{':
data->flag_up = 1;
break;
case '}':
data->flag_down = 1;
break;
}
}
int
cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_swap_pane_data *data;
int opt, n;
const char *errstr;
self->entry->init(self, 0);
data = self->data; data = self->data;
if (key == '{') while ((opt = getopt(argc, argv, "dDt:p:q:U")) != -1) {
data->chflags |= CMD_CHFLAG('U'); switch (opt) {
else if (key == '}') case 'd':
data->chflags |= CMD_CHFLAG('D'); data->flag_detached = 1;
break;
case 'D':
data->flag_up = 0;
data->flag_down = 1;
data->dst = -1;
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'p':
if (data->src == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "src %s", errstr);
goto error;
}
data->src = n;
}
break;
case 'q':
if (data->dst == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "dst %s", errstr);
goto error;
}
data->dst = n;
}
data->flag_up = 0;
data->flag_down = 0;
break;
case 'U':
data->flag_up = 1;
data->flag_down = 0;
data->dst = -1;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 0)
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
} }
int int
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_srcdst_data *data = self->data; struct cmd_swap_pane_data *data = self->data;
struct winlink *src_wl, *dst_wl; struct winlink *wl;
struct window *src_w, *dst_w; struct window *w;
struct window_pane *tmp_wp, *src_wp, *dst_wp; struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *src_lc, *dst_lc; u_int xx, yy;
u_int sx, sy, xoff, yoff; int flags;
if (data == NULL) if (data == NULL)
return (0); return (0);
if ((dst_wl = cmd_find_pane(ctx, data->dst, NULL, &dst_wp)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
dst_w = dst_wl->window; w = wl->window;
if (data->src == NULL) { if (data->src == -1)
src_w = dst_w; src_wp = w->active;
if (data->chflags & CMD_CHFLAG('D')) { else {
src_wp = TAILQ_NEXT(dst_wp, entry); src_wp = window_pane_at_index(w, data->src);
if (src_wp == NULL) if (src_wp == NULL) {
src_wp = TAILQ_FIRST(&dst_w->panes); ctx->error(ctx, "no pane: %d", data->src);
} else if (data->chflags & CMD_CHFLAG('U')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
} else
return (0);
} else {
src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp);
if (src_wl == NULL)
return (-1); return (-1);
src_w = src_wl->window; }
}
if (data->dst == -1)
dst_wp = w->active;
else {
dst_wp = window_pane_at_index(w, data->dst);
if (dst_wp == NULL) {
ctx->error(ctx, "no pane: %d", data->dst);
return (-1);
}
}
if (data->dst == -1 && data->flag_up) {
if ((dst_wp = TAILQ_PREV(src_wp, window_panes, entry)) == NULL)
dst_wp = TAILQ_LAST(&w->panes, window_panes);
}
if (data->dst == -1 && data->flag_down) {
if ((dst_wp = TAILQ_NEXT(src_wp, entry)) == NULL)
dst_wp = TAILQ_FIRST(&w->panes);
} }
if (src_wp == dst_wp) if (src_wp == dst_wp)
return (0); return (0);
tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry); tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
TAILQ_REMOVE(&dst_w->panes, dst_wp, entry); TAILQ_REMOVE(&w->panes, dst_wp, entry);
TAILQ_REPLACE(&src_w->panes, src_wp, dst_wp, entry); TAILQ_REPLACE(&w->panes, src_wp, dst_wp, entry);
if (tmp_wp == src_wp) if (tmp_wp == src_wp)
tmp_wp = dst_wp; tmp_wp = dst_wp;
if (tmp_wp == NULL) if (tmp_wp == NULL)
TAILQ_INSERT_HEAD(&dst_w->panes, src_wp, entry); TAILQ_INSERT_HEAD(&w->panes, src_wp, entry);
else else
TAILQ_INSERT_AFTER(&dst_w->panes, tmp_wp, src_wp, entry); TAILQ_INSERT_AFTER(&w->panes, tmp_wp, src_wp, entry);
src_lc = src_wp->layout_cell; xx = src_wp->xoff;
dst_lc = dst_wp->layout_cell; yy = src_wp->yoff;
src_lc->wp = dst_wp; flags = src_wp->flags;
dst_wp->layout_cell = src_lc; src_wp->xoff = dst_wp->xoff;
dst_lc->wp = src_wp; src_wp->yoff = dst_wp->yoff;
src_wp->layout_cell = dst_lc; src_wp->flags &= ~PANE_HIDDEN;
src_wp->flags |= dst_wp->flags & PANE_HIDDEN;
src_wp->window = dst_w; dst_wp->xoff = xx;
dst_wp->window = src_w; dst_wp->yoff = yy;
dst_wp->flags &= ~PANE_HIDDEN;
dst_wp->flags |= flags & PANE_HIDDEN;
sx = src_wp->sx; sy = src_wp->sy; xx = src_wp->sx;
xoff = src_wp->xoff; yoff = src_wp->yoff; yy = src_wp->sy;
src_wp->xoff = dst_wp->xoff; src_wp->yoff = dst_wp->yoff;
window_pane_resize(src_wp, dst_wp->sx, dst_wp->sy); window_pane_resize(src_wp, dst_wp->sx, dst_wp->sy);
dst_wp->xoff = xoff; dst_wp->yoff = yoff; window_pane_resize(dst_wp, xx, yy);
window_pane_resize(dst_wp, sx, sy);
if (!(data->chflags & CMD_CHFLAG('d'))) { if (!data->flag_detached) {
if (src_w != dst_w) { tmp_wp = dst_wp;
window_set_active_pane(src_w, dst_wp); if (tmp_wp->flags & PANE_HIDDEN)
window_set_active_pane(dst_w, src_wp); tmp_wp = src_wp;
} else { window_set_active_pane(w, tmp_wp);
tmp_wp = dst_wp; layout_refresh(w, 0);
if (!window_pane_visible(tmp_wp))
tmp_wp = src_wp;
window_set_active_pane(src_w, tmp_wp);
}
} else {
if (src_w->active == src_wp)
window_set_active_pane(src_w, dst_wp);
if (dst_w->active == dst_wp)
window_set_active_pane(dst_w, src_wp);
} }
server_redraw_window(src_w);
server_redraw_window(dst_w);
return (0); return (0);
} }
void
cmd_swap_pane_send(struct cmd *self, struct buffer *b)
{
struct cmd_swap_pane_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
}
void
cmd_swap_pane_recv(struct cmd *self, struct buffer *b)
{
struct cmd_swap_pane_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
}
void
cmd_swap_pane_free(struct cmd *self)
{
struct cmd_swap_pane_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
xfree(data);
}
size_t
cmd_swap_pane_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_swap_pane_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len &&
(data->flag_down || data->flag_up || data->flag_detached)) {
off += xsnprintf(buf + off, len - off, " -");
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, "d");
if (off < len && data->flag_up)
off += xsnprintf(buf + off, len - off, "D");
if (off < len && data->flag_down)
off += xsnprintf(buf + off, len - off, "U");
}
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->src != -1)
off += xsnprintf(buf + off, len - off, " -p %d", data->src);
if (off < len && data->dst != -1)
off += xsnprintf(buf + off, len - off, " -q %d", data->dst);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-window.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-swap-window.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_window_entry = { const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw", "swap-window", "swapw",
"[-d] " CMD_SRCDST_WINDOW_USAGE, "[-d] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d'), CMD_DFLAG,
cmd_srcdst_init, cmd_srcdst_init,
cmd_srcdst_parse, cmd_srcdst_parse,
cmd_swap_window_exec, cmd_swap_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free, cmd_srcdst_free,
cmd_srcdst_print cmd_srcdst_print
}; };
@@ -59,7 +61,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl_dst->window = wl_src->window; wl_dst->window = wl_src->window;
wl_src->window = w; wl_src->window = w;
if (!(data->chflags & CMD_CHFLAG('d'))) { if (!(data->flags & CMD_DFLAG)) {
session_select(dst, wl_dst->idx); session_select(dst, wl_dst->idx);
if (src != dst) if (src != dst)
session_select(src, wl_src->idx); session_select(src, wl_src->idx);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-switch-client.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-switch-client.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,6 +29,8 @@
int cmd_switch_client_parse(struct cmd *, int, char **, char **); int cmd_switch_client_parse(struct cmd *, int, char **, char **);
int cmd_switch_client_exec(struct cmd *, struct cmd_ctx *); int cmd_switch_client_exec(struct cmd *, struct cmd_ctx *);
void cmd_switch_client_send(struct cmd *, struct buffer *);
void cmd_switch_client_recv(struct cmd *, struct buffer *);
void cmd_switch_client_free(struct cmd *); void cmd_switch_client_free(struct cmd *);
size_t cmd_switch_client_print(struct cmd *, char *, size_t); size_t cmd_switch_client_print(struct cmd *, char *, size_t);
@@ -40,10 +42,12 @@ struct cmd_switch_client_data {
const struct cmd_entry cmd_switch_client_entry = { const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc", "switch-client", "switchc",
"[-c target-client] [-t target-session]", "[-c target-client] [-t target-session]",
0, 0, 0,
NULL, NULL,
cmd_switch_client_parse, cmd_switch_client_parse,
cmd_switch_client_exec, cmd_switch_client_exec,
cmd_switch_client_send,
cmd_switch_client_recv,
cmd_switch_client_free, cmd_switch_client_free,
cmd_switch_client_print cmd_switch_client_print
}; };
@@ -107,6 +111,27 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0); return (0);
} }
void
cmd_switch_client_send(struct cmd *self, struct buffer *b)
{
struct cmd_switch_client_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->name);
cmd_send_string(b, data->target);
}
void
cmd_switch_client_recv(struct cmd *self, struct buffer *b)
{
struct cmd_switch_client_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->name = cmd_recv_string(b);
data->target = cmd_recv_string(b);
}
void void
cmd_switch_client_free(struct cmd *self) cmd_switch_client_free(struct cmd *self)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unbind-key.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */ /* $Id: cmd-unbind-key.c,v 1.16 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,24 +26,23 @@
int cmd_unbind_key_parse(struct cmd *, int, char **, char **); int cmd_unbind_key_parse(struct cmd *, int, char **, char **);
int cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *); int cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *);
void cmd_unbind_key_send(struct cmd *, struct buffer *);
void cmd_unbind_key_recv(struct cmd *, struct buffer *);
void cmd_unbind_key_free(struct cmd *); void cmd_unbind_key_free(struct cmd *);
int cmd_unbind_key_table(struct cmd *, struct cmd_ctx *);
struct cmd_unbind_key_data { struct cmd_unbind_key_data {
int key; int key;
int command_key;
char *tablename;
}; };
const struct cmd_entry cmd_unbind_key_entry = { const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind", "unbind-key", "unbind",
"[-cn] [-t key-table] key", "key",
0, 0, 0,
NULL, NULL,
cmd_unbind_key_parse, cmd_unbind_key_parse,
cmd_unbind_key_exec, cmd_unbind_key_exec,
cmd_unbind_key_send,
cmd_unbind_key_recv,
cmd_unbind_key_free, cmd_unbind_key_free,
NULL NULL
}; };
@@ -52,23 +51,12 @@ int
cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause) cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
{ {
struct cmd_unbind_key_data *data; struct cmd_unbind_key_data *data;
int opt, no_prefix = 0; int opt;
self->data = data = xmalloc(sizeof *data); self->data = data = xmalloc(sizeof *data);
data->command_key = 0;
data->tablename = NULL;
while ((opt = getopt(argc, argv, "cnt:")) != -1) { while ((opt = getopt(argc, argv, "")) != -1) {
switch (opt) { switch (opt) {
case 'c':
data->command_key = 1;
break;
case 'n':
no_prefix = 1;
break;
case 't':
data->tablename = xstrdup(optarg);
break;
default: default:
goto usage; goto usage;
} }
@@ -82,8 +70,6 @@ cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
xasprintf(cause, "unknown key: %s", argv[0]); xasprintf(cause, "unknown key: %s", argv[0]);
goto error; goto error;
} }
if (!no_prefix)
data->key |= KEYC_PREFIX;
return (0); return (0);
@@ -102,33 +88,27 @@ cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
if (data == NULL) if (data == NULL)
return (0); return (0);
if (data->tablename != NULL)
return (cmd_unbind_key_table(self, ctx));
key_bindings_remove(data->key); key_bindings_remove(data->key);
return (0); return (0);
} }
int void
cmd_unbind_key_table(struct cmd *self, struct cmd_ctx *ctx) cmd_unbind_key_send(struct cmd *self, struct buffer *b)
{ {
struct cmd_unbind_key_data *data = self->data; struct cmd_unbind_key_data *data = self->data;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
if ((mtab = mode_key_findtable(data->tablename)) == NULL) { buffer_write(b, data, sizeof *data);
ctx->error(ctx, "unknown key table: %s", data->tablename); }
return (-1);
}
mtmp.key = data->key & ~KEYC_PREFIX; void
mtmp.mode = data->command_key ? 1 : 0; cmd_unbind_key_recv(struct cmd *self, struct buffer *b)
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) { {
SPLAY_REMOVE(mode_key_tree, mtab->tree, mbind); struct cmd_unbind_key_data *data;
xfree(mbind);
} self->data = data = xmalloc(sizeof *data);
return (0); buffer_read(b, data, sizeof *data);
} }
void void
@@ -136,7 +116,5 @@ cmd_unbind_key_free(struct cmd *self)
{ {
struct cmd_unbind_key_data *data = self->data; struct cmd_unbind_key_data *data = self->data;
if (data->tablename != NULL)
xfree(data->tablename);
xfree(data); xfree(data);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unlink-window.c,v 1.16 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-unlink-window.c,v 1.13 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,11 +28,13 @@ int cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_unlink_window_entry = { const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw", "unlink-window", "unlinkw",
"[-k] " CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('k'), 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_unlink_window_exec, cmd_unlink_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -50,7 +52,7 @@ cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
if (!(data->chflags & CMD_CHFLAG('k')) && wl->window->references == 1) { if (wl->window->references == 1) {
ctx->error(ctx, "window is only linked to one session"); ctx->error(ctx, "window is only linked to one session");
return (-1); return (-1);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-up-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-up-pane.c,v 1.7 2009-04-01 21:10:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_up_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_up_pane_entry = { const struct cmd_entry cmd_up_pane_entry = {
"up-pane", "upp", "up-pane", "upp",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_up_pane_exec, cmd_up_pane_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -52,8 +54,8 @@ cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_PREV(w->active, window_panes, entry); w->active = TAILQ_PREV(w->active, window_panes, entry);
if (w->active == NULL) if (w->active == NULL)
w->active = TAILQ_LAST(&w->panes, window_panes); w->active = TAILQ_LAST(&w->panes, window_panes);
} while (!window_pane_visible(w->active)); layout_refresh(w, 1);
server_status_window(wl->window); } while (w->active->flags & PANE_HIDDEN);
return (0); return (0);
} }

777
cmd.c
View File

@@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.115 2009-08-31 22:30:15 tcunha Exp $ */ /* $Id: cmd.c,v 1.97 2009-06-25 16:21:32 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,7 +19,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <fnmatch.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@@ -30,7 +29,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_attach_session_entry, &cmd_attach_session_entry,
&cmd_bind_key_entry, &cmd_bind_key_entry,
&cmd_break_pane_entry, &cmd_break_pane_entry,
&cmd_choose_client_entry,
&cmd_choose_session_entry, &cmd_choose_session_entry,
&cmd_choose_window_entry, &cmd_choose_window_entry,
&cmd_clear_history_entry, &cmd_clear_history_entry,
@@ -41,12 +39,9 @@ const struct cmd_entry *cmd_table[] = {
&cmd_copy_mode_entry, &cmd_copy_mode_entry,
&cmd_delete_buffer_entry, &cmd_delete_buffer_entry,
&cmd_detach_client_entry, &cmd_detach_client_entry,
&cmd_display_message_entry,
&cmd_display_panes_entry,
&cmd_down_pane_entry, &cmd_down_pane_entry,
&cmd_find_window_entry, &cmd_find_window_entry,
&cmd_has_session_entry, &cmd_has_session_entry,
&cmd_if_shell_entry,
&cmd_kill_pane_entry, &cmd_kill_pane_entry,
&cmd_kill_server_entry, &cmd_kill_server_entry,
&cmd_kill_session_entry, &cmd_kill_session_entry,
@@ -85,12 +80,10 @@ const struct cmd_entry *cmd_table[] = {
&cmd_send_prefix_entry, &cmd_send_prefix_entry,
&cmd_server_info_entry, &cmd_server_info_entry,
&cmd_set_buffer_entry, &cmd_set_buffer_entry,
&cmd_set_environment_entry,
&cmd_set_option_entry, &cmd_set_option_entry,
&cmd_set_password_entry, &cmd_set_password_entry,
&cmd_set_window_option_entry, &cmd_set_window_option_entry,
&cmd_show_buffer_entry, &cmd_show_buffer_entry,
&cmd_show_environment_entry,
&cmd_show_options_entry, &cmd_show_options_entry,
&cmd_show_window_options_entry, &cmd_show_window_options_entry,
&cmd_source_file_entry, &cmd_source_file_entry,
@@ -106,77 +99,13 @@ const struct cmd_entry *cmd_table[] = {
NULL NULL
}; };
struct session *cmd_newest_session(struct sessions *);
struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(const char *, int *);
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
int cmd_lookup_index(struct session *, const char *, int *);
int
cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
{
size_t arglen;
int i;
*buf = '\0';
for (i = 0; i < argc; i++) {
if (strlcpy(buf, argv[i], len) >= len)
return (-1);
arglen = strlen(argv[i]) + 1;
buf += arglen;
len -= arglen;
}
return (0);
}
int
cmd_unpack_argv(char *buf, size_t len, int argc, char ***argv)
{
int i;
size_t arglen;
if (argc == 0)
return (0);
*argv = xcalloc(argc, sizeof **argv);
buf[len - 1] = '\0';
for (i = 0; i < argc; i++) {
if (len == 0) {
cmd_free_argv(argc, *argv);
return (-1);
}
arglen = strlen(buf) + 1;
(*argv)[i] = xstrdup(buf);
buf += arglen;
len -= arglen;
}
return (0);
}
void
cmd_free_argv(int argc, char **argv)
{
int i;
if (argc == 0)
return;
for (i = 0; i < argc; i++) {
if (argv[i] != NULL)
xfree(argv[i]);
}
xfree(argv);
}
struct cmd * struct cmd *
cmd_parse(int argc, char **argv, char **cause) cmd_parse(int argc, char **argv, char **cause)
{ {
const struct cmd_entry **entryp, *entry; const struct cmd_entry **entryp, *entry;
struct cmd *cmd; struct cmd *cmd;
char s[BUFSIZ]; char s[BUFSIZ];
int opt, ambiguous = 0; int opt;
*cause = NULL; *cause = NULL;
if (argc == 0) { if (argc == 0) {
@@ -188,7 +117,6 @@ cmd_parse(int argc, char **argv, char **cause)
for (entryp = cmd_table; *entryp != NULL; entryp++) { for (entryp = cmd_table; *entryp != NULL; entryp++) {
if ((*entryp)->alias != NULL && if ((*entryp)->alias != NULL &&
strcmp((*entryp)->alias, argv[0]) == 0) { strcmp((*entryp)->alias, argv[0]) == 0) {
ambiguous = 0;
entry = *entryp; entry = *entryp;
break; break;
} }
@@ -196,15 +124,13 @@ cmd_parse(int argc, char **argv, char **cause)
if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0) if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0)
continue; continue;
if (entry != NULL) if (entry != NULL)
ambiguous = 1; goto ambiguous;
entry = *entryp; entry = *entryp;
/* Bail now if an exact match. */ /* Bail now if an exact match. */
if (strcmp(entry->name, argv[0]) == 0) if (strcmp(entry->name, argv[0]) == 0)
break; break;
} }
if (ambiguous)
goto ambiguous;
if (entry == NULL) { if (entry == NULL) {
xasprintf(cause, "unknown command: %s", argv[0]); xasprintf(cause, "unknown command: %s", argv[0]);
return (NULL); return (NULL);
@@ -265,6 +191,53 @@ cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
return (cmd->entry->exec(cmd, ctx)); return (cmd->entry->exec(cmd, ctx));
} }
void
cmd_send(struct cmd *cmd, struct buffer *b)
{
const struct cmd_entry **entryp;
u_int n;
n = 0;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
if (*entryp == cmd->entry)
break;
n++;
}
if (*entryp == NULL)
fatalx("command not found");
buffer_write(b, &n, sizeof n);
if (cmd->entry->send != NULL)
cmd->entry->send(cmd, b);
}
struct cmd *
cmd_recv(struct buffer *b)
{
const struct cmd_entry **entryp;
struct cmd *cmd;
u_int m, n;
buffer_read(b, &m, sizeof m);
n = 0;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
if (n == m)
break;
n++;
}
if (*entryp == NULL)
fatalx("command not found");
cmd = xmalloc(sizeof *cmd);
cmd->entry = *entryp;
if (cmd->entry->recv != NULL)
cmd->entry->recv(cmd, b);
return (cmd);
}
void void
cmd_free(struct cmd *cmd) cmd_free(struct cmd *cmd)
{ {
@@ -282,621 +255,141 @@ cmd_print(struct cmd *cmd, char *buf, size_t len)
return (cmd->entry->print(cmd, buf, len)); return (cmd->entry->print(cmd, buf, len));
} }
/* void
* Figure out the current session. Use: 1) the current session, if the command cmd_send_string(struct buffer *b, const char *s)
* context has one; 2) the session containing the pty of the calling client, if {
* any 3) the session specified in the TMUX variable from the environment (as size_t n;
* passed from the client); 3) the newest session.
*/ if (s == NULL) {
n = 0;
buffer_write(b, &n, sizeof n);
return;
}
n = strlen(s) + 1;
buffer_write(b, &n, sizeof n);
buffer_write(b, s, n);
}
char *
cmd_recv_string(struct buffer *b)
{
char *s;
size_t n;
buffer_read(b, &n, sizeof n);
if (n == 0)
return (NULL);
s = xmalloc(n);
buffer_read(b, s, n);
s[n - 1] = '\0';
return (s);
}
struct session * struct session *
cmd_current_session(struct cmd_ctx *ctx) cmd_current_session(struct cmd_ctx *ctx)
{ {
struct msg_command_data *data = ctx->msgdata; struct msg_command_data *data = ctx->msgdata;
struct client *c = ctx->cmdclient; struct timeval *tv;
struct session *s; struct session *s, *newest = NULL;
struct sessions ss;
struct winlink *wl;
struct window_pane *wp;
u_int i; u_int i;
int found;
if (ctx->curclient != NULL && ctx->curclient->session != NULL) if (ctx->cursession != NULL)
return (ctx->curclient->session); return (ctx->cursession);
/*
* 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
* newest.
*/
if (c != NULL && c->tty.path != NULL) {
ARRAY_INIT(&ss);
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
found = 0;
RB_FOREACH(wl, winlinks, &s->windows) {
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
if (strcmp(wp->tty, c->tty.path) == 0) {
found = 1;
break;
}
}
if (found)
break;
}
if (found)
ARRAY_ADD(&ss, s);
}
s = cmd_newest_session(&ss);
ARRAY_FREE(&ss);
if (s != NULL)
return (s);
}
/* Use the session from the TMUX environment variable. */
if (data != NULL && data->pid != -1) { if (data != NULL && data->pid != -1) {
if (data->pid != getpid()) if (data->pid != getpid()) {
ctx->error(ctx, "wrong server: %ld", (long) data->pid);
return (NULL); return (NULL);
if (data->idx > ARRAY_LENGTH(&sessions)) }
if (data->idx > ARRAY_LENGTH(&sessions)) {
ctx->error(ctx, "index out of range: %d", data->idx);
return (NULL); return (NULL);
if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL) }
if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL) {
ctx->error(ctx, "session doesn't exist: %u", data->idx);
return (NULL); return (NULL);
}
return (s); return (s);
} }
return (cmd_newest_session(&sessions)); tv = NULL;
} for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
/* Find the newest session. */ if (s != NULL && (tv == NULL || timercmp(&s->tv, tv, >))) {
struct session * newest = ARRAY_ITEM(&sessions, i);
cmd_newest_session(struct sessions *ss)
{
struct session *s, *snewest;
struct timeval *tv = NULL;
u_int i;
snewest = NULL;
for (i = 0; i < ARRAY_LENGTH(ss); i++) {
if ((s = ARRAY_ITEM(ss, i)) == NULL)
continue;
if (tv == NULL || timercmp(&s->tv, tv, >)) {
snewest = s;
tv = &s->tv; tv = &s->tv;
} }
} }
return (newest);
return (snewest);
} }
/* 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) cmd_find_client(struct cmd_ctx *ctx, const char *arg)
{ {
struct client *c; struct client *c;
char *tmparg;
size_t arglen;
/* A NULL argument means the current client. */
if (arg == NULL) if (arg == NULL)
return (ctx->curclient); c = ctx->curclient;
tmparg = xstrdup(arg); else {
if ((c = arg_parse_client(arg)) == NULL) {
/* Trim a single trailing colon if any. */ if (arg != NULL)
arglen = strlen(tmparg); ctx->error(ctx, "client not found: %s", arg);
if (arglen != 0 && tmparg[arglen - 1] == ':') else
tmparg[arglen - 1] = '\0'; ctx->error(ctx, "no client found");
}
/* Find the client, if any. */ }
c = cmd_lookup_client(tmparg);
/* If no client found, report an error. */
if (c == NULL)
ctx->error(ctx, "client not found: %s", tmparg);
xfree(tmparg);
return (c); return (c);
} }
/*
* Lookup a client by device path. Either of a full match and a match without a
* leading _PATH_DEV ("/dev/") is accepted.
*/
struct client *
cmd_lookup_client(const char *name)
{
struct client *c;
const char *path;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
continue;
path = c->tty.path;
/* Check for exact matches. */
if (strcmp(name, path) == 0)
return (c);
/* Check without leading /dev if present. */
if (strncmp(path, _PATH_DEV, (sizeof _PATH_DEV) - 1) != 0)
continue;
if (strcmp(name, path + (sizeof _PATH_DEV) - 1) == 0)
return (c);
}
return (NULL);
}
/* Lookup a session by name. If no session is found, NULL is returned. */
struct session *
cmd_lookup_session(const char *name, int *ambiguous)
{
struct session *s, *sfound;
u_int i;
*ambiguous = 0;
/*
* Look for matches. Session names must be unique so an exact match
* can't be ambigious and can just be returned.
*/
sfound = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
/* Check for an exact match and return it if found. */
if (strcmp(name, s->name) == 0)
return (s);
/* Then check for pattern matches. */
if (strncmp(name, s->name, strlen(name)) == 0 ||
fnmatch(name, s->name, 0) == 0) {
if (sfound != NULL) {
*ambiguous = 1;
return (NULL);
}
sfound = s;
}
}
return (sfound);
}
/*
* Lookup a window or return -1 if not found or ambigious. First try as an
* index and if invalid, use fnmatch or leading prefix. Return NULL but fill in
* idx if the window index is a valid number but there is now window with that
* index.
*/
struct winlink *
cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
{
struct winlink *wl, *wlfound;
const char *errstr;
u_int idx;
*ambiguous = 0;
/* First see if this is a valid window index in this session. */
idx = strtonum(name, 0, INT_MAX, &errstr);
if (errstr == NULL) {
if ((wl = winlink_find_by_index(&s->windows, idx)) != NULL)
return (wl);
}
/* Look for exact matches, error if more than one. */
wlfound = NULL;
RB_FOREACH(wl, winlinks, &s->windows) {
if (strcmp(name, wl->window->name) == 0) {
if (wlfound != NULL) {
*ambiguous = 1;
return (NULL);
}
wlfound = wl;
}
}
if (wlfound != NULL)
return (wlfound);
/* Now look for pattern matches, again error if multiple. */
wlfound = NULL;
RB_FOREACH(wl, winlinks, &s->windows) {
if (strncmp(name, wl->window->name, strlen(name)) == 0 ||
fnmatch(name, wl->window->name, 0) == 0) {
if (wlfound != NULL) {
*ambiguous = 1;
return (NULL);
}
wlfound = wl;
}
}
if (wlfound != NULL)
return (wlfound);
return (NULL);
}
/*
* Find a window index - if the window doesn't exist, check if it is a
* potential index and return it anyway.
*/
int
cmd_lookup_index(struct session *s, const char *name, int *ambiguous)
{
struct winlink *wl;
const char *errstr;
u_int idx;
if ((wl = cmd_lookup_window(s, name, ambiguous)) != NULL)
return (wl->idx);
if (*ambiguous)
return (-1);
idx = strtonum(name, 0, INT_MAX, &errstr);
if (errstr == NULL)
return (idx);
return (-1);
}
/* 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) cmd_find_session(struct cmd_ctx *ctx, const char *arg)
{ {
struct session *s; struct session *s;
struct client *c;
char *tmparg;
size_t arglen;
int ambiguous;
/* A NULL argument means the current session. */
if (arg == NULL) if (arg == NULL)
return (cmd_current_session(ctx)); s = cmd_current_session(ctx);
tmparg = xstrdup(arg); else {
if ((s = arg_parse_session(arg)) == NULL) {
/* Trim a single trailing colon if any. */ if (arg != NULL)
arglen = strlen(tmparg); ctx->error(ctx, "session not found: %s", arg);
if (arglen != 0 && tmparg[arglen - 1] == ':') else
tmparg[arglen - 1] = '\0'; ctx->error(ctx, "no session found");
}
/* Find the session, if any. */
s = cmd_lookup_session(tmparg, &ambiguous);
/* If it doesn't, try to match it as a client. */
if (s == NULL && (c = cmd_lookup_client(tmparg)) != NULL)
s = c->session;
/* If no session found, report an error. */
if (s == NULL) {
if (ambiguous)
ctx->error(ctx, "more than one session: %s", tmparg);
else
ctx->error(ctx, "session not found: %s", tmparg);
} }
xfree(tmparg);
return (s); return (s);
} }
/* 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_ctx *ctx, const char *arg, struct session **sp)
{ {
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
const char *winptr; int idx;
char *sessptr = NULL;
int ambiguous = 0;
/* wl = NULL;
* Find the current session. There must always be a current session, if if (arg_parse_window(arg, &s, &idx) != 0) {
* it can't be found, report an error. ctx->error(ctx, "bad window: %s", arg);
*/
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
return (NULL); return (NULL);
} }
if (s == NULL)
/* A NULL argument means the current session and window. */ s = ctx->cursession;
if (arg == NULL) { if (s == NULL)
if (sp != NULL) s = cmd_current_session(ctx);
*sp = s; if (s == NULL)
return (s->curw);
}
/* Time to look at the argument. If it is empty, that is an error. */
if (*arg == '\0')
goto not_found;
/* Find the separating colon and split into window and session. */
winptr = strchr(arg, ':');
if (winptr == NULL)
goto no_colon;
winptr++; /* skip : */
sessptr = xstrdup(arg);
*strchr(sessptr, ':') = '\0';
/* Try to lookup the session if present. */
if (*sessptr != '\0') {
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL)
goto no_session;
}
if (sp != NULL)
*sp = s;
/*
* Then work out the window. An empty string is the current window,
* otherwise try to look it up in the session.
*/
if (*winptr == '\0')
wl = s->curw;
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL)
goto not_found;
if (sessptr != NULL)
xfree(sessptr);
return (wl);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
wl = s->curw;
}
if (sp != NULL)
*sp = s;
return (wl);
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
else
ctx->error(ctx, "session not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (NULL);
not_found:
if (ambiguous)
ctx->error(ctx, "multiple windows: %s", arg);
else
ctx->error(ctx, "window not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (NULL);
}
/*
* Find the target session and window index, whether or not it exists in the
* session. Return -2 on error or -1 if no window index is specified. This is
* used when parsing an argument for a window target that may not exist (for
* example if it is going to be created).
*/
int
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
{
struct session *s;
const char *winptr;
char *sessptr = NULL;
int idx, ambiguous = 0;
/*
* Find the current session. There must always be a current session, if
* it can't be found, report an error.
*/
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
return (-2);
}
/* A NULL argument means the current session and "no window" (-1). */
if (arg == NULL) {
if (sp != NULL)
*sp = s;
return (-1);
}
/* Time to look at the argument. If it is empty, that is an error. */
if (*arg == '\0')
goto not_found;
/* Find the separating colon. If none, assume the current session. */
winptr = strchr(arg, ':');
if (winptr == NULL)
goto no_colon;
winptr++; /* skip : */
sessptr = xstrdup(arg);
*strchr(sessptr, ':') = '\0';
/* Try to lookup the session if present. */
if (sessptr != NULL && *sessptr != '\0') {
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL)
goto no_session;
}
if (sp != NULL)
*sp = s;
/*
* Then work out the window. An empty string is a new window otherwise
* try to look it up in the session.
*/
if (*winptr == '\0')
idx = -1;
else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
ctx->error(ctx, "invalid index: %s", arg);
idx = -2;
}
if (sessptr != NULL)
xfree(sessptr);
return (idx);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
idx = -1;
}
if (sp != NULL)
*sp = s;
return (idx);
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
else
ctx->error(ctx, "session not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (-2);
not_found:
if (ambiguous)
ctx->error(ctx, "multiple windows: %s", arg);
else
ctx->error(ctx, "window not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (-2);
}
/*
* Find the target session, window and pane number or report an error and
* return NULL. The pane number is separated from the session:window by a .,
* such as mysession:mywindow.0.
*/
struct winlink *
cmd_find_pane(struct cmd_ctx *ctx,
const char *arg, struct session **sp, struct window_pane **wpp)
{
struct session *s;
struct winlink *wl;
const char *period;
char *winptr, *paneptr;
const char *errstr;
u_int idx;
/* Get the current session. */
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
return (NULL); return (NULL);
}
if (sp != NULL) if (sp != NULL)
*sp = s; *sp = s;
/* A NULL argument means the current session, window and pane. */ if (idx == -1)
if (arg == NULL) {
*wpp = s->curw->window->active;
return (s->curw);
}
/* Look for a separating period. */
if ((period = strrchr(arg, '.')) == NULL)
goto no_period;
/* Pull out the window part and parse it. */
winptr = xstrdup(arg);
winptr[period - arg] = '\0';
if (*winptr == '\0')
wl = s->curw; wl = s->curw;
else if ((wl = cmd_find_window(ctx, winptr, sp)) == NULL) else
goto error; wl = winlink_find_by_index(&s->windows, idx);
if (wl == NULL)
/* Find the pane section and look it up. */ ctx->error(ctx, "window not found: %s:%d", s->name, idx);
paneptr = winptr + (period - arg) + 1;
if (*paneptr == '\0')
*wpp = wl->window->active;
else {
idx = strtonum(paneptr, 0, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "pane %s: %s", errstr, paneptr);
goto error;
}
*wpp = window_pane_at_index(wl->window, idx);
if (*wpp == NULL) {
ctx->error(ctx, "no such pane: %u", idx);
goto error;
}
}
xfree(winptr);
return (wl); return (wl);
no_period:
/* Try as a pane number alone. */
idx = strtonum(arg, 0, INT_MAX, &errstr);
if (errstr != NULL)
goto lookup_window;
/* Try index in the current session and window. */
if ((*wpp = window_pane_at_index(s->curw->window, idx)) == NULL)
goto lookup_window;
return (s->curw);
lookup_window:
/* Try as a window and use the active pane. */
if ((wl = cmd_find_window(ctx, arg, sp)) != NULL)
*wpp = wl->window->active;
return (wl);
error:
xfree(winptr);
return (NULL);
}
/* Replace the first %% or %idx in template by s. */
char *
cmd_template_replace(char *template, const char *s, int idx)
{
char ch;
char *buf, *ptr;
int replaced;
size_t len;
if (strstr(template, "%") == NULL)
return (xstrdup(template));
buf = xmalloc(1);
*buf = '\0';
len = 0;
replaced = 0;
ptr = template;
while (*ptr != '\0') {
switch (ch = *ptr++) {
case '%':
if (*ptr < '1' || *ptr > '9' || *ptr - '0' != idx) {
if (*ptr != '%' || replaced)
break;
replaced = 1;
}
ptr++;
len += strlen(s);
buf = xrealloc(buf, 1, len + 1);
strlcat(buf, s, len + 1);
continue;
}
buf = xrealloc(buf, 1, len + 2);
buf[len++] = ch;
buf[len] = '\0';
}
return (buf);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: colour.c,v 1.7 2009-09-11 14:13:52 tcunha Exp $ */ /* $Id: colour.c,v 1.6 2009-05-18 15:42:30 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,42 +18,13 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "tmux.h" #include "tmux.h"
/*
* Colour to string conversion functions. Bit 8 of the colour means it is one
* of the 256 colour palette.
*/
void
colour_set_fg(struct grid_cell *gc, int c)
{
if (c & 0x100)
gc->flags |= GRID_FLAG_FG256;
gc->fg = c;
}
void
colour_set_bg(struct grid_cell *gc, int c)
{
if (c & 0x100)
gc->flags |= GRID_FLAG_BG256;
gc->bg = c;
}
const char * const char *
colour_tostring(int c) colour_tostring(u_char c)
{ {
static char s[32];
if (c & 0x100) {
xsnprintf(s, sizeof s, "colour%u", c & ~0x100);
return (s);
}
switch (c) { switch (c) {
case 0: case 0:
return ("black"); return ("black");
@@ -80,16 +51,6 @@ colour_tostring(int c)
int int
colour_fromstring(const char *s) colour_fromstring(const char *s)
{ {
const char *errstr;
int n;
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
if (errstr != NULL)
return (-1);
return (n | 0x100);
}
if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0')) if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0'))
return (0); return (0);
if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0')) if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0'))

View File

@@ -1,4 +1,4 @@
/* $Id: compat.h,v 1.17 2009-09-03 20:54:39 tcunha Exp $ */ /* $Id: compat.h,v 1.6 2009-07-02 07:30:59 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,19 +16,11 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef HAVE_U_INT
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t;
#endif
#ifndef HAVE_PATHS_H #ifndef HAVE_PATHS_H
#define _PATH_BSHELL "/bin/sh" #define _PATH_BSHELL "/bin/sh"
#define _PATH_TMP "/tmp/" #define _PATH_TMP "/tmp/"
#define _PATH_DEVNULL "/dev/null" #define _PATH_DEVNULL "/dev/null"
#define _PATH_TTY "/dev/tty" #define _PATH_TTY "/dev/tty"
#define _PATH_DEV "/dev/"
#endif #endif
#ifdef HAVE_QUEUE_H #ifdef HAVE_QUEUE_H
@@ -52,8 +44,6 @@ typedef uint64_t u_int64_t;
#ifdef HAVE_POLL #ifdef HAVE_POLL
#include <poll.h> #include <poll.h>
#else #else
#define POLLNVAL 0
#define POLLHUP 0
#include "compat/bsd-poll.h" #include "compat/bsd-poll.h"
#endif #endif
@@ -87,23 +77,6 @@ typedef uint64_t u_int64_t;
#include "compat/vis.h" #include "compat/vis.h"
#endif #endif
#ifndef HAVE_IMSG
#include "compat/imsg.h"
#endif
#ifdef HAVE_LOGIN_CAP
#include <login_cap.h>
#endif
#ifdef HAVE_BROKEN_CMSG_FIRSTHDR
/* Broken on OS X. */
#undef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(mhdr) \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(mhdr)->msg_control : \
(struct cmsghdr *)NULL)
#endif
#ifndef INFTIM #ifndef INFTIM
#define INFTIM -1 #define INFTIM -1
#endif #endif
@@ -142,32 +115,66 @@ typedef uint64_t u_int64_t;
} while (0) } while (0)
#endif #endif
#ifndef PASS_MAX
#define PASS_MAX 128
#endif
#ifndef TTY_NAME_MAX #ifndef TTY_NAME_MAX
#define TTY_NAME_MAX 32 #define TTY_NAME_MAX 32
#endif #endif
#ifndef _PW_BUF_LEN
#define _PW_BUF_LEN 1024
#endif
#ifndef HAVE_BZERO
#define bzero(buf, len) memset((buf), 0, (len));
#endif
#ifndef HAVE_STRCASESTR #ifndef HAVE_STRCASESTR
/* strcasestr.c */ /* strcasestr.c */
char *strcasestr(const char *, const char *); char *strcasestr(const char *, const char *);
#endif #endif
#ifndef HAVE_STRSEP #ifndef HAVE_STRTONUM
/* strsep.c */ /* strtonum.c */
char *strsep(char **, const char *); long long strtonum(const char *, long long, long long, const char **);
#endif #endif
#ifndef HAVE_STRLCPY
/* strlcpy.c */
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
/* strlcat.c */
size_t strlcat(char *, const char *, size_t);
#endif
#ifndef HAVE_DAEMON
/* daemon.c */
int daemon(int, int);
#endif
#ifndef HAVE_FORKPTY
/* forkpty.c */
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
#ifndef HAVE_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_GETOPT
/* getopt.c */
extern int BSDopterr;
extern int BSDoptind;
extern int BSDoptopt;
extern int BSDoptreset;
extern char *BSDoptarg;
int BSDgetopt(int, char *const *, const char *);
#define getopt(ac, av, o) BSDgetopt(ac, av, o)
#define opterr BSDopterr
#define optind BSDoptind
#define optopt BSDoptopt
#define optreset BSDoptreset
#define optarg BSDoptarg
#endif
#ifndef HAVE_STRTONUM #ifndef HAVE_STRTONUM
/* strtonum.c */ /* strtonum.c */
long long strtonum(const char *, long long, long long, const char **); long long strtonum(const char *, long long, long long, const char **);

View File

@@ -1,4 +1,4 @@
/* $Id: forkpty-aix.c,v 1.4 2009-09-20 18:31:16 nicm Exp $ */ /* $Id: forkpty-aix.c,v 1.2 2009-03-31 22:08:45 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,7 +27,8 @@
#include "tmux.h" #include "tmux.h"
pid_t pid_t
forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws) forkpty(int *master,
unused char *name, unused struct termios *tio, struct winsize *ws)
{ {
int slave, fd; int slave, fd;
char *path; char *path;
@@ -70,8 +71,6 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
fatal("open failed"); fatal("open failed");
close(fd); close(fd);
if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
fatal("tcsetattr failed");
if (ioctl(slave, TIOCSWINSZ, ws) == -1) if (ioctl(slave, TIOCSWINSZ, ws) == -1)
fatal("ioctl failed"); fatal("ioctl failed");

View File

@@ -1,4 +1,4 @@
/* $Id: forkpty-sunos.c,v 1.8 2009-09-20 18:31:16 nicm Exp $ */ /* $Id: forkpty-sunos.c,v 1.6 2008-06-23 21:54:48 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,7 +27,8 @@
#include "tmux.h" #include "tmux.h"
pid_t pid_t
forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws) forkpty(int *master,
unused char *name, unused struct termios *tio, struct winsize *ws)
{ {
int slave; int slave;
char *path; char *path;
@@ -62,8 +63,6 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
if (ioctl(slave, I_PUSH, "ldterm") == -1) if (ioctl(slave, I_PUSH, "ldterm") == -1)
fatal("ioctl failed"); fatal("ioctl failed");
if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
fatal("tcsetattr failed");
if (ioctl(slave, TIOCSWINSZ, ws) == -1) if (ioctl(slave, TIOCSWINSZ, ws) == -1)
fatal("ioctl failed"); fatal("ioctl failed");
@@ -71,7 +70,7 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
dup2(slave, 1); dup2(slave, 1);
dup2(slave, 2); dup2(slave, 2);
if (slave > 2) if (slave > 2)
close(slave); close(slave);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: getopt.c,v 1.2 2009-08-09 18:35:38 nicm Exp $ */ /* $Id: getopt.c,v 1.1 2009-05-13 22:20:48 nicm Exp $ */
/* /*
* Copyright (c) 1987, 1993, 1994 * Copyright (c) 1987, 1993, 1994
@@ -87,7 +87,7 @@ BSDgetopt(nargc, nargv, ostr)
++BSDoptind; ++BSDoptind;
if (BSDopterr && *ostr != ':') if (BSDopterr && *ostr != ':')
(void)fprintf(stderr, (void)fprintf(stderr,
"%s: unknown option -- %c\n", __progname, BSDoptopt); "%s: illegal option -- %c\n", __progname, BSDoptopt);
return (BADCH); return (BADCH);
} }
if (*++oli != ':') { /* don't need argument */ if (*++oli != ':') { /* don't need argument */

View File

@@ -1,303 +0,0 @@
/* $Id: imsg-buffer.c,v 1.4 2009-09-15 23:59:40 tcunha Exp $ */
/* $OpenBSD: imsg-buffer.c,v 1.2 2009/09/15 18:12:51 jacekm Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
*
* 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 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/param.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
int buf_realloc(struct buf *, size_t);
void buf_enqueue(struct msgbuf *, struct buf *);
void buf_dequeue(struct msgbuf *, struct buf *);
struct buf *
buf_open(size_t len)
{
struct buf *buf;
if ((buf = calloc(1, sizeof(struct buf))) == NULL)
return (NULL);
if ((buf->buf = malloc(len)) == NULL) {
free(buf);
return (NULL);
}
buf->size = buf->max = len;
buf->fd = -1;
return (buf);
}
struct buf *
buf_dynamic(size_t len, size_t max)
{
struct buf *buf;
if (max < len)
return (NULL);
if ((buf = buf_open(len)) == NULL)
return (NULL);
if (max > 0)
buf->max = max;
return (buf);
}
int
buf_realloc(struct buf *buf, size_t len)
{
u_char *b;
/* on static buffers max is eq size and so the following fails */
if (buf->wpos + len > buf->max) {
errno = ENOMEM;
return (-1);
}
b = realloc(buf->buf, buf->wpos + len);
if (b == NULL)
return (-1);
buf->buf = b;
buf->size = buf->wpos + len;
return (0);
}
int
buf_add(struct buf *buf, const void *data, size_t len)
{
if (buf->wpos + len > buf->size)
if (buf_realloc(buf, len) == -1)
return (-1);
memcpy(buf->buf + buf->wpos, data, len);
buf->wpos += len;
return (0);
}
void *
buf_reserve(struct buf *buf, size_t len)
{
void *b;
if (buf->wpos + len > buf->size)
if (buf_realloc(buf, len) == -1)
return (NULL);
b = buf->buf + buf->wpos;
buf->wpos += len;
return (b);
}
void *
buf_seek(struct buf *buf, size_t pos, size_t len)
{
/* only allowed to seek in already written parts */
if (pos + len > buf->wpos)
return (NULL);
return (buf->buf + pos);
}
size_t
buf_size(struct buf *buf)
{
return (buf->wpos);
}
size_t
buf_left(struct buf *buf)
{
return (buf->max - buf->wpos);
}
void
buf_close(struct msgbuf *msgbuf, struct buf *buf)
{
buf_enqueue(msgbuf, buf);
}
int
buf_write(struct msgbuf *msgbuf)
{
struct iovec iov[IOV_MAX];
struct buf *buf;
unsigned int i = 0;
ssize_t n;
bzero(&iov, sizeof(iov));
TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
if (i >= IOV_MAX)
break;
iov[i].iov_base = buf->buf + buf->rpos;
iov[i].iov_len = buf->wpos - buf->rpos;
i++;
}
if ((n = writev(msgbuf->fd, iov, i)) == -1) {
if (errno == EAGAIN || errno == ENOBUFS ||
errno == EINTR) /* try later */
return (0);
else
return (-1);
}
if (n == 0) { /* connection closed */
errno = 0;
return (-2);
}
msgbuf_drain(msgbuf, n);
return (0);
}
void
buf_free(struct buf *buf)
{
free(buf->buf);
free(buf);
}
void
msgbuf_init(struct msgbuf *msgbuf)
{
msgbuf->queued = 0;
msgbuf->fd = -1;
TAILQ_INIT(&msgbuf->bufs);
}
void
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
{
struct buf *buf, *next;
for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
buf = next) {
next = TAILQ_NEXT(buf, entry);
if (buf->rpos + n >= buf->wpos) {
n -= buf->wpos - buf->rpos;
buf_dequeue(msgbuf, buf);
} else {
buf->rpos += n;
n = 0;
}
}
}
void
msgbuf_clear(struct msgbuf *msgbuf)
{
struct buf *buf;
while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
buf_dequeue(msgbuf, buf);
}
int
msgbuf_write(struct msgbuf *msgbuf)
{
struct iovec iov[IOV_MAX];
struct buf *buf;
unsigned int i = 0;
ssize_t n;
struct msghdr msg;
struct cmsghdr *cmsg;
union {
struct cmsghdr hdr;
char buf[CMSG_SPACE(sizeof(int))];
} cmsgbuf;
bzero(&iov, sizeof(iov));
bzero(&msg, sizeof(msg));
TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
if (i >= IOV_MAX)
break;
iov[i].iov_base = buf->buf + buf->rpos;
iov[i].iov_len = buf->wpos - buf->rpos;
i++;
if (buf->fd != -1)
break;
}
msg.msg_iov = iov;
msg.msg_iovlen = i;
if (buf != NULL && buf->fd != -1) {
msg.msg_control = (caddr_t)&cmsgbuf.buf;
msg.msg_controllen = sizeof(cmsgbuf.buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(cmsg) = buf->fd;
}
if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
if (errno == EAGAIN || errno == ENOBUFS ||
errno == EINTR) /* try later */
return (0);
else
return (-1);
}
if (n == 0) { /* connection closed */
errno = 0;
return (-2);
}
/*
* assumption: fd got sent if sendmsg sent anything
* this works because fds are passed one at a time
*/
if (buf != NULL && buf->fd != -1) {
close(buf->fd);
buf->fd = -1;
}
msgbuf_drain(msgbuf, n);
return (0);
}
void
buf_enqueue(struct msgbuf *msgbuf, struct buf *buf)
{
TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
msgbuf->queued++;
}
void
buf_dequeue(struct msgbuf *msgbuf, struct buf *buf)
{
TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
if (buf->fd != -1)
close(buf->fd);
msgbuf->queued--;
buf_free(buf);
}

Some files were not shown because too many files have changed in this diff Show More