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.
373 lines
10 KiB
373 lines
10 KiB
/***************************************************************************
|
|
smb4kprint - The printing core class.
|
|
-------------------
|
|
begin : Tue Mar 30 2004
|
|
copyright : (C) 2004 by Alexander Reinholdt
|
|
email : dustpuppy@mail.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 <tqtimer.h>
|
|
#include <tqfile.h>
|
|
|
|
// KDE includes
|
|
#include <kurl.h>
|
|
#include <tdefileitem.h>
|
|
#include <kdebug.h>
|
|
|
|
// system includes
|
|
#include <sys/types.h>
|
|
#include <pwd.h>
|
|
|
|
// application specific includes
|
|
#include "smb4kprint.h"
|
|
#include "smb4kdefs.h"
|
|
#include "smb4kerror.h"
|
|
#include "smb4tdeglobal.h"
|
|
#include "smb4kauthinfo.h"
|
|
#include "smb4kpasswordhandler.h"
|
|
#include "smb4kprintinfo.h"
|
|
#include "smb4ksettings.h"
|
|
|
|
using namespace Smb4TDEGlobal;
|
|
|
|
|
|
|
|
Smb4KPrint::Smb4KPrint( TQObject *parent, const char *name ) : TQObject( parent, name )
|
|
{
|
|
m_proc = new TDEProcess( this, "PrintProcess" );
|
|
m_proc->setUseShell( true );
|
|
|
|
m_info = NULL;
|
|
|
|
m_working = false;
|
|
|
|
connect( m_proc, TQT_SIGNAL( receivedStdout( TDEProcess *, char *, int ) ),
|
|
this, TQT_SLOT( slotReceivedStdout( TDEProcess *, char *, int ) ) );
|
|
|
|
connect( m_proc, TQT_SIGNAL( receivedStderr( TDEProcess *, char *, int ) ),
|
|
this, TQT_SLOT( slotReceivedStderr( TDEProcess *, char *, int ) ) );
|
|
|
|
connect( m_proc, TQT_SIGNAL( processExited( TDEProcess * ) ),
|
|
this, TQT_SLOT( slotProcessExited( TDEProcess * ) ) );
|
|
}
|
|
|
|
|
|
Smb4KPrint::~Smb4KPrint()
|
|
{
|
|
abort();
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Aborts the current process.
|
|
****************************************************************************/
|
|
|
|
void Smb4KPrint::abort()
|
|
{
|
|
if ( m_proc->isRunning() )
|
|
{
|
|
m_proc->kill();
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Start the printing.
|
|
****************************************************************************/
|
|
|
|
bool Smb4KPrint::print( Smb4KPrintInfo *info )
|
|
{
|
|
// Do nothing if we receive a NULL pointer:
|
|
if ( !info )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_working = true;
|
|
m_info = info;
|
|
|
|
// Start processing the file:
|
|
if ( TQFile::exists( m_info->path() ) )
|
|
{
|
|
// Determine the mimetype of the file:
|
|
KURL url;
|
|
url.setPath( m_info->path() );
|
|
|
|
KFileItem file_item = KFileItem( KFileItem::Unknown, KFileItem::Unknown, url, false );
|
|
|
|
if ( TQString::compare( file_item.mimetype(), "application/postscript" ) == 0 ||
|
|
TQString::compare( file_item.mimetype(), "application/pdf" ) == 0 ||
|
|
file_item.mimetype().startsWith( "image" ) )
|
|
{
|
|
setDeviceURI();
|
|
printNormal();
|
|
}
|
|
else if ( TQString::compare( file_item.mimetype(), "application/x-dvi" ) == 0 &&
|
|
!Smb4KSettings::dvips().isEmpty() )
|
|
{
|
|
setDeviceURI();
|
|
printDVI();
|
|
}
|
|
else if ( (file_item.mimetype().startsWith( "text" ) ||
|
|
file_item.mimetype().startsWith( "message" ) ||
|
|
TQString::compare( file_item.mimetype(), "application/x-shellscript" ) == 0) &&
|
|
!Smb4KSettings::enscript().isEmpty() )
|
|
{
|
|
setDeviceURI();
|
|
printText();
|
|
}
|
|
else
|
|
{
|
|
Smb4KError::information( INFO_MIMETYPE_NOT_SUPPORTED, file_item.mimetype() );
|
|
|
|
delete m_info;
|
|
m_info = NULL;
|
|
|
|
m_working = false;
|
|
emit state( PRINT_STOP );
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Smb4KError::error( ERROR_FILE_NOT_FOUND, m_info->path() );
|
|
|
|
delete m_info;
|
|
m_info = NULL;
|
|
|
|
m_working = false;
|
|
emit state( PRINT_STOP );
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Sets the device URI
|
|
****************************************************************************/
|
|
|
|
void Smb4KPrint::setDeviceURI()
|
|
{
|
|
Smb4KAuthInfo *auth = passwordHandler()->readAuth( new Smb4KAuthInfo( m_info->workgroup(),
|
|
m_info->host(), m_info->printer() ) );
|
|
|
|
TQString uri;
|
|
|
|
// It seems that we must not quote the entries for the DEVICE_URI
|
|
// environment variable. Printing will fail if you do it.
|
|
|
|
if ( !m_info->workgroup().isEmpty() )
|
|
{
|
|
if ( !auth->user().isEmpty() )
|
|
{
|
|
uri = TQString( "smb://%1:%2@%3/%4/%5" ).arg( auth->user().data(), auth->password().data() ).arg( m_info->workgroup(), m_info->host(), m_info->printer() );
|
|
}
|
|
else
|
|
{
|
|
uri = TQString( "smb://%1/%2/%3" ).arg( m_info->workgroup(), m_info->host(), m_info->printer() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !auth->user().isEmpty() )
|
|
{
|
|
uri = TQString( "smb://%1:%2@%3/%4" ).arg( auth->user().data(), auth->password().data() ).arg( m_info->host(), m_info->printer() );
|
|
}
|
|
else
|
|
{
|
|
uri = TQString( "smb://%1/%2" ).arg( m_info->host(), m_info->printer() );
|
|
}
|
|
}
|
|
|
|
m_proc->setEnvironment( "DEVICE_URI", uri );
|
|
|
|
delete auth;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Do normal printing.
|
|
****************************************************************************/
|
|
|
|
void Smb4KPrint::printNormal()
|
|
{
|
|
TQString command;
|
|
|
|
command.append( "smbspool 111 "+TQString( getpwuid( getuid() )->pw_name ) );
|
|
command.append( " \"Smb4K print job\" "+TQString( "%1" ).arg( m_info->copies() ) );
|
|
command.append( " \"\" "+TDEProcess::quote( m_info->path() ) );
|
|
|
|
*m_proc << command;
|
|
|
|
emit state( PRINT_START );
|
|
|
|
m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Print DVI files.
|
|
****************************************************************************/
|
|
|
|
void Smb4KPrint::printDVI()
|
|
{
|
|
// The temporary file.
|
|
TQString temp_file = tempDir()+"/smb4k_print.ps";
|
|
|
|
TQString command;
|
|
|
|
// First we need the conversion:
|
|
command.append( "cd "+TDEProcess::quote( m_info->path().section( "/", 0, -2 ) )+" && " );
|
|
command.append( "dvips -P pdf -o "+temp_file+" "+TDEProcess::quote( m_info->path().section( "/", -1, -1 ) )+" && " );
|
|
|
|
// The actual print command:
|
|
command.append( "smbspool 111 "+TQString( getpwuid( getuid() )->pw_name ) );
|
|
command.append( " \"Smb4K print job\" "+TQString( "%1" ).arg( m_info->copies() ) );
|
|
command.append( " \"\" "+TDEProcess::quote( temp_file )+" && " );
|
|
|
|
// Clean up:
|
|
command.append( "rm -f "+temp_file );
|
|
|
|
*m_proc << command;
|
|
|
|
emit state( PRINT_START );
|
|
|
|
m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Print text files.
|
|
****************************************************************************/
|
|
|
|
void Smb4KPrint::printText()
|
|
{
|
|
// The temporary file.
|
|
TQString temp_file = tempDir()+"/smb4k_print.ps";
|
|
|
|
TQString command;
|
|
|
|
// Conversion:
|
|
command.append( "enscript --columns=1 --no-header --ps-level=2 " );
|
|
command.append( "-o "+TDEProcess::quote( temp_file )+" " );
|
|
command.append( TDEProcess::quote( m_info->path() )+ " && " );
|
|
|
|
// The actual print command:
|
|
command.append( "smbspool 111 "+TQString( getpwuid( getuid() )->pw_name ) );
|
|
command.append( " \"Smb4K print job\" "+TQString( "%1" ).arg( m_info->copies() ) );
|
|
command.append( " \"\" "+TDEProcess::quote( temp_file )+" && " );
|
|
|
|
// Clean up:
|
|
command.append( "rm -f "+temp_file );
|
|
|
|
*m_proc << command;
|
|
|
|
emit state( PRINT_START );
|
|
|
|
m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TQT_SLOT IMPLEMENTATIONS
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
void Smb4KPrint::slotReceivedStdout( TDEProcess *, char *buf, int len )
|
|
{
|
|
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
|
|
}
|
|
|
|
|
|
void Smb4KPrint::slotReceivedStderr( TDEProcess *, char *buf, int len )
|
|
{
|
|
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
|
|
|
|
if ( m_buffer.contains( "NT_STATUS" ) != 0 )
|
|
{
|
|
abort();
|
|
}
|
|
}
|
|
|
|
|
|
void Smb4KPrint::slotProcessExited( TDEProcess * )
|
|
{
|
|
bool retry = false;
|
|
|
|
if ( m_buffer.contains( "NT_STATUS", true ) != 0 ||
|
|
m_buffer.contains( "enscript", true ) != 0 ||
|
|
m_buffer.contains( "dvips", true ) != 0 )
|
|
{
|
|
if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 || m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 )
|
|
{
|
|
int state = Smb4KPasswordHandler::None;
|
|
|
|
if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 )
|
|
{
|
|
state = Smb4KPasswordHandler::AccessDenied;
|
|
}
|
|
else if (m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 )
|
|
{
|
|
state = Smb4KPasswordHandler::LogonFailure;
|
|
}
|
|
|
|
if ( passwordHandler()->askpass( m_info->workgroup(), m_info->host(), m_info->printer(), state ) )
|
|
{
|
|
retry = true;
|
|
TQTimer::singleShot( 50, this, TQT_SLOT( slotRetry() ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Smb4KError::error( ERROR_PRINTING, m_info->path(), m_buffer );
|
|
|
|
// Clean up:
|
|
TQFile::remove( TQString( "%1/smb4k_print.ps" ).arg( tempDir() ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Clean up:
|
|
TQFile::remove( TQString( "%1/smb4k_print.ps" ).arg( tempDir() ) );
|
|
}
|
|
|
|
m_proc->clearArguments();
|
|
|
|
if ( !retry )
|
|
{
|
|
delete m_info;
|
|
m_info = NULL;
|
|
}
|
|
|
|
m_working = false;
|
|
emit state( PRINT_STOP );
|
|
}
|
|
|
|
|
|
void Smb4KPrint::slotRetry()
|
|
{
|
|
print( m_info );
|
|
}
|
|
|
|
|
|
#include "smb4kprint.moc"
|