summaryrefslogtreecommitdiffstats
path: root/smb4k/core/smb4tdefileio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'smb4k/core/smb4tdefileio.cpp')
-rw-r--r--smb4k/core/smb4tdefileio.cpp1795
1 files changed, 1795 insertions, 0 deletions
diff --git a/smb4k/core/smb4tdefileio.cpp b/smb4k/core/smb4tdefileio.cpp
new file mode 100644
index 0000000..617763c
--- /dev/null
+++ b/smb4k/core/smb4tdefileio.cpp
@@ -0,0 +1,1795 @@
+/***************************************************************************
+ smb4tdefileio - Does file IO operations for Smb4K
+ -------------------
+ begin : Do Jan 1 2004
+ copyright : (C) 2004-2007 by Alexander Reinholdt
+ email : dustpuppy@users.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 <tqdir.h>
+#include <tqfile.h>
+#include <tqtextstream.h>
+
+// KDE includes
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+// system specific includes
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <grp.h>
+#include <pwd.h>
+
+// application specific includes
+#include "smb4tdefileio.h"
+#include "smb4kdefs.h"
+#include "smb4kerror.h"
+#include "smb4kglobal.h"
+#include "smb4ksettings.h"
+
+using namespace Smb4TDEGlobal;
+
+
+
+Smb4KFileIO::Smb4KFileIO( TQObject *parent, const char *name ) : TQObject( parent, name )
+{
+ m_operation = NoOperation;
+ m_state = Idle;
+ m_error_occurred = false;
+
+ m_proc = new TDEProcess( this, "FileIOProcess" );
+ m_proc->setUseShell( true );
+
+ connect( m_proc, TQT_SIGNAL( receivedStderr( TDEProcess *, char *, int ) ),
+ this, TQT_SLOT( slotReceivedStderr( TDEProcess *, char *, int ) ) );
+
+ connect( m_proc, TQT_SIGNAL( receivedStdout( TDEProcess *, char *, int ) ),
+ this, TQT_SLOT( slotReceivedStdout( TDEProcess *, char *, int ) ) );
+
+ connect( m_proc, TQT_SIGNAL( processExited( TDEProcess * ) ),
+ this, TQT_SLOT( slotProcessExited( TDEProcess * ) ) );
+
+ connect( kapp, TQT_SIGNAL( shutDown() ),
+ this, TQT_SLOT( slotShutdown() ) );
+}
+
+
+Smb4KFileIO::~Smb4KFileIO()
+{
+}
+
+
+bool Smb4KFileIO::writeSudoers( Smb4KFileIO::Operation operation )
+{
+ m_operation = operation;
+ bool ok = false;
+
+ // Stop here if nothing has changed:
+ if ( m_operation == NoOperation )
+ {
+ emit finished();
+
+ ok = true;
+
+ return ok;
+ }
+
+ TQString file = "sudoers";
+
+ if ( createLockFile( file ) )
+ {
+ // Find the file first:
+ TQCString canonical_path = findFile( file );
+
+ if ( !canonical_path.isEmpty() )
+ {
+ // Stat the file, so that we know that it is safe to
+ // read from and write to it and whether we need to
+ // ask for the super user's password:
+ struct stat buf;
+
+ if ( lstat( canonical_path, &buf ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, canonical_path, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Look for the groups the user is in:
+ long ngroups_max;
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+
+ gid_t list[ngroups_max];
+
+ if ( getgroups( ngroups_max, list ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_GIDS, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ return ok; // false
+ }
+
+ gid_t sup_gid = 65534; // set this to gid 'nobody' for initialization
+ bool found_gid = false;
+ int i = 0;
+
+ while ( list[i] )
+ {
+ if ( list[i] == buf.st_gid )
+ {
+ sup_gid = list[i];
+ found_gid = true;
+ }
+
+ i++;
+ }
+
+ // Error out if the file is irregular.
+ // Yes, yes, I know that this is normally done in a different
+ // way and that there might be a race here, but, hey, right here
+ // I don't care!
+ if ( !S_ISREG( buf.st_mode ) || S_ISFIFO( buf.st_mode ) || S_ISLNK( buf.st_mode ) )
+ {
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, canonical_path, TQString() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Check access rights:
+ if ( (buf.st_uid == getuid() && (buf.st_mode & 00600) == (S_IWUSR | S_IRUSR)) /* user */ ||
+ (found_gid && buf.st_gid == sup_gid && (buf.st_mode & 00060) == (S_IWGRP | S_IRGRP)) /* group */ ||
+ ((buf.st_mode & 00006) == (S_IWOTH | S_IROTH)) /* others */ )
+ {
+ // The user has read and write access.
+
+ TQFile file ( canonical_path );
+ TQStringList contents;
+
+ if ( file.open( IO_ReadWrite ) )
+ {
+ TQTextStream ts( &file );
+ ts.setEncoding( TQTextStream::Locale );
+
+ contents = TQStringList::split( "\n", ts.read(), true );
+
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ TQString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( "User_Alias\tSMB4KUSERS = "+TQString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+ contents.append( "Defaults:SMB4KUSERS\tenv_keep += \"PASSWD USER\"" );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_kill() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_umount() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_mount() );
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+TQString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) )
+ {
+ TQString users = (*it).section( "=", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( TQString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ TQStringList list = TQStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ file.close();
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ };
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ TQStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Now write the contents to the file. The permissions
+ // will be preserved by this action.
+ ts << contents.join( "\n" ) << endl;
+
+ file.close();
+ }
+ else
+ {
+ // The entries are already in the file.
+ }
+
+ ok = true;
+
+ emit finished();
+
+ removeLockFile();
+
+ return ok;
+ }
+ else
+ {
+ Smb4KError::error( ERROR_OPENING_FILE, canonical_path, file.errorString() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The user does not have enough access rights to perform
+ // the modification of the sudoers file. So, we need to use
+ // tdesu to get the contents of the file.
+
+ // Compose the command:
+ TQString command;
+ command.append( "tdesu -t -c \"smb4k_cat " );
+ command.append( canonical_path+"\"" );
+ command.append( " ; sleep 2" );
+
+ m_state = ReadSudoers;
+
+ ok = true;
+
+ *m_proc << command;
+ m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
+
+ // The process is not finished, so finished() will be emitted
+ // later and the lock file will also be removed at the end.
+
+ return ok;
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_FILE_NOT_FOUND, canonical_path );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The error message has already been shown by
+ // Smb4KFileIO::createLockFile()
+ emit failed();
+ emit finished();
+
+ // We need not remove the lock file here.
+
+ return ok; // false
+ }
+
+ return ok;
+}
+
+
+bool Smb4KFileIO::writeSuperTab( Smb4KFileIO::Operation operation )
+{
+ m_operation = operation;
+ bool ok = false;
+
+ // Stop here if nothing has changed:
+ if ( m_operation == NoOperation )
+ {
+ emit finished();
+
+ ok = true;
+
+ return ok;
+ }
+
+ TQString file = "super.tab";
+
+ if ( createLockFile( file ) )
+ {
+ // Find the file first:
+ TQCString canonical_path = findFile( file );
+
+ if ( !canonical_path.isEmpty() )
+ {
+ // Stat the file, so that we know that it is safe to
+ // read from and write to it and whether we need to
+ // ask for the super user's password:
+ struct stat buf;
+
+ if ( lstat( canonical_path, &buf ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, canonical_path, strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Look for the groups the user is in:
+ long ngroups_max;
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+
+ gid_t list[ngroups_max];
+
+ if ( getgroups( ngroups_max, list ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_GIDS, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ return ok; // false
+ }
+
+ gid_t sup_gid = 65534; // set this to gid 'nobody' for initialization
+ bool found_gid = false;
+ int i = 0;
+
+ while ( list[i] )
+ {
+ if ( list[i] == buf.st_gid )
+ {
+ sup_gid = list[i];
+ found_gid = true;
+ }
+
+ i++;
+ }
+
+ // Error out if the file is irregular.
+ // Yes, yes, I know that this is normally done in a different
+ // way and that there might be a race here, but, hey, right here
+ // I don't care!
+ if ( !S_ISREG( buf.st_mode ) || S_ISFIFO( buf.st_mode ) || S_ISLNK( buf.st_mode ) )
+ {
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, canonical_path, TQString() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ // Check access rights:
+ if ( (buf.st_uid == getuid() && (buf.st_mode & 00600) == (S_IWUSR | S_IRUSR)) /* user */ ||
+ (found_gid && buf.st_gid == sup_gid && (buf.st_mode & 00060) == (S_IWGRP | S_IRGRP)) /* group */ ||
+ ((buf.st_mode & 00006) == (S_IWOTH | S_IROTH)) /* others */ )
+ {
+ // The user has read and write access.
+
+ TQFile file ( canonical_path );
+ TQStringList contents;
+
+ if ( file.open( IO_ReadWrite ) )
+ {
+ TQTextStream ts( &file );
+ ts.setEncoding( TQTextStream::Locale );
+
+ contents = TQStringList::split( "\n", ts.read(), true );
+
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+
+ TQString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( ":define Smb4KUsers "+TQString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+#ifndef __FreeBSD__
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root\tenv=PASSWD,USER" );
+#else
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel\tsetenv=HOME=$CALLER_HOME\tenv=PASSWD,USER" );
+#endif
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+TQString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) )
+ {
+ TQString users = (*it).section( "Smb4KUsers", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( TQString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ TQStringList list = TQStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ file.close();
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ };
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ TQStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Now write the contents to the file. The permissions
+ // will be preserved by this action.
+ ts << contents.join( "\n" ) << endl;
+
+ file.close();
+ }
+ else
+ {
+ // The entries are already in the file.
+ }
+
+ ok = true;
+
+ emit finished();
+
+ removeLockFile();
+
+ return ok;
+ }
+ else
+ {
+ Smb4KError::error( ERROR_OPENING_FILE, canonical_path, file.errorString() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The user does not have enough access rights to perform
+ // the modification of the sudoers file. So, we need to use
+ // tdesu to get the contents of the file.
+
+ // Compose the command:
+ TQString command;
+ command.append( "tdesu -t -c \"smb4k_cat " );
+ command.append( canonical_path+"\"" );
+ command.append( " ; sleep 2" );
+
+ m_state = ReadSuperTab;
+
+ ok = true;
+
+ *m_proc << command;
+ m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
+
+ // The process is not finished, so finished() will be emitted
+ // later and the lock file will also be removed at the end.
+
+ return ok;
+ }
+ }
+ else
+ {
+ Smb4KError::error( ERROR_FILE_NOT_FOUND, canonical_path );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // The error message has already been shown by
+ // Smb4KFileIO::createLockFile()
+ emit failed();
+ emit finished();
+
+ // We need not remove the lock file here.
+
+ return ok; // false
+ }
+
+ return ok;
+}
+
+
+bool Smb4KFileIO::createLockFile( const TQString &filename )
+{
+ bool ok = false;
+
+ // Determine the directory where to write the lock file. First, try
+ // /var/lock and than /var/tmp. If that does not work either, fall
+ // back to /tmp.
+ if ( m_lock_file.isEmpty() )
+ {
+ TQValueList<TQCString> dirs;
+ dirs << "/var/lock" << "/var/tmp" << "/tmp";
+
+ struct stat buf;
+
+ for ( TQValueList<TQCString>::ConstIterator it = dirs.begin(); it != dirs.end(); ++it )
+ {
+ // First check if the directory is available and writable
+ if ( lstat( *it, &buf ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_number != EACCES && error_number != ENOENT )
+ {
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, *it, strerror( error_number ) );
+
+ return ok; // false
+ }
+ }
+ else
+ {
+ // Look for the groups the user is in:
+ long ngroups_max;
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+
+ gid_t list[ngroups_max];
+
+ if ( getgroups( ngroups_max, list ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_GIDS, TQString(), strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ gid_t sup_gid = 65534; // set this to gid 'nobody' for initialization
+ bool found_gid = false;
+ int i = 0;
+
+ while ( list[i] )
+ {
+ if ( list[i] == buf.st_gid )
+ {
+ sup_gid = list[i];
+ found_gid = true;
+ }
+
+ i++;
+ }
+
+ // Check whether we are stat'ing a directory and that the
+ // user has read/write permissions.
+ if ( S_ISDIR( buf.st_mode ) /* is directory */ &&
+ (buf.st_uid == getuid() && (buf.st_mode & 00600) == (S_IWUSR | S_IRUSR)) /* user */ ||
+ (found_gid && buf.st_gid == sup_gid && (buf.st_mode & 00060) == (S_IWGRP | S_IRGRP)) /* group */ ||
+ ((buf.st_mode & 00006) == (S_IWOTH | S_IROTH)) /* others */ )
+ {
+ m_lock_file = *it+"/smb4k.lock";
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+ }
+
+ int file_descriptor;
+
+ // Create the lock file if necessary and open it:
+ if ( (file_descriptor = open( m_lock_file, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH )) == -1 )
+ {
+ // Error out if the opening failed:
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_OPENING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+ else
+ {
+ // Check what we actually opened:
+
+ struct stat file_stat;
+
+ if ( fstat( file_descriptor, &file_stat ) == -1 )
+ {
+ // Error out if we could not get the information about the file:
+ int error_number = errno;
+
+ // FIXME for >= 0.8.x: Change error code to ERROR_GETTING_STAT
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, TQString(), strerror( error_number ) );
+
+ return ok;
+ }
+
+ if ( !S_ISREG( file_stat.st_mode ) || S_ISFIFO( file_stat.st_mode ) || S_ISLNK( file_stat.st_mode ) )
+ {
+ // Close the file and error out, if we have opened an
+ // "irregular" file (i.e. a symlink, a fifo, etc.).
+
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, m_lock_file );
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+ else
+ {
+ // Continue if the file is regular.
+
+ char buffer[1000];
+ ssize_t size;
+
+ if ( (size = read( file_descriptor, buffer, 1000 )) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_READING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ if ( size >= 1000 )
+ {
+ // FIXME for >= 0.8.x: Change error code to ERROR_BUFFER_EXCEEDED
+ Smb4KError::error( ERROR_UNKNOWN, TQString(), i18n( "Buffer size exceeded" ) );
+
+ return ok; // false
+ }
+
+ TQStringList contents = TQStringList::split( '\n', TQString::fromLocal8Bit( buffer, size ), false );
+ TQString test_string = ":"+filename;
+ TQString entry = contents.grep( test_string, true ).join( "\n" ).stripWhiteSpace();
+
+ if ( !entry.isEmpty() )
+ {
+ Smb4KError::error( ERROR_LOCKED, entry );
+
+ return ok; // false
+ }
+ else
+ {
+ contents << TQString( "%1:%2" ).arg( getpwuid( getuid() )->pw_name ).arg( filename );
+ TQCString out = contents.join( "\n" ).local8Bit();
+
+ if ( write( file_descriptor, out, out.length() ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_WRITING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+
+ return ok; // false
+ }
+
+ ok = true;
+ }
+ }
+ }
+
+ return ok;
+}
+
+
+bool Smb4KFileIO::removeLockFile( const bool error_message )
+{
+ // We already have the name and location of the lock
+ // file, so we do not need to define it here.
+
+ int file_descriptor;
+ bool ok = false;
+
+ // Open the lock file:
+ if ( (file_descriptor = open( m_lock_file, O_RDWR )) == -1 )
+ {
+ // Error out if the opening failed:
+ int error_number = errno;
+
+ if ( error_message && error_number != ENOENT )
+ {
+ Smb4KError::error( ERROR_OPENING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+ else
+ {
+ // Check what we actually opened:
+
+ struct stat file_stat;
+
+ if ( fstat( file_descriptor, &file_stat ) == -1 )
+ {
+ // Error out if we could not get the information about the file:
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ // FIXME for >= 0.8.x: Change error code to ERROR_GETTING_STAT
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, TQString(), strerror( error_number ) );
+ }
+
+ return ok;
+ }
+
+ if ( !S_ISREG( file_stat.st_mode ) || S_ISFIFO( file_stat.st_mode ) || S_ISLNK( file_stat.st_mode ) )
+ {
+ // Close the file and error out, if we have opened an
+ // "irregular" file (i.e. a symlink, a fifo, etc.).
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_FILE_IS_IRREGULAR, m_lock_file );
+ }
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+ }
+
+ return ok; // false
+ }
+ else
+ {
+ // Continue if the file is regular.
+
+ char buffer[1000];
+ ssize_t size;
+
+ if ( (size = read( file_descriptor, buffer, 1000 )) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_READING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ if ( size >= 1000 )
+ {
+ if ( error_message )
+ {
+ // FIXME for >= 0.8.x: Change error code to ERROR_BUFFER_EXCEEDED
+ Smb4KError::error( ERROR_UNKNOWN, TQString(), i18n( "Buffer size exceeded" ) );
+ }
+
+ return ok; // false
+ }
+
+ TQStringList contents = TQStringList::split( '\n', TQString::fromLocal8Bit( buffer, size ), false );
+
+ // Prepare the contents of the file and write it to the disk.
+ // It it should be empty, remove the lock file.
+ for ( TQStringList::Iterator it = contents.begin(); it != contents.end(); it++ )
+ {
+ if ( (*it).startsWith( TQString( getpwuid( getuid() )->pw_name )+":" ) )
+ {
+ *it = TQString();
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ contents.remove( TQString() );
+
+ if ( !contents.isEmpty() )
+ {
+ // Write the remaining contents to the lock file:
+
+ TQCString out = contents.join( "\n" ).local8Bit();
+
+ if ( write( file_descriptor, out, out.length() ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ ok = true;
+ }
+ else
+ {
+ // Close and remove the lock file:
+
+ if ( close( file_descriptor ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ Smb4KError::error( ERROR_CLOSING_FILE, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ if ( unlink( m_lock_file ) == -1 )
+ {
+ int error_number = errno;
+
+ if ( error_message )
+ {
+ // FIXME for > 0.8.x: Replace error code with ERROR_REMOVING_FILE
+ Smb4KError::error( ERROR_UNKNOWN, m_lock_file, strerror( error_number ) );
+ }
+
+ return ok; // false
+ }
+
+ ok = true;
+ }
+ }
+ }
+
+ return ok;
+}
+
+
+const TQCString Smb4KFileIO::findFile( const TQString &filename )
+{
+ TQStringList paths;
+ paths << "/etc";
+ paths << "/etc/samba";
+ paths << "/usr/local/etc";
+ paths << "/usr/local/etc/samba";
+
+ TQString canonical_path = TQString();
+
+ for ( TQStringList::ConstIterator it = paths.begin(); it != paths.end(); it++ )
+ {
+ TQDir::setCurrent( *it );
+
+ if ( TQFile::exists( filename ) )
+ {
+ canonical_path = TQDir::current().canonicalPath()+"/"+filename;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ return canonical_path.local8Bit();
+}
+
+
+void Smb4KFileIO::processSudoers()
+{
+ // If the output buffer is empty, we stop, because
+ // that most likely means, the user cancelled the
+ // tdesu dialog.
+ if ( m_buffer.stripWhiteSpace().isEmpty() )
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ TQStringList contents = TQStringList::split( "\n", m_buffer, true );
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+
+ TQString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( "User_Alias\tSMB4KUSERS = "+TQString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+ contents.append( "Defaults:SMB4KUSERS\tenv_keep += \"PASSWD USER\"" );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_kill() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_umount() );
+ contents.append( "SMB4KUSERS\t"+hostname+" = NOPASSWD: "+Smb4KSettings::smb4k_mount() );
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+TQString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the sudoers file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( "User_Alias\tSMB4KUSERS" ) )
+ {
+ TQString users = (*it).section( "=", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( TQString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ TQStringList list = TQStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+ }
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ TQStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Create a temporary file and write the data to it:
+ TQCString template_string = tempDir().local8Bit()+"/XXXXXX";
+ char tmp[template_string.length()+1];
+ (void) tqstrncpy( tmp, template_string, template_string.length()+1 );
+
+ TQFile temp_file;
+ int file_descriptor;
+
+ if ( (file_descriptor = mkstemp( tmp )) == -1 )
+ {
+ int err = errno;
+
+ Smb4KError::error( ERROR_CREATING_TEMP_FILE, tmp, strerror( err ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ if ( temp_file.open( IO_WriteOnly, file_descriptor ) )
+ {
+ TQTextStream ts( &temp_file );
+ ts.setEncoding( TQTextStream::Locale );
+
+ ts << contents.join( "\n" ) << endl;
+
+ temp_file.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, temp_file.name() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ // Now move the file to the right location. Preserve the permissions
+ // and the owner:
+ TQString canonical_path = findFile( "sudoers" );
+ struct stat file_stat;
+
+ if ( stat( canonical_path.local8Bit(), &file_stat ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ TQString perms = TQString( "%1" ).arg( (int)file_stat.st_mode, 0, 8 );
+ perms = perms.right( 4 );
+ TQString owner = TQString( "%1" ).arg( (int)file_stat.st_uid );
+ TQString group = TQString( "%1" ).arg( (int)file_stat.st_gid );
+ TQString temp_file_name = TQString( tmp );
+
+ // Assemble the command.
+ TQString command;
+ command.append( "tdesu -n -c \"smb4k_mv "+owner+":"+group+" "+perms+" " );
+ command.append( temp_file_name+" " );
+ command.append( canonical_path+"\" ; " );
+ command.append( "rm -f "+temp_file_name );
+
+ m_state = WriteSudoers;
+
+ *m_proc << command;
+
+ m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
+ }
+ else
+ {
+ // Everything OK.
+ emit finished();
+
+ removeLockFile();
+ }
+}
+
+
+void Smb4KFileIO::processSuperTab()
+{
+ // If the output buffer is empty, we stop, because
+ // that most likely means, the user cancelled the
+ // tdesu dialog.
+ if ( m_buffer.stripWhiteSpace().isEmpty() )
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ TQStringList contents = TQStringList::split( "\n", m_buffer, true );
+ bool write = false;
+
+ switch ( m_operation )
+ {
+ case Insert:
+ {
+ size_t hostnamelen = 255;
+ char *hn = new char[hostnamelen];
+
+ if ( gethostname( hn, hostnamelen ) == -1 )
+ {
+ int error_number = errno;
+ Smb4KError::error( ERROR_GETTING_HOSTNAME, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+
+ TQString hostname( hn );
+
+ delete [] hn;
+
+ if ( contents.grep( "# Entries for Smb4K users." ).count() == 0 )
+ {
+ contents.append( "# Entries for Smb4K users." );
+ contents.append( "# Generated by Smb4K. Please do not modify!" );
+ contents.append( ":define Smb4KUsers "+TQString( "%1" ).arg( getpwuid( getuid() )->pw_name ) );
+#ifndef __FreeBSD__
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=root\tenv=PASSWD,USER" );
+#else
+ contents.append( "smb4k_kill\t"+Smb4KSettings::smb4k_kill()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_umount\t"+Smb4KSettings::smb4k_umount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel" );
+ contents.append( "smb4k_mount\t"+Smb4KSettings::smb4k_mount()+
+ "\t$(Smb4KUsers)\tuid=root\tgid=wheel\tsetenv=HOME=$CALLER_HOME\tenv=PASSWD,USER" );
+#endif
+ contents.append( "# End of Smb4K user entries." );
+
+ write = true;
+ }
+ else
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) && (*it).contains( getpwuid( getuid() )->pw_name, true ) == 0 )
+ {
+ (*it).append( ","+TQString( getpwuid( getuid() )->pw_name ) );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+ case Remove:
+ {
+ // Find the beginning and the end of the entries in
+ // the super.tab file:
+ TQStringList::Iterator begin = contents.find( "# Entries for Smb4K users." );
+ TQStringList::Iterator end = contents.find( "# End of Smb4K user entries." );
+
+ // Now, check if the user is in the list of users. If he is,
+ // remove him from there or remove all if he is the only one:
+ for ( TQStringList::Iterator it = begin; it != end; ++it )
+ {
+ if ( (*it).startsWith( ":define Smb4KUsers" ) )
+ {
+ TQString users = (*it).section( "Smb4KUsers", 1, 1 ).stripWhiteSpace();
+
+ if ( users.contains( "," ) == 0 )
+ {
+ // In this case, there is only one user in the list. Check if
+ // it is the user who requested the removal:
+ if ( TQString::compare( users, getpwuid( getuid() )->pw_name ) == 0 )
+ {
+ // They are equal. Remove everything:
+ contents.erase( begin, end );
+ contents.remove( end );
+
+ write = true;
+
+ break;
+ }
+ else
+ {
+ // They are not equal: Do nothing.
+ break;
+ }
+ }
+ else
+ {
+ // In this case there is more than one user in the list.
+ // Remove the user who requested the removal:
+ TQStringList list = TQStringList::split( ",", users, false );
+ list.remove( getpwuid( getuid() )->pw_name );
+
+ (*it).replace( users, list.join( "," ) );
+
+ write = true;
+
+ break;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+ }
+
+ if ( write )
+ {
+ // Prepare the contents: remove empty lines from the end.
+ TQStringList::Iterator it = contents.end();
+
+ // Move the iterator to the last entry in the list:
+ --it;
+
+ while ( (*it).stripWhiteSpace().isEmpty() )
+ {
+ it = contents.remove( it );
+ --it;
+ }
+
+ // Create a temporary file and write the data to it:
+ TQCString template_string = tempDir().local8Bit()+"/XXXXXX";
+ char tmp[template_string.length()+1];
+ (void) tqstrncpy( tmp, template_string, template_string.length()+1 );
+
+ TQFile temp_file;
+ int file_descriptor;
+
+ if ( (file_descriptor = mkstemp( tmp )) == -1 )
+ {
+ int err = errno;
+
+ Smb4KError::error( ERROR_CREATING_TEMP_FILE, tmp, strerror( err ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ if ( temp_file.open( IO_WriteOnly, file_descriptor ) )
+ {
+ TQTextStream ts( &temp_file );
+ ts.setEncoding( TQTextStream::Locale );
+
+ ts << contents.join( "\n" ) << endl;
+
+ temp_file.close();
+ }
+ else
+ {
+ Smb4KError::error( ERROR_WRITING_FILE, temp_file.name() );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ // Now move the file to the right location. Preserve the permissions
+ // and the owner:
+ TQString canonical_path = findFile( "super.tab" );
+ struct stat file_stat;
+
+ if ( stat( canonical_path.local8Bit(), &file_stat ) == -1 )
+ {
+ int error_number = errno;
+
+ Smb4KError::error( ERROR_GETTING_PERMISSIONS, TQString(), strerror( error_number ) );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+
+ return;
+ }
+
+ TQString perms = TQString( "%1" ).arg( (int)file_stat.st_mode, 0, 8 );
+ perms = perms.right( 4 );
+ TQString owner = TQString( "%1" ).arg( (int)file_stat.st_uid );
+ TQString group = TQString( "%1" ).arg( (int)file_stat.st_gid );
+ TQString temp_file_name = TQString( tmp );
+
+ // Assemble the command.
+ TQString command;
+ command.append( "tdesu -n -c \"smb4k_mv "+owner+":"+group+" "+perms+" " );
+ command.append( temp_file_name+" " );
+ command.append( canonical_path+"\" ; " );
+ command.append( "rm -f "+temp_file_name );
+
+ m_state = WriteSuperTab;
+
+ *m_proc << command;
+
+ m_proc->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput );
+ }
+ else
+ {
+ // Everything OK.
+ emit finished();
+
+ removeLockFile();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// TQT_SLOT IMPLEMENTATIONS
+/////////////////////////////////////////////////////////////////////////////
+
+void Smb4KFileIO::slotShutdown()
+{
+ removeLockFile( false );
+}
+
+
+void Smb4KFileIO::slotReceivedStderr( TDEProcess *, char *buf, int len )
+{
+ TQString error_output = TQString::fromLocal8Bit( buf, len );
+
+ if ( error_output.contains( "smb4k_mv" ) != 0 )
+ {
+ m_error_occurred = true;
+
+ TQString canonical_path = findFile( (m_state == WriteSudoers ? "sudoers" : "super.tab") );
+
+ Smb4KError::error( ERROR_WRITING_FILE, canonical_path, m_buffer );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+ else if ( error_output.contains( "smb4k_cat" ) != 0 )
+ {
+ m_error_occurred = true;
+
+ TQString canonical_path = findFile( (m_state == ReadSudoers ? "sudoers" : "super.tab") );
+
+ Smb4KError::error( ERROR_READING_FILE, canonical_path, m_buffer );
+
+ emit failed();
+ emit finished();
+
+ removeLockFile();
+ }
+}
+
+
+void Smb4KFileIO::slotReceivedStdout( TDEProcess *, char *buf, int len )
+{
+ m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
+}
+
+
+void Smb4KFileIO::slotProcessExited( TDEProcess * )
+{
+ m_proc->clearArguments();
+
+ if ( !m_error_occurred )
+ {
+ switch ( m_state )
+ {
+ case ReadSudoers:
+ {
+ processSudoers();
+
+ break;
+ }
+ case WriteSudoers:
+ {
+ emit finished();
+
+ removeLockFile();
+
+ break;
+ }
+ case ReadSuperTab:
+ {
+ processSuperTab();
+
+ break;
+ }
+ default:
+ {
+ emit finished();
+
+ removeLockFile();
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Smb4KFileIO::slotReceivedStderr() has already done the
+ // necessary things.
+ }
+
+ m_buffer = TQString();
+ m_state = Idle;
+ m_error_occurred = false;
+}
+
+#include "smb4tdefileio.moc"