/*
 * Copyright (C) 2004 Judd Baileys <jbaileys@bigpond.net.au>
 */
#define OPTIONSPATH "/etc/ppp/kdsl/conf."
#define PPPOEOPTIONS "/etc/ppp/kdsl/options."
#define LOGFILE "/etc/ppp/kdsl/kdsl.log"
#define PPPSETTINGSDIR "/etc/ppp/kdsl/"
#define PPPSETTINGSDIRII "/etc/ppp/kdsl/Accounts/"
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

#include "main.h"
#include "kdsl.h"
#include "configuration.h"
#include "prefdialog.h"
#include "pppstats.h"
#include "prefgeneral.h"
#include "prefgenerallayout.h"
#include "docking.h"
#include "connections.h"
#include "requester.h"
#include "auth.h"
#include "docbrowser.h"
#include "startwin.h"

// QT Includes
#include <qvariant.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qframe.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qimage.h>
#include <qpixmap.h>
#include <qstring.h>
#include <qdir.h>
#include <qevent.h>
#include <kpassdlg.h>
#include <qtextstream.h>
#include <qregexp.h>
#include <qtextview.h>
#include <qtimer.h>
#include <qimage.h>
#include <qptrlist.h>

// KDE Includes
#include <kmainwindow.h>
#include <klocale.h>
#include <kcombobox.h>
#include <klineedit.h>
#include <kpushbutton.h>
#include <kconfig.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include <kwin.h>
#include <kdialogbase.h>
#include <kprocess.h>
#include <kiconloader.h>
#include "notify.h"
#include <kmessagebox.h>
#include <krun.h>
#include <kaudioplayer.h>
//  #include <kdesu/su.h>
#include <kstdaction.h>
#include <kaboutdata.h>
#include <qptrlist.h>

 extern PPPStats* stats;
 extern DockWidget* dock_widget;
 extern Notify* notify_widget;
 extern Startwin* startwin;
 extern kdsl* m_kdsl;
 extern KdslStats *kdsl_stats;
// extern StartProcess* lister;
//   static QPtrList<Accounts> *accounts =0;
 //pid_t pid = 0;
kdsl::kdsl(QWidget *parent, const char *name)
      : QWidget(parent, name),m_prefDialog(0),
     minutes(0),
    seconds(0),
    hours(0),
    days(0) //,
//    tl1(0)
{
	if(gpppdata.defaultAccount().isEmpty()) {
		gpppdata.setThemename("kdsl");	
		gpppdata.setStoreClock(TRUE);
		gpppdata.setStoreConnect(FALSE);
		gpppdata.setStoreAutostart(FALSE);
		gpppdata.setStoreEnableNotify(FALSE);
		gpppdata.setStoreEnableSound(FALSE);
		gpppdata.setStoreHideIP(TRUE);
		gpppdata.save();

	}
	
    if(gpppdata.themecount() < 1) {
        gpppdata.setDefaultTheme("kdsl");
 	gpppdata.setThemename("kdsl");
	gpppdata.save();   
    
//    KMessageBox::error(this, i18n("NO Theme Installed"));
    }	
	
     if(gpppdata.defaultTheme().isEmpty()) {
 //       m_prefTheme->currentThemeTextLabel->setText("kdsl");
	gpppdata.setThemename("kdsl");
	gpppdata.save();
     }
		

 	QDir d( PPPSETTINGSDIR );                        // Setting up Configuration Directories
         if ( !d.exists() ) {
	 if(getuid()!=0){  
	 KMessageBox::error(this, i18n("<qt><center><b><h2>Accounts not setup!</h2></b>Kdsl needs to be initially executed in<br>root mode so accounts can be set up.<br><br>Kdsl will now exit.</center></qt>"));
	 exit(0);
	 }  
        qWarning( "/etc/ppp/kdsl/ does not exist.  Creating now" );
	d.mkdir ( "/etc/ppp/kdsl/",  TRUE ) ;
	}
 	QDir d2( PPPSETTINGSDIRII );                     // Setting up Configuration Directories	 
         if ( !d2.exists() ) {
        qWarning( "/etc/ppp/kdsl/Accounts does not exist.  Creating now" );	               
	d2.mkdir ( "/etc/ppp/kdsl/Accounts", TRUE );
	}
	
 installEventFilter(this);
//	online = false;
//	docking = true;
	stats = new PPPStats;
    // set the shell's ui resource file
//    setXMLFile("kdslui.rc");
    StartwinLayoutMain = new QGridLayout( this, 1, 1, 11, 6, "StartwinLayoutMain");
    startwin = new Startwin(this, "Startwin");
     StartwinLayoutMain->addWidget(startwin,0,0,0);
//         StartwinLayoutMain->setResizeMode( QLayout::FreeResize );
      resize( QSize(449, 234).expandedTo(minimumSizeHint()) );    
//     resize(StartwinLayoutMain->sizeHint().expandedTo(minimumSizeHint()));
     clearWState( WState_Polished );
        
    m_device="eth0";
    dock_widget = new DockWidget(this, "dockw", stats);

     edit = new QTextEdit;
     edit->setMinimumSize( QSize( 300, 300 ) );
     edit->setReadOnly(true);
     
   logWindow = new QTextView();
   logWindow->resize( 300, 300);
   logWindow->setCaption("Kdsl Log Window");

 // kdsl_stats = new kdslStats(this, "statsw", stats);
   
       kapp->processEvents();

    connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );
    connect( startwin->passwordLineEdit, SIGNAL(textChanged(const QString&) ), this, SLOT( passwordChanged() )  );
    connect( startwin->setupButton, SIGNAL( clicked() ), this, SLOT( expandbutton() ) );
    connect( startwin->passwordLineEdit, SIGNAL(returnPressed() ), this, SLOT( checkStatus() ) );
    connect( startwin->connectionComboBox, SIGNAL( activated(int) ), this, SLOT( newdefaultaccount(int) ) );
//    if(gpppdata.storeScheduler()==0)
    connect(kapp, SIGNAL(shutDown()), this, SLOT(shutDown()));
//    else
    connect(stats, SIGNAL( resetStatus() ), this, SLOT(getStats()));
    connect(stats, SIGNAL( interfaceUp() ), this, SLOT(interfaceUp()));
    connect(stats, SIGNAL( interfaceDown() ), this, SLOT(interfaceDown()));
    connect(stats, SIGNAL( lostConnection() ), this, SLOT(lostConnection()));
    connect(stats, SIGNAL( ipUp() ), this, SLOT(ipUp()));
    connect(dock_widget,SIGNAL( iconDisconnect() ), this, SLOT (iconDisconnect()));
    connect(dock_widget, SIGNAL(setWidgets() ), this, SLOT (setWidgets()));
    connect(dock_widget,SIGNAL( iconConnect() ), this, SLOT (iconConnect()));    
    connect(startwin->logWindowCheckBox, SIGNAL(toggled(bool) ), edit, SLOT( setShown(bool) ) );
    connect(dock_widget, SIGNAL( configSetup() ), this, SLOT (expandbutton() ) );

   kapp->processEvents();

  clocktimer = new QTimer(this);
  connect(clocktimer, SIGNAL(timeout()), SLOT(timeclick())); 
  
  timeout_timer = new QTimer(this);
  connect(timeout_timer, SIGNAL(timeout()), SLOT(script_timed_out()));
  
  inittimer = new QTimer(this);
  connect(inittimer, SIGNAL(timeout()), SLOT(init()));  
  
  if_timeout_timer = new QTimer(this);
  connect(if_timeout_timer, SIGNAL(timeout()), SLOT(if_waiting_timed_out()));

  connect(this,SIGNAL(if_waiting_signal()),this,SLOT(if_waiting_slot()));
  
   if_timer = new QTimer(this);
  connect(if_timer,SIGNAL(timeout()), SLOT(if_waiting_slot()));

    resetaccounts();

   if(gpppdata.access() != KConfig::ReadWrite){
   startwin->setupButton->setEnabled(false); }
      else
   startwin->setupButton->setEnabled(TRUE);
   resetaccounts();
   startwin->logWindowCheckBox->setEnabled(FALSE);
   

  
this->show();
dock_widget->show(); 
//kapp->setTopWidget(dock_widget);
//kapp->setMainWidget(dock_widget);
dock_widget->disFromProv->setEnabled(FALSE);
startwin->logWindowCheckBox->hide();

//  Here we check to see if the root user has added any more accounts to the system, and we install them here into the user's account.  
//  The method used is traversing the directory contained in /etc/ppp/kdsl/Accounts/ and looking for the filenames there.  Any filenames 
//  that are not unique to the configuration files are opened and the information saved into the configuration file.  

if(getuid()!=0) {  // Checking to make sure we're not running as root 
	QDir dir( "/etc/ppp/kdsl/Accounts/");
	dir.setFilter( QDir::Files );
	const QFileInfoList* fileinfolist = dir.entryInfoList();
	QFileInfoListIterator it( *fileinfolist );
	QFileInfo* fi;
	while( ( fi = it.current() ) ){
	if( fi->fileName() == "." || fi->fileName() == ".." ) {
		++it;
		continue;
//        if( fi->fileName() == gpppdata.defaultAccount()) {
//		++it;
//		continue;
//	}
	}
	QString name=fi->fileName();  // This really isnt necessary but we're using it anyway, just in case.  We could call fi->fileName instead of name below
	QString icon;
	
	if( gpppdata.isUniqueAccname(name) )  // Here we check to make sure that the name of the account is a new account.
	  if(gpppdata.defaultAccount()!=name) { // We also check that the name in the directoy is not identical to the current account.
	  QString path="/etc/ppp/kdsl/Accounts/"+name;
// We read the file to get the icon to use for the display. 
	   QFile file( path );
  	  if ( file.open( IO_ReadOnly ) ) {
	 QStringList lines;
        QTextStream stream( &file );
        QString line;
	while ( !stream.atEnd() ) {
            line = stream.readLine(); // line of text excluding '\n'
	    icon=line.data();
//	    KMessageBox::information(this, i18n("%1").arg(line.data()));
 //           printf( "%3d: %s\n", i++, line.latin1() );
            lines += line;
        }
        file.close();
    }
	    gpppdata.newaccount();   // Setting Kdsl to install a newshutDown2 account
	    gpppdata.setAccname(name) ; // Setting the Account Name
	    gpppdata.setAccountIconName(icon); //Setting the Icon Name;
	    gpppdata.save(); //Saving our information to the configuration file
	    resetaccounts(); // Resetting the accounts so they display in the combobox.
 //   searchstring = '"' + m_prefGeneral->usernameLineEdit->text() + '"' + "[\\s\t]+[^\".]+[\\s\t]+\"[^\".]+\"";
        }
		++it;
		continue;
	resetaccounts();
	}

// Now we have to do the reverse, and delete accounts which are no longer available.  This can either be accounts the root user deleted, 
// or accounts the Root user doesn't want made available to other users.

	QString deletePath="/etc/ppp/kdsl/delete.Accounts";
	QString accountdelete;
	QFile file(deletePath);
	if ( file.open( IO_ReadOnly ) ) {
	QStringList deleteLines;
        QTextStream stream( &file );	
	QString deleteLine;
	while( !stream.atEnd() ) {
	    deleteLine = stream.readLine();
	    accountdelete=deleteLine.data();
	    deleteLines += deleteLine;
	 QString nameofAccount=deleteLine.data();
	 gpppdata.deleteAccount(nameofAccount);
	}
	file.close();
	gpppdata.save();
	resetaccounts();
}
	resetaccounts();

// 	delete fileinfolist;
 //  Here we check to see if we have set the start connection at startup option enabled.  
 //  If the option is enabled, then we start the connection with startProcess().  However, because when we start kdsl for the very first time  
 //  the values will always start the process even though no value is given.  Therefore, the easiest way to prevent the startup sequence 
 //  is to check to see if there is a default account name.  If there isnt, it returns out of the sequence, and nothing happens (which is good).  
 // Otherwise, it passes through to the startProcess.

 //   if(gpppdata.storeConnect()==1){
//        if(gpppdata.accname().isEmpty())    
//	 return;
//	 else
 //     startProcess();	 
    
//	}
  

    }
    
     if(gpppdata.storeConnect()==1){
        if(gpppdata.accname().isEmpty())    
	 return;
	 else
      startProcess();	 
    
	}   
      // Setting Up the Scheduler Timer	
  if(gpppdata.storeAutoStartScheduler()!=0) {
     autostart_timer = new QTimer(this);
     connect(autostart_timer, SIGNAL(timeout()), SLOT(autostart_end()));
     
  // Now we check the system clock to see if the time is the same as the scheduled time.  If it is, Connect to the internet.  If
  // we are already connected, we will avoid trying to connect.
  

  autostart_timer->start(1000);   // we are checking every second to see if the times match - this is not ideal.
         
     }	
    
}

void kdsl::autostart_end() {
 //  KMessageBox::information(this, i18n("Current Time is %1").arg(QTime::currentTime().toString()));
 if(startwin->statusTextLabel->text()=="Disconnected") {
 if (gpppdata.storeScheduler()==TRUE)
 if (gpppdata.storeAutoStartScheduler()==TRUE)
  if(gpppdata.autoStartTime()==QTime::currentTime().toString())
     startProcess();
   }
   if(gpppdata.storeAutoStartScheduler()==TRUE) { 
   if(startwin->statusTextLabel->text()!="Disconnected") 
  if(gpppdata.autoStopTime()!="Never")
  if(gpppdata.autoStopTime()==QTime::currentTime().toString()){
    emit iconDisconnect();
    this->show();
    }
 //   startwin->statusTextLabel->setText( tr2i18n( "Disconnected by Scheduler" ) );
    }
     if(gpppdata.taskcount() > 0) {
    for(int i=0; i <= gpppdata.taskcount()-1; i++) {
      gpppdata.setTaskbyIndex(i); 
     if(gpppdata.storedTaskEndDate()<=QDate::currentDate().toString()) {
          gpppdata.deleteTask();
	}
      if(gpppdata.storedTaskStartDate()==QDate::currentDate().toString())
        if(gpppdata.storedTaskStartTime()==QTime::currentTime().toString())
	   if(gpppdata.storedTaskFrequency()=="daily") {
//	   	KMessageBox::information(this, i18n("Testing Scheduled Task\n%1").arg(gpppdata.taskname()) );
	if(startwin->statusTextLabel->text()=="Disconnected")
	  startProcess();
//	KRun *run=new KRun(KURL(gpppdata.taskname()));
	
		}
		}
	}
       
//  Iterate over the Scheduled programs to run

}

void kdsl::startClock() {
  minutes = 0;
  seconds = 0;
  hours = 0;
  startwin->clockTextLabel->show();
  startwin->clockTextLabel->setText("00:00:00");
  clocktimer->start(1000);
}


bool kdsl::queryExit()
{

 if (KMessageBox::warningContinueCancel(this, i18n("Exiting kdsl will disconnect\n"
        "any internet connections which\nare active.  Continue?\n\n"), i18n("Quitting"),
        i18n("OK"), i18n("Do Not Remind Me"))==KMessageBox::Cancel)
	{
	return false;
	}	

	  signal(SIGINT, sighandler);
          signal(SIGCHLD, sighandler);
          signal(SIGUSR1, sighandler);
          signal(SIGTERM, SIG_IGN);
          signal(SIGUSR1, sighandler);
//  signal(SIGTERM, SIG_IGN);
           kapp->processEvents();
           Requester::rq->killPPPDaemon();
           QApplication::flushX();	  
	   return true;
}

kdsl::~kdsl()
{
	  signal(SIGINT, sighandler);
          signal(SIGCHLD, sighandler);
          signal(SIGUSR1, sighandler);
          signal(SIGTERM, SIG_IGN);
          signal(SIGUSR1, sighandler);
//  signal(SIGTERM, SIG_IGN);
           kapp->processEvents();
           Requester::rq->killPPPDaemon();
           QApplication::flushX();	  
}

bool kdsl::setShown() {
return true;
}

void kdsl::log_window_toggled(bool on) {
  gpppdata.set_show_log_window(on);
  }

void kdsl::init()
{
      inittimer->stop();
      gpppdata.setpppdError(0);

      kapp->processEvents();

      if_timeout_timer->start(gpppdata.pppdTimeout()*1000);
      kdDebug("kdsl") << "started if timeout timer with " << gpppdata.pppdTimeout()*1000 << endl; 
      timerEvent((QTimerEvent *) 0); 
}

void kdsl::timerEvent(QTimerEvent*)
{
      int result;
            stats->setUnit(pppInterfaceNumber());
 //     kapp->flushX();
      result = execppp();

//	execppp();
//      emit debugMessage(i18n("Starting pppd..."));
      kdDebug("kdsl") << "execppp() returned with return-code " << result << endl;
       if(result) {  
        if(!gpppdata.autoDNS())
          adddns();
	
	// O.K we are done here, let's change over to the if_ loop
	// where we wait for the ppp if (interface) to come up.

	emit if_waiting_signal();  

      } else {
	
	if_timeout_timer->stop();	
	 	startwin->statusTextLabel->setText( tr2i18n( "Disconnected" ) );
		startwin->ipTextLabel->setText(" ");
		startwin->pixmapLabel1->setPixmap ( UserIcon ("kpppoff") );
		   startwin->connectButton->setText(i18n("Connect"));
 		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(discon() ) );
                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );		

		kapp->processEvents();		
		}
		return;
}

void adddns()
{
  int fd;

  if ((fd = Requester::rq->openResolv(O_WRONLY|O_APPEND)) >= 0) {
    QStringList &dnslist = gpppdata.dns();
    for ( QStringList::Iterator it = dnslist.begin();
          it != dnslist.end();
          ++it )
    {
      QCString dns = "nameserver " + (*it).local8Bit() +
		     " \t#kppp temp entry\n";
      write(fd, dns.data(), dns.length());
    }
    close(fd);
  }

//  add_domain(gpppdata.domain());
}

void addpeerdns() {
  int fd, fd2;

  if((fd = Requester::rq->openResolv(O_WRONLY|O_APPEND)) >= 0) {
    if((fd2 = open("/etc/ppp/resolv.conf", O_RDONLY)) >= 0) {
      char c;
      int i = 0;
      while(i++ < 100 && read(fd2, &c, 1) == 1) {
        if(c == '\n')
          write(fd, "\t#kdsl temp entry\n", 18);
        else
          write(fd, &c, 1);
      }
      close(fd2);
    } else
      fprintf(stderr, "failed to read from /etc/ppp/resolv.conf\n");
    close(fd);
  }
//  add_domain(gpppdata.domain());
}

void kdsl::script_timed_out()
{
}

void removedns() {

  int fd;
  char c;
  QString resolv[MAX_RESOLVCONF_LINES];

  if((fd = Requester::rq->openResolv(O_RDONLY)) >= 0) {

    int i=0;
    while(read(fd, &c, 1) == 1 && i < MAX_RESOLVCONF_LINES) {
      if(c == '\n') {
	i++;
      }
      else {
	resolv[i] += c;
      }
    }
    close(fd);

    if((fd = Requester::rq->openResolv(O_WRONLY|O_TRUNC)) >= 0) {
      for(int j=0; j < i; j++) {
	if(resolv[j].contains("#kdsl temp entrystartProcess")) continue;
	if(resolv[j].contains("#entry disabled by kdsl")) {
          QCString tmp = resolv[j].local8Bit();
	  write(fd, tmp.data()+2, tmp.length() - 27);
	  write(fd, "\n", 1);
	}
	else {
	  QCString tmp = resolv[j].local8Bit() + "\n";
	  write(fd, tmp, tmp.length());
	}
      }
    }
    close(fd);

    }
  }
  
  bool kdsl::execppp()
  {
  QString command;
  QString connectionPath;
  connectionPath = PPPOEOPTIONS + gpppdata.accname();
  command = "pppd";
  command += " ";
  command += "file";
  command += " ";
  command += connectionPath;
  kapp->flushX();
  return Requester::rq->execPPPDaemon(command);  
}

bool kdsl::eventFilter(QObject *o, QEvent *e) {
  if(e->type() == QEvent::User) {
    switch(((SignalEvent*)e)->sigType()) {
    case SIGINT:
      kdDebug("kdsl") << "Received a SIGINT" << endl;
      interruptConnection();
      break;
    case SIGCHLD:
      sigChld();
      break;
    case SIGUSR1:
      sigPPPDDied();
      break;
    }
    return true;
  }

    if(o == startwin->connectButton) {
      if(e->type() == QEvent::KeyPress) {
        if(startwin->connectButton->hasFocus() && ((QKeyEvent *)e)->key() == Qt::Key_Return) {
          startProcess();
          return true;
        }
      }
    }

    return false;
}

void kdsl::executePreferencesDlg()
{
    if (m_prefDialog==0){
        m_prefDialog=new PrefDialog(this);
	}
	connect(m_prefDialog, SIGNAL( resetaccounts() ), this, SLOT(resetaccounts()));
}


void kdsl::applyPreferences()
{

     resetaccounts();
     gpppdata.save();
//     dock_widget->show();
}

void kdsl::resetaccounts()
{
       dock_widget->show();
       dock_widget->useMeter->setEnabled(gpppdata.storeUsage());
	dock_widget->refreshIcon();
	
     if(!gpppdata.storeHideIP()) {
       startwin->ipTextLabel->hide();   
       }
       else {
       startwin->ipTextLabel->show();
       }
       
     if(!gpppdata.storeClock()) {
     startwin->clockTextLabel->hide();
     startwin->accountTypeTextLabel->hide();
     }
     else {
     startwin->accountTypeTextLabel->show();   
     startwin->clockTextLabel->show();
     }  
    startwin->connectionComboBox->clear();
    startwin->passwordLineEdit->clear();
    startwin->connectButton->setEnabled(true);
    int count = gpppdata.count();
    startwin->connectionComboBox->setEnabled(count > 0);

    if((startwin->statusTextLabel->text())!="Disconnected")
       startwin->connectionComboBox->setEnabled(FALSE);
    startwin->usernameLineEdit->setEnabled(count > 0);
    startwin->passwordLineEdit->setEnabled(count > 0);
//    dock_widget->discon();
    
    for(int i=0; i < count; i++) {
       gpppdata.setAccountbyIndex(i);
	QImage picFile = gpppdata.accountIconName();
        QPixmap pic = picFile.scale(16,16);     
       startwin->connectionComboBox->insertItem(pic,gpppdata.accname());
               if(getuid()==0) {
	       startwin->usernameLineEdit->setText(gpppdata.storedUsername());
	       startwin->passwordLineEdit->setText(gpppdata.storedPassword());
	       }
    }
    if(!gpppdata.defaultAccount().isEmpty()) {
      startwin->connectButton->setEnabled(TRUE);
       for(int i=0; i < count; i++)
  //        gpppdata.setDefaultAccount(startwin->connectionComboBox->text());
          if(gpppdata.defaultAccount() == startwin->connectionComboBox->text(i)) {
	    startwin->connectionComboBox->setCurrentItem(i);
	    gpppdata.setAccountbyIndex(i);

	    startwin->usernameLineEdit->setText(gpppdata.storedUsername());
	    if(getuid()==0)	  
	    startwin->accountTypeTextLabel->setText(i18n("Account Type - %1").arg(gpppdata.storedAccType() ));
	    else
            startwin->accountTypeTextLabel->setText(i18n("Time Connected"));	    
      if(gpppdata.storePassword())
      {
        startwin->passwordLineEdit->setText(gpppdata.storedPassword());
	startwin->connectButton->setEnabled(true);
      }
      else
      {
	startwin->passwordLineEdit->clear();
        startwin->connectButton->setEnabled(false);
       }
       if(getuid()!=0){
       startwin->passwordTextLabel->setText(i18n("Ready to Connect!"));
       startwin->passwordLineEdit->setEnabled(FALSE);
       startwin->usernameTextLabel->setText(i18n(""));
       startwin->accountTypeTextLabel->setText(i18n("Time Connected"));
//       startwin->usernameLineEdit->hid
       }
	  }
     }

else
   if(count > 0) {
      startwin->connectButton->setEnabled(true);
      gpppdata.setDefaultAccount(startwin->connectionComboBox->text(0));
      gpppdata.save();
      startwin->usernameLineEdit->setText(gpppdata.storedUsername());
      if(gpppdata.storePassword()) {
        startwin->passwordLineEdit->setText(gpppdata.storedPassword());
	startwin->connectButton->setEnabled(true);
      }
      else
      {
     startwin->passwordLineEdit->clear();
     startwin->connectButton->setEnabled(false);
     }
   }
}


void kdsl::con()
{
//	    online = false;
	    QString m_user;
                if (m_user != gpppdata.storedPassword() ) {
		      KMessageBox::error(this, i18n("Password was incorrect") );
		}
		else {
  		   startwin->statusTextLabel->setText( tr2i18n( "Trying to Connect" ) );
 		   startwin->pixmapLabel1->setPixmap( UserIcon ("kpppcon") );
 		   startwin->connectionComboBox->setEnabled(FALSE);
  		   startwin->connectButton->setText(i18n("Disconnect"));
  		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(startProcess() ) );
                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( discon() ) );
	           QFile configFile;
	           QString configfilestring;
	           QTextStream outstream, instream;
                   configfilestring = OPTIONSPATH + gpppdata.accname();

	           configFile.setName(configfilestring);

	           outstream.setDevice(&configFile);

	           if ((configFile.open(IO_ReadOnly)) == 0) {
                        KMessageBox::error(this, i18n( "Account does not exist.\n  Please login as root and set up accounts\nor contact your System Administrator." ) );
	                configFile.close();
	 	        startwin->statusTextLabel->setText( tr2i18n( "Disconnected" ) );
		        startwin->ipTextLabel->setText(" ");
		        startwin->pixmapLabel1->setPixmap ( UserIcon ("kpppoff") );
			
	
			startwin->clockTextLabel->show();
	                return;
	           }
		   startProcess();
		   }
}

void kdsl::checkStatus()
{
	QFile configFile;
	QString searchstring, configfilestring, textstring, newstring;
	QRegExp expression;
	QTextStream outstream, instream;
//	searchstring ='"' + m_prefGeneral->usernameLineEdit->text() + '"' + "[\\s\t]+[^\".]+[\\s\t]+\"[^\"]+\"";
	searchstring = "NONROOT=OK";
	expression.setPattern(searchstring);
        configfilestring = OPTIONSPATH + gpppdata.accname();

	configFile.setName(configfilestring);


	if ((configFile.open(IO_ReadOnly)) == 0) {
      KMessageBox::error(this, i18n( "Account does not exist.\n  Please login as root and set up accounts\nor contact your System Administrator." ) );
	configFile.close();
	 	startwin->statusTextLabel->setText( tr2i18n( "Disconnected" ) );
		startwin->ipTextLabel->setText(" ");
		startwin->pixmapLabel1->setPixmap ( UserIcon ("kpppoff") );	
  		   startwin->connectButton->setText(i18n("Disconnect"));
 		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(startProcess() ) );
                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( discon() ) );		
	return;
	}


	outstream.setDevice(&configFile);
  	textstring = outstream.read();
	configFile.close();

	if (textstring.find(expression, 0) ==-1){
	KMessageBox::error(this, i18n("Non root users are not authorized to use this account.\nContact your system administrator") );
	return;
	}
	con();
}

void kdsl::discon()
{
//    online = false;
//    start->kill();
    stats->stop();
    startwin->statusTextLabel->setText( tr2i18n( "Disconnecting" ) );
    startwin->pixmapLabel1->setPixmap( UserIcon ("kpppcon") );
    startwin->connectionComboBox->setEnabled(TRUE);
   		   startwin->connectButton->setText(i18n("Connect"));
		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(discon() ) );
                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );	
		   dock_widget->conToProv->setEnabled(TRUE);
		   dock_widget->disFromProv->setEnabled(FALSE);			   	   
        disconnected();
    startwin->passwordLineEdit->clear();
    if(gpppdata.storePassword() )   
   startwin->passwordLineEdit->setText(gpppdata.storedPassword());
    startwin->passwordLineEdit->setEnabled(true);
      stopClock();
      startwin->clockTextLabel->hide();
}

void kdsl::lostConnection()
{
  if_timer->stop();
  if_timeout_timer->stop();

stats->stop();
startwin->clockTextLabel->hide();
dock_widget->discon();
  stopClock();
}

void kdsl::timeclick() {  

  seconds++;

  if(seconds >= 60 ) {
    minutes ++;
    seconds = 0;
  }

  if (minutes >= 60){
    minutes = 0;
    hours ++;
  }

  if( hours >= 24){
    days ++;
    hours = 0;
  }

  time_string.sprintf("%02d:%02d\n",hours,minutes);
  time_string2 = "";
  if (days)
      time_string2.sprintf("%d d %02d:%02d:%02d\n",
			   days,hours,minutes,seconds);

  else
    time_string2.sprintf("%02d:%02d:%02d\n",hours,minutes,seconds);

  startwin->clockTextLabel->setText(time_string2);
QString timestring;
QString tooltip;
//tooltip = i18n("<b>Connected to %1</b>\nConnection Time %2\n" "%3" "\n\n\n%4\n").arg(gpppdata.accname()).arg(time_string2).arg(istatus).arg(ostatus);
tooltip = i18n("<qt><center><b><h3>Connected to %1</h3></b>%2<br>%3<br>Connected For  %3</center></qt>" ).arg(gpppdata.accname()).arg(stats->istatus).arg(stats->ostatus).arg(time_string2);
timestring = i18n("%1").arg(time_string2);
QToolTip::add(dock_widget, tooltip);
dock_widget->clock(timestring);

//kdsl_stats->timeLabel->setText(timestring);

}

void kdsl::stopClock() {
  clocktimer->stop();
}

void kdsl::if_waiting_timed_out()
{
if_timer->stop();
if_timeout_timer->stop();
QString msg;
 gpppdata.setpppdError(E_IF_TIMEOUT);   
   
 Requester::rq->killPPPDaemon();
disconnected();
}

void kdsl::if_waiting_slot() {
	    	    
  if(stats->ifIsUp()) {
    if_timeout_timer->stop();
  if_timer->stop();
  
//  usleep(200000);
   connected();
   kapp->flushX();
  return;
  }
     else {
//    usleep(200000);
          
    if(gpppdata.pppdError() != 0) {
      // we are here if pppd died immediately after starting it.
     lostConnection();
      // error message handled in main.cpp: sigPPPDDied()
     return;
   }

   if_timer->start(100, TRUE); // single shot{

   return;
   }

  }

void kdsl::connected()
{
	stats->setUnit(pppInterfaceNumber());
//	stats->ifIsUp();
        stats->start();
        dock_widget->statusSetup();
	dock_widget->refreshIcon();
 //       clocktimer->start(1000);
//	addpeerdns();

}

void kdsl::startProcess()
{
 		   startwin->connectionComboBox->setEnabled(FALSE);
		   startwin->usernameLineEdit->setEnabled(FALSE);
		   startwin->passwordLineEdit->setEnabled(FALSE);
  		   startwin->statusTextLabel->setText( tr2i18n( "Trying to Connect" ) );
 		   startwin->pixmapLabel1->setPixmap( UserIcon ("kpppcon") );
 		   startwin->connectionComboBox->setEnabled(false);
   		   startwin->connectButton->setText(i18n("Disconnect"));
		   dock_widget->conToProv->setEnabled(FALSE);
		   dock_widget->disFromProv->setEnabled(TRUE);	
  		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(startProcess() ) );
                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( discon() ) );		   		   
//		   setupButton->setEnabled(false);

	 if(getuid()==0 ){
	QFile papsecrets, options, chapsecrets;
	QString searchstring, papfilestring, chapfilestring, textstring, newstring, password;
	QRegExp expression;
	QTextStream outstream, instream;
	password = startwin->passwordLineEdit->text();

//	searchstring ='"' + m_prefGeneral->usernameLineEdit->text() + '"' + "[\\s\t]+[^\".]+[\\s\t]+\"[^\"]+\"";
	searchstring = '"' + startwin->usernameLineEdit->text() + '"' + "[\\s\t]+[^\".]+[\\s\t]+\"[^\".]+\"";
	password ='"' + startwin->usernameLineEdit->text() + '"' + " * " + '"' + '"'+ '\n';
	expression.setPattern(searchstring);
	papfilestring = "/etc/ppp/pap-secrets";
	chapfilestring = "/etc/ppp/chap-secrets";

	papsecrets.setName(papfilestring);
	papsecrets.encodeName(papfilestring);
	chapsecrets.setName(chapfilestring);
	if ((papsecrets.open(IO_ReadOnly)) == 0) {
	KMessageBox::error(this, i18n("Could not open /etc/ppp/pap-secrets"));
//	return ERROR_OPENING_PAPSECRETS_FOR_READ;
	}

	outstream.setDevice(&papsecrets);
  	textstring = outstream.read();
	papsecrets.close();

	if (textstring.find(expression, 0) ==-1)
	{

	textstring.remove(password);
		newstring = '"' + startwin->usernameLineEdit->text() + '"' + " * " + '"' + startwin->passwordLineEdit->text() + '"' + '\n';
		textstring.insert(0, newstring);
	}
	else
	{
		newstring = '"' + startwin->usernameLineEdit->text() + '"' + " * " + '"' +  startwin->passwordLineEdit->text() + '"';
		textstring.remove(password);
		textstring.replace(expression, newstring);
//		textstring.insert(0, newstring);
	}
	
	if ((papsecrets.open(IO_WriteOnly)) == 0) 
	KMessageBox::error(this, i18n("Can not write to /etc/ppp/pap-secrets")); //return ERROR_OPENING_PAPSECRETS_FOR_WRITE;
	instream.setDevice(&papsecrets);
//	instream.setDevice(&chapsecrets);
	instream << textstring;
	papsecrets.close();
//	chapsecrets.close();

	if ((chapsecrets.open(IO_WriteOnly)) == 0) //return ERROR_OPENING_CHAPSECRETS_FOR_WRITE;
	KMessageBox::error(this, i18n("Can not write to /etc/ppp/chap-secrets"));
	instream.setDevice(&chapsecrets);
	instream << textstring;
	chapsecrets.close();
	//return EVERYTHING_OK;	    
}

 //      if (setreuid(0,0) !=0) {
 //      KMessageBox::information(this, i18n("TESTING THE PASSWORD THING"));
 //      gpppdata.setStoredPassword(passwordLineEdit->text()) ;
//       }

        inittimer->start(100);

       gpppdata.setAccount(startwin->connectionComboBox->currentText());
       gpppdata.setPassword(startwin->passwordLineEdit->text());

       #if 0

       #endif

}

void kdsl::disconnected( void )
{

       kapp->processEvents();
       Requester::rq->killPPPDaemon();
       QApplication::flushX();
 // execute_command(gpppdata.command_on_disconnect());

 		startwin->connectionComboBox->setEnabled(TRUE);
		if(getuid()!=0){
		    startwin->usernameLineEdit->setEnabled(FALSE);
		   startwin->passwordLineEdit->setEnabled(FALSE);
		   }
		 else {
		    startwin->usernameLineEdit->setEnabled(TRUE);
		   startwin->passwordLineEdit->setEnabled(TRUE);	
		   }	 
		
		
 		startwin->statusTextLabel->setText( tr2i18n( "Disconnected" ) );
		startwin->ipTextLabel->setText(" ");
		startwin->pixmapLabel1->setPixmap ( UserIcon ("kpppoff") );
//		dock_widget->hide();
		dock_widget->stop_stats();
		startwin->connectButton->setText( tr2i18n( "Connect"));
    		disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(discon() ) );
                connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );	
		dock_widget->disFromProv->setEnabled(FALSE);
		dock_widget->conToProv->setEnabled(TRUE);					
		removedns();
 		clocktimer->stop();
//		kdsl_stats->stop_stats();
}

void kdsl::getStats()
{
		stats->stop();
	  	startwin->statusTextLabel->setText( tr2i18n( "Failed to Connect" ) );
                startwin->pixmapLabel1->setPixmap( UserIcon ("kppperror") );
		startwin->ipTextLabel->setText( " ");
		startwin->connectButton->setText( tr2i18n( "Connect"));
    		disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(discon() ) );
                connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );				
 		startwin->connectionComboBox->setEnabled(TRUE);  		
		startwin->passwordLineEdit->setEnabled(true);
}

void kdsl::interfaceUp()
{
     QString m_configdir;
     QString m_connected;
     m_configdir = gpppdata.accname();
     m_connected = "\nConnected to " + m_configdir;
     startwin->statusTextLabel->setText( tr2i18n( m_connected ) );
     dock_widget->show();     

     	QString text = "\nConnected To";
	QString provider = gpppdata.accname();
        if(gpppdata.storeEnableNotify()==0)
	dock_widget->addBalloon();
	if(gpppdata.storeEnableSound()==0) {
	    KStandardDirs *dirs = KGlobal::dirs();
    QString themePath;
    themePath = dirs->findResource ("data", "kdsl/pics/");
	        KAudioPlayer::play(themePath + "online.wav");
		}
//	notify->login(text,provider);	    
   
     startClock();
       dock_widget->take_stats();
             
     if (!gpppdata.autoDNS() ) {
        adddns();
     } else {
     addpeerdns();
     }

     startwin->pixmapLabel1->setPixmap( UserIcon( "kpppon") );
     if(gpppdata.storeHideIP())
     startwin->ipTextLabel->show();
     startwin->passwordLineEdit->setEnabled(false);
     }


void kdsl::interfaceDown()
{
         if (stats->online) {
         QString m_configdir;
     	 QString m_connected;
     	 m_configdir = gpppdata.accname();
//      	 m_connected = "Connection to %1 has been terminated\n  Check the log file to see the possible cause.";
	 }

//	KMessageBox::error(this, i18n("Is this any different?") );
	  	startwin->statusTextLabel->setText( tr2i18n( "Failed to Connect" ) );
                startwin->pixmapLabel1->setPixmap( UserIcon ("kppperror") );
		startwin->ipTextLabel->setText( " ");
		startwin->clockTextLabel->hide();
   		   startwin->connectButton->setText(i18n("Connect"));
		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(discon() ) );
                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );				
 		startwin->connectionComboBox->setEnabled(TRUE);
  		startwin->ipTextLabel->hide();
		startwin->passwordLineEdit->setEnabled(true);
}

void kdsl::ipUp()
{
      startwin->ipTextLabel->setText( tr2i18n( "Local IP Address: %1").arg(stats->local_ip_address));

}

void kdsl::setWidgets()
{
 kapp->setMainWidget(this);
 kapp->setTopWidget(this);
 }
 
void kdsl::iconDisconnect()
{
      kapp->processEvents();
//     online = false;
    startwin->statusTextLabel->setText( tr2i18n( "Disconnecting" ) );
    startwin-> pixmapLabel1->setPixmap( UserIcon ("kpppdiscon") );    
    		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(discon() ) );
                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );				
 		startwin->connectionComboBox->setEnabled(TRUE);  
     startwin->clockTextLabel->hide();      
     disconnected();
    startwin->passwordLineEdit->clear();
    if(gpppdata.storePassword() )
   startwin->passwordLineEdit->setText(gpppdata.storedPassword());
    startwin->passwordLineEdit->setEnabled(true);     
}

void kdsl::iconConnect()
{
      kapp->processEvents();
//    online = false;
    startwin->statusTextLabel->setText( tr2i18n( "Connecting" ) );
    startwin-> pixmapLabel1->setPixmap( UserIcon ("kpppdiscon") );    
//    		   disconnect(startwin->connectButton, SIGNAL( clicked()), this, SLOT(con() ) );
//                   connect( startwin->connectButton, SIGNAL( clicked() ), this, SLOT( startProcess() ) );				
 		startwin->connectionComboBox->setEnabled(FALSE);  
     startwin->clockTextLabel->show();      
     startProcess();
    startwin->passwordLineEdit->clear();
    if(gpppdata.storePassword() )
   startwin->passwordLineEdit->setText(gpppdata.storedPassword());
    startwin->passwordLineEdit->setEnabled(false);     
}




void kdsl::passwordChanged()
{
startwin->connectButton->setEnabled(true);
}

void kdsl::newdefaultaccount( int i)
{
  gpppdata.setDefaultAccount(startwin->connectionComboBox->text(i));
  gpppdata.save();
  startwin->usernameLineEdit->setText(gpppdata.storedUsername());
  startwin->accountTypeTextLabel->setText(gpppdata.storedAccType() );
  if(getuid()==0)
  startwin->accountTypeTextLabel->setText(i18n("Account Type - %1").arg(gpppdata.storedAccType() ));
  else
  startwin->accountTypeTextLabel->setText(i18n("Time Connected"));
  startwin->connectButton->setEnabled(true);
  startwin->passwordLineEdit->setEnabled(true);
  if (gpppdata.storePassword() )  {
  startwin->connectButton->setEnabled(true);
       startwin->passwordLineEdit->setText(gpppdata.storedPassword());
       }
   else {
    startwin->passwordLineEdit->clear();
    startwin->connectButton->setEnabled(false);
    }
 // passwordLineEdit->setText(gpppdata.storedPassword());
}

void kdsl::saveMyself()
{
     gpppdata.save();

}

void kdsl::shutDown()
{

   kapp->flushX();
    if(getuid()==0) 
   {
    QStringList lines;
    QString accountconfigFile = KGlobal::dirs()->saveLocation("config")
    + QString(kapp->name()) + "rc";      
    QFile file( accountconfigFile );
    if ( file.open( IO_ReadOnly ) ) {
        QTextStream stream( &file );
        QString line;
//        int i = 1;
        while ( !stream.atEnd() ) {
            line = stream.readLine(); // line of text excluding '\n'
            lines += line;
        }
    }
}  

  saveMyself();
  signal(SIGINT, sighandler);
  signal(SIGCHLD, sighandler);
  signal(SIGUSR1, sighandler);
  signal(SIGTERM, SIG_IGN);
   kapp->processEvents();
  Requester::rq->killPPPDaemon();
  QApplication::flushX();	  
 
}

void kdsl::expandbutton()
{
  setup();
}

QString kdsl::encodeWord(const QString &s) {
    QString r = s;
    r.replace(QRegExp("\\"), "\\\\");
	KMessageBox::error(this, (r ));
	KMessageBox::error(this, (s ));
    return r;
}

void kdsl::setup()
{

   executePreferencesDlg();
       if(m_prefDialog->exec()) {
//	encodeWord(gpppdata.storedUsername());
//	 encodeWord(gpppdata.storedPassword());;
	
      gpppdata.save();

       }

       else
   
  gpppdata.cancel();
}

void kdsl::sigPPPDDied() {
      kdDebug("kdsl") << "Received a SIGUSR1" << endl;

    // if we are not connected pppdpid is -1 so have have to check for that
    // in the followin line to make sure that we don't raise a false alarm
    // such as would be the case when the log file viewer exits.
    if(gpppdata.pppdRunning() || gpppdata.pppdError()) {
      kdDebug("kdsl") << "It was pppd that terminated" << endl;
//      disconnected();
      
          // when we killpppd() on Cancel in ConnectWidget
      // we set pppid to -1 so we won't
      // enter this block

      // just to be sure
//      Requester::rq->removeSecret(AUTH_PAP);
//      Requester::rq->removeSecret(AUTH_CHAP);

      gpppdata.setpppdRunning(false);

      kdDebug("kdsl") << "Executing command on disconnect since pppd has died." << endl;
      QApplication::flushX();
      execute_command(gpppdata.command_on_disconnect());

        if(!gpppdata.pppdError())
        gpppdata.setpppdError(E_PPPD_DIED);    
      
        gpppdata.setpppdRunning(false);
		QString msg;
	if (gpppdata.pppdError() == E_IF_TIMEOUT)
	    msg = i18n("Timeout expired while waiting for the PPP interface "
                       "to come up!");
	else {
	    msg = i18n("<p>The pppd daemon died unexpectedly!</p>");
	    Requester::rq->pppdExitStatus();
	    if (Requester::rq->lastStatus != 99) {	// more recent pppds only
	    	     msg = (i18n("Connection Timed Out"));

	    if(Requester::rq->lastStatus == 1)
	    msg = (i18n("<qt><center><b><h3>Kdsl could not fully execute the pppd process.</h3></b><br>Usually this occurs if some ppp modules are not loaded.<br>Please check your Setup.</center></qt>"));
    
	    if(Requester::rq->lastStatus ==2)
	    msg = (i18n("<qt><center>pppd did not recognise at least one of the options<br>in the options file.<br><br>Please look at the log file for more details</center></qt>"));

	    if(Requester::rq->lastStatus ==4)
	    msg = (i18n("<qt><center>The kernel does not support PPP.<br><br>Check the kernel drivers are loaded or compiled into the kernel</center></qt>"));	    
	    if(Requester::rq->lastStatus == 5)
	    msg = (i18n("<qt><center>pppd was sent a disconnect signal</center></qt>"));	    

	    if(Requester::rq->lastStatus == 6)
	    msg = (i18n("<qt><center>The modem device could not be locked\nEdit your account and uncheck the lock modem option.</center></qt>"));		    
	    if(Requester::rq->lastStatus == 7)
	    msg = (i18n("<qt><center>The serial port your modem is connected to\ncould not be opened.</center></qt>"));	    
	    	    
	    if(Requester::rq->lastStatus == 8)
	    msg = (i18n("<qt><center>Kdsl's connection script failed</center></qt>"));	 
	      	    	    
	    if(Requester::rq->lastStatus ==9)
	    msg = (i18n("<qt><center>A command in the connection script could not be executed<br></center></qt>"));	 
	       
	    if(Requester::rq->lastStatus ==12)
	    msg = (i18n("<qt><center>Kdsl has disconnected because the idle timeout has been reached.<br></center></qt>"));
	    
	    if(Requester::rq->lastStatus ==16)
	    msg = (i18n("<qt><center>The modem has hung up<br></center></qt>"));	    
	    
	    
	    if(Requester::rq->lastStatus == 19) 
	    msg =( i18n("<qt><center><b><h3>Authentication Failure</h3></b>Please check your Username and password</center></qt>"));

	}
	}
	
	KMessageBox::error(this, i18n("%1").arg(msg));
	}

//  gpppdata.setpppdError(0);
  disconnected();
}

void kdsl::interruptConnection() {

  // disconnect if online
  if (gpppdata.pppdRunning())
    emit disconnect();
}


 void kdsl::sigChld() {
  kdDebug("kdsl") << "sigchld()" << endl;
    QString msg = i18n("kdsl's helper process just died.\n"
                       "Since a further execution would be pointless, "
                       "kppp will shut down now.");
    KMessageBox::error(0L, msg);
    remove_pidfile();
    exit(1);
    //  }
} 

void kdsl::setpasswordLineEdit(const QString &pw) {
  startwin->passwordLineEdit->setText(pw);
}

void kdsl::showAbout(){
	aboutDialog->exec();
}

#include "kdsl.moc"

