1 /* $Id: cmd-server-info.c,v 1.14 2009-04-02 23:28:16 nicm Exp $ */
4 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
20 #include <sys/utsname.h>
31 * Show various information about server.
34 int cmd_server_info_exec(struct cmd
*, struct cmd_ctx
*);
36 const struct cmd_entry cmd_server_info_entry
= {
37 "server-info", "info",
50 cmd_server_info_exec(unused
struct cmd
*self
, struct cmd_ctx
*ctx
)
52 struct tty_term
*term
;
57 struct window_pane
*wp
;
58 struct tty_code
*code
;
59 struct tty_term_code_entry
*ent
;
69 tim
= ctime(&start_time
);
70 *strchr(tim
, '\n') = '\0';
72 "tmux " BUILD
", pid %ld, started %s", (long) getpid(), tim
);
73 ctx
->print(ctx
, "socket path %s, debug level %d%s",
74 socket_path
, debug_level
, be_quiet
? ", quiet" : "");
75 if (uname(&un
) == 0) {
76 ctx
->print(ctx
, "system is %s %s %s %s",
77 un
.sysname
, un
.release
, un
.version
, un
.machine
);
80 ctx
->print(ctx
, "configuration file is %s", cfg_file
);
82 ctx
->print(ctx
, "configuration file not specified");
83 ctx
->print(ctx
, "protocol version is %d", PROTOCOL_VERSION
);
84 ctx
->print(ctx
, "%u clients, %u sessions",
85 ARRAY_LENGTH(&clients
), ARRAY_LENGTH(&sessions
));
88 ctx
->print(ctx
, "Clients:");
89 for (i
= 0; i
< ARRAY_LENGTH(&clients
); i
++) {
90 c
= ARRAY_ITEM(&clients
, i
);
91 if (c
== NULL
|| c
->session
== NULL
)
94 ctx
->print(ctx
, "%2d: %p %s (%d, %d): %s [%ux%u %s] "
95 "[flags=0x%x/0x%x]", i
, c
, c
->tty
.path
, c
->fd
, c
->tty
.fd
,
96 c
->session
->name
, c
->tty
.sx
, c
->tty
.sy
, c
->tty
.termname
,
97 c
->flags
, c
->tty
.flags
);
101 ctx
->print(ctx
, "Sessions: [%zu/%zu]",
102 sizeof (struct grid_cell
), sizeof (struct grid_utf8
));
103 for (i
= 0; i
< ARRAY_LENGTH(&sessions
); i
++) {
104 s
= ARRAY_ITEM(&sessions
, i
);
110 *strchr(tim
, '\n') = '\0';
112 ctx
->print(ctx
, "%2u: %p %s: %u windows (created %s) [%ux%u] "
113 "[flags=0x%x]", i
, s
, s
->name
, winlink_count(&s
->windows
),
114 tim
, s
->sx
, s
->sy
, s
->flags
);
115 RB_FOREACH(wl
, winlinks
, &s
->windows
) {
117 ctx
->print(ctx
, "%4u: %p/%p %s [%ux%u] [flags=0x%x, "
118 "references=%u, layout=%u]", wl
->idx
, wl
, w
, w
->name
,
119 w
->sx
, w
->sy
, w
->flags
, w
->references
, w
->layout
);
121 TAILQ_FOREACH(wp
, &w
->panes
, entry
) {
122 lines
= ulines
= size
= usize
= 0;
124 for (k
= 0; k
< gd
->hsize
+ gd
->sy
; k
++) {
125 if (gd
->data
[k
] != NULL
) {
127 size
+= gd
->size
[k
] *
130 if (gd
->udata
[k
] != NULL
) {
132 usize
+= gd
->usize
[k
] *
133 sizeof (**gd
->udata
);
136 ctx
->print(ctx
, "%6u: %p %s %lu %d %u/%u, %zu "
137 "bytes; UTF-8 %u/%u, %zu bytes", j
, wp
,
138 wp
->tty
, (u_long
) wp
->pid
, wp
->fd
, lines
,
139 gd
->hsize
+ gd
->sy
, size
, ulines
,
140 gd
->hsize
+ gd
->sy
, usize
);
147 ctx
->print(ctx
, "Terminals:");
148 SLIST_FOREACH(term
, &tty_terms
, entry
) {
149 ctx
->print(ctx
, "%s [references=%u, flags=0x%x]:",
150 term
->name
, term
->references
, term
->flags
);
151 for (i
= 0; i
< NTTYCODE
; i
++) {
152 ent
= &tty_term_codes
[i
];
153 code
= &term
->codes
[ent
->code
];
154 switch (code
->type
) {
156 ctx
->print(ctx
, "%2u: %s: [missing]",
157 ent
->code
, ent
->name
);
160 strnvis(out
, code
->value
.string
,
161 sizeof out
, VIS_OCTAL
|VIS_WHITE
);
162 out
[(sizeof out
) - 1] = '\0';
164 ctx
->print(ctx
, "%2u: %s: (string) %s",
165 ent
->code
, ent
->name
, out
);
168 ctx
->print(ctx
, "%2u: %s: (number) %d",
169 ent
->code
, ent
->name
, code
->value
.number
);
172 ctx
->print(ctx
, "%2u: %s: (flag) %s",
173 ent
->code
, ent
->name
,
174 code
->value
.flag
? "true" : "false");