/***************************************************************************
 * $Id: tork.cpp,v 1.202 2010/07/24 12:18:36 hoganrobert Exp $
 *   Copyright (C) 2006 - 2008 Robert Hogan                                *
 *   robert@roberthogan.net                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
 ***************************************************************************/


#include <ntqdragobject.h>
#include <kprinter.h>
#include <ntqpainter.h>
#include <ntqpaintdevicemetrics.h>
#include <ntqtimer.h>
#include <ntqgroupbox.h>

#include <tdeconfigdialog.h>
#include <tdeglobal.h>
#include <tdelocale.h>
#include <kiconloader.h>
#include <tdeversion.h>
#include <tdemenubar.h>
#include <kstatusbar.h>
#include <kkeydialog.h>
#include <ksqueezedtextlabel.h>
#include <kedittoolbar.h>
#include <tdetoolbarbutton.h>
#include <krun.h>
#include <tdestdaccel.h>
#include <tdeaction.h>
#include <kstdaction.h>
#include <tdepopupmenu.h>
#include <kprocio.h>
#include <tdemessagebox.h>
#include <dcopref.h>
#include <tdeconfig.h>
#include <tdemessagebox.h>
#include <tdelocale.h>
#include <kpassivepopup.h>
#include <tdeio/netaccess.h>
#include <tdehtml_part.h>
#include <dom/html_misc.h>
#include <kurl.h>
#include <tdehtmlview.h>
#include <kstandarddirs.h>
#include <ktip.h>
#include <twin.h>
#include <knotifyclient.h>
#include <tdelistviewsearchline.h>

#include <ntqtooltip.h>
#include <ntqlabel.h>
#include <ntqfile.h>
#include <ntqdir.h>
#include <ntqtabwidget.h>
#include <ntqhostaddress.h>
#include <dcopref.h>
#include <dcopclient.h>
#include <tdecmdlineargs.h>

#ifndef EXTERNAL_GEOIP
# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
#else
# include <GeoIP.h>
#endif

#include "tork.h"
#include "crypto.h"
#include "configdialog.h"
#include "quickconfig.h"
#include "torkconfig.h"
#include "functions.h"
#include "dndlistview.h"
#include "newfirstrunwizard.h"
#include "introwizard.h"
#include "serverwizard.h"
#include "warnings.h"
#include "questions.h"
#include "portsandicons.h"
#include "likeback.h"
#include "version.h"
#include "hiddensrvs.h"

#include "../config.h"

tork *tdemain = 0L;

using namespace tk;

const char *dayweekmonth[] = {
    "day",
    "week",
    "month"
};

TQValueVector<TQString> serverCondition(9);
TQValueVector<TQString> logType(5);
TQValueVector<TQString> torkifyApp(5);
TQValueVector<TQString> torTrafficType(9);
TQValueVector<TQString> nonTorTrafficType(9);
TQValueVector<TQString> subnetType(256);
TQValueVector<TQString> countryType(256);


tork::tork()
    : DCOPObject( "DCOPTork" ),
      TDEMainWindow( 0, "TorK" ),
      m_view(new torkView(this)),
      m_printer(0),
      m_servererrornag(true),
      m_contactinfonag(true),
      m_serverworking(true),
      m_toolTipShowing(false),
      waitingForServers(false),
      stillStarting(false),
      m_DNSTorified(false),
      m_showstopperAlreadyDisplayed(false),
      m_routerDiscovered(false),
      m_ShutdownRequested(false),
      m_CanApplyServerSettingsIfSet(false),
      myHiddenDialog(0L),
      privoxytest(0L)
{


    // Register with DCOP
//     if ( !kapp->dcopClient()->isRegistered() ) {
         kapp->dcopClient()->registerAs( "tork", false );
         kapp->dcopClient()->setDefaultObject( objId() );
//     }

	tdemain = this;
    client = 0L;
    childproc = 0L;
    privoxyproc = 0L;
    netstatproc = 0L;
    tfPrivoxy = 0L;
    tfTor = 0L;
    bwtimer = 0L;
    bwLimitTimer = 0L;
    updater=0L;

    serverCondition[0] = "All";
    serverCondition[1] = "Valid";
    serverCondition[2] = "Fast";
    serverCondition[3] = "Authority";
    serverCondition[4] = "Named";
    serverCondition[5] = "Exit";
    serverCondition[6] = "Running";
    serverCondition[7] = "Guard";
    serverCondition[8] = "Stable";

    logType[0] = "All";
    logType[1] = "NOTICE";
    logType[2] = "WARN";
    logType[3] = "ERR";
    logType[4] = "DEBUG";
   
    torkifyApp[0] = "konversation";
    torkifyApp[1] = "kopete";
    torkifyApp[2] = "gaim";
    torkifyApp[3] = "pidgin";
    torkifyApp[4] = "konsole";

    torTrafficType[0] = "All";
    torTrafficType[1] = ":80";
    torTrafficType[2] = ":443";
    torTrafficType[3] = ":110";
    torTrafficType[4] = ":25";
    torTrafficType[5] = ":22";
    torTrafficType[6] = ":23";
    torTrafficType[7] = ":21";
    torTrafficType[8] = ":53";

    nonTorTrafficType[0] = "All";
    nonTorTrafficType[1] = ":80";
    nonTorTrafficType[2] = ":443";
    nonTorTrafficType[3] = ":110";
    nonTorTrafficType[4] = ":25";
    nonTorTrafficType[5] = ":22";
    nonTorTrafficType[6] = ":23";
    nonTorTrafficType[7] = ":21";
    nonTorTrafficType[8] = ":53";

    for ( int country_id = 0; country_id != 250; ++country_id)
       countryType[country_id] = GeoIP_country_code[country_id];
    countryType[251] = "All";


    // accept dnd
    //setAcceptDrops(true);


    // then, setup our actions
    setupActions();

    // Instanciate the LikeBack system, and show the first-use information dialog if the button-bar is shown:
     LikeBack *likeBack = new LikeBack(LikeBack::AllButtons, LikeBack::isDevelopmentVersion(TORK_VERSION)); // Show button-bar only in beta-versions
     likeBack->setServer("tork.sourceforge.net", "/likeback/send.php");
     likeBack->setAcceptedLanguages(TQStringList::split(";", "en;fr"), i18n("Please write in English or French."));

     // Comment the following line once you are sure all your windows have a name:
     likeBack->setWindowNamesListing(LikeBack::WarnUnnamedWindows);

     // This line should be called early in your TDEMainWindow constructor because it references actionCollection().
     // It should be called before createGUI() for the action to be plugged in the Help menu:
     likeBack->sendACommentAction(actionCollection());

    // and a status bar
    statusBar()->show();

	m_statusInfo = new TQLabel(this);
	m_statusTransfer = new TQLabel(this);

	statusBar()->addWidget(m_statusInfo,2);
	statusBar()->addWidget(m_statusTransfer,2);

    // apply the saved mainwindow settings, if any, and ask the mainwindow
    // to automatically save settings if changed: window size, toolbar
    // position, icon size, etc.
    setAutoSaveSettings();

	//currentChanged(0);
	//applySettings(false);

    // tell the TDEMainWindow that this is indeed the main widget
    setCentralWidget(m_view);

	setStandardToolBarMenuEnabled(true);

    
    setUpnpDirPort(TorkConfig::dirListenAddress());
    setUpnpORPort(TorkConfig::oRListenAddress());

    // allow the view to change the statusbar and caption
     connect(m_view, SIGNAL(updateTrayStats(const TQString&, const TQString&,
                                            const TQString&, const TQString&)),
             this,   SLOT(updateTrayStats(const TQString&,const TQString&,
                                          const TQString&, const TQString&)));
     connect(m_view->m_osd, SIGNAL(requestHideMonitor()),
             this,   SLOT(toggleTorMon2()));
     connect(m_view->m_osd, SIGNAL(requestToggleTDE()),
             this,   SLOT(toggleTDESetting()));
     connect(m_view->m_osd, SIGNAL(requestChangeID()),
             this,   SLOT(useNewIdentity()));

    connect(m_view, SIGNAL(showSecurityNotice(const TQString&)),
             this,   SLOT(showSecurityNotice(const TQString&)));
    connect(m_view, SIGNAL(showScreamingNotice(const TQString&)),
             this,   SLOT(showScreamingNotice(const TQString&)));

    connect(m_view, SIGNAL(newIdentity()),
             this,   SLOT(useNewIdentity()));
    connect(m_view, SIGNAL(konqWithTor()),
             this,   SLOT(toggleTDESettingAndLaunchKonq()));
    connect(m_view, SIGNAL(networkList()),
             this,   SLOT(networkList()));
    connect(m_view, SIGNAL(hiddenServices()),
             this,   SLOT(hiddenServices()));
    connect(m_view, SIGNAL(mixminionHome()),
             this,   SLOT(mixminionHome()));
    connect(m_view, SIGNAL(showMyKonqueror()),
             this,   SLOT(showMyKonqueror()));
    connect(m_view, SIGNAL(showMyHiddenServices()),
             this,   SLOT(showMyHiddenServices()));
    connect(m_view, SIGNAL(riskySession()),
             this,   SLOT(readEavesdropping()));
    connect(m_view, SIGNAL(aboutTorify()),
             this,   SLOT(aboutTorify()));
    connect(m_view, SIGNAL(aboutTor()),
             this,   SLOT(aboutTor()));
    connect(m_view, SIGNAL(configurePrivoxy()),
             this,   SLOT(configurePrivoxy()));
    connect(m_view, SIGNAL(aboutParanoidMode()),
             this,   SLOT(aboutParanoidMode()));
    connect(m_view, SIGNAL(startEverything()),
             this,   SLOT(startEverything()));
    connect(m_view, SIGNAL(stopEverything()),
             this,   SLOT(stopTorGracefully()));

    connect(m_view, SIGNAL(toggleTorTraffic(bool)),
             this,   SLOT(toggleTorTraffic(bool)));

    connect(m_view, SIGNAL(toggleNonTorTraffic(bool)),
             this,   SLOT(toggleNonTorTraffic(bool)));

    connect(m_view, SIGNAL(processWarning(const TQString& , const TQString& )),
             this,   SLOT(processWarning(const TQString& , const TQString& )));

    connect(m_view, SIGNAL(copyOldConfig()),
             this,   SLOT(copyOldConfig()));

    connect(UPnPManager::Manager(),SIGNAL(routerDiscovered( kt::UPnPRouter* )),
                this,SLOT(routerDiscovered( kt::UPnPRouter* )));
    connect(UPnPManager::Manager(),SIGNAL(forwardingOK(kt::UPnPRouter*, const TQString &, bool )),
                this,SLOT(upnpForwardingOK(kt::UPnPRouter*, const TQString & , bool)));
    connect(UPnPManager::Manager(),SIGNAL(forwardingError(kt::UPnPRouter*, const TQString &, bool )),
                this,SLOT(upnpForwardingError(kt::UPnPRouter*, const TQString &, bool )));

/*    if (!TorkConfig::clientOnly() && TorkConfig::forwardPorts()){
        upnpmanager->discover();*/
    TQTimer::singleShot( 20000, this, SLOT(checkRouterDiscovered()) );
/*    }*/


//    setupGUI();

    changeStatusbar("zero","zero");
    sayWhatImDoing(i18n("To connect to Tor, press play."));
    showTipOnStart();
    turnOffTDE();

	if ((TDEApplication::kApplication()->isRestored()))
        startEverything();

    TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
    if( args->isSet( "toggleTDE" ) ){
        startEverything();
        enableTDE(true);
    }

    if( args->isSet( "anonymousFirefox" ) ){
        startEverything();
        if (args->count() > 0)
            m_view->anonymizedFirefox(args->arg(0));
        else
            m_view->anonymousFirefox();
    }

    if( args->isSet( "anonymousOpera" ) ){
        startEverything();
        if (args->count() > 0)
            m_view->anonymizedOpera(args->arg(0));
        else
            m_view->anonymousOpera();
    }

    if( args->isSet( "anonymousKopete" ) ){
        startEverything();
        m_view->torify("kopete  --caption 'Anonymous IM Session - Launched From TorK'");
    }

    if( args->isSet( "anonymousKonversation" ) ){
        startEverything();
        m_view->torify("konversation  --caption 'Anonymous IM Session - Launched From TorK'");
    }

    if( args->isSet( "anonymousPidgin" ) ){
        startEverything();
        m_view->torify("pidgin  --caption 'Anonymous IM Session - Launched From TorK'");
    }

    if( args->isSet( "anonymousGaim" ) ){
        startEverything();
        m_view->torify("gaim  --caption 'Anonymous IM Session - Launched From TorK'");
    }

    if( args->isSet( "anonymousKonsole" ) ){
        startEverything();
        m_view->torify("konsole  --caption 'Anonymous Shell Session - Launched From TorK'");
    }

    if( args->isSet( "anonymousEmail" ) ){
        startEverything();
        hide();
        m_view->sendAnonymousEmail();
    }

    //Toggle 'advanced' toolbar if necessary
    if (TorkConfig::advancedMode()){
      m_ModeButton->plug( toolBar("TorToolBar") );
      toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(2),true);
      toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(2));
      toolBar("MoreToolBar")->show();
    }else{
      toolBar("TorToolBar")->setIconText( TDEToolBar::IconTextRight, false );
      m_ModeButton->plug( toolBar("TorToolBar") );
      toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(2),true);
      toolBar("MoreToolBar")->hide();
      toolBar("TorToolBar")->setIconText( TDEToolBar::IconOnly, false );
    }

}

tork::~tork()
{
    prepareToShut();

}

void tork::prepareToShut()
{

    if (client != 0L){
        client->cleanUp();
        client->socketReadyRead();
        client->deleteLater();
        client = 0L;
    }

    TDEConfig* config = new TDEConfig("tdeioslaverc", false, false);
    config->setGroup( "Proxy Settings" );
    config->writeEntry( "httpProxy", TorkConfig::originalHttpProxy() );
    config->writeEntry( "httpsProxy", TorkConfig::originalHttpsProxy() );
    config->writeEntry( "ProxyType", TorkConfig::originalProxyType() );
    config->sync();

    //delete config;
    // Inform all running io-slaves about the changes...
    // if we cannot update, ioslaves inform the end user...
    if (!DCOPRef("*", "TDEIO::Scheduler").send("reparseSlaveConfiguration", TQString::null))
    {
        TQString caption = i18n("Update Failed");
        TQString message = i18n("You have to restart the running applications "
                            "for these changes to take effect.");
        KMessageBox::information (this, message, caption);
        return;
    }
    if (childproc !=0L){
        childproc->kill();
        delete childproc;
        childproc = 0L;
    }

    if (privoxyproc !=0L){
        privoxyproc->kill();
        delete privoxyproc;
        privoxyproc = 0L;
    }

 
    if (tfPrivoxy !=0L){
        delete tfPrivoxy;
        tfPrivoxy = 0L;
    }

    if (tfTor !=0L){
        delete tfTor;
        tfTor = 0L;
    }

    if (privoxytest !=0L){
        delete privoxytest;
        privoxytest = 0L;
    }

    m_view->m_osd->saveSettings(TDEGlobal::config());

    TorkConfig::writeConfig();


}

bool tork::queryClose()
{

    if (client && !kapp->sessionSaving()) { 
        hide(); 
        return false; 
    } 

    return true;
}

void tork::shuttingDown()
{


    if (m_DNSTorified){
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("<b>You are now in "
                             "FailSafe Mode</b>. <br> You need to be in Normal Mode before "
                             "you can close TorK."));
        return;
    }


    KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", "TorK Has Closed And Returned "
                         "TDE To Its Non-Anonymous State! Goodbye!");

    prepareToShut();

    kapp->quit();
}

void tork::setupActions()
{

    //Set up system tray
  	_tray = new TrayIcon(this);
	_tray->setPixmap(KSystemTray::loadIcon("tork_pressplay"));
	connect(_tray,SIGNAL(quitSelected()),SLOT(shuttingDown()));
	TDEPopupMenu *conf_menu = _tray->contextMenu();
    torkConfigure = new TDEAction(i18n("&Configure TorK"), "configure", 0,
                    this, SLOT(optionsPreferences()),actionCollection(),"configure_tor");

	torkStart = new TDEAction(i18n("Connect To Tor"), "tork_play", 0,this,
                            SLOT(startEverything()),actionCollection(),"start_tor");
    torkStop = new TDEAction(i18n("Disconnect From Tor"),"tork_stop", 0,this,
                            SLOT(stopTorGracefully()),actionCollection(),"stop_tor");
    enableKonqi = new TDEAction(i18n("Enable/Disable Konqueror's use of Tor"),"konqueror", 0,this,
                              SLOT(toggleTDESetting()),actionCollection(),"enable_konqi");
    enableTormon = new TDEAction(i18n("Toggle Tor Traffic OSD"),"tork_konsole", 0,this,
                               SLOT(toggleTorMon()),actionCollection(),"enable_tormon");
    browseHiddenServices = new TDEAction(i18n("Browse Hidden Services"),"tork_tor", 0,this,
                               SLOT(hiddenServices()),actionCollection(),"hidden_services");
    browseNetworkList = new TDEAction(i18n("Browse Tor Network Status"),"application-vnd.tde.info", 0,this,
                                    SLOT(networkList()),actionCollection(),"network_list");
#ifndef LIVECD
	torkUpdateTork = new TDEAction(i18n("Download Tork"), "tork_green", 0,this,
                                 SLOT(updateTork()),actionCollection(),"update_tork");
	torkUpdateStable = new TDEAction(i18n("Download Tor (Stable Version)"), "tork_tor", 0,this,
                                   SLOT(updateTorStable()),actionCollection(),"update_torstable");
	torkUpdateUnstable = new TDEAction(i18n("Download Tor (Experimental Version)"), "tork_tor", 0,this,
                              SLOT(updateTorUnstable()),actionCollection(),"update_torunstable");
	torkUpdatePrivoxy = new TDEAction(i18n("Download Privoxy (Proxy)"), "proxy", 0,this,
                                  SLOT(updatePrivoxy()),actionCollection(),"update_privoxy");
#endif
	torkFirstRunWizard = new TDEAction(i18n("First Run Wizard"), "wizard", 0,this,
                                     SLOT(runWizard()),actionCollection(),"firstrun_wizard");
	toggleTorbar = new TDEAction(i18n("Toggle Tor Bar"), "tork_tor", 0,this,
                                     SLOT(toggleTorBar()),actionCollection(),"toggle_torbar");

	connect(m_view->TorkTabs,SIGNAL(currentChanged( TQWidget* )),SLOT(currentTabChanged( TQWidget* )));

    //Servers Filter

    m_ServerFilterButton = new TDEActionMenu( i18n( "Servers" ), "filter", actionCollection() );
    m_ServerFilterButton->setDelayed( false );
    m_ServerFilterMenu = m_ServerFilterButton->popupMenu();
    m_ServerFilterMenu->insertItem( i18n( "All" ), this, SLOT( filterServers( int ) ), 0, 0 );
    m_ServerFilterMenu->insertItem( i18n( "Valid" ), this, SLOT( filterServers( int ) ), 0, 1 );
    m_ServerFilterMenu->insertItem( i18n( "Fast" ), this, SLOT( filterServers( int ) ), 0, 2 );
    m_ServerFilterMenu->insertItem( i18n( "Authority" ), this, SLOT( filterServers( int ) ), 0, 3 );
    m_ServerFilterMenu->insertItem( i18n( "Named" ), this, SLOT( filterServers( int ) ), 0, 4 );
    m_ServerFilterMenu->insertItem( i18n( "Exit" ), this, SLOT( filterServers( int ) ), 0, 5 );
    m_ServerFilterMenu->insertItem( i18n( "Running" ), this, SLOT( filterServers( int ) ), 0, 6 );
    m_ServerFilterMenu->insertItem( i18n( "Guard" ), this, SLOT( filterServers( int ) ), 0, 7 );
    m_ServerFilterMenu->insertItem( i18n( "Stable" ), this, SLOT( filterServers( int ) ), 0, 8 );
    m_ServerFilterMenu->insertSeparator();
    m_ServerFilterMenu->insertItem( i18n( "Show IP" ), this,
                                    SLOT( toggleIP( int ) ), 0, 10 );
    m_ServerFilterMenu->insertSeparator();
    m_ServerFilterMenu->insertItem( i18n( "Sort By Country" ), this, SLOT( sortByCountry( ) ), 0, 9 );

    m_ServerFilterMenu->setItemChecked( 0, true );


    m_CountryMenu =  new TDEPopupMenu( this );
    m_ServerFilterMenu->insertItem( i18n( "Show Countries" ), m_CountryMenu );

    m_CountryMenuEU =  new TDEPopupMenu( this );
    m_CountryMenuAF =  new TDEPopupMenu( this );
    m_CountryMenuAS =  new TDEPopupMenu( this );
    m_CountryMenuNA =  new TDEPopupMenu( this );
    m_CountryMenuAN =  new TDEPopupMenu( this );
    m_CountryMenuSA =  new TDEPopupMenu( this );
    m_CountryMenuNN =  new TDEPopupMenu( this );
    m_CountryMenuOC =  new TDEPopupMenu( this );

    continentMapList["EU"] = m_CountryMenuEU;
    continentMapList["AF"] = m_CountryMenuAF;
    continentMapList["AS"] = m_CountryMenuAS;
    continentMapList["NA"] = m_CountryMenuNA;
    continentMapList["AN"] = m_CountryMenuAN;
    continentMapList["SA"] = m_CountryMenuSA;
    continentMapList["OC"] = m_CountryMenuOC;
    continentMapList["--"] = m_CountryMenuNN;

    m_CountryMenu->insertItem( i18n( "All" ), this, SLOT( filterCountries( int ) ), 0, 251 );
    m_CountryMenu->insertItem( i18n( "Europe" ), m_CountryMenuEU );
    m_CountryMenu->insertItem( i18n( "N America" ), m_CountryMenuNA );
    m_CountryMenu->insertItem( i18n( "S America" ), m_CountryMenuSA );
    m_CountryMenu->insertItem( i18n( "Africa" ), m_CountryMenuAF );
    m_CountryMenu->insertItem( i18n( "Asia" ), m_CountryMenuAS );
    m_CountryMenu->insertItem( i18n( "Oceania" ), m_CountryMenuOC );
    m_CountryMenu->insertItem( i18n( "Satellite" ), m_CountryMenuNN );
    m_CountryMenu->insertItem( i18n( "Antarctica" ), m_CountryMenuAN );

	connect(m_CountryMenu,SIGNAL(aboutToShow()),SLOT(populateCountryMenu( )));
    m_CountryMenu->setItemChecked( 251, true );

    m_ServerFilterMenu->insertSeparator();
    m_ServerFilterMenu->insertItem( i18n( "Text Filter" ), this, 
                                    SLOT( toggleTextFilter( int ) ), 0, 11 );
    m_view->clearButton->setHidden(true);
    m_view->serverFilter->setHidden(true);

    // Launch Filter
    m_LaunchMenuButton = new TDEActionMenu( i18n( "Launch" ), "tork_tor", actionCollection() );
    m_LaunchMenuButton->setDelayed( false );
    m_LaunchMenu = m_LaunchMenuButton->popupMenu();
    m_LaunchMenu->insertItem( SmallIcon("tork_mail"), i18n( "Anonymous Email" ), m_view, 
                              SLOT( sendAnonymousEmail( ) ) );
    if (m_view->firefoxitem)
        m_LaunchMenu->insertItem( SmallIcon("tork_firefox"), i18n( "Anonymous Firefox" ), 
                                  m_view, SLOT( anonymousFirefox( ) ) );
    if (m_view->operaitem)
        m_LaunchMenu->insertItem( SmallIcon("tork_opera"), i18n( "Anonymous Opera" ), 
                                  m_view, SLOT( anonymousOpera( ) ));
    if (m_view->konversationitem)
        m_LaunchMenu->insertItem( SmallIcon("konversation"), i18n( "Anonymous Konversation" ),
                                  this,SLOT( torkify( int )), 0, 0 );
    if (m_view->kopeteitem)
        m_LaunchMenu->insertItem( SmallIcon("kopete"), i18n( "Anonymous Kopete" ),
                                  this,SLOT( torkify( int )), 0, 1 );
    if (m_view->gaimitem)
        m_LaunchMenu->insertItem( SmallIcon("gaim"), i18n( "Anonymous Gaim" ),
                                  this,SLOT( torkify( int )), 0, 2 );
    if (m_view->pidginitem)
        m_LaunchMenu->insertItem( SmallIcon("pidgin"), i18n( "Anonymous Pidgin" ),
                                  this,SLOT( torkify( int )), 0, 3 );
    if (m_view->sshitem)
        m_LaunchMenu->insertItem( SmallIcon("tork_konsolessh"), i18n( "Anonymous SSH/Telnet" ),
                                  this,SLOT( torkify( int )), 0, 4 );

    // Log Filter
    m_LogFilterButton = new TDEActionMenu( i18n( "Tor Log" ), "filter", actionCollection() );
    m_LogFilterButton->setDelayed( false );
    m_LogFilterMenu = m_LogFilterButton->popupMenu();
    m_LogFilterMenu->insertItem( i18n( "All" ), this, SLOT( filterLog( int ) ), 0, 0 );
    m_LogFilterMenu->insertItem( i18n( "NOTICE" ), this, SLOT( filterLog( int ) ), 0, 1 );
    m_LogFilterMenu->insertItem( i18n( "WARNING" ), this, SLOT( filterLog( int ) ), 0, 2 );
    m_LogFilterMenu->insertItem( i18n( "ERROR" ), this, SLOT( filterLog( int ) ), 0, 3 );
    m_LogFilterMenu->insertItem( i18n( "DEBUG" ), this, SLOT( filterLog( int ) ), 0, 4 );
    m_LogFilterMenu->setItemChecked( 0, true );

    // Traffic Filter
    m_TrafficFilterButton = new TDEActionMenu( i18n( "Traffic" ), "filter", actionCollection() );
    m_TrafficFilterButton->setDelayed( false );
    m_TrafficFilterMenu = m_TrafficFilterButton->popupMenu();
    m_TorTrafficFilterMenu =  new TDEPopupMenu( this );
    m_NonTorTrafficFilterMenu =  new TDEPopupMenu( this );

    m_TrafficFilterMenu->insertItem( i18n( "Tor Traffic" ), m_TorTrafficFilterMenu );
    m_TrafficFilterMenu->insertItem( i18n( "Non-Tor Traffic" ), m_NonTorTrafficFilterMenu );
 
    m_TorTrafficFilterMenu->insertItem( i18n( "All" ), this, SLOT( filterTorTraffic( int ) ), 0, 0 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("konqueror"), i18n( "Http" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 1 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_konqueror_https"),i18n( "Https" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 2 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Receive" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 3 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Send" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 4 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_konsolessh"),i18n( "SSH" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 5 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_konsole"),i18n( "Telnet" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 6 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("konqueror"),i18n( "FTP" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 7 );
    m_TorTrafficFilterMenu->insertItem( SmallIcon("network"),i18n( "DNS" ), this, 
                                        SLOT( filterTorTraffic( int ) ), 0, 8 );
    m_TorTrafficFilterMenu->setItemChecked( 0, true );

    m_NonTorTrafficFilterMenu->insertItem( i18n( "All" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 0 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("konqueror"), i18n( "Http" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 1 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_konqueror_https"),i18n( "Https" ), this,
                                        SLOT( filterNonTorTraffic( int ) ), 0, 2 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Receive" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 3 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Send" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 4 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_konsolessh"),i18n( "SSH" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 5 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_konsole"),i18n( "Telnet" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 6 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("konqueror"),i18n( "FTP" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 7 );
    m_NonTorTrafficFilterMenu->insertItem( SmallIcon("network"),i18n( "DNS" ), this, 
                                        SLOT( filterNonTorTraffic( int ) ), 0, 8 );
    m_NonTorTrafficFilterMenu->setItemChecked( 0, true );


    m_IdentityButton = new TDEAction(i18n("Change Identity"),"tork_identity", 0,this,
                                   SLOT(useNewIdentity()),actionCollection());

    //Pseudonymity Buttons

    m_PseudoButton = new TDEActionMenu( i18n( "Be From.." ), "tork_internet",
                                      actionCollection() );
    m_PseudoButton->setDelayed( false );
    m_PseudoMenu = m_PseudoButton->popupMenu();
    m_PseudoMenuEU =  new TDEPopupMenu( this );
    m_PseudoMenuAF =  new TDEPopupMenu( this );
    m_PseudoMenuAS =  new TDEPopupMenu( this );
    m_PseudoMenuNA =  new TDEPopupMenu( this );
    m_PseudoMenuAN =  new TDEPopupMenu( this );
    m_PseudoMenuSA =  new TDEPopupMenu( this );
    m_PseudoMenuNN =  new TDEPopupMenu( this );
    m_PseudoMenuOC =  new TDEPopupMenu( this );

    continentMap["EU"] = m_PseudoMenuEU;
    continentMap["AF"] = m_PseudoMenuAF;
    continentMap["AS"] = m_PseudoMenuAS;
    continentMap["NA"] = m_PseudoMenuNA;
    continentMap["AN"] = m_PseudoMenuAN;
    continentMap["SA"] = m_PseudoMenuSA;
    continentMap["OC"] = m_PseudoMenuOC;
    continentMap["--"] = m_PseudoMenuNN;

    m_PseudoMenu->insertItem( i18n( "Anonymous" ), this, SLOT( applyPseudonymity( int ) ), 0, 999 );
    m_PseudoMenu->insertItem( i18n( "Europe" ), m_PseudoMenuEU );
    m_PseudoMenu->insertItem( i18n( "N America" ), m_PseudoMenuNA );
    m_PseudoMenu->insertItem( i18n( "S America" ), m_PseudoMenuSA );
    m_PseudoMenu->insertItem( i18n( "Africa" ), m_PseudoMenuAF );
    m_PseudoMenu->insertItem( i18n( "Asia" ), m_PseudoMenuAS );
    m_PseudoMenu->insertItem( i18n( "Oceania" ), m_PseudoMenuOC );
    m_PseudoMenu->insertItem( i18n( "Satellite" ), m_PseudoMenuNN );
    m_PseudoMenu->insertItem( i18n( "Antarctica" ), m_PseudoMenuAN );

	connect(m_PseudoMenu,SIGNAL(aboutToShow()),SLOT(populatePseudoMenu( )));
    m_PseudoMenu->setItemChecked(999,true);

    // Server Button
    m_ServerButton = new TDEActionMenu( i18n( "Run Server" ), "server", actionCollection() );
    m_ServerButton->setDelayed( false );
    m_ServerButtonMenu = m_ServerButton->popupMenu();
    m_ServerButtonMenu->insertItem( i18n( "None" ), this, SLOT( configureServer( int ) ), 0, 0 );
    m_ServerButtonMenu->insertItem( i18n( "To Exit Tor Traffic" ), this, 
                                    SLOT( configureServer( int ) ), 0, 1 );
    m_ServerButtonMenu->insertItem( i18n( "To Relay Tor Traffic" ), this, 
                                    SLOT( configureServer( int ) ), 0, 2 );
    m_ServerButtonMenu->insertItem( i18n( "To Defeat Censorship Of Tor" ), this, 
                                    SLOT( configureServer( int ) ), 0, 3 );
    m_ServerButtonMenu->insertSeparator();
    m_ServerButtonMenu->insertItem( TDEGlobal::iconLoader()->loadIconSet("configure", TDEIcon::Small),
                        i18n( "Configure Server" ), this, SLOT( configureServer( int ) ), 0, 4 );
    m_ServerButtonMenu->insertItem( TDEGlobal::iconLoader()->loadIconSet("tork_agent", TDEIcon::Small),
                        i18n( "Manage Hidden Services" ), this, SLOT( configureServer( int ) ), 0, 5 );

    m_ServerButtonMenu->setItemChecked( 0, true );

    m_ServerButtonMenu->setItemEnabled( 4, !TorkConfig::clientOnly() );

    // Server Button
    m_SecurityButton = new TDEActionMenu( i18n( "Fail-Safe" ), "tork_penguin", actionCollection() );
    m_SecurityButton->setDelayed( false );
    m_SecurityButtonMenu = m_SecurityButton->popupMenu();
    m_SecurityButtonMenu->insertItem( TDEGlobal::iconLoader()->loadIconSet("tork_penguin", TDEIcon::Small),
                                   i18n( "None" ), this, SLOT( configureSecurity( int ) ), 0, 0 );
    m_SecurityButtonMenu->insertItem(TDEGlobal::iconLoader()->loadIconSet("tork_agent", TDEIcon::Small),
                            i18n( "DNS FailSafe" ), this, SLOT( configureSecurity( int ) ), 0, 1 );
    m_SecurityButtonMenu->insertItem(  TDEGlobal::iconLoader()->loadIconSet("gv", TDEIcon::Small),
                          i18n( "System FailSafe" ),this, SLOT( configureSecurity( int ) ), 0, 2 );
    m_SecurityButtonMenu->insertSeparator();
    m_SecurityButtonMenu->insertItem( TDEGlobal::iconLoader()->loadIconSet("configure",
         TDEIcon::Small),i18n( "Configure FailSafe" ), this, SLOT( configureSecurity( int ) ), 0, 3 );
    m_SecurityButtonMenu->setItemChecked( 0, true );

    m_UnCensorButton = new TDEAction(i18n("Un-Censor"),"tork_uncensor", 0,this,
                                   SLOT(showFirewallEvasion()),actionCollection());

	torkTip = new TDEAction(i18n("Tip of the Day"), "idea", 0,this,
                          SLOT(showTip()),actionCollection(),"help_show_tip");

    //set up all other actions

    KStdAction::quit(kapp, SLOT(quit()), actionCollection());


    setStandardToolBarMenuEnabled(true); 
    m_statusbarAction = KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()),
                                                  actionCollection());

    KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
    KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
    KStdAction::preferences(this, SLOT(optionsPreferences()), actionCollection());

    createGUI();

    m_ModeButton = new TDEAction(i18n("More Options"),"add", 0,this,
                               SLOT(switchMode()),actionCollection());

    //Set Up Advanced Toolbar
    toolBar("MoreToolBar")->setIconText( TDEToolBar::IconTextRight, false );
    m_PseudoButton->plug( toolBar("MoreToolBar") );
    m_ServerButton->plug( toolBar("MoreToolBar") );
#ifndef LIVECD
    #ifdef USE_FAILSAFE
    m_SecurityButton->plug( toolBar("MoreToolBar") );
    #endif
#endif
    toolBar("MoreToolBar")->setIconText( TDEToolBar::IconOnly, false );

    //Set Up Core Toolbar
    toolBar("TorToolBar")->setIconText( TDEToolBar::IconTextRight, false );
    m_UnCensorButton->plug( toolBar("TorToolBar") );
#ifndef LIVECD
    //m_IdentityButton->plug( toolBar("TorToolBar") );
#endif
    toolBar("TorToolBar")->setIconText( TDEToolBar::IconOnly, false );


    m_PseudoButton->setToolTip( i18n( "Pretend you're using the Internet <br> in another country." ) );
    m_IdentityButton->setToolTip( i18n( "Reset all Tor's open channels (i.e. 'circuits') and <br>" 
                                        "enter the internet " 
                                        "from a new set of channels." ) );
    m_UnCensorButton->setToolTip( i18n( "Evade a state or service provider's attempts <br> to block"
                                        " your use of Tor." ) );
    m_ModeButton->setToolTip( i18n( "Show/hide TorK's advanced features <br> and configuration options."
                                     ) );
    enableTormon->setToolTip( i18n( "Show/hide TorK's on-screen display (OSD) <br> of your active "
                                     "connections." ) );
    m_SecurityButton->setToolTip( i18n( "Ensure selected traffic is <br> forced through Tor." ) );
    m_ServerButton->setToolTip( i18n( "Run a Server on the Tor Network. <br> 'Relay Tor Traffic' "
                                      "is Recommended for Home Use." ) );

    m_ServerButton->setEnabled(false);
    torkStart->setEnabled(true);
    m_LaunchMenuButton->setEnabled(false);
    m_IdentityButton->setEnabled(false);
    m_PseudoButton->setEnabled(false);
    m_ServerFilterButton->setEnabled(false);
    m_SecurityButton->setEnabled(false);
    torkStop->setEnabled(false);
    enableKonqi->setEnabled(false);
    browseHiddenServices->setEnabled(false);

	torkStart->plug(conf_menu);
	torkStop->plug(conf_menu);
    m_IdentityButton->plug(conf_menu);
    enableKonqi->plug(conf_menu);
	torkConfigure->plug(conf_menu);



	m_set_max_rate = new SetMaxRate(this);
	_tray->contextMenu()->insertItem(i18n("Server Bandwidth"),m_set_max_rate);

    _tray->updateStats(BytesPerSecToString(0),BytesPerSecToString(0),
                       BytesPerSecToString(0),BytesPerSecToString(0),
                       TQStringList("<font color='#990000'>Status Not Known</font>"),
                       TQStringList("<font color='#990000'>Status Not Known</font>"),
                       BytesPerSecToString(0));
    _tray->show();


    toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(0),true);
    if (m_view->getShowTormon())
        toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(0));

}

void tork::populateCountryMenu()
{
    //GeoIP_country_name

    TQValueList<int> tmplist = m_view->countryList();
    qHeapSort( tmplist );
	for ( TQValueList<int>::Iterator it = tmplist.begin(); it != tmplist.end(); ++it )
	{
        if (!continentMapList.contains(GeoIP_country_continent[(*it)])) {
            kdDebug() << "unknown continent" << GeoIP_country_continent[(*it)] << endl;
            continue;
        }

        if ( continentMapList[GeoIP_country_continent[(*it)]]->findItem( (*it) ) ){
            continue;
        }
        continentMapList[GeoIP_country_continent[(*it)]]->insertItem(
             TQString(GeoIP_country_code[(*it)]).contains("--") ? SmallIcon("help") :
             SmallIcon(TQString("tork_%1").arg(GeoIP_country_code[(*it)]).lower()),
             GeoIP_country_name[(*it)], 
             this, SLOT( filterCountries( int ) ), 0, (*it) );
    }

}

void tork::populatePseudoMenu()
{
    //GeoIP_country_name

    TQValueList<int> tmplist = m_view->countryList();
    qHeapSort( tmplist );
	for ( TQValueList<int>::Iterator it = tmplist.begin(); it != tmplist.end(); ++it )
	{
        if (!continentMap.contains(GeoIP_country_continent[(*it)])) {
            kdDebug() << "unknown continent" << GeoIP_country_continent[(*it)] << endl;
            continue;
        }

        if ( continentMap[GeoIP_country_continent[(*it)]]->findItem( (*it) ) )
            continue;
        continentMap[GeoIP_country_continent[(*it)]]->insertItem(
             TQString(GeoIP_country_code[(*it)]).contains("--") ? SmallIcon("help") :
             SmallIcon(TQString("tork_%1").arg(GeoIP_country_code[(*it)]).lower()),
             GeoIP_country_name[(*it)], 
             this, SLOT( applyPseudonymity( int ) ), 0, (*it) );
    }

}

void tork::applyPseudonymity( int country_id )
{
    if (!continentMap.contains(GeoIP_country_continent[country_id])) {
        kdDebug() << "unknown continent" << GeoIP_country_continent[country_id] << endl;
        return;
    }

    // Update Menu
	for ( TQMap<TQString, TDEPopupMenu*>::Iterator menu = continentMap.begin(); menu != continentMap.end(); ++menu )
	{
        for (unsigned int index = 0; index != menu.data()->count(); ++index){
                menu.data()->setItemChecked( menu.data()->idAt(index),false);
        }
    }

    if (country_id == 999){
        TorkConfig::setCurrentExitNodes("");
        if (client != 0L){
            client->updateExitNodes();
            client->strictExitNodes(false);
        }
        m_PseudoMenu->setItemChecked(999,true);
        return;
    }


    // Select all exits in chosen country as our preferred exit nodes

    continentMap[GeoIP_country_continent[country_id]]->setItemChecked( country_id,
                 !continentMap[GeoIP_country_continent[country_id]]->isItemChecked(country_id) ); //uncheck old item

    TQStringList currentList;
    TQString cc = TQString("%1").arg(country_id);

    TQListViewItemIterator it(m_view->serverList);
    while ( it.current() ) {
        if ((*it)->text(4) == cc){
            TQString node = "$"+getFPFromFPDigest((*it)->text(2));
            currentList.append(node);
        }
        ++it;
    }
    TorkConfig::setCurrentExitNodes(currentList);


    // Update Tor with new exit list and flush all existing circuits
    if (client != 0L){
        //Close all open circuits first
        TQListView* tmp = dynamic_cast<TQListView*>(m_view->circuitList);
        client->closeAllCircuits(tmp);
        //Then apply new exit list
        client->updateExitNodes();
    }

    // Then ensure a new circuit is chosen
    useNewIdentity();
    m_PseudoMenu->setItemChecked(999,false);

}

void tork::populateSubNetMenu()
{

    if ( !m_IPFilterMenu->findItem( 0 ) ){
        subnetType[0] = "All";
        m_IPFilterMenu->insertItem( "All", this, SLOT( filterSubnets( int ) ), 0, 0);
    }

    TQStringList tmplist = m_view->subnet16List();
    tmplist.sort();
	for ( TQStringList::Iterator it = tmplist.begin(); it != tmplist.end(); ++it )
	{
		if ((*it).isEmpty())
			continue;
        TQString tmpit = (*it);
        int index = tmpit.replace(".","").toInt();

        if ( m_IPFilterMenu->findItem( index ) )
            continue;
        subnetType[index] = (*it);
        m_IPFilterMenu->insertItem( (*it)+"*", this, SLOT( filterSubnets( int ) ), 0, index );
    }

}

void tork::torkify(int id)
{

    m_view->torify(torkifyApp[id]);

}

void
tork::currentTabChanged(TQWidget* cur )  //SLOT
{

    toolBar()->setIconText( TDEToolBar::IconTextRight, false );

    if (cur == prev)
        return;

    prev = m_view->TorkTabs->currentPage();

    if (cur == m_view->TorkTabs->page(0)){
        m_LaunchMenuButton->plug( toolBar() );
        m_ServerFilterButton->unplug( toolBar() );
        m_LogFilterButton->unplug( toolBar() );
        m_TrafficFilterButton->unplug( toolBar() );
    }else if (cur == m_view->TorkTabs->page(1)){
        m_ServerFilterButton->plug( toolBar() );
        m_LaunchMenuButton->unplug( toolBar() );
        m_LogFilterButton->unplug( toolBar() );
        m_TrafficFilterButton->unplug( toolBar() );
    }else if (cur == m_view->TorkTabs->page(2)){
        m_LogFilterButton->plug( toolBar() );
        m_ServerFilterButton->unplug( toolBar() );
        m_LaunchMenuButton->unplug( toolBar() );
        m_TrafficFilterButton->unplug( toolBar() );
    }else if (cur == m_view->TorkTabs->page(3)){
        m_TrafficFilterButton->plug( toolBar() );
        m_ServerFilterButton->unplug( toolBar() );
        m_LaunchMenuButton->unplug( toolBar() );
        m_LogFilterButton->unplug( toolBar() );

    }

    toolBar()->setIconText( TDEToolBar::IconOnly, false );
	m_ServerFilterButton->setToolTip( i18n( "Filter the List of Servers." ) );
	m_LaunchMenuButton->setToolTip( i18n( "Launch anonymized applications <br> with a single click." ) );
	m_LogFilterButton->setToolTip( i18n( "Filter Log Messages by Type." ) );
	m_TrafficFilterButton->setToolTip( i18n( "Filter displayed traffic by type." ) );

}

void
tork::toggleTextFilter( int id )  //SLOT
{

    m_view->clearButton->setHidden(!m_view->clearButton->isHidden());
    m_view->serverFilter->setHidden(!m_view->serverFilter->isHidden());
    m_ServerFilterMenu->setItemChecked( id, !m_view->serverFilter->isHidden() );
    m_view->serverFilter->setFocus();
    if (m_view->clearButton->isHidden())
        m_view->serverFilter->clear();
}

void
tork::sortByCountry( )  //SLOT
{

    m_view->serverList->setSortColumn(4);
    m_view->serverList->sort();

}


void
tork::filterSubnets( int )  //SLOT
{
   //filterView(subnetType, (TQListView*&)m_view->serverList, m_IPFilterMenu, id, 5);
}

void
tork::filterNonTorTraffic( int id )  //SLOT
{
    TQListViewItemIterator it(m_view->NonTorTraffic);
    while ( it.current() ) {
        it.current()->setVisible(false);
        ++it;
    }

   m_NonTorTrafficFilterMenu->setItemChecked( id, !m_NonTorTrafficFilterMenu->isItemChecked(id) ); // Toggle selected item

   filterView(nonTorTrafficType, m_view->NonTorTraffic, m_NonTorTrafficFilterMenu, id, 1);
}

void
tork::filterTorTraffic( int id )  //SLOT
{
    TQListViewItemIterator it(m_view->TorTraffic);
    while ( it.current() ) {
        it.current()->setVisible(false);
        ++it;
    }

   m_TorTrafficFilterMenu->setItemChecked( id, !m_TorTrafficFilterMenu->isItemChecked(id) ); // Toggle selected item

   filterView(torTrafficType, m_view->TorTraffic, m_TorTrafficFilterMenu, id, 2);
}

void
tork::toggleServerButton( bool on )  //SLOT
{
    m_ServerButton->setEnabled(!on);
    if (!on)
	   m_ServerButton->setToolTip( i18n( "Run a Server on the Tor Network. <br> 'Relay Tor Traffic' "
                                      "is Recommended for Home Use." ) );
    else
       m_ServerButton->setToolTip( i18n( "You Can't Run a Server While <br> Using Tor's Un-Censor "
                                         "Feature." ) );

}

void
tork::updateServerButton( )  //SLOT
{
    //Set quick-select dropdown to reflect setting in config panel
    m_view->welcomeitem->score->setCurrentItem(TorkConfig::quickConfigure());

    for (unsigned int index = 0; index != 3; ++index){
        m_ServerButtonMenu->setItemChecked( index, false ); //uncheck old item
    }

    if (TorkConfig::clientOnly()){
        m_ServerButtonMenu->setItemChecked( 0, true );
        return;
    }

    if (TorkConfig::middleMan()){
        m_ServerButtonMenu->setItemChecked( 2, true );
        return;
    }
    
    m_ServerButtonMenu->setItemChecked( 1, true );

}

void
tork::switchMode()  //SLOT
{
    TorkConfig::setAdvancedMode(!TorkConfig::advancedMode());
    TorkConfig::writeConfig();


    if (TorkConfig::advancedMode()){
      m_ModeButton->unplug( toolBar("TorToolBar") );
      toolBar("TorToolBar")->setIconText( TDEToolBar::IconOnly, false );
      m_ModeButton->plug( toolBar("TorToolBar") );
      toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(2),true);
      toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(2));
      toolBar("MoreToolBar")->show();

    }else{
      m_ModeButton->unplug( toolBar("TorToolBar") );
      toolBar("TorToolBar")->setIconText( TDEToolBar::IconTextRight, false );
      m_ModeButton->plug( toolBar("TorToolBar") );
      toolBar("MoreToolBar")->hide();
    }
}

void
tork::configureServer( int id )  //SLOT
{
    kdDebug() << "configuring server" << endl;
    if ((TorkConfig::runFirstServerWizard()) && (id !=0 && id != 4)){
        ServerWizard wizard;
        wizard.setCaption( i18n( "Server Assistant" ));
        wizard.setServerType(id);
        connect( &wizard, SIGNAL(setUpServer(int)),this,
            SLOT(configureServer(int )) );

        wizard.exec();
        return;
    }
    /* We need to let upnp configuration through now, even if settings
       were not originally applied */
    m_CanApplyServerSettingsIfSet=true;
    
    if (id < 4){

        for (unsigned int index = 0; index != 4; ++index){
            m_ServerButtonMenu->setItemChecked( index, false ); //uncheck old item
        }
        m_ServerButtonMenu->setItemChecked( id, true );

    }

	switch(id)
	{
	case 0:
		TorkConfig::setClientOnly(true); 
        if (client != 0L)
            client->configureServer(upnpORPort(), upnpDirPort());
        break;
	case 1:
		TorkConfig::setClientOnly(false); 
        TorkConfig::setBridgeRelay(false); 
        TorkConfig::setMiddleMan(false); 
        if (client != 0L)
            client->configureServer(upnpORPort(), upnpDirPort()); 
        break;
	case 2:
		TorkConfig::setClientOnly(false); 
        TorkConfig::setMiddleMan(true); 
        TorkConfig::setBridgeRelay(false); 
        if (client != 0L)
            client->configureServer(upnpORPort(), upnpDirPort());
        break;
	case 3:
		TorkConfig::setClientOnly(false); 
        TorkConfig::setMiddleMan(true); 
        TorkConfig::setBridgeRelay(true); 
        if (client != 0L)
            client->configureServer(upnpORPort(), upnpDirPort());
        break;
    case 4:
        openConfig("My Tor Server");return;
    case 5:
        showMyHiddenServices();return;
	default:
		break;
	}


    if ((!TorkConfig::clientOnly()) && (TorkConfig::forwardPorts())){
        // Do we need to forward ports on the router?
        if (UPnPManager::Manager()->routersDiscovered())
            configureRouter(false);
    }

    m_ServerButtonMenu->setItemEnabled( 4, !TorkConfig::clientOnly() );
    TorkConfig::writeConfig();
}

void
tork::configureSecurity( int id )  //SLOT
{

    if (m_SecurityButtonMenu->isItemChecked( id))
        return;

    TQString cmd;
    TQString iconstring;
    TQString filterRequest;

    filterId = id;

	cmd = createFailSafeCommand(TorkConfig::filterRules(), false);
    cmd += createFailSafeCommand(TorkConfig::systemFilterRules(), false);

	switch(id)
	{
	case 0:
        iconstring = "tork_penguin";
        filterRequest = "Normal Mode";
        break;
	case 1:
		cmd += createFailSafeCommand(TorkConfig::filterRules(), true);
        iconstring = "agent";
        filterRequest = "DNS FailSafe";
        break;
	case 2:
		cmd += createFailSafeCommand(TorkConfig::filterRules(), true);
        cmd += createFailSafeCommand(TorkConfig::systemFilterRules(), true);
        iconstring = "gv";
        filterRequest = "System FailSafe";
        break;

    case 3:
        openConfig("FailSafe");return;
	default:
		return;
	}

    filterError = "";
    filterWasApplied = false;

    cmd += "echo run";

    filterproc = new KProcIO();
    filterproc->setUseShell(TRUE);
    TQString filterCommand= TQString("tdesu --noignorebutton --miniicon tork --caption '%1' -t -i %2 -d -c "
                                    "'%3'").arg(filterRequest).arg(iconstring).arg(cmd);
	connect( filterproc, SIGNAL(readReady(KProcIO * )),
		SLOT(processFilter(KProcIO * )) );
	connect( filterproc, SIGNAL(processExited(TDEProcess *)),
			SLOT(filterExited()) );

    *filterproc<<filterCommand;
    filterproc->start(KProcIO::NotifyOnExit,TRUE);

}

void tork::processFilter(KProcIO *filterproc)
{
	TQString item = "";
	int pos;

	while ((pos = (filterproc->readln(item,true))) != -1) {
        if (item.contains("No chain/target/match by that name"))
            continue;
        if (item == "run"){
            filterWasApplied = true;
            continue;
        }
        filterError += item;
	}
	filterproc->ackRead();

}

void tork::filterExited()
{

    if (!filterError.isEmpty()){
        processQuestion( "filterfailed", filterError );
        return;
    }

    if (!filterWasApplied)
        return;

    m_view->toggleParanoidMode(filterId);

    if (filterId < 3){

        for (unsigned int index = 0; index != 3; ++index){
            m_SecurityButtonMenu->setItemChecked( index, false ); //uncheck old item
        }
        m_SecurityButtonMenu->setItemChecked( filterId, true );

    }


	switch(filterId)
	{
	case 0:
        m_DNSTorified = false;
        if (client != 0L){
            client->enableDNS(false);
            client->enableTransPort(false);
        }
        m_SecurityButton->setIconSet(SmallIconSet("tork_penguin"));
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("You are now in <b>Normal Mode</b>. <br> Tor and TorK will operate normally."));
        break;
	case 1:
        m_DNSTorified = true;
        if (client != 0L){
            client->enableDNS(true);
            client->enableTransPort(true);
        }
        m_SecurityButton->setIconSet(SmallIconSet("tork_agent"));
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("You are now in <b>DNS FailSafe Mode</b>. <br> All DNS queries will be routed through Tor."));
        break;
	case 2:
        m_DNSTorified = true;
        if (client != 0L){
            client->enableDNS(true);
            client->enableTransPort(true);
        }
        m_SecurityButton->setIconSet(SmallIconSet("gv"));
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("You are now in <b>System FailSafe Mode</b>. <br> Tor will use new routes for every new connection as often as possible. <br> All secure traffic will be routed through Tor."));
        break;
    default:
        break;
    }

    delete filterproc;
    filterproc = 0L;
}

TQString tork::createFailSafeCommand( const TQStringList &filterRules, bool set )  //SLOT
{


    TQString cmd;
    TQStringList rules = filterRules;
	for ( TQStringList::Iterator it = rules.begin(); it != rules.end(); ++it )
	{
		if ((*it).isEmpty())
			continue;
        TQString active = (*it).section("%:%",0,0);

        if (active.contains("button_cancel") && (set))
            continue;

        TQString entry = (*it).section("%:%",2,2);
        if (set){
            cmd.append(TQString("%1;").arg(entry));
        }else{
            cmd.append(TQString("%1;").arg(entry.replace(" -I "," -D ")));
        }
    }

    return cmd;

}

void
tork::filterLog( int id )  //SLOT
{
    TQListViewItemIterator it(m_view->infoList);
    while ( it.current() ) {
        it.current()->setVisible(false);
        ++it;
    }

   m_LogFilterMenu->setItemChecked( id, !m_LogFilterMenu->isItemChecked(id) ); // Toggle selected item

   filterView(logType, m_view->infoList, m_LogFilterMenu, id, 1);
}

void
tork::filterCountries( int id )  //SLOT
{

    // If 'All' is already selected, return
    if (countryType[id] == "All"){
        if (m_CountryMenu->isItemChecked(251))
            return;
        m_CountryMenu->setItemChecked( 251, true); 
    }else
        m_CountryMenu->setItemChecked( 251, false); 


    // If 'All'is selected, display all entries; otherwise hide all entries
    TQListViewItemIterator it(m_view->serverList);
    while ( it.current() ) {
        it.current()->setVisible(m_CountryMenu->isItemChecked(251));
        ++it;
    }

    //Re-apply any text filter
    if ((m_view->serverFilter->isShown()) &&
       (!m_view->serverFilter->text().isEmpty()))
      m_view->serverFilter->updateSearch();


    // Display servers for each selected country 
	for ( TQMap<TQString, TDEPopupMenu*>::Iterator menu = continentMapList.begin(); 
          menu != continentMapList.end(); ++menu ){
       if (m_CountryMenu->isItemChecked(251)){ // If 'All' selected, deselect all items
           for (unsigned int index = 0; index != menu.data()->count(); ++index){
               menu.data()->setItemChecked( menu.data()->idAt(index), false ); 
           }
           continue;
       }
       menu.data()->setItemChecked( id, !menu.data()->isItemChecked(id) ); // Toggle selected item
       TQListView* tmp = dynamic_cast<TQListView*>(m_view->serverList);
       filterView(countryType, tmp, menu.data(), id, 4);
    }


    //If 'All' type-filter is selected, we are already displaying all servers, so return
    if ( m_ServerFilterMenu->isItemChecked( 0 )){
        return;
    }

    // Of servers displayed above, display only the ones with all selected criteria.
    TQListView* tmp = dynamic_cast<TQListView*>(m_view->serverList);
    filterViewServers(serverCondition, tmp, m_ServerFilterMenu, 99, 3);

}

void
tork::toggleIP( int id )  //SLOT
{

    TQListViewItemIterator it(m_view->serverList);
    if (m_ServerFilterMenu->text( id ).contains("IP")) {
        while ( it.current() ) {
           it.current()->setText(1,it.current()->text(5));
           ++it;
        }
        m_ServerFilterMenu->changeItem( id, "Show Name" );
     } else {
        while ( it.current() ) {
           it.current()->setText(1,getNickNameFromFPDigest(it.current()->text(2)));
           ++it;
        }
        m_ServerFilterMenu->changeItem( id, "Show IP" );
    }

}
void
tork::filterServers( int id )  //SLOT
{

    //If 'All' was clicked and is already selected, just return
    if (serverCondition[id] == "All" && m_ServerFilterMenu->isItemChecked(id))
        return;

    //Uncheck/Check Selected Item
    m_ServerFilterMenu->setItemChecked( id, !m_ServerFilterMenu->isItemChecked(id) );

    //If nothing is selected any longer, check 'All'
    bool somethingchecked = false;
    for (unsigned int index = 1; index != serverCondition.count(); ++index){
        if (m_ServerFilterMenu->isItemChecked( index))
            somethingchecked = true;
    }
    if (!somethingchecked){
        m_ServerFilterMenu->setItemChecked( 0, true );
        id = 0;
    }

    //Re-apply any text filter
    if ((m_view->serverFilter->isShown()) &&
       (!m_view->serverFilter->text().isEmpty()))
      m_view->serverFilter->updateSearch();


    //We always need to get all servers for selected countries again
    if  (m_CountryMenu->isItemChecked( 251 )){ // If 'All' countries are selected

        TQListViewItemIterator it(m_view->serverList);
        while ( it.current() ) {
            it.current()->setVisible(true);
            ++it;
        }

    }else{

        TQListViewItemIterator it(m_view->serverList);
        while ( it.current() ) {
            it.current()->setVisible(false);
            ++it;
        }

        for ( TQMap<TQString, 
              TDEPopupMenu*>::Iterator menu = continentMapList.begin(); 
              menu != continentMapList.end(); ++menu ){
            TQListView* tmp = dynamic_cast<TQListView*>(m_view->serverList);
            filterView(countryType, tmp, menu.data(), 255, 4);
        }
    }


    //If 'All' is selected, just ensure all items are unchecked and return
    if (serverCondition[id] == "All"){

        for (unsigned int index = 1; index != serverCondition.count(); ++index){
            m_ServerFilterMenu->setItemChecked( index, false ); //uncheck old item
        }
        m_ServerFilterMenu->setItemChecked( id, true );
        return;
    }


    //Uncheck 'All' to be sure
    m_ServerFilterMenu->setItemChecked( 0, false ); 

    // Of servers displayed above, display only the ones with all selected
    //criteria.
    TQListView* tmp = dynamic_cast<TQListView*>(m_view->serverList);
    filterViewServers(serverCondition, tmp, m_ServerFilterMenu, id, 3);
}



void
tork::filterView( TQValueVector<TQString> &possibleValues, TQListView* &view, 
                  TDEPopupMenu* &menu, int id, int column ){

    if (possibleValues[id] == "All"){
        TQListViewItemIterator it(view);
        while ( it.current() ) {    
            it.current()->setVisible(true);
            ++it;
        }

        for (unsigned int index = 1; index != possibleValues.count(); ++index){
            menu->setItemChecked( menu->idAt(index), false ); 
        }
        if (menu->findItem(id))
            menu->setItemChecked( id, true ); 
        return;
    }

    if (continentMapList.values().contains(menu))
        menu->setItemChecked( 251, false ); //Uncheck 'All' Item
    else
        menu->setItemChecked( 0, false ); //Uncheck 'All' Item

    TQString check;
    for (unsigned int index = 0; index != possibleValues.count(); ++index){
        if (menu->isItemChecked( menu->idAt(index) )){ 
            TQListViewItemIterator it(view);
            while ( it.current() ) {
                if (possibleValues == countryType)
                    check = GeoIP_country_code[it.current()->text(column).toInt()];
                else
                    check = it.current()->text(column);
                if (check.contains(possibleValues[menu->idAt(index)]))
                        it.current()->setVisible(true);
                ++it;
            }
        }
    }


}

void
tork::filterViewServers( TQValueVector<TQString> &possibleValues, 
                         TQListView* &view, TDEPopupMenu* &menu, int ,
                         int column) //SLOT
{


    for (unsigned int index = 0; index != possibleValues.count(); ++index){
        if (menu->isItemChecked( menu->idAt(index) )){ 
            TQListViewItemIterator it(view,TQListViewItemIterator::Visible);
            while ( it.current() ) {

                if (!it.current()->text(column)
                   .contains(possibleValues[index]))
                    it.current()->setVisible(false);
                else
                    it.current()->setVisible(true);
                ++it;
            }
        }
    }


}

void
tork::createSubnetList( )  //SLOT
{

    TQListViewItem *nextOne;
    TQListViewItem *tm;

    for (TQListViewItem *child = m_view->serverList->firstChild(); child; 
         child = nextOne) {
            nextOne = child->nextSibling();

            TQRegExp rx("^[0-9]{1,3}\\.[0-9]{1,3}\\.");
            rx.search(child->text(5));
            TQString tmp = rx.cap(0);
            if (tmp.isEmpty()){
                break;
            }

            if (!( tm = m_view->serverList->findItem((tmp),0))){
                tm = new TQListViewItem(m_view->serverList, tmp,
                         "a","a","a","a","a");
            }

            m_view->serverList->takeItem(child);
            tm->insertItem(child);
            child->moveItem(tm);
    }

}

void tork::fileNew()
{
    // this slot is called whenever the File->New menu is selected,
    // the New shortcut is pressed (usually CTRL+N) or the New toolbar
    // button is clicked

    // create a new window
    (new tork)->show();
}

void tork::optionsShowToolbar()
{
    // this is all very cut and paste code for showing/hiding the
    // toolbar
    if (m_toolbarAction->isChecked())
        toolBar()->show();
    else
        toolBar()->hide();

}

void tork::optionsShowStatusbar()
{
    // show/hide the statusbar
    if (m_statusbarAction->isChecked())
        statusBar()->show();
    else
        statusBar()->hide();
}

void tork::optionsConfigureKeys()
{
    KKeyDialog::configure(actionCollection());
}

void tork::optionsConfigureToolbars()
{
	// use the standard toolbar editor
    #if defined(TDE_MAKE_VERSION)
    # if TDE_VERSION >= TDE_MAKE_VERSION(3,1,0)
        saveMainWindowSettings(TDEGlobal::config(), autoSaveGroup());
    # else
        saveMainWindowSettings(TDEGlobal::config());
    # endif
    #else
        saveMainWindowSettings(TDEGlobal::config());
    #endif
    KEditToolbar dlg(factory());
    connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(newToolbarConfig()));
    dlg.exec();
}

void tork::newToolbarConfig()
{
    // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
    // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
	createGUI();

    #if defined(TDE_MAKE_VERSION)
    # if TDE_VERSION >= TDE_MAKE_VERSION(3,1,0)
        applyMainWindowSettings(TDEGlobal::config(), autoSaveGroup());
    # else
        applyMainWindowSettings(TDEGlobal::config());
    # endif
    #else
        applyMainWindowSettings(TDEGlobal::config());
    #endif

}

void tork::copyOldConfig()
{

    TorkConfig::writeConfig();
    TDEConfigSkeletonItem::List pitems(TorkConfig::self()->items());
    TDEConfigSkeletonItem::List::ConstIterator it;
    PrevConfig::PrevConfigList::iterator tp;
    
    for( it = pitems.begin(); it != pitems.end(); ++it ) {
        if (((TorkConfig::clientOnly()))  && ((*it)->group() == "MyServer"))
                continue;
        for( tp = prevlist.begin(); tp != prevlist.end(); ++tp ) {

            if ((*tp).name() == (*it)->name()){
                (*tp).setProperty((*it)->property());
                continue;
            }
        }
        if ( tp == prevlist.end())
            prevlist.append(PrevConfig((*it)->name(),(*it)->property()));
    }

    if (client != 0L)
        client->updatePrevConfig(prevlist);


}

void tork::optionsPreferences()
{
	// The preference dialog is derived from prefs-base.ui which is subclassed into Prefs
	//
	// compare the names of the widgets in the .ui file 
	// to the names of the variables in the .kcfg file

    copyOldConfig();


    TorkConfigDialog* dialog = (TorkConfigDialog*) TDEConfigDialog::exists( "settings" );
    
    if( !dialog )
    {

        //TDEConfigDialog didn't find an instance of this dialog, so lets create it :
        dialog = new TorkConfigDialog( this, "settings", TorkConfig::self() );

    }

    //FIXME it seems that if the dialog is on a different desktop it gets lost
    //      what do to? detect and move it?

    if (client != 0L)
        dialog->m_quickconfig->quickGroup->setEnabled(false);
    dialog->show();
    dialog->raise();
    dialog->setActiveWindow();

}

void tork::openConfig(const TQCString& page)
{
    copyOldConfig();

	// The preference dialog is derived from prefs-base.ui which is subclassed into Prefs
	//
	// compare the names of the widgets in the .ui file 
	// to the names of the variables in the .kcfg file
    TorkConfigDialog* dialog = (TorkConfigDialog*) TDEConfigDialog::exists( "settings" );

    if( !dialog )
    {
        //TDEConfigDialog didn't find an instance of this dialog, so lets create it :
        dialog = new TorkConfigDialog( this, "settings", TorkConfig::self() );
    }

    //FIXME it seems that if the dialog is on a different desktop it gets lost
    //      what do to? detect and move it?

    if (client != 0L)
        dialog->m_quickconfig->quickGroup->setEnabled(false);

    dialog->showPage(page);
    dialog->show();
    dialog->raise();
    dialog->setActiveWindow();


}

void tork::updateTrayIcon(const TQString& iconName)
{
    kdDebug() << "show icon " << iconName <<  endl;


    if (iconName.isEmpty())
      _tray->setPixmap(KSystemTray::loadIcon("tork_little"));
    else
      _tray->setPixmap(KSystemTray::loadIcon(iconName));

    if (TorkConfig::clientOnly())
        return;

    TQPixmap icon = KSystemTray::loadIcon( iconName );
    TQPixmap overlay = KSystemTray::loadIcon( "tork_server" );

    if ( !overlay.isNull() )
    {
      int x = icon.width() - overlay.width();
      int y = icon.height() - overlay.height();
      if ( icon.mask() )
      {
        TQBitmap mask = *icon.mask();
        bitBlt( &mask, x, y,
                overlay.mask() ? const_cast<TQBitmap *>(overlay.mask()) : &overlay,
                0, 0, overlay.width(), overlay.height(),
                overlay.mask() ? OrROP : SetROP );
        icon.setMask(mask);
      }
      bitBlt( &icon, x, y, &overlay );
    }

    _tray->setPixmap(icon);

}


void tork::updateTrayStats(const TQString& totin,const TQString& totout, const TQString& in,const TQString& out)
{
    if (client == 0L)
      return;
    TQStringList cli = client->currentClientReport();
    TQStringList server = client->currentServerReport();
    _tray->updateStats(totin, totout, in, out, server, cli, 
                       BytesPerSecToString(client->getCurBandwidthRate()));

    TQString tmp1 = i18n("Transferred up: %1 / down: %2")
            .arg(totout)
            .arg(totin);
    m_statusTransfer->setText(tmp1);
    updateServerClientStatusBar(cli,server);
}

void tork::updateServerClientStatusBar(const TQStringList &client, const TQStringList &server)
{
    static unsigned int iter = 0;
    unsigned int serverCount = server.count();

    if (iter > serverCount){
        iter = 0;
        TQString tmp1 = i18n("Client: %1")
            .arg(client[0]);
        m_statusInfo->setText(tmp1.replace("<font color='#990000'>","")
                              .replace("</font>",""));
    }else if (iter == serverCount){
        m_statusInfo->setText(i18n("%1 servers on network").arg(m_view->serverList->childCount()));
        iter++;
    }else{
        if (TorkConfig::clientOnly()){
            iter = serverCount;
            return;
        }
        m_statusInfo->setText(TQString("Server: %1").arg(server[iter])
                              .replace("<font color='#990000'>","")
                              .replace("</font>",""));
        iter++;
    }

}

void tork::changeStatusbar(const TQString& in,const TQString& out)
{

    if ((in == "zero") && (out =="zero")){
        TQString tmp1 = i18n("Transferred up: 0 B / down: 0 B");
        m_statusTransfer->setText(tmp1);

    }

}

void tork::sayWhatImDoing(const TQString& text)
{
    // display the text on the caption
    m_statusInfo->setText(text);
}

void tork::changeCaption(const TQString& text)
{
    // display the text on the caption
    setCaption(text);
}

void tork::startTor()
{

    m_ShutdownRequested = false;

    if (childproc !=0L)
        return;
    m_list.clear();

    if (TorkConfig::torLocation().isEmpty() || (!TQFile::exists(TorkConfig::torLocation()))){

        processWarning( "notorexecutable",i18n("You can't find me.") );
        return;
    }


    sayWhatImDoing("Starting Tor..");
    childproc = new KProcIO();
    childproc->setUseShell(TRUE);

    TQString torConfFile = writeConf();



    *childproc << TorkConfig::torLocation() << " -f " + torConfFile;

	connect( childproc, SIGNAL(processExited(TDEProcess *)),
			SLOT(childExited()) );
	connect( childproc, SIGNAL(readReady(KProcIO *)),
		SLOT(receivedOutput(KProcIO *)) );

	childproc->start(KProcIO::NotifyOnExit)    ;


}

void tork::stopTorGracefully()
{

    m_ShutdownRequested = true;

    if (TorkConfig::clientOnly()){
        stopTor();
        return;
    }

    if ((childproc !=0L) && (client != 0L)){
        client->terminateTor();
        processQuestion("terminatetor",
                        i18n("Give me 30 seconds to close connections."));
    }else
        stopTor();

}
void tork::stopTor()
{

    if (m_DNSTorified){
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("<b>You are now in FailSafe Mode</b>. <br> You need to be in Normal Mode before you can stop Tor."));
        return;
    }

    // start Tor
    stopController();
    stopNetStat();

    if (privoxyproc !=0L){
        privoxyproc->kill();
        delete privoxyproc;
        privoxyproc = 0L;
    }

    if (tfPrivoxy !=0L){
        delete tfPrivoxy;
        tfPrivoxy = 0L;
    }

    if (tfTor !=0L){
        delete tfTor;
        tfTor = 0L;
    }

    if (childproc !=0L){
        childproc->kill();
        delete childproc;
        childproc = 0L;
    }
    torkStart->setEnabled(true);
    m_LaunchMenuButton->setEnabled(false);
    m_IdentityButton->setEnabled(false);
    m_PseudoButton->setEnabled(false);
    m_ServerFilterButton->setEnabled(false);
    m_ServerButton->setEnabled(false);
    m_SecurityButton->setEnabled(false);

    //Reset Country filter menu to 'All' checked

	for ( TQMap<TQString, TDEPopupMenu*>::Iterator menu = continentMapList.begin(); menu != continentMapList.end(); ++menu ){
           for (unsigned int index = 0; index != menu.data()->count(); ++index){
               menu.data()->setItemChecked( menu.data()->idAt(index), false ); 
           }
    }
    m_CountryMenu->setItemChecked( 251, true );

    //Reset server filter menu to 'All' checked
    for (unsigned int index = 1; index != serverCondition.count(); ++index){
        m_ServerFilterMenu->setItemChecked( index, false ); //uncheck old item
    }
    m_ServerFilterMenu->setItemChecked( 0, true );

    //Reset Pseudonymity filter menu to 'All' checked

	for ( TQMap<TQString, TDEPopupMenu*>::Iterator menu = continentMap.begin(); menu != continentMap.end(); ++menu )
	{
        for (unsigned int index = 0; index != menu.data()->count(); ++index){
                menu.data()->setItemChecked( menu.data()->idAt(index),false);
        }
    }

    m_PseudoMenu->setItemChecked(999,true);

    torkStop->setEnabled(false);
    enableKonqi->setEnabled(false);
    browseHiddenServices->setEnabled(false);
    //timer->stop();
	_tray->setPixmap(KSystemTray::loadIcon("tork_pressplay"));
    changeStatusbar("zero","zero");
    turnOffTDE();
    m_view->m_osd->infoList->clear();
    m_view->m_osd->hide();
    sayWhatImDoing(i18n("To connect to Tor, press play."));

    m_view->toggleAnonymizerTork(false);

}

void tork::stopController()
{
    m_view->resetBWHistory();
    m_view->updateChart();

    disconnect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor()));
    disconnect( client, SIGNAL(torConnectionClosed()), this, SLOT(torClosedConnection()) );
    disconnect( client, SIGNAL(streamStatusUpdate(const TQString &, const TQString &,
        const TQString &, const TQString &, const TQString &)),
        m_view,SLOT(streamStatusUpdated(const TQString &, const TQString &,
        const TQString &, const TQString &, const TQString &)) );
    disconnect( client, SIGNAL(ORStatusUpdate(const TQString &, const TQString &)),
        m_view,SLOT(ORStatusUpdated(const TQString &, const TQString &)) );
    disconnect( client, SIGNAL(guardStatusUpdate(const TQString &, const TQString &)),
        m_view,SLOT(guardStatusUpdated(const TQString &, const TQString &)) );
    disconnect( client, SIGNAL(circuitStatusUpdate(const TQString &, const TQString &, 
                               const TQString &, const TQString &)),
        m_view,SLOT(circuitStatusUpdated(const TQString &, const TQString &, 
                               const TQString &, const TQString &)) );
    disconnect( client, SIGNAL(infoUpdate(const TQString &,const TQString &, const TQString &)),
        this,SLOT(infoUpdated(const TQString &,const TQString &, const TQString &)) );
    disconnect( client, SIGNAL(bwUpdate(const TQString &,const TQString &)),
        m_view,SLOT(bwUpdated(const TQString &,const TQString &)) );
    disconnect( client, SIGNAL(streamBwUpdate(const TQString &,const TQString &,const TQString &)),
        m_view,SLOT(streamBwUpdated(const TQString &,const TQString &,const TQString &)) );

    disconnect( client, SIGNAL(updateActiveServers(const TQStringList &)),
        m_view,SLOT(activeServersUpdated(const TQStringList &)) );
    disconnect( client, SIGNAL(updateServerStatus(const TQString &,const TQString &,
                               const TQString &,const TQString &)),
        m_view,SLOT(serverStatusUpdated(const TQString &,const TQString &,
                               const TQString &,const TQString &)) );

    disconnect( client, SIGNAL(setTorCaption(const TQString &)),
        this,SLOT(setTorCaption(const TQString &)) );


    disconnect(m_view->circuitList, SIGNAL(attach(const TQString &,const TQString &)),
            client, SLOT(attemptAttach(const TQString &,const TQString & )) );
    disconnect(m_view->circuitList, SIGNAL(extendCircuit(const TQString &, const TQString &, bool)),
            client, SLOT(attemptExtendCircuit(const TQString &, const TQString &, bool)) );
    disconnect(m_view->circuitList, SIGNAL(createCircuit(const TQString &, bool)),
            client, SLOT(attemptCreateCircuit(const TQString &, bool)) );


	disconnect( m_view->serverList, SIGNAL(mouseButtonPressed (int, TQListViewItem *,
              const TQPoint &, int)), this, SLOT(slotOnItem ( int, TQListViewItem *,
              const TQPoint &, int )));
	disconnect( m_view->ORList, SIGNAL(pressed ( TQListViewItem * )), this,
		SLOT(slotOnORItem ( TQListViewItem * )));


    disconnect(m_view->m_osd, SIGNAL(closeStream(const TQString &)),
            client, SLOT(attemptCloseStream(const TQString & )) );
    disconnect(m_view, SIGNAL(closeStream(const TQString &)),
            client, SLOT(attemptCloseStream(const TQString & )) );
    disconnect(m_view, SIGNAL(attachStreams(bool)),
            client, SLOT(attemptAttachStreams( bool )) );

    disconnect(m_view, SIGNAL(closeCircuit(const TQString &)),
            client, SLOT(attemptCloseCircuit(const TQString & )) );
    disconnect(m_view, SIGNAL(closeAllCircuits( TQListView* &)),
            client, SLOT(closeAllCircuits( TQListView* & )) );

    disconnect(client, SIGNAL(displayError(const TQString &, const TQString &)),
            m_view, SLOT(displayError(const TQString &,const TQString & )) );
    disconnect(client, SIGNAL(displayServer(const TQString &, const TQString &)),
            m_view, SLOT(displayServer(const TQString &,const TQString & )) );

    disconnect(client, SIGNAL(whatImDoing(const TQString &)),
            this, SLOT(sayWhatImDoing(const TQString & )) );
    disconnect(client, SIGNAL(copyOldConfig()),
            this, SLOT(copyOldConfig()) );

    disconnect(client, SIGNAL(shouldIApplySettings()),
            this, SLOT(shouldIApplySettings()) );

    disconnect(client, SIGNAL(makeTorkStoppable()),
            this, SLOT(makeTorkStoppable()) );

     disconnect(m_view->streamList, SIGNAL(attach(const TQString &,const TQString &)),
             client, SLOT(attemptAttach(const TQString &,const TQString & )) );

    disconnect(client, SIGNAL(warnNoServerInfo()),
            this, SLOT(warnNoServerInfo()) );

    disconnect(client, SIGNAL(needAlphaVersion()),
            this, SLOT(needAlphaVersion()) );

    disconnect(client, SIGNAL(connectedToTor()),
            client, SLOT(authenticate()) );

    disconnect(m_view, SIGNAL(updateExcludeNodes()),
            client, SLOT(updateExcludeNodes()) );
    disconnect(m_view, SIGNAL(updateEntryNodes()),
            client, SLOT(updateEntryNodes()) );
    disconnect(m_view, SIGNAL(updateExitNodes()),
            client, SLOT(updateExitNodes()) );
    disconnect(m_view, SIGNAL(clearNodes()),
            client, SLOT(clearNodes()) );
    disconnect(m_view, SIGNAL(updateStrictExitNodes(bool)),
            client, SLOT(strictExitNodes(bool)) );
    disconnect(m_view, SIGNAL(safeLogging(bool)),
            client, SLOT(safeLogging(bool)) );

    disconnect( m_view, SIGNAL(signalCheckTorNet()),
             client, SLOT( slotCheckTorNet() ) );
    disconnect( m_view, SIGNAL(signalCheckGuards()),
             client, SLOT( slotCheckGuards() ) );
    disconnect( m_view, SIGNAL(signalCheckBWSettings()),
            this, SLOT( checkBandwidthSettings() ) );

    disconnect(client, SIGNAL(processWarning(const TQString& , const TQString& )),
             this,   SLOT(processWarning(const TQString& , const TQString& )));
    disconnect(client, SIGNAL(processQuestion(const TQString& , const TQString& )),
             this,   SLOT(processQuestion(const TQString& , const TQString& )));

    disconnect(client, SIGNAL(updateTrayIcon(const TQString&)),
             this,   SLOT(updateTrayIcon(const TQString&)));

    disconnect( client, SIGNAL(showServerBW(const TQString&)),
            m_view, SLOT( showServerBW(const TQString&) ) );

    disconnect( m_view, SIGNAL(resolveAddress(const TQString&)),
            client, SLOT( resolveAddress(const TQString&) ) );

    disconnect( client, SIGNAL(resolvedAddress(const TQString&)),
            m_view, SLOT( resolvedAddress(const TQString&) ) );

    if (bwtimer != 0L){
        disconnect( bwtimer, SIGNAL( timeout() ), m_view, SLOT( reportBW() ) );
        delete bwtimer;
        bwtimer = 0L;
    }
    if (bwLimitTimer != 0L){
        disconnect( bwLimitTimer, SIGNAL( timeout() ), this, SLOT( checkBandwidthSettings() ) );
        delete bwLimitTimer;
        bwLimitTimer = 0L;
    }

    if (client != 0L){
        client->cleanUp();
        client->socketReadyRead();
        client->deleteLater();
        client = 0L;
    }
	_tray->setPixmap(KSystemTray::loadIcon("tork_pressplay"));

    m_view->circuitList->clear();
    m_view->ORList->clear();
    m_view->serverList->clear();
    m_view->streamList->clear();
    m_list.clear();
    m_view->clearStreamMaps();

    setCaption("");

    TorkConfig::setCurrentExcludeNodes("");
    TorkConfig::setCurrentEntryNodes("");
    TorkConfig::setCurrentExitNodes("");
    TorkConfig::writeConfig();

    m_CanApplyServerSettingsIfSet=false;

    _tray->updateStats(BytesPerSecToString(0),BytesPerSecToString(0),
                       BytesPerSecToString(0),BytesPerSecToString(0),
                       TQStringList("<font color='#990000'>Status Not Known</font>"), 
                       TQStringList("<font color='#990000'>Status Not Known</font>"),
                       BytesPerSecToString(0));
}


TQString tork::writeConf()
{
    if (tfTor != 0L)
        delete tfTor;

    tfTor = new KTempFile();
    tfTor->setAutoDelete(true);
    if ( tfTor->status() != 0 ) {
          tfTor->close();
          KMessageBox::information (this,"KMFilterActionWithCommand: Could not create temp file!");
          return TQString();
    }


	TQTextStream &ts = *(tfTor->textStream());
    
    switch (TorkConfig::quickConfigure()) {
            case 0 : //Tor client and server with default settings
                configureServer(1);
                ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
                ts << "ControlPort " << TorkConfig::controlPort() << "\n";
                ts << "NickName " << TorkConfig::nickName() << "\n";
                ts << "ORPort " << upnpORPort() << "\n";
                ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
                ts << "DirPort " << upnpDirPort() << "\n";
                ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
                ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
                break;
            case 1 : //Tor client and relay server with default settings
                configureServer(2);
                ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
                ts << "ControlPort " << TorkConfig::controlPort() << "\n";
                ts << "NickName " << TorkConfig::nickName() << "\n";
                ts << "ORPort " << upnpORPort() << "\n";
                ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
                ts << "DirPort " << upnpDirPort() << "\n";
                ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
                if (TorkConfig::middleMan()){
                    ts << "ExitPolicy reject *:*\n";
                }
                ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
                break;

            case 2 : //Tor server with default settings
                configureServer(1);
                ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
                ts << "ControlPort " << TorkConfig::controlPort() << "\n";
                ts << "NickName " << TorkConfig::nickName() << "\n";
                ts << "ORPort " << upnpORPort() << "\n";
                ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
                ts << "DirPort " << upnpDirPort() << "\n";
                ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
                ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
                break;

            case 3 : //Tor relay server with default settings
                configureServer(2);
                ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
                ts << "ControlPort " << TorkConfig::controlPort() << "\n";
                ts << "NickName " << TorkConfig::nickName() << "\n";
                ts << "ORPort " << upnpORPort() << "\n";
                ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
                ts << "DirPort " << upnpDirPort() << "\n";
                ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
                if (TorkConfig::middleMan()){
                    ts << "ExitPolicy reject *:*\n";
                }
                ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
                break;

            case 4 : //Tor client with default settings
                configureServer(0);
                ts << "ControlPort " << TorkConfig::controlPort() << "\n";
                ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
                break;


            case 5 : //Use custom settings
                ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
                ts << "NickName " << TorkConfig::nickName() << "\n";
                ts << "ControlPort " << TorkConfig::controlPort() << "\n";
                writeCustomOptions2(ts);
                break;
    }

    if (TorkConfig::useProxy()){
        if ((TorkConfig::httpProxyPort() > 0) && (!TorkConfig::httpProxyHost().isEmpty()))  
            ( ts << "HttpProxy " << TorkConfig::httpProxyHost() << ":" 
                                 << TorkConfig::httpProxyPort() << "\n") ;
        if ((TorkConfig::httpsProxyPort() > 0) && (!TorkConfig::httpsProxyHost().isEmpty()))  
            ( ts << "HttpsProxy " << TorkConfig::httpsProxyHost() << ":" 
                                  << TorkConfig::httpsProxyPort() << "\n") ;
    
        if ((!TorkConfig::httpProxyAuthenticatorUserName().isEmpty()) &&
            (!TorkConfig::httpProxyAuthenticatorPassword().isEmpty()))
            (ts << "HttpProxyAuthenticator " << TorkConfig::httpProxyAuthenticatorUserName() 
                << ":" << TorkConfig::httpProxyAuthenticatorPassword() << "\n");
    
        if ((!TorkConfig::httpsProxyAuthenticatorUserName().isEmpty()) &&
            (!TorkConfig::httpsProxyAuthenticatorPassword().isEmpty()))  
            (ts << "HttpsProxyAuthenticator " << TorkConfig::httpsProxyAuthenticatorUserName() 
                << ":" << TorkConfig::httpsProxyAuthenticatorPassword() << "\n");
    }

    tfTor->close();

    return tfTor->name();

}

void tork::writeCustomOptions2(TQTextStream &ts)
{

    //Add any new servers to excludeNodes that we want excluded by Country
    TQStringList existingServers = TorkConfig::serversHistory();
    TQStringList currentExcludeNodes = TorkConfig::excludeNodes();
	for ( TQStringList::Iterator it = existingServers.begin(); it != existingServers.end(); ++it )
	{
		if ((*it).isEmpty())
			continue;

        int cc = (*it).section("-",0,0).toInt();
        TQString nick = (*it).section("-",1);

        TQString fp = getFPFromFPDigest(nick);
        if (fp.isEmpty())
            continue;

        if ((!TorkConfig::excludeNodes().contains("$"+fp)) &&
            (TorkConfig::excludeCountries().contains(GeoIP_country_code[cc])))
            currentExcludeNodes.append("$"+fp);
    }
    if (!currentExcludeNodes.isEmpty()){
        TorkConfig::setExcludeNodes(currentExcludeNodes);
    }


    TDEConfigSkeletonItem::List items = TorkConfig::self()->items();
    TDEConfigSkeletonItem::List::ConstIterator it;
    for( it = items.begin(); it != items.end(); ++it ) {
        kdDebug() << (*it)->name()  << endl;
        if (elementShouldBeUsed((*it))){
            if (noSpecialProcessing((*it), ts)){
                if ( (*it)->property().type() == TQVariant::String ) {
                    if (!((*it)->property().toString()).isEmpty()){
                        ( ts << (*it)->name() << " " << (*it)->property().toString() << "\n");
                        kdDebug() << (*it)->name() << " " << (*it)->property().toString() << endl;
                    }
                }else if ( (*it)->property().type() == TQVariant::StringList ) {
                    if (!((*it)->property().toStringList()).isEmpty()){
                        ( ts << (*it)->name() << " " << (*it)->property().toStringList().join(",") 
                             << "\n");
                    }
                }else if ( (*it)->property().type() == TQVariant::Int ) {
                    if (((*it)->property().toInt()) > 0){
                        ( ts << (*it)->name() << " " << (*it)->property().toString() << "\n");
                        kdDebug() << (*it)->name() << " " << (*it)->property().toString() << endl;
                    }
                }else if ( (*it)->property().type() == TQVariant::Bool ) {
                    if (((*it)->property().toInt()) > 0){
                        ( ts << (*it)->name() << " " << (*it)->property().toInt() << "\n");
                        kdDebug() << (*it)->name() << " " << (*it)->property().toInt() << endl;
                    }
                }

            }
        }
        //if ( p.type() == TQVariant::Bool ) {
    }


    if ((!TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort()  > -1))
        ( ts << "SOCKSListenAddress " << TorkConfig::sOCKSBindAddressHost() << ":" << TorkConfig::sOCKSBindAddressPort() <<"\n") ;

    if ((TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort()  > -1))
        ( ts << "SOCKSPort " << TorkConfig::sOCKSBindAddressPort() <<"\n") ;

}

bool tork::elementShouldBeUsed(const TDEConfigSkeletonItem* it)
{


    if ((((!TorkConfig::defaultMaxMinOptions())) && ((*it).group() == "MaxMin")) ||
       (((!TorkConfig::defaultRunningNormalOptions())) && ((*it).group() == "RunningNormal")) ||
       ((!(TorkConfig::clientOnly())) && ((*it).group() == "DefaultServerAddress")) ||
       ((TorkConfig::fascistFirewall())  && ((*it).group() == "FirewallEvasion")) ||
       ((TorkConfig::useBridges())  && ((*it).group() == "Censorship")) ||
       (((*it).group() == "RunningSpecial")) ||
       (((*it).group() == "Servers")) ||
       ((!(TorkConfig::clientOnly()))  && ((*it).group() == "MyServer")) ||
       (((*it).group() == "Usability")) ||
       (((*it).group() == "UsingTor")) ||
       (((*it).group() == "MyHiddenServices")) ||
       ((!(TorkConfig::defaultServerPerformance())) && ((*it).group() == "ServerPerformance")))
            return true;


    return false;
}

bool tork::noSpecialProcessing(const TDEConfigSkeletonItem* it, TQTextStream &ts)
{

    if (((*it).name() == "DirListenAddress") ||
        ((*it).name() == "ORListenAddress")){
        ( ts << (*it).name() << "0.0.0.0:" <<
          (*it).property().toString() << "\n");
        return false;
    }

    if (((*it).name() == "BandwidthBurst") ||
        ((*it).name() == "BandwidthRate")){
        ( ts << (*it).name() << " " << (*it).property().toString() << "KB\n");
        return false;
    }

    if ((*it).name() == "MaxAdvertisedBandwidth"){
        ( ts << (*it).name() << " " << (*it).property().toString() << "KB\n");
        return false;
    }

    if ((*it).name() == "AccountingMax"){
        ( ts << (*it).name() << " " << ((*it).property().toInt() * 1024 * 1024) << "bytes\n");
        return false;
    }

    if ((*it).name() == "AccountingStart"){
       if ((*it).property().toString() == "day")
            ( ts << (*it).name() << " " << (*it).property().toString() << " 00:00\n");
       else
            ( ts << (*it).name() << " " << (*it).property().toString() << " 1 00:00\n");
       return false;
    }


    if ((*it).name() == "KeepalivePeriod"){
        if (!TorkConfig::reachableAddresses().isEmpty()){
            ( ts << (*it).name() << " " << ((*it).property().toInt() * 60) << "\n") ;
        }
        return false;
    }

    if ((*it).name() == "TrackHostExits"){
        if (!TorkConfig::trackHostExits().isEmpty()){
            ( ts << (*it).name() << " " << ((*it).property().toStringList().join(",")) << "\n") ;
            if (TorkConfig::trackHostExitsExpire() > 0)  
                ( ts << "TrackHostExitsExpire " << (TorkConfig::trackHostExitsExpire() * 60) << "\n") ;
        }
        return false;
    }


    if ((*it).name() == "SOCKSBindAddressMany"){

        if (!TorkConfig::sOCKSBindAddressMany().isEmpty()){
            TQStringList socksbind = TorkConfig::sOCKSBindAddressMany();
            for ( TQStringList::Iterator it = (socksbind).begin(); it != (socksbind).end(); it++ )
            {
                if ((*it).isEmpty())
                    continue;
                ts << "SOCKSListenAddress " << (*it) << "\n" ;
            }
        }
        return false;
    }

    if ((*it).name() == "HashedControlPassword"){
        if (!TorkConfig::hashedControlPassword().isEmpty()){
            TQString hash = hashPassword(TorkConfig::hashedControlPassword());
            if(!hash.isEmpty())
                ts << "HashedControlPassword 16:" << hash << "\n" ;
        }
        return false;
    }


    if ((*it).name() == "ExitPolicy"){
        if (TorkConfig::middleMan())
            ts << "ExitPolicy " << "reject *:*" << "\n" ;
        else
            ts << "ExitPolicy " << (*it).property().toStringList().join(",") << "\n" ;
        return false;
    }

    if ((*it).name() == "HiddenServices"){
        TQStringList hiddenServices = TorkConfig::hiddenServices();
        for ( TQStringList::Iterator it = (hiddenServices).begin(); it != (hiddenServices).end(); it++ )
        {
            if ((*it).isEmpty())
                continue;
            ts <<  "HiddenServiceDir " << (*it).section("\n",-1) << "\n" ;
            ts <<  "HiddenServicePort " << (*it).section("\n",-4,-4) << " " << (*it).section("\n",-3,-3) << "\n";
        }
        return false;
    }

    if ((*it).name() == "Bridge"){

        TQStringList bridges = TorkConfig::bridge();
        for ( TQStringList::Iterator it = (bridges).begin(); it != (bridges).end(); it++ )
        {
            if ((*it).isEmpty())
                continue;
            ts << "Bridge " << (*it) << "\n";
        }

        return false;
    }

   if ((*it).name() == "MyFamily"){

        TQStringList family = TorkConfig::myFamily();
        TQStringList allfamily;
        for ( TQStringList::Iterator it = (family).begin(); it != (family).end(); it++ )
        {
            if ((*it).isEmpty())
                continue;
            TQString node = "$"+getFPFromFPDigest((*it).section("-",1,1));
            allfamily.append(node) ;
        }
        ts << "MyFamily " << allfamily.join(",") << "\n";

        return false;
    }

    if ((*it).name() == "MapAddress"){
        TQStringList maps = TorkConfig::mapAddress();
        for ( TQStringList::Iterator it = (maps).begin();
              it != (maps).end(); it++ )
        {
            if ((*it).isEmpty())
                continue;
            TQString mapAddress = TQString("\"%2\"").arg((*it));
            ts << "MapAddress " << mapAddress << "\n";
        }
        return false;
    }

    return true;
}


TQString tork::doHashPassword()
{

 	hashproc = new KProcIO();
	hashproc->setUseShell(TRUE);
    m_hashedpassword = "";
	TQString hashCommand=TQString("tor --hash-password %1").arg(TorkConfig::hashedControlPassword());

	*hashproc<<hashCommand;

	connect( hashproc, SIGNAL(readReady(KProcIO * )),
		SLOT(processHashProc(KProcIO * )) );
	hashproc->start(KProcIO::NotifyOnExit,TRUE);

    while (hashproc->isRunning() && m_hashedpassword.isEmpty())
        kapp->processEvents();

    return m_hashedpassword;
}

void tork::processHashProc(KProcIO *hashproc)
{
	TQString item = "";
	int pos;

	while ((pos = (hashproc->readln(item,true))) != -1) {
		if (item.startsWith("16:"))
            m_hashedpassword = item;
	}
	hashproc->ackRead();

}





void tork::childExited()
{

    delete childproc;
    childproc = 0L;
    torkStart->setEnabled(true);
    m_LaunchMenuButton->setEnabled(false);
    m_IdentityButton->setEnabled(false);
    m_PseudoButton->setEnabled(false);
    m_ServerFilterButton->setEnabled(false);
    m_ServerButton->setEnabled(false);
    m_SecurityButton->setEnabled(false);

    torkStop->setEnabled(false);
    enableKonqi->setEnabled(false);
    browseHiddenServices->setEnabled(false);
    sayWhatImDoing(i18n("To connect to Tor, press play."));

    turnOffTDE();



}

void tork::privoxyExited()
{

    bool died = false;
    if ((privoxyproc->normalExit()) || (privoxyproc->signalled())) 
        died = true;

    if (privoxyproc != 0L){
        disconnect( privoxyproc, SIGNAL(processExited(TDEProcess *)),
 			this,SLOT(privoxyExited()) );
        delete privoxyproc;
        privoxyproc = 0L;
    }

    TQString question;
    if (stillStarting)
        question = "privoxycouldntstart";
    else
        question = "privoxydied";

    if (died)
        processQuestion( question, i18n("Nothing.") );


}

void tork::startEverything()
{

    if (client != 0L)
        return;

    m_showstopperAlreadyDisplayed = false;

    switch (TorkConfig::quickConfigure()) {
        case 0 : 
        case 1 : 
        case 2 : 
        case 3 : 
        case 4 :
        case 5 :
            /* This allows upnp/server configuration if we are starting a
               server */
            m_CanApplyServerSettingsIfSet=true;
            startNetStat();
            startPrivoxy();
            startTor();
            break;
        case 6 :
            startNetStat();
            startController();
            break;
        case 7 :
            startNetStat();
            startPrivoxy();
            startController();
            break;
        default:
            return;
    }
}

void tork::checkForSystemManagedPrivoxy()
{
    TQString host;
    int port;

    host = TorkConfig::konqHttpProxy();
    port = TorkConfig::konqHttpProxyPort();
    host = host.replace("http://","");

    if (privoxytest == 0L) {
      privoxytest = new TestPrivoxy();
      connect( privoxytest, SIGNAL(fatalError()),this, SLOT(cannotContactPrivoxy()));
      connect( privoxytest, SIGNAL(connectedToPrivacyProxy()),
              this, SLOT(privacyProxyPassed()) );
    }
    privoxytest->connectTo(host,port);

}

void tork::cannotContactPrivoxy()
{

    processQuestion("privoxynotrunning",i18n("Is your privacy proxy running?"));
    privoxytest->closeConnection();
}

void tork::privacyProxyPassed()
{

    privoxytest->closeConnection();
}

void tork::letTorKManagePrivoxy()
{
    TorkConfig::setSystemProxy(false);
    TorkConfig::setTorkProxy(true);
    TorkConfig::writeConfig();
    startPrivoxy();
}

void tork::startPrivoxy()
{

    stillStarting = true;
    TQTimer::singleShot( 20000, this, SLOT(startingPeriodOver()) );

    if (TorkConfig::systemProxy()) {
        checkForSystemManagedPrivoxy();
        return;
    }

    if (TorkConfig::privoxyLocation().isEmpty()){

        processWarning( "noprivoxyexecutable", i18n("You can't find Privoxy."));
        return;
    }

    if (privoxyproc != 0L){
        disconnect( privoxyproc, SIGNAL(processExited(TDEProcess *)),
 			this,SLOT(privoxyExited()) );
        delete privoxyproc;
        privoxyproc = 0L;
    }

    privoxyproc = new KProcIO();
    privoxyproc->setUseShell(TRUE);

	TQString curpath = (TQString) getenv("PATH");
	privoxyproc->setEnvironment("PATH",curpath +
                 ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin");

    TQString location = getenv("HOME");
    location += "/.tork";
    TQDir torkdir(location);
    if (!torkdir.exists() && !torkdir.mkdir(location))
        location = getenv("HOME");

    TQString privoxypid = TQString("%1/.tork/privoxypid").arg(location);
    TQString privoxyConfFile = writePrivoxyConf();
    *privoxyproc << TorkConfig::privoxyLocation() <<  " --user " << getenv("USER") 
                 << " --no-daemon --pidfile " << privoxypid << " " << privoxyConfFile;

 	connect( privoxyproc, SIGNAL(processExited(TDEProcess *)),
 			SLOT(privoxyExited()) );

	privoxyproc->start(KProcIO::NotifyOnExit)    ;


}


void tork::startingPeriodOver()
{
    stillStarting = false;
}

TQString tork::writePrivoxyConf()
{

    if (tfPrivoxy != 0L)
        delete tfPrivoxy;

    tfPrivoxy = new KTempFile();
    tfPrivoxy->setAutoDelete(true);
    if ( tfPrivoxy->status() != 0 ) {
          tfPrivoxy->close();
          KMessageBox::information (this,"KMFilterActionWithCommand: Could not create temp file!");
          return "";
    }


	TQTextStream &ts = *(tfPrivoxy->textStream());
    
    ts << "forward-socks4a / " << TorkConfig::sOCKSBindAddressHost() << ":" 
       << TorkConfig::sOCKSBindAddressPort() << " ." << "\n";
    ts << "confdir " << locate("data","tork/privoxy/") << "\n";
    ts << "logdir ." << "\n";
    ts << "listen-address " << TorkConfig::konqHttpProxy().replace("http://","") << ":" 
       << TorkConfig::konqHttpProxyPort() << "\n";
    ts << "debug   1    # URLs" << "\n";
    ts << "debug   4096 # Info" << "\n";
    ts << "debug   8192 # Errors - *we highly recommended enabling this*" << "\n";
    ts << "toggle 1" << "\n";
    ts << "buffer-limit 4069" << "\n";
    ts << "forward         192.168.*.*/     ." << "\n";
    ts << "forward            10.*.*.*/     ." << "\n";
    ts << "forward           127.*.*.*/     ." << "\n";

//  Following two config lines removed because of:
//  http://archives.seul.org/or/talk/Oct-2007/msg00291.html
//     ts << "enable-edit-actions 1" << "\n";
//     ts << "enable-remote-toggle 1" << "\n";

    tfPrivoxy->close();

    return tfPrivoxy->name();

}

void tork::startController()
{


    TQString host;
    int port;

    if (TorkConfig::quickConfigure() == 6){ 
        host = TorkConfig::remoteTorAddress();
        port = TorkConfig::remoteTorPort();
    }else if (TorkConfig::quickConfigure() == 7){
        host = "localhost"; 
        port = TorkConfig::remoteTorPort();
    }else{
        host = "localhost";
        port = TorkConfig::controlPort();
    }
    torCaption = TQString("%1:%2").arg(host).arg(port);
    client = new TorClient(host,port);
    setCaption(torCaption);

    connect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor()));
    connect( client, SIGNAL(torConnectionClosed()), SLOT(torClosedConnection()) );
    connect( client, SIGNAL(streamStatusUpdate(const TQString &, const TQString &,
        const TQString &, const TQString &, const TQString &)),
        m_view,SLOT(streamStatusUpdated(const TQString &, const TQString &,
        const TQString &, const TQString &, const TQString &)) );
    connect( client, SIGNAL(ORStatusUpdate(const TQString &, const TQString &)),
        m_view,SLOT(ORStatusUpdated(const TQString &, const TQString &)) );
    connect( client, SIGNAL(guardStatusUpdate(const TQString &, const TQString &)),
        m_view,SLOT(guardStatusUpdated(const TQString &, const TQString &)) );
    connect( client, SIGNAL(circuitStatusUpdate(const TQString &, const TQString &, 
                            const TQString &, const TQString &)),
        m_view,SLOT(circuitStatusUpdated(const TQString &, const TQString &, 
                            const TQString &, const TQString &)) );
    connect( client, SIGNAL(infoUpdate(const TQString &,const TQString &, const TQString &)),
        this,SLOT(infoUpdated(const TQString &,const TQString &, const TQString &)) );
    connect( client, SIGNAL(bwUpdate(const TQString &,const TQString &)),
        m_view,SLOT(bwUpdated(const TQString &,const TQString &)) );
    connect( client, SIGNAL(streamBwUpdate(const TQString &,const TQString &,const TQString &)),
        m_view,SLOT(streamBwUpdated(const TQString &,const TQString &,const TQString &)) );

    connect( client, SIGNAL(updateActiveServers(const TQStringList &)),
        m_view,SLOT(activeServersUpdated(const TQStringList &)) );
    connect( client, SIGNAL(updateServerStatus(const TQString &,const TQString &,
                           const TQString &,const TQString &)),
             m_view,SLOT(serverStatusUpdated(const TQString &,const TQString &,
                         const TQString &,const TQString &)) );

    connect( client, SIGNAL(setTorCaption(const TQString &)),
        this,SLOT(setTorCaption(const TQString &)) );


    connect(m_view->circuitList, SIGNAL(attach(const TQString &,const TQString &)),
            client, SLOT(attemptAttach(const TQString &,const TQString & )) );
    connect(m_view->circuitList, SIGNAL(extendCircuit(const TQString &, const TQString &, bool)),
            client, SLOT(attemptExtendCircuit(const TQString &, const TQString &, bool)) );
    connect(m_view->circuitList, SIGNAL(createCircuit(const TQString &, bool)),
            client, SLOT(attemptCreateCircuit(const TQString &, bool)) );

	connect( m_view->serverList, SIGNAL(mouseButtonPressed ( int, TQListViewItem * , 
                                        const TQPoint &, int )),
		    SLOT(slotOnItem ( int, TQListViewItem * , const TQPoint &, int )));
	connect( m_view->ORList, SIGNAL(pressed ( TQListViewItem * )),
		SLOT(slotOnORItem ( TQListViewItem * )));


    connect(m_view->m_osd, SIGNAL(closeStream(const TQString &)),
            client, SLOT(attemptCloseStream(const TQString & )) );
    connect(m_view, SIGNAL(closeStream(const TQString &)),
            client, SLOT(attemptCloseStream(const TQString & )) );
    connect(m_view, SIGNAL(attachStreams(bool)),
            client, SLOT(attemptAttachStreams( bool )) );

    connect(m_view, SIGNAL(closeCircuit(const TQString &)),
            client, SLOT(attemptCloseCircuit(const TQString & )) );
    connect(m_view, SIGNAL(closeAllCircuits( TQListView* &)),
            client, SLOT(closeAllCircuits( TQListView* & )) );

    connect(client, SIGNAL(displayError(const TQString &, const TQString &)),
            m_view, SLOT(displayError(const TQString &,const TQString & )) );
    connect(client, SIGNAL(displayServer(const TQString &, const TQString &)),
            m_view, SLOT(displayServer(const TQString &,const TQString & )) );

    connect(client, SIGNAL(whatImDoing(const TQString &)),
            this, SLOT(sayWhatImDoing(const TQString & )) );
    connect(client, SIGNAL(copyOldConfig()),
            this, SLOT(copyOldConfig()) );

    connect(client, SIGNAL(shouldIApplySettings()),
            this, SLOT(shouldIApplySettings()) );

    connect(client, SIGNAL(makeTorkStoppable()),
            this, SLOT(makeTorkStoppable()) );

     connect(m_view->streamList, SIGNAL(attach(const TQString &,const TQString &)),
             client, SLOT(attemptAttach(const TQString &,const TQString & )) );

    connect(client, SIGNAL(warnNoServerInfo()),
            this, SLOT(warnNoServerInfo()) );

    connect(client, SIGNAL(needAlphaVersion()),
            this, SLOT(needAlphaVersion()) );

    connect(client, SIGNAL(connectedToTor()),
            client, SLOT(authenticate()) );

    connect(m_view, SIGNAL(updateExcludeNodes()),
            client, SLOT(updateExcludeNodes()) );
    connect(m_view, SIGNAL(updateEntryNodes()),
            client, SLOT(updateEntryNodes()) );
    connect(m_view, SIGNAL(updateExitNodes()),
            client, SLOT(updateExitNodes()) );
    connect(m_view, SIGNAL(clearNodes()),
            client, SLOT(clearNodes()) );
    connect(m_view, SIGNAL(updateStrictExitNodes(bool)),
            client, SLOT(strictExitNodes(bool)) );
    connect(m_view, SIGNAL(safeLogging(bool)),
            client, SLOT(safeLogging(bool)) );

    connect( m_view, SIGNAL(signalCheckTorNet()),
             client, SLOT( slotCheckTorNet() ) );
    connect( m_view, SIGNAL(signalCheckGuards()),
             client, SLOT( slotCheckGuards() ) );
    connect( m_view, SIGNAL(signalCheckBWSettings()),
            this, SLOT( checkBandwidthSettings() ) );

    connect(client, SIGNAL(processWarning(const TQString& , const TQString& )),
             this,   SLOT(processWarning(const TQString& , const TQString& )));
    connect(client, SIGNAL(processQuestion(const TQString& , const TQString& )),
             this,   SLOT(processQuestion(const TQString& , const TQString& )));

    connect(client, SIGNAL(updateTrayIcon(const TQString&)),
             this,   SLOT(updateTrayIcon(const TQString&)));

    connect( client, SIGNAL(showServerBW(const TQString&)),
            m_view, SLOT( showServerBW(const TQString&) ) );

    connect( m_view, SIGNAL(resolveAddress(const TQString&)),
            client, SLOT( resolveAddress(const TQString&) ) );

    connect( client, SIGNAL(resolvedAddress(const TQString&)),
            m_view, SLOT( resolvedAddress(const TQString&) ) );

    TQTimer::singleShot( 10000, this, SLOT(isControllerWorking()) );

    torkStart->setEnabled(false);
    m_view->welcomeitem->setEnabled(false);
	_tray->setPixmap(KSystemTray::loadIcon("tork_green"));

    if( TorkConfig::alwaysAnonymizeTDE())
        enableTDE(true);
    else
        TorkConfig::setTDEUsesTor(false);

    TorkConfig::setCurrentExcludeNodes("");
    TorkConfig::setCurrentEntryNodes("");
    TorkConfig::setCurrentExitNodes("");
    TorkConfig::writeConfig();

    updateServerButton();

#ifndef EXTERNAL_GEOIP
    geoip_db = !locate("data", "tork/geoip/GeoIP.dat").isNull();
#else
    GeoIP * gi = 0;
    gi = GeoIP_new(GEOIP_STANDARD);
    if (gi)
        geoip_db = true;
    else
        geoip_db = false;
#endif

    client->setGeoIPAvailable(geoip_db);
    m_view->setGeoIPAvailable(geoip_db);

    if (!geoip_db)
         processWarning("geoipmissing",i18n("Your GeoIP installation is broken."));

}

void tork::makeTorkStoppable()
{

    torkStop->setEnabled(true);
    m_LaunchMenuButton->setEnabled(true);
    m_IdentityButton->setEnabled(true);
    m_PseudoButton->setEnabled(true);
    m_ServerFilterButton->setEnabled(true);
    toggleServerButton(TorkConfig::useBridges());
    m_SecurityButton->setEnabled(true);

    enableKonqi->setEnabled(true);
    browseHiddenServices->setEnabled(true);
    sayWhatImDoing("Ready for use.");
    m_view->toggleAnonymizerTork(true);

}

void tork::startFromBeginning()
{
    stopController();
    startTor();
}


void tork::receivedOutput(KProcIO *)
{
    int pos;
    TQString item2;

    if (!(childproc))
        return;


	while ((childproc) && ((pos = (childproc->readln(item2,true))) != -1)) {
            if ((pos = (item2.find("Opening Control listener on"))) != -1){
                TQTimer::singleShot( 200, this, SLOT(startController()) );
            }
            int i;
            for (i = 0; _tork_messages[i].logmessage; ++i) {
                message_t *msg = &_tork_messages[i];
                if (item2.contains(msg->logmessage)){
                    if ((*this.*(msg->pt2Member))()){
                        strncpy(msg->torsaid,item2,249);
                        showWarning(msg->state, msg->headline, item2, msg->body, msg->type, 
                                    msg->icon, msg->always, msg->showstopper);
                    }
                }

            }

            for (i = 0; _tork_questions[i].logquestion; ++i) {
                question_t *msg = &_tork_questions[i];
                if (item2.contains(msg->logquestion)){
                    if ((*this.*(msg->pt2Member2))()){
                        (*this.*msg->silentAction)();
                        strncpy(msg->torsaid,item2,249);
                        askQuestion(msg->state, msg->headline, msg->torsaid, msg->body,
                                    msg->question,msg->pt2Member, msg->type, msg->icon, 
                                    msg->persistent, msg->showstopper);
                    }
                }

            }

            item2 = "";


    }


}

void tork::infoUpdated(const TQString &type, const TQString &summary, const TQString &data)
{

            int i;
            for (i = 0; _tork_messages[i].logmessage; ++i) {
                message_t *msg = &_tork_messages[i];
                if (summary.contains(msg->logmessage)){
                    if ((*this.*(msg->pt2Member))()){
                        strncpy(msg->torsaid,summary,249);
                        showWarning(msg->state, msg->headline, summary, msg->body, 
                                    msg->type,msg->icon, msg->always, msg->showstopper);
                    }
                }

            }

            for (i = 0; _tork_questions[i].logquestion; ++i) {
                question_t *msg = &_tork_questions[i];
                if (summary.contains(msg->logquestion)){
                    if ((*this.*(msg->pt2Member2))()){
                        (*this.*msg->silentAction)();
                        strncpy(msg->torsaid,summary,249);
                        askQuestion(msg->state, msg->headline, msg->torsaid, msg->body,
                                    msg->question,msg->pt2Member, msg->type,msg->icon,
                                    msg->persistent, msg->showstopper);
                    }
                }

            }
            m_view->infoUpdated(type,summary,data);
            
            if (waitingForServers){
                if (summary.contains("now have enough directory information")){
                    waitingForServers = false;
                    //TQTimer::singleShot(20000, client, SLOT(slotCheckTorNet()) );
                    if (client != 0L)
                        client->slotCheckTorNet();
                }
            }
}

bool tork::showUsage()
{
    return TorkConfig::showUsageWarnings();
}

bool tork::showSecurityWarnings()
{
    return TorkConfig::showSecurityWarnings();
}

bool tork::showGuideQuestions()
{
    return TorkConfig::showGuideQuestions();
}

bool tork::showApplySettingsQuestions()
{
    return TorkConfig::showApplySettingsQuestions();
}

bool tork::showDNSLeaks()
{
    return TorkConfig::showDNSLeaks();
}

bool tork::contactInfoSet()
{
    if ((TorkConfig::showGuideQuestions()) && (TorkConfig::contactInfo().isEmpty()))
        return true;
    return false;
}

void tork::continueAsClient()
{

    TorkConfig::setQuickConfigure(1);
    startFromBeginning();

}

void tork::reconnectWithCookie()
{

    TorkConfig::setCookieAuthentication(1);
    startEverything();

}

void tork::copyCookie()
{

    KProcIO *catproc = new KProcIO();
    catproc->setUseShell(TRUE);
    TQString whichCommand= TQString(
                          "tdesu -c '"
                          "mkdir -p -m 600 %1/.tor;"
                          "cp -u /var/lib/tor/control_auth_cookie %2/.tor/control_auth_cookie;"
                          "cp -u /usr/local/var/lib/tor/control_auth_cookie %3/.tor/control_auth_cookie;"
                          "chown -R %4 %5/.tor/;"
                          "chown %6 %7/.tor/control_auth_cookie"
                          "'").arg(getenv("HOME")).arg(getenv("HOME")).arg(getenv("HOME"))
                          .arg(getenv("USER")).arg(getenv("HOME"))
                          .arg(getenv("USER")).arg(getenv("HOME"));

    *catproc<<whichCommand;
    catproc->start(KProcIO::NotifyOnExit,TRUE);

}

void tork::shouldIApplySettings()
{

    disconnect(client, SIGNAL(shouldIApplySettings()),
            this, SLOT(shouldIApplySettings()) );

    switch (TorkConfig::quickConfigure()) {
        case 0 : 
        case 1 : 
        case 2 : 
        case 3 : 
        case 4 : 
        case 5 :
            break;
        case 6 :
        case 7 :
            if (!TorkConfig::showApplySettingsQuestions()){
                applySettingsToRunningTor();
                return;
            }
            processQuestion( "applysettings", i18n("Nothing.") );
            break;
        default:
            break;
    }

    makeTorkStoppable();

}

void tork::applySettingsToRunningTor()
{
    m_CanApplyServerSettingsIfSet=true;
    kdDebug() << "applying settings" << endl;
    if (client != 0L){
        sayWhatImDoing("Applying settings to Tor..");
        client->applySettingsToRunningTor();
    }
    if (client != 0L){
        //We're setting the server config here. The server values aren't used if we're 'client only'.
        //It needs to be called so that the sys tray icon reflects our choice of server vs client.
      client->configureServer(upnpORPort(), upnpDirPort());
    }
    // Do we need to forward ports on the router?
    if (m_routerDiscovered)
        configureRouter(true,true);
}

void tork::updateTork()
{
    if (!updater)
      updater = new TorkUpdate(this);
    updater->checkForNewTorkDirectly();

}

void tork::updateTorStable()
{

    if (!updater)
      updater = new TorkUpdate(this);
    updater->checkForNewTorDirectly(false);

}

void tork::updateTorUnstable()
{
    if (!updater)
      updater = new TorkUpdate(this);
    updater->checkForNewTorDirectly(true);

}

void tork::updatePrivoxy()
{
    if (!updater)
      updater = new TorkUpdate(this);
    updater->checkForNewPrivoxyDirectly();

}

void tork::assignPortToRemove()
{
    if (client != 0L)
      client->assignPortToRemove();
}

void tork::allowPlainTextPorts()
{
    if (client != 0L)
      client->allowPlainTextPorts();
}

void tork::runWizard()
{

   if (!client){
        FirstRunWizard wizard;
        wizard.setCaption( i18n( "First-Run Wizard" ));
        wizard.exec();
        m_view->welcomeitem->score->setCurrentItem(TorkConfig::quickConfigure());
   }else{
       processWarning( "torrunning",i18n("You should only run the set-up wizard while TorK is not connected.") );
   }
}


void tork::turnOffTDE()
{
    setTDE(false);
}

void tork::toggleTorBar()
{
    TorkConfig::setShowTorBar(!TorkConfig::showTorBar());

    if (TorkConfig::showTorBar())
        m_view->frame4->show();
    else
        m_view->frame4->hide();
}

void tork::toggleTorMon()
{
    m_view->setShowTormon(!m_view->getShowTormon());
    bool tormon = m_view->getShowTormon();
    TorkConfig::setShowTorMon(tormon);
    if (tormon){
        if (m_view->streamList->childCount() == 0)
            m_view->m_osd->hide();
        else
            m_view->m_osd->show();
    }else{
        m_view->m_osd->hide();
    }

}

void tork::toggleTorMon2()
{
    toggleTorMon();
    toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(0));

}

void tork::mixminionHome()
{

       KURL url = "http://www.mixminion.net";
       kapp->invokeBrowser(url.url(), "0");
}

void tork::hiddenServices()
{

       KURL url = "tor://nnqtnsoohprzqcke.onion";
       kapp->invokeBrowser(url.url(), "0");
}

void tork::networkList()
{

       KURL url = "http://torstatus.blutmagie.de/";
       kapp->invokeBrowser(url.url(), "0");
}

void tork::toggleTDESetting()
{
    TorkConfig::setTDEUsesTor(!TorkConfig::tDEUsesTor());
    setTDE(TorkConfig::tDEUsesTor());

    if (TorkConfig::tDEUsesTor())
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("All <b>Konqueror</b> Sessions Are Now Safe for Anonymous Use. <br> <b>Amarok, Akregator, KTorrent should be treated with caution! </b><br> This is because they may have javascript/java/plugins/flash enabled."));
    else
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("<b>Konqueror</b> is Now Back to "
        "Non-Anonymous Use! <br> Close Konqueror completely and do not use it non-anonymously for a while. <br>"
        "This is because malicious websites could gain access to information from your anonymous "
        "session."));

}

void tork::enableTDE(bool enable)
{
    TorkConfig::setTDEUsesTor(enable);
    setTDE(TorkConfig::tDEUsesTor());

    if (TorkConfig::tDEUsesTor())
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("All <b>Konqueror</b> Sessions Are Now Safe for Anonymous Use. <br> <b>Amarok, Akregator, KTorrent should be treated with caution! </b><br> This is because they may have javascript/java/plugins/flash enabled."));
    else
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled", i18n("<b>Konqueror</b> is Now Back to "
       "Non-Anonymous Use! <br>Close Konqueror completely and do not use it non-anonymously for a while. <br>"
       "This is because malicious websites could gain access to information from your anonymous "
       "session."));

}

void tork::toggleTDESettingAndLaunchKonq()
{
    toggleTDESetting();

    if (TorkConfig::tDEUsesTor()){

        KRun::runCommand( "konqueror --caption \"Anonymous Browsing Session\" "
                          "http://healthcheck.anonymityanywhere.com/",
                          "konqueror", "konqueror" );


    }
}

void tork::enableTDEAndLaunchKonqWithUrl(const TQString &url)
{
    if (!TorkConfig::tDEUsesTor())
        toggleTDESetting();

    if (TorkConfig::tDEUsesTor()){

        KRun::runCommand( TQString("konqueror --caption \"Anonymous Browsing Session\" "
                          "%1").arg(url),
                          "konqueror", "konqueror" );
    }
}

bool tork::getTDESetting()
{
    return TorkConfig::tDEUsesTor();
}

void tork::setTDE(bool set)
{

  if (!m_view->konqitem)
      return;

  TDEConfig* config = new TDEConfig("tdeioslaverc", false, false);
  config->setGroup( "Proxy Settings" );
  if (set){
    config->writeEntry( "httpProxy", TQString("%1:%2")
                        .arg(TorkConfig::konqHttpProxy())
                        .arg(TorkConfig::konqHttpProxyPort()) );
    config->writeEntry( "httpsProxy", TQString("%1:%2")
                        .arg(TorkConfig::konqHttpsProxy())
                        .arg(TorkConfig::konqHttpsProxyPort()) );
    config->writeEntry( "ftpProxy", TQString("%1:%2")
                        .arg(TorkConfig::konqFtpProxy())
                        .arg(TorkConfig::konqFtpProxyPort()) );
    config->writeEntry( "ProxyType", "1" );
    config->sync();
    config = new TDEConfig("kcookiejarrc", false, false);
    config->setGroup( "Cookie Policy" );
    //TDEConfig doesn't return a bool, just a text representation of the bool
    TorkConfig::setOriginalCookies(config->readEntry( "Cookies" )
                                   == "true" ? true : false);
    config->writeEntry( "Cookies", !TorkConfig::disableCookies() );
    TorkConfig::writeConfig();
    config->sync();
    config = new TDEConfig("tdeio_httprc", false, false);
    TorkConfig::setOriginalUseCache(config->readEntry( "UseCache" )
                                    == "true" ? true : false);
    TorkConfig::setOriginalSendUserAgent(config->readEntry("SendUserAgent" )
                                         == "true" ? true : false);
    config->writeEntry( "UseCache", !TorkConfig::disableCaching() );
    config->writeEntry( "SendUserAgent",
                        !TorkConfig::disableBrowserIdentification() );
    TorkConfig::writeConfig();
    config->sync();
    config = new TDEConfig("konquerorrc", false, false);
    config->setGroup( "Java/JavaScript Settings" );
    TorkConfig::setOriginalEnableJavascript(config->readEntry( "EnableJavaScript" )
                                            == "true" ? true : false);
    TorkConfig::setOriginalEnableJava(config->readEntry( "EnableJava" )
                                      == "true" ? true : false);
    TorkConfig::setOriginalEnablePlugins(config->readEntry( "EnablePlugins" )
                                         == "true" ? true : false);
    TorkConfig::writeConfig();
    config->writeEntry( "EnableJavaScript",!TorkConfig::disableJava());
    config->writeEntry( "EnableJava", !TorkConfig::disableJava() );
    config->writeEntry( "EnablePlugins", !TorkConfig::disableJava() );
    config->sync();
  }else{
    config->writeEntry( "httpProxy", TorkConfig::originalHttpProxy() );
    config->writeEntry( "httpsProxy", TorkConfig::originalHttpsProxy() );
    config->writeEntry( "ftpProxy", TorkConfig::originalFtpProxy() );
    config->writeEntry( "ProxyType", TorkConfig::originalProxyType() );
    config->sync();

    config = new TDEConfig("kcookiejarrc", false, false);
    config->setGroup( "Cookie Policy" );
    config->writeEntry( "Cookies", TorkConfig::originalCookies() );
    config->sync();

    config = new TDEConfig("tdeio_httprc", false, false);
    config->writeEntry( "UseCache", TorkConfig::originalUseCache() );
    config->writeEntry( "SendUserAgent", TorkConfig::originalSendUserAgent() );
    config->sync();
    kdDebug() << "UseCache" << config->readEntry( "UseCache" )
              << endl;

    config = new TDEConfig("konquerorrc", false, false);
    config->setGroup( "Java/JavaScript Settings" );
    config->writeEntry( "EnableJavaScript", TorkConfig::originalEnableJavascript() );
    config->writeEntry( "EnableJava", TorkConfig::originalEnableJava() );
    config->writeEntry( "EnablePlugins", TorkConfig::originalEnablePlugins() );

  }
  config->sync();

  // Inform all running io-slaves about the changes...
  // if we cannot update, ioslaves inform the end user...
  if (!DCOPRef("*", "TDEIO::Scheduler").send("reparseSlaveConfiguration", TQString::null))
  {
    TQString caption = i18n("Update Failed");
    TQString message = i18n("You have to restart the running applications "
                        "for these changes to take effect.");
    KMessageBox::information (this, message, caption);
    return;
  }
  DCOPRef("konqueror*", "KonquerorIface").send("reparseConfiguration");


  if (set){
      enableKonqi->setIcon("tork_konqueroroff");
      m_view->m_osd->toggleTDE->setIconSet(SmallIconSet( "tork_konqueroroff"));
      m_view->konqitem->setIcon("tork_konqueror_stop");
      m_view->konqitem->icon->repaint();
      m_view->konqitem->setDescriptionText("<qt>"+
                       i18n("<b>Anonymous Browsing is now enabled.</b> "
                            "Click the icon to disable it.<br>"
                            "- You can toggle this setting at any time "
                            "using the konqueror icon in the toolbar or "
                            "the miniview.<br>"
                      )+"</qt>");



      if (TorkConfig::torkProxy()){
          m_view->configurePriv->setEnabled(true);
          m_view->configurePrivText->setEnabled(true);
      }

  }else{
      enableKonqi->setIcon("tork_konqueroron");
      m_view->m_osd->toggleTDE->setIconSet(SmallIconSet( "tork_konqueroron"));
      m_view->konqitem->setIcon("tork_konqueror_play");
      m_view->konqitem->setDescriptionText("<qt>"+
                       i18n("<b>Click the icon to launch an anonymous "
                            "browsing session. </b><br>"
                      )+"</qt>");
      m_view->konqitem->setPropertiesText("<qt>"+i18n(
                      "- Konqueror uses Privoxy in combination with Tor to "
                      "anonymize your browsing. <br>"
                      "- This will also make any other Konqueror sessions you "
                      "use anonymous. <br>"
                      "- It will <b>partially</b> anonymize applications "
                      "such as <b>KTorrent (tracker/search only)</b> and "
                      "<b>Amarok</b>. <br>"
                      "&nbsp;&nbsp;This is because they may still "
                      "have java/javascript enabled, which can compromise "
                      "anonymity. <br>"
                      "- You can toggle this setting at any time using "
                      "the Konqueror icon in the toolbar or the miniview.<br>"
                      )+"</qt>");



      if (TorkConfig::torkProxy()){
          m_view->configurePriv->setEnabled(false);
          m_view->configurePrivText->setEnabled(false);
      }

  }


}


void tork::checkForKonqWindow(WId id)
{

    if (KWin::WindowInfo(id,0,0).name().contains("Anonymous Browsing Session"))
        KWin::setIcons(id,SmallIcon("tork"),SmallIcon("tork"));

}

void tork::showWarning( display_status_t &msg, const TQString &headline,const TQString &torsaid,const TQString &thismeans, const TQString &type, const TQString &icon, bool always, bool showstopper)
{

    kdDebug() << "in showwarning" << endl;

    if (m_showstopperAlreadyDisplayed)
        return;

    if (m_list.contains(thismeans) && !always)
        return;

    if (m_toolTipShowing){
        msg = DISPLAY_QUEUED;
        return;
    }

    m_showstopperAlreadyDisplayed = showstopper;

    if (!headline.contains("You May Be Leaking DNS Requests!") &&
        !headline.contains("TorK has reset the bandwidth rates on Tor as per your instructions!"))
        m_body = thismeans;
    else
        m_body = "";

    m_toolTipShowing = true;
    m_msg = &msg;

    m_tooltip = new KDE::PopupMessage(statusBar(), m_statusInfo, 40000, type );
    TQString text = i18n( "<b>%1</b>").arg(headline);
    text += TQString( "<br>" ) + i18n( "<b>Message: </b> %1" ).arg(torsaid);
    text += TQString( "<br>" ) + i18n( "<b>This means: </b> %1" ).arg(thismeans);
    text += TQString( "<br>" );

        //connect(m_tooltip, SIGNAL(yesClicked()),this, SLOT(serverHelp()));

    connect(m_tooltip, SIGNAL(noClicked( )), SLOT(noClicked( )));
    connect(m_tooltip, SIGNAL(Closed( )), SLOT(popUpClosed( )));

    m_tooltip->showOkButton( true );
    m_tooltip->showCounter( true );
    m_tooltip->setMaskEffect( KDE::PopupMessage::Slide );
    m_tooltip->setText( text );

    //TQString icon = TQString("tork_%1").arg(type).replace(" ","_");
    m_tooltip->setImage( DesktopIcon( icon, 48 ) );

    m_tooltip->move( x(), y() + m_tooltip->height() );

    m_tooltip->display();

    if (!tdemain->isActiveWindow()){

        KPassivePopup *pop;
    
        TQPoint pnt;
        pop = new KPassivePopup( tdemain->_tray );
        pnt = tdemain->_tray->pos();
        pop->setTimeout(15000);
        pop->setView( i18n("%1").arg(headline),i18n("See TorK window for details.") );
        pop->show(TQPoint(pnt));
    }
   
 
}

void tork::askQuestion(display_status_t &msg, const TQString &headline,const TQString &torsaid,const TQString &body,const TQString &question,void (tork::*pt2Func)(), const TQString &type, const TQString &icon, bool persistent, bool showstopper)
{

    kdDebug() << "in askqeustion" << endl;

    if (m_showstopperAlreadyDisplayed)
        return;

    if (m_list.contains(body))
        return;

    if (m_toolTipShowing){
        msg = DISPLAY_QUEUED;
        return;
    }

    m_showstopperAlreadyDisplayed = showstopper;

    m_body = body;
    m_toolTipShowing = true;
    m_msg = &msg;
    m_persistent = persistent;

    m_pt2Func = pt2Func;
    m_tooltip = new KDE::PopupMessage(statusBar(), m_statusInfo, 40000, type );
    TQString text = i18n( "<b>%1</b>").arg(headline);
    text += TQString( "<br>" ) + i18n( "<b>Message: </b> %1" ).arg(torsaid);
    text += TQString( "<br>" ) + i18n( "<b>Reason: </b> %1" ).arg(body);
    text += TQString( "<br>" ) + i18n( "%1" ).arg(question);

    //damn. functions pointers can't be used in slots. i don't have the heart to unroll it atm.
    connect(m_tooltip, SIGNAL(yesClicked( )), SLOT(slotHandle( )));
    connect(m_tooltip, SIGNAL(noClicked( )), SLOT(noClicked( )));
    connect(m_tooltip, SIGNAL(Closed( )), SLOT(popUpClosed( )));


    m_tooltip->showBothButton( true );
    m_tooltip->showCounter( true );
    m_tooltip->setMaskEffect( KDE::PopupMessage::Slide );
    m_tooltip->setText( text );
    //TQString icon = TQString("tork_%1").arg(type).replace(" ","_").replace("'","");
    m_tooltip->setImage( DesktopIcon( icon, 48 ) );

    m_tooltip->move( x(), y() + m_tooltip->height() );

    m_tooltip->display();

    if (!tdemain->isActiveWindow()){

        KPassivePopup *pop;
    
        TQPoint pnt;
        pop = new KPassivePopup( tdemain->_tray );
        pnt = tdemain->_tray->pos();
        pop->setTimeout(15000);
        pop->setView( i18n("%1").arg(headline),i18n("%1 See TorK window for details.").arg(body) );
        pop->show(TQPoint(pnt));
    }
   
 
}


void tork::slotHandle()
{
    kdDebug() << "in slothandle" << endl;
    (*this.*m_pt2Func)();
    if (!m_body.isEmpty() && !m_persistent)
        m_list.append( m_body  );
    processQueue( );
}

void tork::noClicked()
{
    kdDebug() << "innoclicked" << endl;
    if (!m_body.isEmpty() && !m_persistent)
        m_list.append( m_body  );
    processQueue( );
}


void tork::popUpClosed()
{
    kdDebug() << "in popupclosed" << endl;
    processQueue();
}

void tork::processQueue()
{

    kdDebug() << "in processqueue" << endl;
    m_toolTipShowing = false;
    *m_msg = DISPLAY_NONE;

    int i;
    for (i = 0; _tork_questions[i].logquestion; ++i) {
         question_t *msg = &_tork_questions[i];
         if (msg->state == DISPLAY_QUEUED){
            (*this.*msg->silentAction)();
            askQuestion(msg->state, msg->headline, msg->torsaid, msg->body, 
                        msg->question,msg->pt2Member, msg->type,msg->icon, 
                        msg->persistent, msg->showstopper);
            return;
         }else
            strcpy(msg->torsaid,"");

     }

    for (i = 0; _tork_messages[i].logmessage; ++i) {
         message_t *msg = &_tork_messages[i];
         if (msg->state == DISPLAY_QUEUED){
            showWarning(msg->state, msg->headline, msg->torsaid, msg->body, 
                        msg->type, msg->icon,msg->always, msg->showstopper);
            return;
         }else
            strcpy(msg->torsaid,"");
     }


}


void tork::serverHelp()
{

       KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#Tor.2FTorK_say_my_server_isn.27t_reachable._What_do_I_do.3F";
       kapp->invokeBrowser(url.url(), "0");

}


void tork::readEavesdropping()
{

       KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#Is_Tor_more_secure_than_ordinary_internet_use.3F";
       kapp->invokeBrowser(url.url(), "0");

}

void tork::aboutTorify()
{

       KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#How_do_I_use_TorK_to_anonymize_applications.3F";
       kapp->invokeBrowser(url.url(), "0");

}

void tork::aboutTor()
{

        IntroWizard wizard;
        wizard.setCaption( i18n( "Introduction To TorK" ));
        wizard.exec();

}

void tork::configurePrivoxy()
{

       KURL url = "http://config.privoxy.org";
       kapp->invokeBrowser(url.url(), "0");

}

void tork::aboutParanoidMode()
{

       KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#What_is_.27Paranoid_Mode.27.3F";
       kapp->invokeBrowser(url.url(), "0");

}

void tork::enterContactInfo()
{

    openConfig("My Tor Server");

}

void tork::cannotContactTor()
{

    stopTor();

    processQuestion( "cannotcontacttor", i18n("Nothing. TorK tried to connect to Tor and failed.")  );


}

void tork::torClosedConnection()
{


    if (m_DNSTorified){
        KNotifyClient::event(tdemain->_tray->winId(),"TorDisabled",
                             i18n("<b>You are still in"
        " FailSafe Mode</b>. <br> If Tor is still running its capacity to route FailSafe traffic <br> will"
        " remain enabled. Enter your password to return <br> the rest of your system to Normal Mode."));
        configureSecurity(0);
        m_DNSTorified = false;
    }

    stopTor();

    if (!m_ShutdownRequested)
        processWarning( "torclosedconnection",
                        i18n("Did something happen to me?")  );

    return;


}

void tork::quickConfig()
{
    openConfig("Quick Configure");

}

void tork::fixAddressPort()
{
    TorkConfig::setQuickConfigure(7);
    TorkConfig::writeConfig();
    startEverything();

}

void tork::slotOnItem( int button, TQListViewItem * item, const TQPoint &, int)
{

    if ((item == NULL) || (button == 2))
        return;
    if (client != 0L)
        client->fetchServerInfo(item->text(2));
    m_prevItem = item;

}

void tork::slotOnORItem( TQListViewItem * item)
{

    if (item == NULL)
        return;
    if (client != 0L)
        client->fetchServerInfoByNick(item->text(1));
    m_prevItem = item;

}

void tork::slotOffItem( )
{

    m_view->hidePopup( );
}

void tork::isControllerWorking( )
{
    if (!client)
        return;

    if (!client->isControllerWorking()){

        processQuestion( "jdsklajdkslajdskla", i18n("TorK can't communicate with Tor on the controller port %1. Do you have something limiting/blocking traffic on that port?").arg(TorkConfig::controlPort()) );
        TQTimer::singleShot( 10000, this, SLOT(isControllerWorking()) );

    }

}

void tork::warnNoServerInfo( )
{
        processWarning( "we have none",i18n("I don't have a list of any servers yet!") );
        waitingForServers = true;

}

void tork::needAlphaVersion( )
{
        processQuestion( "needalpha",i18n("The feature it needs is available in 0.1.2.6 alpha and forward!") );
        waitingForServers = true;

}

void tork::showTip()
{
   KTipDialog::showTip(this,TQString::null,true);
}

void tork::showTipOnStart()
{
      KTipDialog::showTip(this);
}


void tork::startNetStat()
{

    // Don't log netstat traffic if the feature is disabled or we are running a relay
    if (!TorkConfig::logNonTorTraffic()
        || !TorkConfig::clientOnly())
        return;

    netstatproc = new KProcIO();
    netstatproc->setUseShell(TRUE);

    TQString netstatcmd = "netstat -ntucpe";
    if (!TorkConfig::netstatLocation().isEmpty())
        netstatcmd = TQString("%1 -ntucpe").arg(TorkConfig::netstatLocation());

    *netstatproc << netstatcmd;

	connect( netstatproc, SIGNAL(processExited(TDEProcess *)),
			SLOT(netStatExited()) );
	connect( netstatproc, SIGNAL(readReady(KProcIO *)),
		SLOT(receivedNetStatOutput(KProcIO *)) );

	netstatproc->start(KProcIO::NotifyOnExit)    ;

}

void tork::stopNetStat()
{
    
    if (netstatproc !=0L){
        netstatproc->kill();
        delete netstatproc;
        netstatproc = 0L;
    }

}

void tork::netStatExited()
{

    delete netstatproc;
    netstatproc = 0L;
}


void tork::receivedNetStatOutput(KProcIO *)
{
    int pos;
    TQString item2;

    // Don't print netstat output if we are running a relay
    if (!TorkConfig::clientOnly())
        return;

    if (!(netstatproc))
        return;


	while ((netstatproc) && ((pos = (netstatproc->readln(item2,true))) != -1)) {
            TQString foreignAddress = item2.mid(44,24);
            TQString state = item2.mid(68,11);
            TQString inode = item2.mid(90,11);
            TQString program = item2.mid(102,19).stripWhiteSpace();
            TQListViewItem* nonTorTrafficLine;

            uint tmpents = TorkConfig::nonTorTrafficMaxEntries();
            if (inodes.count() > tmpents){
                inodes.clear();
                m_view->NonTorTraffic->clear();

            }
            if (program.isEmpty())
                program = "unknown";

            if  (foreignAddress.contains("*:*"))
                continue;
            if  (foreignAddress.contains("127.0.0.1"))
                continue;
            if ((!item2.left(3).contains("tcp")) && (!item2.left(3).contains("udp")))
                continue;

            TQListViewItem* ba = inodes.find( inode );

            if (ba)
                continue;


            nonTorTrafficLine = new TQListViewItem(m_view->NonTorTraffic,TQDateTime::currentDateTime ().toString(TQt::ISODate).replace("T"," "), foreignAddress,program,inode);
            inodes.insert( inode, nonTorTrafficLine );
            TQString cleanedTarget = foreignAddress.section(":",0,0).stripWhiteSpace();
            TQString cleanedPort = foreignAddress.section(":",1,1).stripWhiteSpace();
            TQString iconPath = locate("cache", KMimeType::favIconForURL("http://"+cleanedTarget)+".png");

            if (!iconPath.isEmpty()){
                nonTorTrafficLine->setPixmap( 1, TQPixmap( iconPath ) );
            }else{
                int i;
                for (i = 0; _port_icon[i].port; ++i) {
                    portsandicons_t *pics = &_port_icon[i];
                    if (cleanedPort == pics->port){
                        nonTorTrafficLine->setPixmap( 1, SmallIcon(pics->icon) );
                    }
                }
            }

            if (program.endsWith("/tor"))
            continue;

            if ((foreignAddress.contains(":domain")) || (foreignAddress.contains(":53 "))){
                m_program = program;
                TQTimer::singleShot( 3000, this, SLOT(torUsedAfterDNSRequest()) );
            }

            item2 = "";

    }


}

void tork::torUsedAfterDNSRequest()
{

    if (TQTime::currentTime().secsTo(m_view->timeTorWasLastUsed()) > -6){
        processWarning("dnsrequestsdetected",i18n("Shortly before traffic to %1 passed through Tor, the program <b>%2</b> bypassed Tor to turn a domain name to an IP address. Traffic to <b>%3</b> may therefore not be fully anonymous.").arg(m_view->addrTorWasLastUsed()).arg(m_program).arg(m_view->addrTorWasLastUsed()));

    }


}

void tork::processWarning(const TQString& type, const TQString& text)
{

      int i;
      for (i = 0; _tork_messages[i].logmessage; ++i) {
          message_t *msg = &_tork_messages[i];
          if (TQString(msg->logmessage).contains(type)){
              if ((*this.*(msg->pt2Member))()){
                  strncpy(msg->torsaid,text,249);
                  showWarning(msg->state, msg->headline, msg->torsaid, 
                              msg->body, msg->type, msg->icon, msg->always, msg->showstopper);
                  m_view->infoUpdated("TorK",msg->headline,msg->body);
              }
          }
      }

}

void tork::processQuestion(const TQString& type, const TQString& text)
{

    TQString tmptext = text;
    tmptext.replace(",",", ");
    int i;
    for (i = 0; _tork_questions[i].logquestion; ++i) {
        question_t *msg = &_tork_questions[i];
        if ((*this.*(msg->pt2Member2))()){
           if (TQString(msg->logquestion).contains(type)){
                 (*this.*msg->silentAction)();
                 strncpy(msg->torsaid,tmptext,249);
                 askQuestion(msg->state, msg->headline, msg->torsaid, msg->body,
                             msg->question,msg->pt2Member, msg->type, msg->icon,
                             msg->persistent, msg->showstopper);
                 m_view->infoUpdated("TorK",msg->headline,msg->body);
            }
        }

    }

    
}

void tork::showSecurityNotice(const TQString& port)
{

    processQuestion("securitynotice",i18n("Traffic on port %1 is not "
                    "encrypted. <b> Passwords </b> transmitted on this "
                    "channel could be harvested by the owner of the exit "
                    "node.").arg(port));

}

void tork::showScreamingNotice(const TQString& port)
{

    if (TorkConfig::currentTorVersion().left(3) != "0.1")
      return;

    processQuestion("screamingnotice",i18n("Now that I have your attention: "
                    "Traffic on port %1 is not encrypted and usually involves "
                    "passwords. <b> Passwords </b> transmitted on this channel"
                    " could be harvested by the owner of the exit node.")
                    .arg(port));


}

void tork::showFirewallEvasion()
{
    openConfig("Firewall/Censor Evasion");
} 

void tork::showMyServer()
{
    openConfig("My Tor Server");
} 

void tork::showMyHiddenServices()
{

    if (!myHiddenDialog)
      myHiddenDialog = new MyHidden(this);

    myHiddenDialog->show();
    myHiddenDialog->raise();
    myHiddenDialog->setActiveWindow();

} 

void tork::showMyKonqueror()
{
    openConfig("Konqueror");
} 

void tork::useNewIdentity()
{

    if (recentNewIdentityRequest)
        return;

    if (client != 0L){
        recentNewIdentityRequest = true;
        TQTimer::singleShot( 20000, this, SLOT(allowNewIdentityRequests()) );

        client->newIdentity();

    }
} 

void tork::allowNewIdentityRequests()
{

    recentNewIdentityRequest = false;

}
void tork::createService(const TQString& dir, const TQString& port)
{

    if (client != 0L)
        client->createService(dir,port);

} 

void tork::toggleNonTorTraffic(bool state)
{
    if (state)
        startNetStat();
    else
        stopNetStat();
} 

void tork::toggleTorTraffic(bool )
{

} 

void tork::checkBandwidthSettings( )
{

    if (client == 0L)
        return;
    if (TorkConfig::bandwidthSlots().isEmpty() || !TorkConfig::useScheduledBandwidth())
        return;


    TQString newBW, newLdBW, nextBW;
    int largestCandidateSoFar = -86400, newCandidate = 0, bestCandidate = -86400;
    int nextScheduledCandidate =0, nextCandidate = 0;
    int BWDayAsInt = 0;
    int TodayAsInt = TQDate::currentDate().dayOfWeek();
    // Get current date/time
    TQDateTime currentDateTime = TQDateTime::currentDateTime();
    TQDate nextDate;
    TQTime nextTime;

    TQStringList bandwidthSlots = TorkConfig::bandwidthSlots();
	for ( TQStringList::Iterator it = bandwidthSlots.begin(); it != bandwidthSlots.end(); ++it )
	{
		if ((*it).isEmpty())
			continue;

        //Get the entry's day as an int between 1 and 7
        if ((*it).section("\n",-4,-4) == "Day")
            BWDayAsInt = TodayAsInt;
        else{
            for (int i=1; i<8;i++){
                if ((*it).section("\n",-4,-4) == TQDate::longDayName(i)){
                    BWDayAsInt = i;
                    break;
                }
            }
        }

        //Construct entry's date/time
        TQDateTime BWDateTime = TQDateTime::currentDateTime();
        BWDateTime.setTime(TQTime::fromString((*it).section("\n",-5,-5)));
        signed int daysFrom = BWDayAsInt - TodayAsInt;
        newCandidate = currentDateTime.secsTo(BWDateTime.addDays(daysFrom));

        // Find the next scheduled change of BW after this one, for reporting
        // to user if we change the BW now.

        if (newCandidate < 0){
            daysFrom = ((*it).section("\n",-4,-4) != "Day")?daysFrom+7:1;
            nextCandidate =  currentDateTime.secsTo(BWDateTime.addDays(daysFrom));
        }else{
            nextCandidate = newCandidate;
        }
        if ((nextScheduledCandidate == 0) || (nextCandidate < nextScheduledCandidate)){
            nextScheduledCandidate = nextCandidate;
            nextDate = BWDateTime.addDays(daysFrom).date();
            nextTime = BWDateTime.addDays(daysFrom).time();
        }

        //Remember the largest date/time combination because if there is no other
        // date/time combination in the past, then the largest is the most recent
        if (newCandidate > largestCandidateSoFar){
            largestCandidateSoFar = newCandidate;
            newLdBW = (*it);
        }

        //If the date/time combo is in the past and it is 'larger' than our current
        //candidate then we have a new candidate
        if ((newCandidate < 0) && (newCandidate > bestCandidate)){
            bestCandidate = newCandidate;
            newBW = (*it);
        }

    }

    if (newBW.isEmpty())
        newBW = newLdBW;

    if (newBW.isEmpty())
        return;

    unsigned long int cndBWRate = (newBW.section("\n",-3,-3).toInt() * 1024);
    unsigned long int cndBWBurst = (newBW.section("\n",-2,-2).toInt() * 1024);
    unsigned long int cndBWMax = (newBW.section("\n",-1).toInt() * 1024 );

    if ((cndBWRate != client->getCurBandwidthRate()) ||
       (cndBWBurst != client->getCurBandwidthBurst()) ||
       (cndBWMax != client->getCurMaxAdvertisedBandwidth())){
        client->setBandwidth(newBW.section("\n",-3,-3),newBW.section("\n",-2,-2),
                             newBW.section("\n",-1));
        TQTime bwtime = TQTime::fromString(nextBW.section("\n",-5,-5));
        processWarning( "bwreset",i18n("Tor bandwidth has been reset to: Max Incoming -"
                        " <b>%1 KB/s</b>."
                        " Max Burst - <b>%2 KB/s</b>. Max Advertised - <b>%3 KB/s</b>."
                        " Your next scheduled bandwidth change is on %4 at %5.")
                        .arg(newBW.section("\n",-3,-3)).arg(newBW.section("\n",-2,-2))
                        .arg(newBW.section("\n",-1)).arg(nextDate.toString("dddd MMMM d"))
                        .arg(nextTime.toString("h:mm ap")));
        client->getBandwidth();

    }
} 

void tork::setBandwidthFromSysTray(int rate )
{
    if (client == 0L)
        return;

    client->setBandwidth(TQString("%1").arg(rate),TQString("%1").arg(rate*2),
                             "");
    client->getBandwidth();

}

void tork::setTorCaption(const TQString& caption)
{
    setCaption(TQString("%1 using Tor %2").arg(torCaption).arg(caption));
    TorkConfig::setCurrentTorVersion(caption);
    TorkConfig::writeConfig();

    if (caption.left(3) == "0.1"){
      m_view->streamList->hideColumn(1);
      m_view->streamList->header()->setResizeEnabled(FALSE, 1);
      m_view->streamList->setResizeMode( TQListView::NoColumn );
      m_UnCensorButton->unplug( toolBar("TorToolBar") );
      m_SecurityButton->unplug( toolBar("MoreToolBar") );
      m_ServerButtonMenu->setItemEnabled( 3, false );
      emit processWarning("featuresdisabled",i18n("Nothing."));
    }
}

void tork::resetTor()
{
    KProcIO *catproc = new KProcIO();
    catproc->setUseShell(TRUE);
    TQString whichCommand= "tdesu -c 'killall -s HUP tor'";
    *catproc<<whichCommand;
    catproc->start(KProcIO::NotifyOnExit,TRUE);
	connect( catproc, SIGNAL(processExited(TDEProcess *)),
			SLOT(resetExited()) );

} 

void tork::resetExited()
{
    startEverything();
} 

void tork::upnpForwardingOK(kt::UPnPRouter* router,const TQString& string, bool fwd)
{
    kdDebug() << "UPNPforwardingok" << endl;
    TQString tmpports = TQStringList::split("<NewExternalPort>",string)[1];
    TQString extport = TQStringList::split("</NewExternalPort>",tmpports)[0];
    tmpports = TQStringList::split("<NewInternalPort>",string)[1];
    TQString intport = TQStringList::split("</NewInternalPort>",tmpports)[0];


//     if (!(router->forwardedPorts()->contains(net::ForwardPort(443,
//                                    TorkConfig::oRListenAddress(),
//                                    net::TCP,false))) ||
//        (!router->forwardedPorts()->contains(net::ForwardPort(80,
//                                    TorkConfig::dirListenAddress(),
//                                    net::TCP,false))))
//         return;

    if (client != 0L)
        client->configureServer(upnpORPort(), upnpDirPort()); 

    if (UPnPManager::Manager()->silentUpdate())
        return;

    if (fwd)
        processWarning("fwdok",i18n("Ports 80 and 443 on your router "
                                 "<b>%1</b> successfully forwarded to the ports " 
                                 "%2 and %3 used by your Tor server.")
                                 .arg(router->getDescription().friendlyName)
                                 .arg(TorkConfig::dirListenAddress())
                                 .arg(TorkConfig::oRListenAddress()));
    else
        processWarning("unfwok",i18n("Ports 80 and 443 on "
                                 "<b>%1</b> have been successfully unmapped "
                                 "from the ports "
                                 "%2 and %3 used by your Tor server.")
                                 .arg(router->getDescription().friendlyName)
                                 .arg(TorkConfig::dirListenAddress())
                                 .arg(TorkConfig::oRListenAddress()));


}


void tork::upnpForwardingError(kt::UPnPRouter* router,const TQString& string, bool fwd)
{

    TQString tmpports = TQStringList::split("<NewExternalPort>",string)[1];
    TQString extport = TQStringList::split("</NewExternalPort>",tmpports)[0];
    tmpports = TQStringList::split("<NewInternalPort>",string)[1];
    TQString intport = TQStringList::split("</NewInternalPort>",tmpports)[0];

    //Reset the ORPort or DirPort to the non-forwarded value
    if (extport == "80")
      setUpnpDirPort(TorkConfig::dirListenAddress());
    else
      setUpnpORPort(TorkConfig::oRListenAddress());

    if (client != 0L)
        client->configureServer(upnpORPort(), upnpDirPort()); 

    if (UPnPManager::Manager()->silentUpdate())
        return;

    if (fwd)
        processWarning("fwderror",i18n("There was a problem forwarding port %1 "
                                    " on your router <b>%1</b> to port %3 on Tor.")
                               .arg(extport).arg(router->getServer()).arg(intport));
    else
        processWarning("unfwerror",i18n("There was a problem un-forwarding port %1 "
                                    " on your router <b>%1</b> to port %3 on Tor.")
                               .arg(extport).arg(router->getServer()).arg(intport));

}

void tork::routerDiscovered(kt::UPnPRouter* r)
{
    kdDebug() << r->getServer() << endl;
    kdDebug() << "routerdiscovered" << endl;
    discoveredRouters.append(r->getDescription().friendlyName);
    m_routerDiscovered = true;

    configureRouter(false);
}

void tork::configureRouter(bool force, bool silent)
{

    if (!m_CanApplyServerSettingsIfSet)
        return;
    if (TorkConfig::clientOnly())
        return;

    kdDebug() << "configuring router" << endl;
    kdDebug() << TorkConfig::forwardPorts() << endl;

    forwardPortList = new ForwardPortList();

    if (TorkConfig::forwardPorts()){
      setUpnpORPort(443);
      setUpnpDirPort(80);
    }else{
      setUpnpORPort(TorkConfig::oRListenAddress());
      setUpnpORPort(TorkConfig::dirListenAddress());
    }


    forwardPortList->addNewForwardPort(443,
                       TorkConfig::oRListenAddress(),net::TCP,false);
    forwardPortList->addNewForwardPort(80,
                       TorkConfig::dirListenAddress(),net::TCP,false);

    if (TorkConfig::forwardPorts())
      UPnPManager::Manager()->forward(*forwardPortList, force, silent);
    else
      UPnPManager::Manager()->undoForward(*forwardPortList,silent);

}

void tork::checkRouterDiscovered()
{

    if (!m_routerDiscovered)
        processWarning("cantfindrouter",i18n("TorK can't contact your router to optimize "
                                    " it's configuration for Tor."));

}

void tork::dummyAction()
{

}

void tork::retryUPnP()
{
  //Force UPnP forwarding, even if we think it's already forwarded.
  //Do not inform user of the result.
  configureRouter(true,true);
}

#include "tork.moc"