[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Konsole Part improvements
From:       Kevin Puetz <puetzk () iastate ! edu>
Date:       2002-04-23 3:17:29
[Download RAW message or body]

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
["konsole-exec.diff" (text/x-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; i<m_schema->count(); 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();
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic