summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-console/MyPty.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-console/MyPty.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/MyPty.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp
index 534f79a..b0f0275 100644
--- a/noncore/apps/opie-console/MyPty.cpp
+++ b/noncore/apps/opie-console/MyPty.cpp
@@ -97,247 +97,254 @@
97 actual size of the window. 97 actual size of the window.
98*/ 98*/
99 99
100void MyPty::setSize(int lines, int columns) 100void MyPty::setSize(int lines, int columns)
101{ 101{
102 qWarning("setting size"); 102 qWarning("setting size");
103 struct winsize wsize; 103 struct winsize wsize;
104 wsize.ws_row = (unsigned short)lines; 104 wsize.ws_row = (unsigned short)lines;
105 wsize.ws_col = (unsigned short)columns; 105 wsize.ws_col = (unsigned short)columns;
106 if(m_fd < 0) return; 106 if(m_fd < 0) return;
107 ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); 107 ioctl(m_fd,TIOCSWINSZ,(char *)&wsize);
108} 108}
109 109
110 110
111void MyPty::donePty() 111void MyPty::donePty()
112{ 112{
113 // This is code from the Qt DumbTerminal example 113 // This is code from the Qt DumbTerminal example
114 114
115 ::close(m_fd); 115 ::close(m_fd);
116 116
117 if (m_cpid) { 117 if (m_cpid) {
118 kill(m_cpid, SIGHUP); 118 kill(m_cpid, SIGHUP);
119 //waitpid(m_cpid, &status, 0); 119 //waitpid(m_cpid, &status, 0);
120 delete m_sn_e; 120 delete m_sn_e;
121 delete m_sn_r; 121 delete m_sn_r;
122 m_sn_e = 0l; 122 m_sn_e = 0l;
123 m_sn_r = 0l; 123 m_sn_r = 0l;
124 } 124 }
125 125
126 m_cpid = 0; 126 m_cpid = 0;
127 m_fd = -1; 127 m_fd = -1;
128// emit done(status); 128// emit done(status);
129} 129}
130 130
131 131
132const char* MyPty::deviceName() 132const char* MyPty::deviceName()
133{ 133{
134 return m_ttynam; 134 return m_ttynam;
135} 135}
136 136
137 137
138void MyPty::error() 138void MyPty::error()
139{ 139{
140 // This is code from the Qt DumbTerminal example 140 // This is code from the Qt DumbTerminal example
141 donePty(); 141 donePty();
142} 142}
143 143
144void MyPty::start() { 144void MyPty::start() {
145 char* cmd = "/bin/sh";
146
147 if ( QFile::exists( "/bin/bash" ) ) {
148 cmd = "/bin/bash";
149 }
150
151 QStrList lis; 145 QStrList lis;
152 int r =run(cmd, lis, 0, 0); 146 int r =run(m_cmd.latin1(), lis, 0, 0);
153 r = r; 147 r = r;
154} 148}
155/*! 149/*!
156 start the client program. 150 start the client program.
157*/ 151*/
158int MyPty::run(const char* cmd, QStrList &, const char*, int) 152int MyPty::run(const char* cmd, QStrList &, const char*, int)
159{ 153{
160 // This is code from the Qt DumbTerminal example 154 // This is code from the Qt DumbTerminal example
161 m_cpid = fork(); 155 m_cpid = fork();
162 156
163 if ( !m_cpid ) { 157 if ( !m_cpid ) {
164 // child - exec shell on tty 158 // child - exec shell on tty
165 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); 159 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
166 int ttyfd = ::open(m_ttynam, O_RDWR); 160 int ttyfd = ::open(m_ttynam, O_RDWR);
167 dup2(ttyfd, STDIN_FILENO); 161 dup2(ttyfd, STDIN_FILENO);
168 dup2(ttyfd, STDOUT_FILENO); 162 dup2(ttyfd, STDOUT_FILENO);
169 dup2(ttyfd, STDERR_FILENO); 163 dup2(ttyfd, STDERR_FILENO);
170 // should be done with tty, so close it 164 // should be done with tty, so close it
171 ::close(ttyfd); 165 ::close(ttyfd);
172 static struct termios ttmode; 166 static struct termios ttmode;
173 if ( setsid() < 0 ) 167 if ( setsid() < 0 )
174 perror( "failed to set process group" ); 168 perror( "failed to set process group" );
175#if defined (TIOCSCTTY) 169#if defined (TIOCSCTTY)
176 // grabbed from APUE by Stevens 170 // grabbed from APUE by Stevens
177 ioctl(STDIN_FILENO, TIOCSCTTY, 0); 171 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
178#endif 172#endif
179 tcgetattr( STDIN_FILENO, &ttmode ); 173 tcgetattr( STDIN_FILENO, &ttmode );
180 ttmode.c_cc[VINTR] = 3; 174 ttmode.c_cc[VINTR] = 3;
181 ttmode.c_cc[VERASE] = 8; 175 ttmode.c_cc[VERASE] = 8;
182 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); 176 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
183 setenv("TERM",m_term,1); 177 setenv("TERM",m_term,1);
184 setenv("COLORTERM","0",1); 178 setenv("COLORTERM","0",1);
185 179 EnvironmentMap::Iterator it;
180 for (it = m_env.begin(); it != m_env.end(); it++) {
181 setenv(it.key().latin1(), it.data().latin1(), 1);
182 }
186 if (getuid() == 0) { 183 if (getuid() == 0) {
187 char msg[] = "WARNING: You are running this shell as root!\n"; 184 char msg[] = "WARNING: You are running this shell as root!\n";
188 write(ttyfd, msg, sizeof(msg)); 185 write(ttyfd, msg, sizeof(msg));
189 } 186 }
190 execl(cmd, cmd, 0); 187 execl(cmd, cmd, 0);
191 188
192 donePty(); 189 donePty();
193 exit(-1); 190 exit(-1);
194 } 191 }
195 192
196 // parent - continue as a widget 193 // parent - continue as a widget
197 delete m_sn_r; 194 delete m_sn_r;
198 m_sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); 195 m_sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this);
199 delete m_sn_e; 196 delete m_sn_e;
200 m_sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this); 197 m_sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this);
201 connect(m_sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); 198 connect(m_sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
202 connect(m_sn_e,SIGNAL(activated(int)),this,SLOT(error())); 199 connect(m_sn_e,SIGNAL(activated(int)),this,SLOT(error()));
203 200
204 return 0; 201 return 0;
205} 202}
206 203
207int MyPty::openPty() 204int MyPty::openPty()
208{ 205{
209 // This is code from the Qt DumbTerminal example 206 // This is code from the Qt DumbTerminal example
210 int ptyfd = -1; 207 int ptyfd = -1;
211 208
212#ifdef HAVE_OPENPTY 209#ifdef HAVE_OPENPTY
213 int ttyfd; 210 int ttyfd;
214 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) 211 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
215 ptyfd = -1; 212 ptyfd = -1;
216 else 213 else
217 close(ttyfd); // we open the ttynam ourselves. 214 close(ttyfd); // we open the ttynam ourselves.
218#else 215#else
219 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { 216 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
220 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { 217 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
221 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1); 218 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1);
222 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1); 219 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1);
223 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) { 220 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) {
224 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) { 221 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) {
225 ::close(ptyfd); 222 ::close(ptyfd);
226 ptyfd = -1; 223 ptyfd = -1;
227 } 224 }
228 } 225 }
229 } 226 }
230 } 227 }
231#endif 228#endif
232 229
233 if ( ptyfd < 0 ) { 230 if ( ptyfd < 0 ) {
234 //qApp->exit(1); 231 //qApp->exit(1);
235 return -1; 232 return -1;
236 } 233 }
237 234
238 return ptyfd; 235 return ptyfd;
239} 236}
240 237
241/*! 238/*!
242 Create an instance. 239 Create an instance.
243*/ 240*/
244MyPty::MyPty(const Profile& prof) : m_cpid(0) 241MyPty::MyPty(const Profile& prof) : m_cpid(0)
245{ 242{
246 243
247 int term = prof.readNumEntry("Terminal", Profile::VT100 ); 244 int term = prof.readNumEntry("Terminal", Profile::VT100 );
248 switch( term ) { 245 switch( term ) {
249 default: 246 default:
250 case Profile::VT100: 247 case Profile::VT100:
251 case Profile::VT102: 248 case Profile::VT102:
252 m_term = "vt100"; 249 m_term = "vt100";
253 break; 250 break;
254 case Profile::Linux: 251 case Profile::Linux:
255 m_term = "linux"; 252 m_term = "linux";
256 break; 253 break;
257 case Profile::XTerm: 254 case Profile::XTerm:
258 m_term = "xterm"; 255 m_term = "xterm";
259 break; 256 break;
260 } 257 }
261 m_sn_e = 0l; 258 m_sn_e = 0l;
262 m_sn_r = 0l; 259 m_sn_r = 0l;
263 m_fd = openPty(); 260 m_fd = openPty();
264 ProcCtl* ctl = ProcCtl::self(); 261 ProcCtl* ctl = ProcCtl::self();
265 Q_UNUSED(ctl); 262 Q_UNUSED(ctl);
263 reload(prof);
266} 264}
267 265
268/*! 266/*!
269 Destructor. 267 Destructor.
270 Note that the related client program is not killed 268 Note that the related client program is not killed
271 (yet) when a instance is deleted. 269 (yet) when a instance is deleted.
272*/ 270*/
273MyPty::~MyPty() 271MyPty::~MyPty()
274{ 272{
275 donePty(); 273 donePty();
276} 274}
277QString MyPty::identifier()const { 275QString MyPty::identifier()const {
278 return QString::fromLatin1("term"); 276 return QString::fromLatin1("term");
279} 277}
280QString MyPty::name()const{ 278QString MyPty::name()const{
281 return identifier(); 279 return identifier();
282} 280}
283bool MyPty::open() { 281bool MyPty::open() {
284 if (m_fd < 0) 282 if (m_fd < 0)
285 m_fd = openPty(); 283 m_fd = openPty();
286 284
287 start(); 285 start();
288 return true; 286 return true;
289} 287}
290void MyPty::close() { 288void MyPty::close() {
291 donePty(); 289 donePty();
292 m_fd = openPty(); 290 m_fd = openPty();
293} 291}
294void MyPty::reload( const Profile& ) { 292void MyPty::reload( const Profile& prof) {
295 293 m_env.clear();
294 m_cmd = prof.readEntry("Command", "/bin/bash");
295 int envcount = prof.readNumEntry("EnvVars", 0);
296 for (int i=0; i<envcount; i++) {
297 QString name = prof.readEntry("Env_Name_" + QString::number(i), "");
298 QString value = prof.readEntry("Env_Value_" + QString::number(i), "");
299 if (!(name.isEmpty() || value.isEmpty())) {
300 m_env.insert(name, value);
301 }
302 }
296} 303}
297/*! sends len bytes through the line */ 304/*! sends len bytes through the line */
298void MyPty::send(const QByteArray& ar) 305void MyPty::send(const QByteArray& ar)
299{ 306{
300#ifdef VERBOSE_DEBUG 307#ifdef VERBOSE_DEBUG
301 // verbose debug 308 // verbose debug
302 printf("sending bytes:\n"); 309 printf("sending bytes:\n");
303 for (uint i = 0; i < ar.count(); i++) 310 for (uint i = 0; i < ar.count(); i++)
304 printf("%c", ar[i]); 311 printf("%c", ar[i]);
305 printf("\n"); 312 printf("\n");
306#endif 313#endif
307 314
308 ::write(m_fd, ar.data(), ar.count()); 315 ::write(m_fd, ar.data(), ar.count());
309} 316}
310 317
311/*! indicates that a block of data is received */ 318/*! indicates that a block of data is received */
312void MyPty::readPty() 319void MyPty::readPty()
313{ 320{
314 QByteArray buf(4096); 321 QByteArray buf(4096);
315 322
316 int len = ::read( m_fd, buf.data(), 4096 ); 323 int len = ::read( m_fd, buf.data(), 4096 );
317 324
318 if (len == -1 || len == 0) { 325 if (len == -1 || len == 0) {
319 donePty(); 326 donePty();
320 return; 327 return;
321 } 328 }
322 329
323 if (len < 0) 330 if (len < 0)
324 return; 331 return;
325 332
326 333
327 buf.resize(len); 334 buf.resize(len);
328 emit received(buf); 335 emit received(buf);
329 336
330#ifdef VERBOSE_DEBUG 337#ifdef VERBOSE_DEBUG
331 // verbose debug 338 // verbose debug
332 printf("read bytes:\n"); 339 printf("read bytes:\n");
333 for (uint i = 0; i < buf.count(); i++) 340 for (uint i = 0; i < buf.count(); i++)
334 printf("%c", buf[i]); 341 printf("%c", buf[i]);
335 printf("\n"); 342 printf("\n");
336#endif 343#endif
337 344
338} 345}
339QBitArray MyPty::supports()const { 346QBitArray MyPty::supports()const {
340 QBitArray ar(3); 347 QBitArray ar(3);
341 //autoconnect 348 //autoconnect
342 ar[0] = 1; 349 ar[0] = 1;
343 // 350 //