From kde-core-devel Tue Apr 23 03:17:29 2002 From: Kevin Puetz Date: Tue, 23 Apr 2002 03:17:29 +0000 To: kde-core-devel Subject: Konsole Part improvements X-MARC-Message: https://marc.info/?l=kde-core-devel&m=101955160309112 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--------------Boundary-00=_5T30B07UNRHWFAVA1CFQ" --------------Boundary-00=_5T30B07UNRHWFAVA1CFQ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8bit As part of some improvements I'd like to make to the kpackage APT(debian) frontend, I would like to add the ability to execute commands (other than $SHELL) to the konsolepart so we could drop the stupid MultiLineEdit being used there and have real terminal emulation for the output from these commands (some of which would really prefer . I've added handling for openURL("exec:/command args") to the konsolepart (we seem to use this idiom a few other places, and it seems as sane as any). This means the konsolepart now accepts two kinds of URL's - local directories (launch a shell and CD there) and programs(launch that program). Patch attached, any objections/comments (espescially in the security regard, since this allows konsolepart to run commands in response to URL's). Konqueror (the main place where a a part risks picking up stray URL's) seems not to send exec URI's when the konsolepart and another view are linked. The only other users I'm aware of are kate (but kate is a trusted source) and, when I'm done, kpackage (which will be sending only internally-generated commands, so also a trusted source) But I'm not entirely sure where in konqueror they are filtered out, so I'm not sure whether to trust this or not. Does anyone know? How should a part go about determining the 'trustedness' of it's URL source, or is it up to apps to not do stupid things like let a webpage link URL find it's way to a konsolepart? -- Kevin Alan Puetz (515)572-0927 puetzk@iastate.edu --------------Boundary-00=_5T30B07UNRHWFAVA1CFQ Content-Type: text/x-diff; charset="us-ascii"; name="konsole-exec.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="konsole-exec.diff" Index: konsole/konsole_part.cpp =================================================================== RCS file: /home/kde/kdebase/konsole/konsole/konsole_part.cpp,v retrieving revision 1.50 diff -u -p -r1.50 konsole_part.cpp --- konsole/konsole_part.cpp 2002/03/26 06:54:09 1.50 +++ konsole/konsole_part.cpp 2002/04/23 02:46:46 @@ -156,34 +156,15 @@ konsolePart::konsolePart(QWidget *_paren // Without this -> crash on keypress... (David) KeyTrans::loadAll(); - QStrList eargs; - - const char* shell = getenv("SHELL"); - if (shell == NULL || *shell == '\0') shell = "/bin/sh"; - eargs.append(shell); te = new TEWidget(parentWidget,widgetName); te->setMinimumSize(150,70); // allow resizing, cause resize in TEWidget + /* launchSession(); used to do most of it here, but we can't set the schema yet */ + + setWidget(te); - se = new TESession(te,shell,eargs,"xterm"); - connect( se,SIGNAL(done(TESession*,int)), - this,SLOT(doneSession(TESession*,int)) ); - connect( se,SIGNAL(openURLRequest(const QString &)), - this,SLOT(emitOpenURLRequest(const QString &)) ); connect( te,SIGNAL(configureRequest(TEWidget*,int,int,int)), this,SLOT(configureRequest(TEWidget*,int,int,int)) ); - connect( se, SIGNAL( updateTitle() ), - this, SLOT( updateTitle() ) ); - connect( se, SIGNAL(restoreAllListenToKeyPress()), - this, SLOT(restoreAllListenToKeyPress()) ); - // We ignore the following signals - //connect( se, SIGNAL(renameSession(TESession*,const QString&)), - // this, SLOT(slotRenameSession(TESession*, const QString&)) ); - //connect( se->getEmulation(), SIGNAL(changeColumns(int)), - // this, SLOT(changeColumns(int)) ); - //connect( se, SIGNAL(clearAllListenToKeyPress()), - // this, SLOT(clearAllListenToKeyPress()) ); - se->setConnect(TRUE); te->currentSession = se; rootxpm = new KRootPixmap(te); @@ -206,8 +187,8 @@ konsolePart::konsolePart(QWidget *_paren for (uint i=0; icount(); i++) m_schema->setItemChecked(i,false); + m_schema->setItemChecked(curr_schema,true); - se->setSchemaNo(curr_schema); // insert keymaps into menu for (int i = 0; i < KeyTrans::count(); i++) { @@ -218,7 +199,7 @@ konsolePart::konsolePart(QWidget *_paren applySettingsToGUI(); // kDebugInfo("Loading successful"); - se->run(); + launchSession(); /* move it down after the schema stuff is allocated */ connect( se, SIGNAL( destroyed() ), this, SLOT( sessionDestroyed() ) ); } @@ -267,6 +248,68 @@ konsolePart::~konsolePart() //te is deleted by the framework } +void konsolePart::launchSession(const QString & cmd) +{ + if(se != NULL) /* close the existing session */ + { + se->closeSession(); /* SIGHUP */ + /* we're doing this disconnect on purpose, so don't quit */ + disconnect( se, SIGNAL( destroyed() ), this, SLOT( sessionDestroyed() ) ); + delete se; + } + QStrList eargs; + + const char* shell = getenv("SHELL"); + if (shell == NULL || *shell == '\0') shell = "/bin/sh"; + eargs.append(shell); + + if(!cmd.isNull()) + { + eargs.append("-c"); + eargs.append(QFile::encodeName(cmd)); + /* we launched some specific command */ + m_isShell = false; + } + else + { /* just a bare shell */ + m_isShell = true; + } + + se = new TESession(te,shell,eargs,"xterm"); + + connect( se,SIGNAL(done(TESession*,int)), + this,SLOT(doneSession(TESession*,int)) ); + connect( se,SIGNAL(openURLRequest(const QString &)), + this,SLOT(emitOpenURLRequest(const QString &)) ); + connect( se, SIGNAL( updateTitle() ), + this, SLOT( updateTitle() ) ); + connect( se, SIGNAL(restoreAllListenToKeyPress()), + this, SLOT(restoreAllListenToKeyPress()) ); + // We ignore the following signals + //connect( se, SIGNAL(renameSession(TESession*,const QString&)), + // this, SLOT(slotRenameSession(TESession*, const QString&)) ); + //connect( se->getEmulation(), SIGNAL(changeColumns(int)), + // this, SLOT(changeColumns(int)) ); + //connect( se, SIGNAL(clearAllListenToKeyPress()), + // this, SLOT(clearAllListenToKeyPress()) ); + se->setConnect(TRUE); + + se->setSchemaNo(curr_schema); + se->setKeymapNo(n_keytab); + + if (b_histEnabled && m_histSize) + se->setHistory(HistoryTypeBuffer(m_histSize)); + else if (b_histEnabled && !m_histSize) + se->setHistory(HistoryTypeFile()); + else + se->setHistory(HistoryTypeNone()); + + se->setFontNo(n_font); + + se->run(); + connect( se, SIGNAL( destroyed() ), this, SLOT( sessionDestroyed() ) ); +} + bool konsolePart::openURL( const KURL & url ) { //kdDebug(1211) << "konsolePart::openURL " << url.prettyURL() << endl; @@ -282,12 +325,16 @@ bool konsolePart::openURL( const KURL & emit started( 0 ); if ( url.isLocalFile() ) { + if(!m_isShell) + launchSession(); /* make it a bare shell */ struct stat buff; stat( QFile::encodeName( url.path() ), &buff ); QString text = ( S_ISDIR( buff.st_mode ) ? url.path() : url.directory() ); KRun::shellQuote(text); - text = QString::fromLatin1("cd ") + text + '\n'; - te->emitText( text ); + /* send the session a cd command, it's a shell */ + se->sendSession( QString("cd ") + text); + } else if(url.protocol() == "exec") { + launchSession(url.path().mid(1)); } emit completed(); @@ -498,14 +545,6 @@ void konsolePart::readProperties() pixmap_menu_activated(sch->alignment()); } - if (b_histEnabled && m_histSize) - se->setHistory(HistoryTypeBuffer(m_histSize)); - else if (b_histEnabled && !m_histSize) - se->setHistory(HistoryTypeFile()); - else - se->setHistory(HistoryTypeNone()); - - se->setKeymapNo(n_keytab); te->setBellMode(n_bell); te->setBlinkingCursor(config->readBoolEntry("BlinkingCursor",FALSE)); te->setFrameStyle( b_framevis?(QFrame::WinPanel|QFrame::Sunken):QFrame::NoFrame ); @@ -595,7 +634,8 @@ void konsolePart::setFont(int fontno) KMessageBox::error((KMainWindow*)parentWidget, msg); return; } - se->setFontNo(fontno); + if(se) /* don't break things if we don't have a session yet */ + se->setFontNo(fontno); te->setVTFont(f); n_font = fontno; } @@ -603,8 +643,11 @@ void konsolePart::setFont(int fontno) void konsolePart::updateKeytabMenu() { m_keytab->setItemChecked(n_keytab,FALSE); - m_keytab->setItemChecked(se->keymapNo(),TRUE); - n_keytab = se->keymapNo(); + if(se) + { + m_keytab->setItemChecked(se->keymapNo(),TRUE); + n_keytab = se->keymapNo(); + } } void konsolePart::keytab_menu_activated(int item) @@ -682,7 +725,8 @@ void konsolePart::setSchema(ColorSchema* } te->setColorTable(s->table()); - se->setSchemaNo(s->numb()); + if(se) + se->setSchemaNo(s->numb()); } void konsolePart::pixmap_menu_activated(int item) @@ -730,26 +774,26 @@ void konsolePart::pixmap_menu_activated( void konsolePart::slotHistoryType() { - HistoryTypeDialog dlg(se->history(), m_histSize, (KMainWindow*)parentWidget); - if (dlg.exec()) { - if (dlg.isOn()) { - if (dlg.nbLines() > 0) { - se->setHistory(HistoryTypeBuffer(dlg.nbLines())); - m_histSize = dlg.nbLines(); - b_histEnabled = true; - } - else { - se->setHistory(HistoryTypeFile()); - m_histSize = 0; - b_histEnabled = true; - } - } - else { - se->setHistory(HistoryTypeNone()); - m_histSize = dlg.nbLines(); - b_histEnabled = false; - } - } + HistoryTypeDialog dlg(se->history(), m_histSize, (KMainWindow*)parentWidget); + if (dlg.exec()) { + if (dlg.isOn()) { + if (dlg.nbLines() > 0) { + se->setHistory(HistoryTypeBuffer(dlg.nbLines())); + m_histSize = dlg.nbLines(); + b_histEnabled = true; + } + else { + se->setHistory(HistoryTypeFile()); + m_histSize = 0; + b_histEnabled = true; + } + } + else { + se->setHistory(HistoryTypeNone()); + m_histSize = dlg.nbLines(); + b_histEnabled = false; + } + } } void konsolePart::slotSelectBell() { Index: konsole/konsole_part.h =================================================================== RCS file: /home/kde/kdebase/konsole/konsole/konsole_part.h,v retrieving revision 1.12 diff -u -p -r1.12 konsole_part.h --- konsole/konsole_part.h 2002/03/26 06:54:09 1.12 +++ konsole/konsole_part.h 2002/04/23 02:46:46 @@ -110,6 +110,12 @@ class konsolePart: public KParts::ReadOn konsoleBrowserExtension *m_extension; KURL currentURL; + /* launch the specified command in the konsole we are managing, + * if no argument given launch $SHELL */ + void launchSession(const QString & command = QString::null); + /* true if the current command is a shell (can change directories with cd) */ + bool m_isShell; + void makeGUI(); void applySettingsToGUI(); --------------Boundary-00=_5T30B07UNRHWFAVA1CFQ--