Mercurial > dropbear
comparison cli-chansession.c @ 39:0883c0906870
tty raw mode support works mostly
adding cli-{chansession,runopts}.c which were missing
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 30 Jul 2004 12:29:53 +0000 |
parents | |
children | b4874d772210 |
comparison
equal
deleted
inserted
replaced
38:5c6f9d27ea1c | 39:0883c0906870 |
---|---|
1 #include "includes.h" | |
2 #include "packet.h" | |
3 #include "buffer.h" | |
4 #include "session.h" | |
5 #include "dbutil.h" | |
6 #include "channel.h" | |
7 #include "ssh.h" | |
8 #include "runopts.h" | |
9 | |
10 static void cli_closechansess(struct Channel *channel); | |
11 static int cli_initchansess(struct Channel *channel); | |
12 | |
13 static void start_channel_request(struct Channel *channel, unsigned char *type); | |
14 | |
15 static void send_chansess_pty_req(struct Channel *channel); | |
16 static void send_chansess_shell_req(struct Channel *channel); | |
17 | |
18 static void cli_tty_setup(); | |
19 static void cli_tty_cleanup(); | |
20 | |
21 static const struct ChanType clichansess = { | |
22 0, /* sepfds */ | |
23 "session", /* name */ | |
24 cli_initchansess, /* inithandler */ | |
25 NULL, /* checkclosehandler */ | |
26 NULL, /* reqhandler */ | |
27 cli_closechansess, /* closehandler */ | |
28 }; | |
29 | |
30 /* If the main session goes, we close it up */ | |
31 static void cli_closechansess(struct Channel *channel) { | |
32 | |
33 /* This channel hasn't gone yet, so we have > 1 */ | |
34 if (ses.chancount > 1) { | |
35 dropbear_log(LOG_INFO, "Waiting for other channels to close..."); | |
36 } | |
37 | |
38 cli_tty_cleanup(); /* Restore tty modes etc */ | |
39 | |
40 } | |
41 | |
42 static void start_channel_request(struct Channel *channel, | |
43 unsigned char *type) { | |
44 | |
45 CHECKCLEARTOWRITE(); | |
46 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_REQUEST); | |
47 buf_putint(ses.writepayload, channel->remotechan); | |
48 | |
49 buf_putstring(ses.writepayload, type, strlen(type)); | |
50 | |
51 } | |
52 | |
53 | |
54 /* Taken from OpenSSH's sshtty.c: | |
55 * RCSID("OpenBSD: sshtty.c,v 1.5 2003/09/19 17:43:35 markus Exp "); */ | |
56 static void cli_tty_setup() { | |
57 | |
58 struct termios tio; | |
59 | |
60 TRACE(("enter cli_pty_setup")); | |
61 | |
62 if (cli_ses.tty_raw_mode == 1) { | |
63 TRACE(("leave cli_tty_setup: already in raw mode!")); | |
64 return; | |
65 } | |
66 | |
67 if (tcgetattr(STDIN_FILENO, &tio) == -1) { | |
68 dropbear_exit("Failed to set raw TTY mode"); | |
69 } | |
70 | |
71 /* make a copy */ | |
72 cli_ses.saved_tio = tio; | |
73 | |
74 tio.c_iflag |= IGNPAR; | |
75 tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); | |
76 #ifdef IUCLC | |
77 tio.c_iflag &= ~IUCLC; | |
78 #endif | |
79 tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); | |
80 #ifdef IEXTEN | |
81 tio.c_lflag &= ~IEXTEN; | |
82 #endif | |
83 tio.c_oflag &= ~OPOST; | |
84 tio.c_cc[VMIN] = 1; | |
85 tio.c_cc[VTIME] = 0; | |
86 if (tcsetattr(STDIN_FILENO, TCSADRAIN, &tio) == -1) { | |
87 dropbear_exit("Failed to set raw TTY mode"); | |
88 } | |
89 | |
90 cli_ses.tty_raw_mode = 1; | |
91 TRACE(("leave cli_tty_setup")); | |
92 } | |
93 | |
94 static void cli_tty_cleanup() { | |
95 | |
96 TRACE(("enter cli_tty_cleanup")); | |
97 | |
98 if (cli_ses.tty_raw_mode == 0) { | |
99 TRACE(("leave cli_tty_cleanup: not in raw mode")); | |
100 } | |
101 | |
102 if (tcsetattr(STDIN_FILENO, TCSADRAIN, &cli_ses.saved_tio) == -1) { | |
103 dropbear_log(LOG_WARNING, "Failed restoring TTY"); | |
104 } else { | |
105 cli_ses.tty_raw_mode = 0; | |
106 } | |
107 | |
108 TRACE(("leave cli_tty_cleanup")); | |
109 } | |
110 | |
111 static void send_chansess_pty_req(struct Channel *channel) { | |
112 | |
113 unsigned char* termmodes = "\0"; | |
114 unsigned char* term = NULL; | |
115 int termc = 80, termr = 25, termw = 0, termh = 0; /* XXX TODO matt */ | |
116 | |
117 TRACE(("enter send_chansess_pty_req")); | |
118 start_channel_request(channel, "pty-req"); | |
119 | |
120 term = getenv("TERM"); | |
121 if (term == NULL) { | |
122 term = "vt100"; | |
123 } | |
124 | |
125 /* XXX TODO */ | |
126 buf_putbyte(ses.writepayload, 0); /* Don't want replies */ | |
127 buf_putstring(ses.writepayload, term, strlen(term)); | |
128 buf_putint(ses.writepayload, termc); /* Cols */ | |
129 buf_putint(ses.writepayload, termr); /* Rows */ | |
130 buf_putint(ses.writepayload, termw); /* Width */ | |
131 buf_putint(ses.writepayload, termh); /* Height */ | |
132 | |
133 buf_putstring(ses.writepayload, termmodes, 1); /* XXX TODO */ | |
134 //m_free(termmodes); | |
135 | |
136 encrypt_packet(); | |
137 TRACE(("leave send_chansess_pty_req")); | |
138 } | |
139 | |
140 static void send_chansess_shell_req(struct Channel *channel) { | |
141 | |
142 unsigned char* reqtype = NULL; | |
143 | |
144 TRACE(("enter send_chansess_shell_req")); | |
145 | |
146 if (cli_opts.cmd) { | |
147 reqtype = "exec"; | |
148 } else { | |
149 reqtype = "shell"; | |
150 } | |
151 | |
152 start_channel_request(channel, reqtype); | |
153 | |
154 /* XXX TODO */ | |
155 buf_putbyte(ses.writepayload, 0); /* Don't want replies */ | |
156 if (cli_opts.cmd) { | |
157 buf_putstring(ses.writepayload, cli_opts.cmd, strlen(cli_opts.cmd)); | |
158 } | |
159 | |
160 encrypt_packet(); | |
161 TRACE(("leave send_chansess_shell_req")); | |
162 } | |
163 | |
164 static int cli_initchansess(struct Channel *channel) { | |
165 | |
166 channel->infd = STDOUT_FILENO; | |
167 //channel->outfd = STDIN_FILENO; | |
168 //channel->errfd = STDERR_FILENO; | |
169 | |
170 if (cli_opts.wantpty) { | |
171 send_chansess_pty_req(channel); | |
172 } | |
173 | |
174 cli_opts.cmd = "df"; | |
175 send_chansess_shell_req(channel); | |
176 | |
177 if (cli_opts.wantpty) { | |
178 cli_tty_setup(); | |
179 } | |
180 | |
181 return 0; /* Success */ | |
182 | |
183 } | |
184 | |
185 | |
186 void cli_send_chansess_request() { | |
187 | |
188 TRACE(("enter cli_send_chansess_request")); | |
189 if (send_msg_channel_open_init(STDIN_FILENO, &clichansess) | |
190 == DROPBEAR_FAILURE) { | |
191 dropbear_exit("Couldn't open initial channel"); | |
192 } | |
193 | |
194 /* No special channel request data */ | |
195 encrypt_packet(); | |
196 TRACE(("leave cli_send_chansess_request")); | |
197 | |
198 } |