diff options
Diffstat (limited to 'smb4k/core/smb4kprint.cpp')
-rw-r--r-- | smb4k/core/smb4kprint.cpp | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/smb4k/core/smb4kprint.cpp b/smb4k/core/smb4kprint.cpp new file mode 100644 index 0000000..9567926 --- /dev/null +++ b/smb4k/core/smb4kprint.cpp @@ -0,0 +1,372 @@ +/*************************************************************************** + 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 * + ***************************************************************************/ + +// Qt includes +#include <qtimer.h> +#include <qfile.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( QObject *parent, const char *name ) : QObject( parent, name ) +{ + m_proc = new KProcess( this, "PrintProcess" ); + m_proc->setUseShell( true ); + + m_info = NULL; + + m_working = false; + + connect( m_proc, SIGNAL( receivedStdout( KProcess *, char *, int ) ), + this, SLOT( slotReceivedStdout( KProcess *, char *, int ) ) ); + + connect( m_proc, SIGNAL( receivedStderr( KProcess *, char *, int ) ), + this, SLOT( slotReceivedStderr( KProcess *, char *, int ) ) ); + + connect( m_proc, SIGNAL( processExited( KProcess * ) ), + this, 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 ( QFile::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 ( QString::compare( file_item.mimetype(), "application/postscript" ) == 0 || + QString::compare( file_item.mimetype(), "application/pdf" ) == 0 || + file_item.mimetype().startsWith( "image" ) ) + { + setDeviceURI(); + printNormal(); + } + else if ( QString::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" ) || + QString::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() ) ); + + QString 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 = QString( "smb://%1:%2@%3/%4/%5" ).arg( auth->user(), auth->password() ).arg( m_info->workgroup(), m_info->host(), m_info->printer() ); + } + else + { + uri = QString( "smb://%1/%2/%3" ).arg( m_info->workgroup(), m_info->host(), m_info->printer() ); + } + } + else + { + if ( !auth->user().isEmpty() ) + { + uri = QString( "smb://%1:%2@%3/%4" ).arg( auth->user(), auth->password() ).arg( m_info->host(), m_info->printer() ); + } + else + { + uri = QString( "smb://%1/%2" ).arg( m_info->host(), m_info->printer() ); + } + } + + m_proc->setEnvironment( "DEVICE_URI", uri ); + + delete auth; +} + + +/**************************************************************************** + Do normal printing. +****************************************************************************/ + +void Smb4KPrint::printNormal() +{ + QString command; + + command.append( "smbspool 111 "+QString( getpwuid( getuid() )->pw_name ) ); + command.append( " \"Smb4K print job\" "+QString( "%1" ).arg( 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. + QString temp_file = tempDir()+"/smb4k_print.ps"; + + QString 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 "+QString( getpwuid( getuid() )->pw_name ) ); + command.append( " \"Smb4K print job\" "+QString( "%1" ).arg( 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. + QString temp_file = tempDir()+"/smb4k_print.ps"; + + QString 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 "+QString( getpwuid( getuid() )->pw_name ) ); + command.append( " \"Smb4K print job\" "+QString( "%1" ).arg( 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 ); +} + + +///////////////////////////////////////////////////////////////////////////// +// SLOT IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////////////// + +void Smb4KPrint::slotReceivedStdout( KProcess *, char *buf, int len ) +{ + m_buffer.append( QString::fromLocal8Bit( buf, len ) ); +} + + +void Smb4KPrint::slotReceivedStderr( KProcess *, char *buf, int len ) +{ + m_buffer.append( QString::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; + QTimer::singleShot( 50, this, SLOT( slotRetry() ) ); + } + } + else + { + Smb4KError::error( ERROR_PRINTING, m_info->path(), m_buffer ); + + // Clean up: + QFile::remove( QString( "%1/smb4k_print.ps" ).arg( tempDir() ) ); + } + } + else + { + // Clean up: + QFile::remove( QString( "%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" |