1 static void client_sigwinch_handler(int sig
) {
2 client
.need_resize
= true;
5 static bool client_send_packet(Packet
*pkt
) {
6 print_packet("client-send:", pkt
);
7 if (send_packet(server
.socket
, pkt
))
10 server
.running
= false;
14 static bool client_recv_packet(Packet
*pkt
) {
15 if (recv_packet(server
.socket
, pkt
)) {
16 print_packet("client-recv:", pkt
);
19 debug("client-recv: FAILED\n");
20 server
.running
= false;
24 static void client_restore_terminal(void) {
27 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &orig_term
);
28 if (alternate_buffer
) {
29 printf("\033[?25h\033[?1049l");
31 alternate_buffer
= false;
35 static void client_setup_terminal(void) {
38 atexit(client_restore_terminal
);
41 cur_term
.c_iflag
&= ~(IGNBRK
|BRKINT
|PARMRK
|ISTRIP
|INLCR
|IGNCR
|ICRNL
|IXON
|IXOFF
);
42 cur_term
.c_oflag
&= ~(OPOST
);
43 cur_term
.c_lflag
&= ~(ECHO
|ECHONL
|ICANON
|ISIG
|IEXTEN
);
44 cur_term
.c_cflag
&= ~(CSIZE
|PARENB
);
45 cur_term
.c_cflag
|= CS8
;
46 cur_term
.c_cc
[VLNEXT
] = _POSIX_VDISABLE
;
47 cur_term
.c_cc
[VMIN
] = 1;
48 cur_term
.c_cc
[VTIME
] = 0;
49 tcsetattr(STDIN_FILENO
, TCSANOW
, &cur_term
);
51 if (!alternate_buffer
) {
52 printf("\033[?1049h\033[H");
54 alternate_buffer
= true;
58 static int client_mainloop(void) {
59 sigset_t emptyset
, blockset
;
60 sigemptyset(&emptyset
);
61 sigemptyset(&blockset
);
62 sigaddset(&blockset
, SIGWINCH
);
63 sigprocmask(SIG_BLOCK
, &blockset
, NULL
);
65 client
.need_resize
= true;
69 .len
= sizeof(pkt
.u
.i
),
71 client_send_packet(&pkt
);
73 while (server
.running
) {
76 FD_SET(STDIN_FILENO
, &fds
);
77 FD_SET(server
.socket
, &fds
);
79 if (client
.need_resize
) {
81 if (ioctl(STDIN_FILENO
, TIOCGWINSZ
, &ws
) != -1) {
84 .u
= { .ws
= { .rows
= ws
.ws_row
, .cols
= ws
.ws_col
} },
85 .len
= sizeof(pkt
.u
.ws
),
87 if (client_send_packet(&pkt
))
88 client
.need_resize
= false;
92 if (pselect(server
.socket
+1, &fds
, NULL
, NULL
, NULL
, &emptyset
) == -1) {
95 die("client-mainloop");
98 if (FD_ISSET(server
.socket
, &fds
)) {
100 if (client_recv_packet(&pkt
)) {
104 write_all(STDOUT_FILENO
, pkt
.u
.msg
, pkt
.len
);
107 client
.need_resize
= true;
110 client_send_packet(&pkt
);
111 close(server
.socket
);
117 if (FD_ISSET(STDIN_FILENO
, &fds
)) {
118 Packet pkt
= { .type
= MSG_CONTENT
};
119 ssize_t len
= read(STDIN_FILENO
, pkt
.u
.msg
, sizeof(pkt
.u
.msg
));
120 if (len
== -1 && errno
!= EAGAIN
&& errno
!= EINTR
)
123 debug("client-stdin: %c\n", pkt
.u
.msg
[0]);
125 if (KEY_REDRAW
&& pkt
.u
.msg
[0] == KEY_REDRAW
) {
126 client
.need_resize
= true;
127 } else if (pkt
.u
.msg
[0] == KEY_DETACH
) {
128 pkt
.type
= MSG_DETACH
;
130 client_send_packet(&pkt
);
131 close(server
.socket
);
133 } else if (!(client
.flags
& CLIENT_READONLY
)) {
134 client_send_packet(&pkt
);
136 } else if (len
== 0) {
137 debug("client-stdin: EOF\n");