/***************************************************************************
    smb4kfileio  -  Does file IO operations for Smb4K
                             -------------------
    begin                : Do Jan 1 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., 59 Temple Place, Suite 330, Boston,   *
 *   MA  02111-1307 USA                                                    *
 ***************************************************************************/

#ifndef SMB4KFILEIO_H
#define SMB4KFILEIO_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

// Qt includes
#include <qobject.h>
#include <qvaluelist.h>
#include <qstring.h>
#include <qcstring.h>

// application specific includes
#include "smb4kuser.h"

/**
 * This class belongs to the core classes of Smb4K. It handles IO
 * operations that are performed on system configuration files.
 *
 * @author Alexander Reinholdt <dustpuppy@mail.berlios.de>
 */

class Smb4KFileIO : public QObject
{
  Q_OBJECT

  public:
    /**
     * The constructor
     *
     * @param parent      The parent object of this class
     *
     * @param name        The name of this class
     */
    Smb4KFileIO( QObject *parent = 0, const char *name = 0 );

    /**
     * The destructor
     */
    ~Smb4KFileIO();

    /**
     * Writes the entries needed to gain super user rights to either the super.tab or
     * the sudoers file depending on the input values.
     *
     * @param program         The name of the program that should be used to gain super
     *                        user privileges.
     *
     * @param force           Should be TRUE is the "Force Unmount" config entry will be/is set to TRUE.
     *
     * @param full_use        Should be TRUE if the "Run SUID" config entry will be/is set to TRUE.
     */
    bool writeSuperUserEntries( const QString &program, bool force = false, bool full_use = false );

    /**
     * Removes the entries of a user from the file /etc/super.tab.
     *
     * @return true in case of success and false otherwise.
     */
    bool removeSuperUserEntries( const QString &program = QString::null );

    /**
     * Returns the list of non-system users. For this purpose, the file /etc/
     */
    const QValueList<Smb4KUser *> getUsers();

  signals:
    /**
     * This signal is emitted when somthing went wrong with the writing to
     * the system configuration files.
     */
    void failed();

    /**
     * This signal is emitted when the writing to the system configuration
     * files has finished. It is emitted in case the writing was successful
     * as well as in case it wasn't.
     */
    void finished();

  protected slots:
    /**
     * This slot is invokes when the application is closed. It is connected
     * to KApplication::shutDown().
     */
    void slotShutdown();
    /**
     * This slot receives shell program output from Stderr.
     */
    void slotReceivedStderr( KProcess *proc, char *buf, int len );
    /**
     * This slot receives shell program output from Stdout.
     */
    void slotReceivedStdout( KProcess *proc, char *buf, int len );
    /**
     * This slot is called, when the process exited.
     */
    void slotProcessExited( KProcess * );

  private:
    /**
     * Read a system configuration file. This function takes the name of the
     * file and returns its contents.
     *
     * @param filename        The name of the file (e.g. passwd)
     *
     * @returns the contents of the file.
     */
    QStringList readFile( const QString &filename );

    /**
     * Write a system configuration file. This function needs the file name
     * and the contents that is to be written to succeed. It returns TRUE on
     * success and FALSE otherwise.
     *
     * @param filename        The name of the file
     *
     * @param contents        The contents that should be written
     *
     * @returns TRUE on success and FALSE otherwise.
     */
    bool writeFile( const QString &filename, const QStringList &contents );

    /**
     * This function creates a lock file in /tmp if it does not
     * exist already. If the user is not allowed to write to the
     * desired file a the moment, the user will be shown an error
     * dialog and the function will return FALSE.
     *
     * Checks are performed to make sure it is save to write to an
     * existing lock file using the system call lstat().
     *
     * @param filename        The name of the file that is to be modified.
     *
     * @returns TRUE if the creation was successful and FALSE if
     * something went wrong.
     */
    bool createLockFile( const QString &filename );

    /**
     * This function removes the lock file or at least the
     * entry within it.
     *
     * Checks are performed to make sure it is save to write to an
     * existing lock file using the system call lstat().
     *
     * @param shutdown        Should be set to FALSE if you do not want to have
     *                        any error message shown. Otherwise you should set it
     *                        to TRUE.
     *
     * @returns TRUE if the removal was successful and FALSE if
     * something went wrong.
     */
    bool removeLockFile( const bool error_message = true );

    /**
     * This function finds a file.
     *
     * @param filename        The name of the file
     *
     * @returns the canonical path of the file or an empty string if it could not be
     *          found.
     */
    const QString findFile( const QString &filename );

    /**
     * This enumeration is for the processes that are used to read and write files.
     *
     * @param WriteSuperTab   Write the file super.tab
     *
     * @param ReadSuperTab    Read the file super.tab
     *
     * @param WriteSudoers    Write the file sudoers
     *
     * @param ReadSudoers     Read the file sudoers
     *
     * @param Idle            Do nothing
     */
    enum Processes{ WriteSuperTab, ReadSuperTab, WriteSudoers, ReadSudoers, Idle };

    /**
     * This enumeration determines what to do when processing data that
     * was retrieved via the smb4k_cat method.
     *
     * @param SuperTabAdd     Add an entry to the /etc/super.tab
     *
     * @param SuperTabRemove  Remove an entry from the super.tab
     *
     * @param SudoersAdd      Add an entry to /etc/sudoers
     *
     * @param SudoersRemove   Remove an entry from /etc/sudoers
     *
     * @param DoNothing       Do nothing
     */
    enum TODO{ SuperTabAdd, SuperTabRemove, SudoersAdd, SudoersRemove, DoNothing };

    /**
     * This integer holds one of the entries of the enumeration above.
     */
    int m_state;

    /**
     * This integer holds a value from the @p TODO enumeration.
     */
    int m_todo;

    /**
     * This buffer holds the output that was received at Stdout.
     */
    QString m_output_buffer;

    /**
     * This function precesses the output that was retrieved by a shell
     * process.
     *
     * @param filename        The name of the file that should later be written
     */
    void processOutput( const QString &filename );

    /**
     * Enumeration for errors.
     */
    enum Error{ None, Move, Cat };

    /**
     * Holds the error code.
     */
    int m_error_code;

   /**
    * This is the absolute path of the lock file.
    */
   QCString m_lock_file;
};


#endif
