You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
10 KiB
362 lines
10 KiB
/***************************************************************************
|
|
smb4kpreviewer - This class queries a remote share for a preview
|
|
-------------------
|
|
begin : Mo Mai 28 2007
|
|
copyright : (C) 2007 by Alexander Reinholdt
|
|
email : dustpuppy@users.berlios.de
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* 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 Street, Fifth Floor, Boston, *
|
|
* MA 02110-1301 USA *
|
|
***************************************************************************/
|
|
|
|
// TQt includes
|
|
#include <tqapplication.h>
|
|
|
|
// KDE includes
|
|
#include <tdeapplication.h>
|
|
#include <kdebug.h>
|
|
|
|
// application specific includes
|
|
#include "smb4kpreviewer.h"
|
|
#include "smb4kpreviewitem.h"
|
|
#include "smb4kdefs.h"
|
|
#include "smb4tdeglobal.h"
|
|
#include "smb4kpasswordhandler.h"
|
|
#include "smb4kauthinfo.h"
|
|
#include "smb4ksambaoptionshandler.h"
|
|
#include "smb4kerror.h"
|
|
|
|
using namespace Smb4TDEGlobal;
|
|
|
|
|
|
Smb4KPreviewer::Smb4KPreviewer( TQObject *parent, const char *name )
|
|
: TQObject( parent, name )
|
|
{
|
|
m_item = NULL;
|
|
|
|
m_buffer = TQString();
|
|
|
|
m_working = false;
|
|
|
|
m_proc = new TDEProcess( this, "PreviewProcess" );
|
|
m_proc->setUseShell( true );
|
|
|
|
connect( m_proc, TQT_SIGNAL( receivedStdout( TDEProcess *, char *, int ) ),
|
|
this, TQT_SLOT( slotReceivedStdout( TDEProcess *, char *, int ) ) );
|
|
|
|
connect( m_proc, TQT_SIGNAL( processExited( TDEProcess* ) ),
|
|
this, TQT_SLOT( slotProcessExited( TDEProcess * ) ) );
|
|
|
|
connect( m_proc, TQT_SIGNAL( receivedStderr( TDEProcess *, char *, int ) ),
|
|
this, TQT_SLOT( slotReceivedStderr( TDEProcess *, char *, int ) ) );
|
|
}
|
|
|
|
|
|
Smb4KPreviewer::~Smb4KPreviewer()
|
|
{
|
|
// Do not delete m_item here, because it belongs to an
|
|
// outside class.
|
|
}
|
|
|
|
|
|
bool Smb4KPreviewer::preview( Smb4KPreviewItem *item )
|
|
{
|
|
// If there is no item, stop right here.
|
|
if ( !item )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( TQString::compare( item->share(), "homes" ) == 0 )
|
|
{
|
|
TQString share_name = specifyUser( item->host(), kapp->mainWidget() ? kapp->mainWidget() : 0, "SpecifyUser" );
|
|
|
|
if ( !share_name.isEmpty() )
|
|
{
|
|
// The Smb4KPreviewItem::setShare() function will take care
|
|
// that no share name is overwritten, that is *not* named
|
|
// 'homes'.
|
|
item->setShare( share_name );
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
m_timer_id = startTimer( TIMER_INTERVAL );
|
|
|
|
m_queue.enqueue( item );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void Smb4KPreviewer::abort()
|
|
{
|
|
m_queue.clear();
|
|
|
|
if ( m_proc->isRunning() )
|
|
{
|
|
m_proc->kill();
|
|
}
|
|
}
|
|
|
|
|
|
void Smb4KPreviewer::timerEvent( TQTimerEvent * )
|
|
{
|
|
if ( m_working )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Declare the previewer working:
|
|
emit state( PREVIEWER_START );
|
|
|
|
m_working = true;
|
|
|
|
m_item = m_queue.dequeue();
|
|
|
|
// Assemble the command.
|
|
//
|
|
// Here are some things to remember:
|
|
// (a) Do not convert the path to local 8 bit. It won't work with umlauts or other
|
|
// special characters.
|
|
// (b) Do not pass the path unquoted, or you'll get a NT_STATUS_OBJECT_NAME_NOT_FOUND
|
|
// error message in the case the path is empty.
|
|
TQString command;
|
|
command.append( TQString( "smbclient //%1/%2 " ).arg( TDEProcess::quote( m_item->host() ), TDEProcess::quote( m_item->share() ) ) );
|
|
command.append( TQString( " -d1 -W %1 -D %2 " ).arg( TDEProcess::quote( m_item->workgroup() ), TDEProcess::quote( m_item->path() ) ) );
|
|
command.append( " -c \"ls\" " );
|
|
|
|
if ( !m_item->ip().isEmpty() )
|
|
{
|
|
command.append( TQString( " -I %1 " ).arg( m_item->ip() ) );
|
|
}
|
|
|
|
command.append( optionsHandler()->smbclientOptions( "//"+m_item->host()+"/"+m_item->share() ) );
|
|
|
|
Smb4KAuthInfo *auth = passwordHandler()->readAuth( new Smb4KAuthInfo( m_item->workgroup(), m_item->host(), m_item->share() ) );
|
|
|
|
if ( !auth->user().isEmpty() )
|
|
{
|
|
command.append( TQString( " -U %1" ).arg( TDEProcess::quote( auth->user() ) ) );
|
|
|
|
if ( !auth->password().isEmpty() )
|
|
{
|
|
m_proc->setEnvironment( "PASSWD", auth->password() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
command.append( " -U guest%" );
|
|
}
|
|
|
|
delete auth;
|
|
|
|
*m_proc << command;
|
|
|
|
TQApplication::setOverrideCursor( waitCursor );
|
|
|
|
m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TQT_SLOT IMPLEMENTATIONS
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void Smb4KPreviewer::slotReceivedStdout( TDEProcess *, char *buf, int len )
|
|
{
|
|
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
|
|
}
|
|
|
|
|
|
void Smb4KPreviewer::slotReceivedStderr( TDEProcess *, char *buf, int len )
|
|
{
|
|
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
|
|
}
|
|
|
|
|
|
void Smb4KPreviewer::slotProcessExited( TDEProcess * )
|
|
{
|
|
// Disconnect the timer:
|
|
if ( m_queue.isEmpty() )
|
|
{
|
|
killTimer( m_timer_id );
|
|
}
|
|
|
|
m_proc->clearArguments();
|
|
|
|
TQStringList list = TQStringList::split( "\n", m_buffer, false );
|
|
|
|
m_buffer = TQString();
|
|
|
|
// Check whether an error occurred:
|
|
if ( list.grep( "NT_STATUS" ).count() != 0 )
|
|
{
|
|
// Something went wrong. Let's check if this "only" an
|
|
// authentication issue or if we have to error out:
|
|
|
|
TQString error_code = list.grep( "NT_STATUS" ).first().stripWhiteSpace().section( " ", 0, 0 );
|
|
|
|
// The error output of smbclient is a little bit inconsistent:
|
|
if ( error_code.contains( "NT_STATUS" ) == 0 )
|
|
{
|
|
error_code = list.grep( "NT_STATUS" ).first().stripWhiteSpace().section( " ", -1, -1 );
|
|
}
|
|
|
|
// Authentication issue?
|
|
if ( TQString::compare( error_code, "NT_STATUS_ACCESS_DENIED" ) == 0 ||
|
|
TQString::compare( error_code, "NT_STATUS_LOGON_FAILURE" ) == 0 )
|
|
{
|
|
int state = Smb4KPasswordHandler::None;
|
|
|
|
if ( TQString::compare( error_code, "NT_STATUS_ACCESS_DENIED" ) == 0 )
|
|
{
|
|
state = Smb4KPasswordHandler::AccessDenied;
|
|
}
|
|
else if ( TQString::compare( error_code, "NT_STATUS_LOGON_FAILURE" ) == 0 )
|
|
{
|
|
state = Smb4KPasswordHandler::LogonFailure;
|
|
}
|
|
|
|
if ( passwordHandler()->askpass( m_item->workgroup(), m_item->host(),
|
|
m_item->share(), state,
|
|
kapp->mainWidget() ? kapp->mainWidget() : 0,
|
|
"AskPass" ) )
|
|
{
|
|
// Now we have a password. Retry.
|
|
// NOTE: Since the item is appended to the queue, there might
|
|
// be the case, that another preview is generated before the
|
|
// retry is executed. I think, we can live with that.
|
|
preview( m_item );
|
|
}
|
|
else
|
|
{
|
|
// The user cancelled the askpass dialog. We won't show an
|
|
// error dialog here, but will only clear the contents of
|
|
// the preview item and emit the failed() signal.
|
|
m_item->clearContents();
|
|
|
|
emit failed();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// OK, error out. We cannot recover from it:
|
|
Smb4KError::error( ERROR_GETTING_PREVIEW, TQString(), m_buffer );
|
|
|
|
m_item->clearContents();
|
|
|
|
emit failed();
|
|
}
|
|
}
|
|
else if ( list.grep( "Connection to" ).count() != 0 ||
|
|
(list.grep( "Error returning browse list:" ).count() != 0 &&
|
|
list.grep( "NT_STATUS" ).count() == 0) )
|
|
{
|
|
// These are errors that we cannot work around. Error out.
|
|
Smb4KError::error( ERROR_GETTING_PREVIEW, TQString(), m_buffer );
|
|
|
|
m_item->clearContents();
|
|
|
|
emit failed();
|
|
}
|
|
else
|
|
{
|
|
for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
if ( (*it).stripWhiteSpace().startsWith( "Domain" ) ||
|
|
(*it).stripWhiteSpace().startsWith( "OS" ) ||
|
|
(*it).stripWhiteSpace().startsWith( "Anonymous" ) )
|
|
{
|
|
continue;
|
|
}
|
|
else if ( (*it).contains( "blocks of size" ) != 0 )
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
TQString tmp = (*it).stripWhiteSpace().section( " ", 0, -9 ).stripWhiteSpace();
|
|
|
|
TQString item = tmp.section( " ", 0, -2 ).stripWhiteSpace();
|
|
|
|
if ( !item.isEmpty() && tmp.section( " ", -1, -1 ).contains( "D" ) != 0 )
|
|
{
|
|
// We have a directory here.
|
|
if ( item.startsWith( "." ) &&
|
|
(TQString::compare( item.stripWhiteSpace(), "." ) != 0 &&
|
|
TQString::compare( item.stripWhiteSpace(), ".." ) != 0) )
|
|
{
|
|
m_item->addContents( ContentsItem( Smb4KPreviewItem::HiddenDirectory, item ) );
|
|
}
|
|
else
|
|
{
|
|
m_item->addContents( ContentsItem( Smb4KPreviewItem::Directory, item ) );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if ( item.isEmpty() || tmp.section( " ", -1, -1 ).contains( "D" ) == 0 )
|
|
{
|
|
// We have a file
|
|
if ( item.isEmpty() )
|
|
{
|
|
if ( tmp.startsWith( "." ) )
|
|
{
|
|
m_item->addContents( ContentsItem( Smb4KPreviewItem::HiddenFile, tmp ) );
|
|
}
|
|
else
|
|
{
|
|
m_item->addContents( ContentsItem( Smb4KPreviewItem::File, tmp ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( item.startsWith( "." ) )
|
|
{
|
|
m_item->addContents( ContentsItem( Smb4KPreviewItem::HiddenFile, item ) );
|
|
}
|
|
else
|
|
{
|
|
m_item->addContents( ContentsItem( Smb4KPreviewItem::File, item ) );
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
emit result( m_item );
|
|
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
m_working = false;
|
|
|
|
emit state( PREVIEWER_STOP );
|
|
}
|
|
|
|
#include "smb4kpreviewer.moc"
|