summaryrefslogtreecommitdiffstats
path: root/smb4k/core/smb4kprint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'smb4k/core/smb4kprint.cpp')
-rw-r--r--smb4k/core/smb4kprint.cpp372
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"