/*************************************************************************** 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 #include // KDE includes #include #include #include // system includes #include #include // 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"