22#include "networkscanner.h" 
   24#include <tqprogressbar.h> 
   25#include <kpushbutton.h> 
   29#include <tqcombobox.h> 
   30#include <tqlineedit.h> 
   34#include <kextendedsocket.h> 
   35#include <tdemessagebox.h> 
   36#include <knumvalidator.h> 
   40class NetworkScanner::NetworkScannerPrivate
 
   44    TQString prefixaddress;
 
   48    TQPtrList<NetworkScanner::SocketInfo> printers;
 
   51    KPushButton *scan, *settings;
 
   57    KExtendedSocket *socket;
 
   60    NetworkScannerPrivate( 
int portvalue ) : port( portvalue )
 
   62        prefixaddress = localPrefix();
 
   66        printers.setAutoDelete( 
true );
 
   68    TQString localPrefix();
 
   69    TQString scanString();
 
   72TQString NetworkScanner::NetworkScannerPrivate::localPrefix()
 
   76    if (!gethostname(buf, 
sizeof(buf)))
 
   77        buf[
sizeof(buf)-1] = 
'\0';
 
   78    TQPtrList<KAddressInfo> infos = KExtendedSocket::lookup(buf, TQString::null);
 
   79    infos.setAutoDelete(
true);
 
   80    if (infos.count() > 0)
 
   82        TQString    IPstr = infos.first()->address()->nodeName();
 
   83        int p = IPstr.findRev(
'.');
 
   87    return TQString::null;
 
   90TQString NetworkScanner::NetworkScannerPrivate::scanString()
 
   92    TQString s = prefixaddress + 
".*";
 
   94        s.append( 
":" ).append( TQString::number( port ) );
 
   98NetworkScanner::NetworkScanner( 
int port, TQWidget *parent, 
const char *name )
 
   99    : TQWidget( parent, name )
 
  101    d = 
new NetworkScannerPrivate( port );
 
  102    d->bar = 
new TQProgressBar( 256, 
this );
 
  103    d->settings = 
new KPushButton( KGuiItem( i18n( 
"&Settings" ), 
"configure" ), 
this );
 
  104    d->scan = 
new KPushButton( KGuiItem( i18n( 
"Sc&an" ), 
"viewmag" ), 
this );
 
  105    d->timer = 
new TQTimer( 
this );
 
  107    d->socket = 
new TQSocket( 
this );
 
  109    d->socket = 
new KExtendedSocket();
 
  111    TQLabel *label = 
new TQLabel( i18n( 
"Network scan:" ), 
this );
 
  112    d->subnetlab = 
new TQLabel( i18n( 
"Subnet: %1" ).arg( d->scanString() ), 
this );
 
  114    TQGridLayout *l0 = 
new TQGridLayout( 
this, 4, 2, 0, 10 );
 
  115    l0->addMultiCellWidget( label, 0, 0, 0, 1 );
 
  116    l0->addMultiCellWidget( d->bar, 1, 1, 0, 1 );
 
  117    l0->addMultiCellWidget( d->subnetlab, 2, 2, 0, 1 );
 
  118    l0->addWidget( d->settings, 3, 0 );
 
  119    l0->addWidget( d->scan, 3, 1 );
 
  121    connect( d->timer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotTimeout() ) );
 
  122    connect( d->settings, TQ_SIGNAL( clicked() ), TQ_SLOT( slotSettingsClicked() ) );
 
  123    connect( d->scan, TQ_SIGNAL( clicked() ), TQ_SLOT( slotScanClicked() ) );
 
  125    connect( d->socket, TQ_SIGNAL( connected() ), TQ_SLOT( slotConnectionSuccess() ) );
 
  126    connect( d->socket, TQ_SIGNAL( error( 
int ) ), TQ_SLOT( slotConnectionFailed( 
int ) ) );
 
  128    connect( d->socket, TQ_SIGNAL( connectionSuccess() ), TQ_SLOT( slotConnectionSuccess() ) );
 
  129    connect( d->socket, TQ_SIGNAL( connectionFailed( 
int ) ), TQ_SLOT( slotConnectionFailed( 
int ) ) );
 
  133NetworkScanner::~NetworkScanner()
 
  141void NetworkScanner::start()
 
  148    d->settings->setEnabled( 
false );
 
  149    d->scan->setGuiItem( KGuiItem( i18n( 
"&Abort" ), 
"process-stop" ) );
 
  150    d->currentaddress = -1;
 
  155void NetworkScanner::slotScanClicked()
 
  159        if ( d->localPrefix() == d->prefixaddress ||
 
  160                KMessageBox::warningContinueCancel( this->parentWidget(),
 
  161                    i18n( 
"You are about to scan a subnet (%1.*) that does not " 
  162                          "correspond to the current subnet of this computer (%2.*). Do you want " 
  163                          "to scan the specified subnet anyway?" ).arg( d->prefixaddress ).arg( d->localPrefix() ),
 
  164                    TQString::null, KGuiItem( i18n( 
"&Scan" ), 
"viewmag" ), 
"askForScan" ) == KMessageBox::Continue )
 
  172        d->socket->cancelAsyncConnect();
 
  178void NetworkScanner::finish()
 
  183    d->settings->setEnabled( 
true );
 
  184    d->scan->setGuiItem( KGuiItem( i18n( 
"Sc&an" ), 
"viewmag" ) );
 
  190void NetworkScanner::slotSettingsClicked()
 
  192    NetworkScannerConfig dlg( 
this );
 
  196void NetworkScanner::slotNext()
 
  203    d->socket->connectToHost( d->prefixaddress + 
"." + TQString::number( d->currentaddress ), d->port );
 
  204    kdDebug() << 
"Address: " << d->socket->peerName() << 
", Port: " << d->socket->peerPort() << endl;
 
  206    d->socket->setAddress( d->prefixaddress + 
"." + TQString::number( d->currentaddress ), d->port );
 
  207    d->socket->startAsyncLookup();
 
  208    kdDebug() << 
"Address: " << d->socket->host() << 
", Port: " << d->socket->port() << endl;
 
  210    d->timer->start( d->timeout, 
true );
 
  213void NetworkScanner::next()
 
  217    if ( d->currentaddress >= 256 )
 
  221        d->bar->setProgress( d->currentaddress );
 
  222        TQTimer::singleShot( 0, 
this, TQ_SLOT( slotNext() ) );
 
  226void NetworkScanner::slotTimeout()
 
  228    kdDebug() << 
"Timeout" << endl;
 
  235    d->socket->cancelAsyncConnect();
 
  240void NetworkScanner::slotConnectionSuccess()
 
  242    kdDebug() << 
"Success" << endl;
 
  244    TDESocketAddress *addr = KExtendedSocket::peerAddress( d->socket->socket() );
 
  246    TDESocketAddress *addr = 
const_cast<TDESocketAddress*
>( d->socket->peerAddress() );
 
  248    kdDebug() << 
"Connection success: " << ( addr ? addr->pretty() : TQString( 
"ERROR" ) ) << endl;
 
  249    kdDebug() << 
"Socket: " << d->socket->socket() << endl;
 
  252        SocketInfo *info = 
new SocketInfo;
 
  254        info->IP = d->socket->peerName();
 
  256        info->IP = d->socket->host();
 
  258        info->Port = d->port;
 
  260        KExtendedSocket::resolve( addr, info->Name, portname );
 
  261        d->printers.append( info );
 
  266        kdDebug() << 
"Unconnected socket, skipping" << endl;
 
  270void NetworkScanner::slotConnectionFailed( 
int )
 
  272    kdDebug() << 
"Failure" << endl;
 
  276const TQPtrList<NetworkScanner::SocketInfo>* NetworkScanner::printerList()
 
  278    return &( d->printers );
 
  281int NetworkScanner::timeout()
 const 
  286void NetworkScanner::setTimeout( 
int to )
 
  291TQString NetworkScanner::subnet()
 const 
  293    return d->prefixaddress;
 
  296void NetworkScanner::setSubnet( 
const TQString& sn )
 
  298    d->prefixaddress = sn;
 
  299    d->subnetlab->setText( i18n( 
"Subnet: %1" ).arg( d->scanString() ) );
 
  302int NetworkScanner::port()
 const 
  307void NetworkScanner::setPort( 
int p )
 
  310    d->subnetlab->setText( i18n( 
"Subnet: %1" ).arg( d->scanString() ) );
 
  313bool NetworkScanner::checkPrinter( 
const TQString& host, 
int port )
 
  316    TQPtrListIterator<NetworkScanner::SocketInfo> it( d->printers );
 
  317    for ( ; it.current(); ++it )
 
  319        if ( port == it.current()->Port && ( host == it.current()->IP ||
 
  320                    host == it.current()->Name ) )
 
  325    KExtendedSocket extsock( host, port );
 
  326    extsock.setBlockingMode( 
false );
 
  327    extsock.setTimeout( 0, d->timeout * 1000 );
 
  328    return ( extsock.connect() == 0 );
 
  331NetworkScannerConfig::NetworkScannerConfig(NetworkScanner *scanner, 
const char *name)
 
  332    : KDialogBase(scanner, name, true, TQString::null, Ok|Cancel, Ok, true)
 
  335    TQWidget    *dummy = 
new TQWidget(
this);
 
  336    setMainWidget(dummy);
 
  337        KIntValidator *val = 
new KIntValidator( 
this );
 
  338    TQLabel *masklabel = 
new TQLabel(i18n(
"&Subnetwork:"),dummy);
 
  339    TQLabel *portlabel = 
new TQLabel(i18n(
"&Port:"),dummy);
 
  340    TQLabel *toutlabel = 
new TQLabel(i18n(
"&Timeout (ms):"),dummy);
 
  341    TQLineEdit  *mm = 
new TQLineEdit(dummy);
 
  342    mm->setText(TQString::fromLatin1(
".[0-255]"));
 
  343    mm->setReadOnly(
true);
 
  344    mm->setFixedWidth(fontMetrics().width(mm->text())+10);
 
  346    mask_ = 
new TQLineEdit(dummy);
 
  347    mask_->setAlignment(TQt::AlignRight);
 
  348    port_ = 
new TQComboBox(
true,dummy);
 
  349        if ( port_->lineEdit() )
 
  350            port_->lineEdit()->setValidator( val );
 
  351    tout_ = 
new TQLineEdit(dummy);
 
  352        tout_->setValidator( val );
 
  354    masklabel->setBuddy(mask_);
 
  355    portlabel->setBuddy(port_);
 
  356    toutlabel->setBuddy(tout_);
 
  358    mask_->setText(scanner_->subnet());
 
  359    port_->insertItem(
"631");
 
  360    port_->insertItem(
"9100");
 
  361    port_->insertItem(
"9101");
 
  362    port_->insertItem(
"9102");
 
  363    port_->setEditText(TQString::number(scanner_->port()));
 
  364    tout_->setText(TQString::number(scanner_->timeout()));
 
  366    TQGridLayout    *main_ = 
new TQGridLayout(dummy, 3, 2, 0, 10);
 
  367    TQHBoxLayout    *lay1 = 
new TQHBoxLayout(0, 0, 5);
 
  368    main_->addWidget(masklabel, 0, 0);
 
  369    main_->addWidget(portlabel, 1, 0);
 
  370    main_->addWidget(toutlabel, 2, 0);
 
  371    main_->addLayout(lay1, 0, 1);
 
  372    main_->addWidget(port_, 1, 1);
 
  373    main_->addWidget(tout_, 2, 1);
 
  374    lay1->addWidget(mask_,1);
 
  375    lay1->addWidget(mm,0);
 
  378    setCaption(i18n(
"Scan Configuration"));
 
  381NetworkScannerConfig::~NetworkScannerConfig()
 
  385void NetworkScannerConfig::slotOk()
 
  388    TQRegExp    re(
"(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})");
 
  389    if (!re.exactMatch(mask_->text()))
 
  390        msg = i18n(
"Wrong subnetwork specification.");
 
  393        for (
int i=1; i<=3; i++)
 
  394            if (re.cap(i).toInt() >= 255)
 
  396                msg = i18n(
"Wrong subnetwork specification.");
 
  402    int     v = tout_->text().toInt(&ok);
 
  404        msg = i18n(
"Wrong timeout specification.");
 
  405    v = port_->currentText().toInt(&ok);
 
  407        msg = i18n(
"Wrong port specification.");
 
  410        KMessageBox::error(
this,msg);
 
  414    scanner_->setTimeout( tout_->text().toInt() );
 
  415    scanner_->setSubnet( mask_->text() );
 
  416    scanner_->setPort( port_->currentText().toInt() );
 
  418    KDialogBase::slotOk();
 
  421#include "networkscanner.moc"