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.
smb4k/smb4k/core/smb4kprint.cpp

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 <kfileitem.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 "smb4kglobal.h"
#include "smb4kauthinfo.h"
#include "smb4kpasswordhandler.h"
#include "smb4kprintinfo.h"
#include "smb4ksettings.h"
using namespace Smb4KGlobal;
Smb4KPrint::Smb4KPrint( TQObject *tqparent, const char *name ) : TQObject( tqparent, name )
{
m_proc = new KProcess( this, "PrintProcess" );
m_proc->setUseShell( true );
m_info = NULL;
m_working = false;
connect( m_proc, TQT_SIGNAL( receivedStdout( KProcess *, char *, int ) ),
this, TQT_SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
connect( m_proc, TQT_SIGNAL( receivedStderr( KProcess *, char *, int ) ),
this, TQT_SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
connect( m_proc, TQT_SIGNAL( processExited( KProcess * ) ),
this, TQT_SLOT( slotProcessExited( KProcess * ) ) );
}
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" ).tqarg( auth->user().data(), auth->password().data() ).tqarg( m_info->workgroup(), m_info->host(), m_info->printer() );
}
else
{
uri = TQString( "smb://%1/%2/%3" ).tqarg( m_info->workgroup(), m_info->host(), m_info->printer() );
}
}
else
{
if ( !auth->user().isEmpty() )
{
uri = TQString( "smb://%1:%2@%3/%4" ).tqarg( auth->user().data(), auth->password().data() ).tqarg( m_info->host(), m_info->printer() );
}
else
{
uri = TQString( "smb://%1/%2" ).tqarg( 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" ).tqarg( m_info->copies() ) );
command.append( " \"\" "+KProcess::quote( m_info->path() ) );
*m_proc << command;
emit state( PRINT_START );
m_proc->start( KProcess::NotifyOnExit, KProcess::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 "+KProcess::quote( m_info->path().section( "/", 0, -2 ) )+" && " );
command.append( "dvips -P pdf -o "+temp_file+" "+KProcess::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" ).tqarg( m_info->copies() ) );
command.append( " \"\" "+KProcess::quote( temp_file )+" && " );
// Clean up:
command.append( "rm -f "+temp_file );
*m_proc << command;
emit state( PRINT_START );
m_proc->start( KProcess::NotifyOnExit, KProcess::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 "+KProcess::quote( temp_file )+" " );
command.append( KProcess::quote( m_info->path() )+ " && " );
// The actual print command:
command.append( "smbspool 111 "+TQString( getpwuid( getuid() )->pw_name ) );
command.append( " \"Smb4K print job\" "+TQString( "%1" ).tqarg( m_info->copies() ) );
command.append( " \"\" "+KProcess::quote( temp_file )+" && " );
// Clean up:
command.append( "rm -f "+temp_file );
*m_proc << command;
emit state( PRINT_START );
m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
}
/////////////////////////////////////////////////////////////////////////////
// TQT_SLOT IMPLEMENTATIONS
/////////////////////////////////////////////////////////////////////////////
void Smb4KPrint::slotReceivedStdout( KProcess *, char *buf, int len )
{
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
}
void Smb4KPrint::slotReceivedStderr( KProcess *, char *buf, int len )
{
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
if ( m_buffer.contains( "NT_STATUS" ) != 0 )
{
abort();
}
}
void Smb4KPrint::slotProcessExited( KProcess * )
{
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" ).tqarg( tempDir() ) );
}
}
else
{
// Clean up:
TQFile::remove( TQString( "%1/smb4k_print.ps" ).tqarg( 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"