Annotation of src/usr.bin/tmux/server-fn.c, Revision 1.14
1.14 ! nicm 1: /* $OpenBSD: server-fn.c,v 1.13 2009/08/08 21:52:43 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
21: #include <string.h>
1.5 nicm 22: #include <time.h>
1.1 nicm 23: #include <unistd.h>
24:
25: #include "tmux.h"
26:
27: int server_lock_callback(void *, const char *);
28:
1.13 nicm 29: void
30: server_fill_environ(struct session *s, struct environ *env)
1.1 nicm 31: {
1.13 nicm 32: char tmuxvar[MAXPATHLEN], *term;
33: u_int idx;
1.1 nicm 34:
35: if (session_index(s, &idx) != 0)
36: fatalx("session not found");
37: xsnprintf(tmuxvar, sizeof tmuxvar,
1.13 nicm 38: "%s,%ld,%u", socket_path, (long) getpid(), idx);
39: environ_set(env, "TMUX", tmuxvar);
1.1 nicm 40:
1.13 nicm 41: term = options_get_string(&s->options, "default-terminal");
42: environ_set(env, "TERM", term);
1.1 nicm 43: }
44:
45: void
1.10 nicm 46: server_write_error(struct client *c, const char *msg)
47: {
48: struct msg_print_data printdata;
49:
50: strlcpy(printdata.msg, msg, sizeof printdata.msg);
51: server_write_client(c, MSG_ERROR, &printdata, sizeof printdata);
52: }
53:
54: void
1.1 nicm 55: server_write_client(
1.11 nicm 56: struct client *c, enum msgtype type, const void *buf, size_t len)
1.1 nicm 57: {
1.14 ! nicm 58: struct imsgbuf *ibuf = &c->ibuf;
1.1 nicm 59:
1.12 nicm 60: if (c->flags & CLIENT_BAD)
61: return;
1.14 ! nicm 62: log_debug("writing %d to client %d", type, c->ibuf.fd);
! 63: imsg_compose(ibuf, type, PROTOCOL_VERSION, -1, -1, (void *) buf, len);
1.1 nicm 64: }
65:
66: void
67: server_write_session(
1.11 nicm 68: struct session *s, enum msgtype type, const void *buf, size_t len)
1.1 nicm 69: {
70: struct client *c;
71: u_int i;
72:
73: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
74: c = ARRAY_ITEM(&clients, i);
75: if (c == NULL || c->session == NULL)
76: continue;
77: if (c->session == s)
78: server_write_client(c, type, buf, len);
79: }
80: }
81:
82: void
83: server_redraw_client(struct client *c)
84: {
85: c->flags |= CLIENT_REDRAW;
86: }
87:
88: void
89: server_status_client(struct client *c)
90: {
91: c->flags |= CLIENT_STATUS;
92: }
93:
94: void
95: server_redraw_session(struct session *s)
96: {
97: struct client *c;
98: u_int i;
99:
100: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
101: c = ARRAY_ITEM(&clients, i);
102: if (c == NULL || c->session == NULL)
103: continue;
104: if (c->session == s)
105: server_redraw_client(c);
106: }
107: }
108:
109: void
110: server_status_session(struct session *s)
111: {
112: struct client *c;
113: u_int i;
114:
115: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
116: c = ARRAY_ITEM(&clients, i);
117: if (c == NULL || c->session == NULL)
118: continue;
119: if (c->session == s)
120: server_status_client(c);
121: }
122: }
123:
124: void
125: server_redraw_window(struct window *w)
126: {
127: struct client *c;
128: u_int i;
129:
130: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
131: c = ARRAY_ITEM(&clients, i);
132: if (c == NULL || c->session == NULL)
133: continue;
134: if (c->session->curw->window == w)
135: server_redraw_client(c);
136: }
137: w->flags |= WINDOW_REDRAW;
138: }
139:
140: void
141: server_status_window(struct window *w)
142: {
143: struct session *s;
144: u_int i;
145:
146: /*
147: * This is slightly different. We want to redraw the status line of any
148: * clients containing this window rather than any where it is the
149: * current window.
150: */
151:
152: for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
153: s = ARRAY_ITEM(&sessions, i);
154: if (s != NULL && session_has(s, w))
155: server_status_session(s);
156: }
157: }
158:
159: void
160: server_lock(void)
161: {
162: struct client *c;
163: u_int i;
164:
165: if (server_locked)
166: return;
167:
168: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
169: c = ARRAY_ITEM(&clients, i);
170: if (c == NULL || c->session == NULL)
171: continue;
172:
173: status_prompt_clear(c);
1.6 nicm 174: status_prompt_set(c,
1.7 nicm 175: "Password: ", server_lock_callback, NULL, c, PROMPT_HIDDEN);
1.1 nicm 176: server_redraw_client(c);
177: }
178: server_locked = 1;
179: }
180:
181: int
182: server_lock_callback(unused void *data, const char *s)
183: {
184: return (server_unlock(s));
185: }
186:
187: int
188: server_unlock(const char *s)
189: {
190: struct client *c;
191: u_int i;
192: char *out;
193:
194: if (!server_locked)
195: return (0);
196: server_activity = time(NULL);
197:
198: if (server_password != NULL) {
199: if (s == NULL)
200: return (-1);
201: out = crypt(s, server_password);
202: if (strcmp(out, server_password) != 0)
203: goto wrong;
204: }
205:
206: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
207: c = ARRAY_ITEM(&clients, i);
208: if (c == NULL)
209: continue;
210:
211: status_prompt_clear(c);
212: server_redraw_client(c);
213: }
214:
215: server_locked = 0;
1.9 nicm 216: password_failures = 0;
1.1 nicm 217: return (0);
218:
219: wrong:
1.9 nicm 220: password_failures++;
1.1 nicm 221: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
222: c = ARRAY_ITEM(&clients, i);
1.10 nicm 223: if (c == NULL || c->prompt_buffer == NULL)
1.1 nicm 224: continue;
225:
226: *c->prompt_buffer = '\0';
227: c->prompt_index = 0;
1.9 nicm 228: server_redraw_client(c);
1.1 nicm 229: }
230:
231: return (-1);
1.8 nicm 232: }
233:
234: void
235: server_kill_window(struct window *w)
236: {
237: struct session *s;
238: struct winlink *wl;
239: struct client *c;
240: u_int i, j;
241: int destroyed;
242:
243:
244: for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
245: s = ARRAY_ITEM(&sessions, i);
246: if (s == NULL || !session_has(s, w))
247: continue;
248: if ((wl = winlink_find_by_window(&s->windows, w)) == NULL)
249: continue;
250:
251: destroyed = session_detach(s, wl);
252: for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
253: c = ARRAY_ITEM(&clients, j);
254: if (c == NULL || c->session != s)
255: continue;
256:
257: if (destroyed) {
258: c->session = NULL;
259: server_write_client(c, MSG_EXIT, NULL, 0);
260: } else
261: server_redraw_client(c);
262: }
263: }
264: recalculate_sizes();
1.1 nicm 265: }