author | zecke <zecke> | 2004-02-29 18:39:07 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-02-29 18:39:07 (UTC) |
commit | 1a59dd467d210703b69d2d694f95988f2e97c27f (patch) (side-by-side diff) | |
tree | 009e2d2c137c4d0d89b4901a8d3a53ff76bd64de | |
parent | f8e1f2c5201f7e86abaa7365040d919e2afcd2ae (diff) | |
download | opie-1a59dd467d210703b69d2d694f95988f2e97c27f.zip opie-1a59dd467d210703b69d2d694f95988f2e97c27f.tar.gz opie-1a59dd467d210703b69d2d694f95988f2e97c27f.tar.bz2 |
from the branch to find the best shell or fallback to /bin/sh
-rw-r--r-- | core/apps/embeddedkonsole/konsole.cpp | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp index eafc12e..084c39d 100644 --- a/core/apps/embeddedkonsole/konsole.cpp +++ b/core/apps/embeddedkonsole/konsole.cpp @@ -1,611 +1,652 @@ /* ---------------------------------------------------------------------- */ /* */ /* [main.C] Konsole */ /* */ /* ---------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole, an X terminal. */ /* */ /* The material contained in here more or less directly orginates from */ /* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */ /* */ /* ---------------------------------------------------------------------- */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ // enhancements added by L.J. Potter <ljp@llornkcor.com> // enhancements added by Phillip Kuhn #include <stdlib.h> +#include <sys/types.h> +#include <pwd.h> +#include <unistd.h> #ifdef QT_QWS_OPIE #include <opie2/ocolorpopupmenu.h> #endif #include <qpe/resource.h> #include <qdir.h> #include <qevent.h> #include <qdragobject.h> #include <qobjectlist.h> #include <qtoolbutton.h> #include <qtoolbar.h> #include <qpushbutton.h> #include <qfontdialog.h> #include <qglobal.h> #include <qpainter.h> #include <qmenubar.h> #include <qmessagebox.h> #include <qaction.h> #include <qapplication.h> #include <qfontmetrics.h> #include <qcombobox.h> #include <qevent.h> #include <qtabwidget.h> #include <qtabbar.h> #include <qpe/config.h> #include <qstringlist.h> #include <qpalette.h> #include <qfontdatabase.h> #include <qfile.h> #include <qspinbox.h> #include <qlayout.h> #include <qvbox.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include "konsole.h" #include "keytrans.h" #include "commandeditdialog.h" class EKNumTabBar : public QTabBar { public: EKNumTabBar(QWidget *parent = 0, const char *name = 0) : QTabBar(parent, name) {} // QList<QTab> *getTabList() { return(tabList()); } void numberTabs() { // Yes, it really is this messy. QTabWidget needs functions // that provide acces to tabs in a sequential way. int m=INT_MIN; for (int i=0; i<count(); i++) { QTab* left=0; QListIterator<QTab> it(*tabList()); int x=INT_MAX; for( QTab* t; (t=it.current()); ++it ) { int tx = t->rect().x(); if ( tx<x && tx>m ) { x = tx; left = t; } } if ( left ) { left->setText(QString::number(i+1)); m = left->rect().x(); } } } virtual QSize sizeHint() const { if (isHidden()) { return(QSize(0,0)); } else { QSize size = QTabBar::sizeHint(); int shrink = 5; if (qApp->desktop()->width() > 600 || qApp->desktop()->height() > 600) { shrink = 10; } size.setHeight(size.height() - shrink); return(size); } } }; class EKNumTabWidget : public QTabWidget { public: EKNumTabWidget(QWidget* parent) : QTabWidget(parent) { setTabBar(new EKNumTabBar(parent,"EKTabBar")); setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); } EKNumTabBar *getTabBar() const { return ((EKNumTabBar*)tabBar()); } void addTab(QWidget* w) { QTab* t = new QTab(QString::number(tabBar()->count()+1)); QTabWidget::addTab(w,t); } void removeTab(QWidget* w) { removePage(w); ((EKNumTabBar*)tabBar())->numberTabs(); } }; // This could be configurable or dynamicly generated from the bash history // file of the user static const char *commonCmds[] = { "ls ", // I left this here, cause it looks better than the first alpha "cardctl eject", "cat ", "cd ", "chmod ", "clear", "cp ", "dc ", "df ", "dmesg", "echo ", "env", "find ", "free", "grep ", "ifconfig ", "ipkg ", "mkdir ", "mv ", "nc localhost 7776", "nc localhost 7777", "netstat ", "nslookup ", "ping ", "ps aux", "pwd ", "qcop QPE/System 'linkChanged(QString)' ''", "qcop QPE/System 'restart()'", "qcop QPE/System 'quit()'", "rm ", "rmdir ", "route ", "set ", "traceroute", /* "gzip", "gunzip", "chgrp", "chown", "date", "dd", "df", "dmesg", "fuser", "hostname", "kill", "killall", "ln", "ping", "mount", "more", "sort", "touch", "umount", "mknod", "netstat", */ "exit", NULL }; +static void konsoleInit(const char** shell) { + if(setuid(getuid()) !=0) qDebug("setuid failed"); + if(setgid(getgid()) != 0) qDebug("setgid failed"); // drop privileges + + +// QPEApplication::grabKeyboard(); // for CTRL and ALT + + qDebug("keyboard grabbed"); +#ifdef FAKE_CTRL_AND_ALT + qDebug("Fake Ctrl and Alt defined"); + QPEApplication::grabKeyboard(); // for CTRL and ALT +#endif + + *shell = getenv("SHELL"); + qWarning("SHell initially is %s", *shell ); + + if (shell == NULL || *shell == '\0') { + struct passwd *ent = 0; + uid_t me = getuid(); + *shell = "/bin/sh"; + + while ( (ent = getpwent()) != 0 ) { + if (ent->pw_uid == me) { + if (ent->pw_shell != "") + *shell = ent->pw_shell; + break; + } + } + endpwent(); + } + + if( putenv((char*)"COLORTERM=") !=0) + qDebug("putenv failed"); // to trigger mc's color detection +} + + Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) : QMainWindow(parent, name, fl) { - QStrList args; - init("/bin/bash",args); + QStrList tmp; const char* shell; + + konsoleInit( &shell); + init(shell,tmp); } Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int) : QMainWindow(0, name) { init(_pgm,_args); } struct HistoryItem { HistoryItem(int c, const QString &l) { count = c; line = l; } int count; QString line; }; class HistoryList : public QList<HistoryItem> { virtual int compareItems( QCollection::Item item1, QCollection::Item item2) { int c1 = ((HistoryItem*)item1)->count; int c2 = ((HistoryItem*)item2)->count; if (c1 > c2) return(1); if (c1 < c2) return(-1); return(0); } }; void Konsole::initCommandList() { // qDebug("Konsole::initCommandList"); Config cfg( "Konsole" ); cfg.setGroup("Commands"); // commonCombo->setInsertionPolicy(QComboBox::AtCurrent); commonCombo->clear(); if (cfg.readEntry("ShellHistory","TRUE") == "TRUE") { QString histfilename = QString(getenv("HOME")) + "/.bash_history"; histfilename = cfg.readEntry("ShellHistoryPath",histfilename); QFile histfile(histfilename); // note: compiler barfed on: // QFile histfile(QString(getenv("HOME")) + "/.bash_history"); if (histfile.open( IO_ReadOnly )) { QString line; uint i; HistoryList items; int lineno = 0; while(!histfile.atEnd()) { if (histfile.readLine(line, 200) < 0) { break; } line = line.left(line.length()-1); lineno++; for(i=0; i<items.count(); i++) { if (line == items.at(i)->line) { // weight recent commands & repeated commands more // by adding up the index of each command items.at(i)->count += lineno; break; } } if (i >= items.count()) { items.append(new HistoryItem(lineno, line)); } } items.sort(); int n = items.count(); if (n > 40) { n = 40; } for(int i=0; i<n; i++) { // should insert start of command, but keep whole thing if (items.at(items.count()-i-1)->line.length() < 30) { commonCombo->insertItem(items.at(items.count()-i-1)->line); } } histfile.close(); } } if (cfg.readEntry("Commands Set","FALSE") == "FALSE") { for (int i = 0; commonCmds[i] != NULL; i++) { commonCombo->insertItem(commonCmds[i]); } } else { for (int i = 0; i < 100; i++) { if (!(cfg.readEntry( QString::number(i),"")).isEmpty()) commonCombo->insertItem(cfg.readEntry( QString::number(i),"")); } } } static void sig_handler(int x) { printf("got signal %d\n",x); } void Konsole::init(const char* _pgm, QStrList & _args) { #if 0 for(int i=1; i<=31; i++) { if (i != SIGPIPE && i != SIGPROF && i != SIGSEGV && i != SIGINT && i != SIGILL && i != SIGTERM && i != SIGBUS) signal(i,sig_handler); } #endif signal(SIGSTOP, sig_handler); signal(SIGCONT, sig_handler); signal(SIGTSTP, sig_handler); b_scroll = TRUE; // histon; n_keytab = 0; n_render = 0; startUp=0; fromMenu = FALSE; fullscreen = false; setCaption( tr( "Konsole" ) ); setIcon( Resource::loadPixmap( "konsole/Terminal" ) ); Config cfg( "Konsole" ); cfg.setGroup("Font"); QString tmp; // initialize the list of allowed fonts /////////////////////////////////// QString cfgFontName = cfg.readEntry("FontName","Lcfont"); int cfgFontSize = cfg.readNumEntry("FontSize",18); cfont = -1; // this code causes repeated access to all the font files // which does slow down startup QFontDatabase fontDB; QStringList familyNames; familyNames = fontDB.families( FALSE ); QString s; int fontIndex = 0; int familyNum = 0; fontList = new QPopupMenu( this ); for(uint j = 0; j < (uint)familyNames.count(); j++) { s = familyNames[j]; if ( s.contains('-') ) { int i = s.find('-'); s = s.right( s.length() - i - 1 ) + " [" + s.left( i ) + "]"; } s[0] = s[0].upper(); QValueList<int> sizes = fontDB.pointSizes( familyNames[j] ); printf("family[%d] = %s with %d sizes\n", j, familyNames[j].latin1(), sizes.count()); if (sizes.count() > 0) { QPopupMenu *sizeMenu; QFont f; int last_width = -1; sizeMenu = NULL; for(uint i = 0; i < (uint)sizes.count() + 4; i++) { // printf("family %s size %d ", familyNames[j].latin1(), sizes[i]); // need to divide by 10 on the Z, but not otherwise int size; if (i >= (uint)sizes.count()) { // try for expandable fonts size = sizes[sizes.count()-1] + 2 * (i - sizes.count() + 1); } else { printf("sizes[%d] = %d\n", i, sizes[i]); size = sizes[i]; } f = QFont(familyNames[j], size); f.setFixedPitch(true); QFontMetrics fm(f); // don't trust f.fixedPitch() or f.exactMatch(), they lie!! if (fm.width("l") == fm.width("m") && (i < (uint)sizes.count() || fm.width("m") > last_width)) { if (i < (uint)sizes.count()) { last_width = fm.width("m"); } if (sizeMenu == NULL) { sizeMenu = new QPopupMenu(); } int id = sizeMenu->insertItem(QString("%1").arg(size), fontIndex); sizeMenu->setItemParameter(id, fontIndex); sizeMenu->connectItem(id, this, SLOT(setFont(int))); QString name = s + " " + QString::number(size); fonts.append(new VTFont(name, f, familyNames[j], familyNum, size)); if (familyNames[j] == cfgFontName && size == cfgFontSize) { cfont = fontIndex; } printf("FOUND: %s family %s size %d\n", name.latin1(), familyNames[j].latin1(), size); fontIndex++; } } if (sizeMenu) { fontList->insertItem(s, sizeMenu, familyNum + 1000); familyNum++; } } } if (cfont < 0 || cfont >= (int)fonts.count()) { cfont = 0; } // create terminal emulation framework //////////////////////////////////// nsessions = 0; tab = new EKNumTabWidget(this); // tab->setMargin(tab->margin()-5); connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*))); // create terminal toolbar //////////////////////////////////////////////// setToolBarsMovable( FALSE ); menuToolBar = new QToolBar( this ); menuToolBar->setHorizontalStretchable( TRUE ); QMenuBar *menuBar = new QMenuBar( menuToolBar ); bool c7xx = false; if (qApp->desktop()->width() > 600 || qApp->desktop()->height() > 600) { c7xx = true; } QFont menuFont; menuFont.setPointSize(c7xx? 18 : 10); qApp->setFont(menuFont, true); setFont(cfont); configMenu = new QPopupMenu( this); colorMenu = new QPopupMenu( this); scrollMenu = new QPopupMenu( this); editCommandListMenu = new QPopupMenu( this); configMenu->insertItem(tr("Command List"), editCommandListMenu); bool listHidden; cfg.setGroup("Menubar"); if( cfg.readEntry("Hidden","FALSE") == "TRUE") { ec_cmdlist = editCommandListMenu->insertItem( tr( "Show command list" )); listHidden=TRUE; } else { ec_cmdlist = editCommandListMenu->insertItem( tr( "Hide command list" )); listHidden=FALSE; } cfg.setGroup("Tabs"); tabMenu = new QPopupMenu(this); tm_bottom = tabMenu->insertItem(tr("Bottom" )); tm_top = tabMenu->insertItem(tr("Top")); tm_hidden = tabMenu->insertItem(tr("Hidden")); configMenu->insertItem(tr("Tabs"), tabMenu); tmp=cfg.readEntry("Position","Top"); if(tmp=="Top") { tab->setTabPosition(QTabWidget::Top); tab->getTabBar()->show(); tabPos = tm_top; } else if (tmp=="Bottom") { tab->setTabPosition(QTabWidget::Bottom); tab->getTabBar()->show(); tabPos = tm_bottom; } else { tab->getTabBar()->hide(); tab->setMargin(tab->margin()); tabPos = tm_hidden; } cm_bw = colorMenu->insertItem(tr( "Black on White")); cm_wb = colorMenu->insertItem(tr( "White on Black")); cm_gb = colorMenu->insertItem(tr( "Green on Black")); // cm_bt = colorMenu->insertItem(tr( "Black on Transparent")); cm_br = colorMenu->insertItem(tr( "Black on Pink")); cm_rb = colorMenu->insertItem(tr( "Pink on Black")); cm_gy = colorMenu->insertItem(tr( "Green on Yellow")); cm_bm = colorMenu->insertItem(tr( "Blue on Magenta")); cm_mb = colorMenu->insertItem(tr( "Magenta on Blue")); cm_cw = colorMenu->insertItem(tr( "Cyan on White")); cm_wc = colorMenu->insertItem(tr( "White on Cyan")); cm_bb = colorMenu->insertItem(tr( "Blue on Black")); cm_ab = colorMenu->insertItem(tr( "Amber on Black")); cm_default = colorMenu->insertItem(tr("default")); #ifdef QT_QWS_OPIE colorMenu->insertItem(tr( "Custom")); #endif configMenu->insertItem(tr( "Colors") ,colorMenu); sessionList = new QPopupMenu(this); sessionList-> insertItem ( Resource::loadPixmap ( "konsole/Terminal" ), tr( "new session" ), this, SLOT(newSession()) ); // connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) )); connect( configMenu, SIGNAL( activated(int) ), this, SLOT( configMenuSelected(int) )); connect( colorMenu, SIGNAL( activated(int) ), this, SLOT( colorMenuIsSelected(int) )); connect( tabMenu, SIGNAL( activated(int) ), this, SLOT( tabMenuSelected(int) )); connect( scrollMenu, SIGNAL(activated(int)),this,SLOT(scrollMenuSelected(int))); connect( editCommandListMenu,SIGNAL(activated(int)),this,SLOT(editCommandListMenuSelected(int))); connect( sessionList, SIGNAL(activated(int)), this, SLOT( sessionListSelected(int) ) ); menuBar->insertItem( tr("View"), configMenu ); menuBar->insertItem( tr("Fonts"), fontList ); menuBar->insertItem( tr("Sessions"), sessionList ); toolBar = new QToolBar( this ); QAction *a; // Button Commands a = new QAction( tr("New"), Resource::loadPixmap( "konsole/Terminal" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolBar ); a = new QAction( tr("Full Screen"), Resource::loadPixmap( "fullscreen" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( toggleFullScreen() ) ); a->addTo( toolBar ); a = new QAction( tr("Zoom"), Resource::loadPixmap( "zoom" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( cycleZoom() ) ); a->addTo( toolBar ); /* a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolBar ); a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 ); |