/////////////////////////////////////////////////////////////////////////////
//                                                                         
// Project:     SMB kioslave for KDE2
//
// File:        kio_smb.h  
//                                                                         
// Abstract:    The main kio slave class declaration.  For convenience, 
//              in concurrent devlopment, the implementation for this class 
//              is separated into several .cpp files -- the file containing
//              the implementation should be noted in the comments for each
//              member function.
//
// Author(s):   Matthew Peterson <mpeterson@caldera.com>
//
//---------------------------------------------------------------------------
//                                                                  
// Copyright (c) 2000  Caldera Systems, Inc.                        
//                                                                         
// 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.1 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 Lesser General Public License for more details.                 
//                                                                         
//     You should have received a copy of the GNU General Public License 
//     along with this program; see the file COPYING.  If not, please obtain
//     a copy from http://www.gnu.org/copyleft/gpl.html   
//                                                                         
/////////////////////////////////////////////////////////////////////////////


#ifndef KIO_SMB_H_INCLUDED
#define KIO_SMB_H_INCLUDED

//-------------
// QT includes
//-------------
#include <qstring.h>
#include <qptrlist.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include <qstrlist.h> 

//--------------
// KDE includes
//--------------
#include <kdebug.h>
#include <kinstance.h>
#include <kio/global.h>
#include <kio/slavebase.h>
#include <kurl.h>
#include <klocale.h>  

//-----------------------------
// Standard C library includes
//-----------------------------
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <stdio.h> 
#include <errno.h>
#include <time.h>


//-------------------------------
// Samba client library includes
//-------------------------------
extern "C" 
{
#include <libsmbclient.h>
}
                                 
//---------------------------
// kio_smb internal includes
//---------------------------
#include "kio_smb_internal.h"

#define MAX_XFER_BUF_SIZE           16348
#define TEXT_UNKNOWN_ERROR          i18n("Unknown error condition")
#define TEXT_SMBC_INIT_FAILED       i18n("libsmbclient failed to initialize")
#define TEXT_OUT_OF_MEMORY          i18n("Out of memory")
#define TEXT_AUTHENTICATION_PROMPT  i18n("Enter workgroup/domain authentication information")
#define TEXT_NOSRV_WG               i18n("Server or workgroup could not be found")
#define KIO_SMB                     7106


using namespace KIO; 

//===========================================================================


class SMBSlave : public KIO::SlaveBase
{
private:
    //---------------------------------------------------------------------
    // please make sure your private data does not duplicate existing data
    //---------------------------------------------------------------------
    bool     m_initialized_smbc;

    /**
     * From Controlcenter
     */
    QString  m_default_user;
    QString  m_default_workgroup;
    QString  m_default_password;
    QString  m_default_encoding;

    /**
     * we store the current url, it's needed for
     * callback authorisation method
     */
    SMBUrl   m_current_url;

    /**
     * From Controlcenter, show SHARE$ or not
     */
    bool m_showHiddenShares;

    QPtrList<SMBAuthInfo> m_auth_cache;

    /**
     * libsmbclient need global variables to store in,
     * else it crashes on exit next method after use cache_stat,
     * looks like gcc (C/C++) failure 
     */
    struct stat st;
protected:
    //---------------------------------------------
    // Authentication functions (kio_smb_auth.cpp) 
    //---------------------------------------------
    // (please prefix functions with auth)


    /**
     * Description :   Initilizes the libsmbclient
     * Return :        0 on success -1 with errno set on error
     */
    int auth_initialize_smbc();

    //---------------------------------------------
    // Cache functions (kio_smb_auth.cpp)
    //---------------------------------------------

    //Authentication methods
    /** Description : open auth dialog and cache userinfo if OK button pressed
        Parameter :   SMBAuthInfo auth, workgroup, server, share are shown in dlg
                                 could be username, domain and passwd are changed
        Return :      false if authDlg cancled, else true and username, domain
                      and passwd are changed in SMBAuth
    */
    bool authDlg(SMBAuthInfo& auth);

    /**
     * Description :  search for a cached userinfo
     * Parameter :    SMBAuth.m_server and SMBAuth.m_share are searchparameter
     * Return :       true if found, else false
     *                if true : SMBAuth.m_username
     *                          SMBAuth.m_domain
     *                          SMBAuth.m_password
     *                are changed
     */
    bool cache_get_AuthInfo( SMBAuthInfo& auth );

    /**
     * Description :  Remove an authinfo
     * Parameter :    SMBAuthInfo.m_server and SMBAuthInfo.m_share are
     *                searchparameter
     */
    void cache_clear_AuthInfo(const SMBAuthInfo& auth);

    /**
     * Description :  cache an authinfo
     * Parameter :    SMBAuthInfo the info to cache
     *                store_in_kdesu if true other kioslaves 
     *                can use the info 
     */
    void cache_set_AuthInfo( const SMBAuthInfo& auth, bool store_in_kdesu=false );

    //Stat methods


    /**
     * Description :  call smbc_stat and return stats of the url
     * Parameter :    SMBUrl the url to stat
     * Return :       stat* of the url
     * Note :         it has some problems with stat in method, looks like
     *                something leave(or removed) on the stack. If your
     *                method segfault on returning try to change the stat*
     *                variable
     */
    int cache_stat( const SMBUrl& url, struct stat* st );

    /**
     * Description :  create a KIO::AuthInfo structure from the SMBAuthInfo struct
     */
    AuthInfo cache_create_AuthInfo( const SMBAuthInfo& auth );


    /**
     * Description :  open a passworddialog and set the new information 
     *                in SMBAuthInfo. Update m_current_url and cache it.
     *                (Not Implemented : we should redirect if new username or
     *                 domain is given)
     * Parameter :    SMBAuthInfo.m_username will be shown in passworddialog
     * Return :       true if user pressed ok, else false
     *                if true   
     *                   SMBAuthInfo.m_username
     *                   SMBAuthInfo.m_domain
     *                   SMBAuthInfo.m_password 
     *                are changed. 
     */
    bool setAuthInfo(SMBAuthInfo &auth);
    
    //-----------------------------------------
    // Browsing functions (kio_smb_browse.cpp) 
    //-----------------------------------------
    // (please prefix functions with browse)

    /**
     * Description :  Return a stat of given SMBUrl. Calls cache_stat and 
     *                pack it in UDSEntry. UDSEntry will not be cleared
     * Parameter :    SMBUrl the url to stat
     * Return :       false if any error occoured (errno), else true 
     */
    bool browse_stat_path(const SMBUrl& url, UDSEntry& udsentry);
    
    //---------------------------------------------
    // Configuration functions (kio_smb_config.cpp) 
    //---------------------------------------------
    // (please prefix functions with config)
    

    //---------------------------------------
    // Directory functions (kio_smb_dir.cpp) 
    //---------------------------------------
    // (please prefix functions with dir)


    //--------------------------------------
    // File IO functions (kio_smb_file.cpp) 
    //--------------------------------------
    // (please prefix functions with file)

    //----------------------------
    // Misc functions (this file)
    //----------------------------


    /**
     * Description :  correct a given URL
     *                valid URL's are
     * 
     *                smb://[[domain;]user[:password]@]server[:port][/share[/path[/file]]]
     *                smb:/[[domain;]user[:password]@][group/[server[/share[/path[/file]]]]]
     *                domain   = workgroup(domain) of the user
     *                user     = username
     *                password = password of useraccount
     *                group    = workgroup(domain) of server
     *                server   = host to connect
     *                share    = a share of the server (host)
     *                path     = a path of the share
     * Parameter :    KURL the url to check
     * Return :       new KURL if its corrected. else the same KURL
     */
    const KURL checkURL(const KURL& kurl);

    /**
     * Change from char* (MS Windows's character encoding) to QString
     */
    QString toUnicode( char *_str ) const;

public:

    //-----------------------------------------------------------------------
    // smbclient authentication callback (note that this is called by  the
    // global ::auth_smbc_get_data() call.
    void auth_smbc_get_data(const char *server,const char *share,
                            char *workgroup, int wgmaxlen,
                            char *username, int unmaxlen,
                            char *password, int pwmaxlen);


    //-----------------------------------------------------------------------
    // Overwritten functions from the base class that define the operation of
    // this slave. (See the base class headerfile slavebase.h for more 
    // details)
    //-----------------------------------------------------------------------

    // Functions overwritten in kio_smb.cpp
    SMBSlave(const QCString& pool, const QCString& app);
    virtual ~SMBSlave();
    
    // Functions overwritten in kio_smb_browse.cpp
    virtual void listDir( const KURL& url );
    virtual void stat( const KURL& url );

    // Functions overwritten in kio_smb_config.cpp
    virtual void reparseConfiguration();

    // Functions overwritten in kio_smb_dir.cpp
    virtual void copy( const KURL& src, const KURL &dest, int permissions, bool overwrite );
    virtual void del( const KURL& kurl, bool isfile);
    virtual void mkdir( const KURL& kurl, int permissions );
    virtual void rename( const KURL& src, const KURL& dest, bool overwrite );

    // Functions overwritten in kio_smb_file.cpp
    virtual void get( const KURL& kurl );
    virtual void put( const KURL& kurl, int permissions, bool overwrite, bool resume );

    // Functions not implemented  (yet)
    //virtual void setHost(const QString& host, int port, const QString& user, const QString& pass);
    //virtual void openConnection();
    //virtual void closeConnection();
    //virtual void slave_status();
    //virtual void special( const QByteArray & );
};

//===========================================================================
// pointer to the slave created in kdemain
extern SMBSlave* G_TheSlave;


//==========================================================================
// the global libsmbclient authentication callback function
extern "C"
{

void auth_smbc_get_data(const char *server,const char *share,
                        char *workgroup, int wgmaxlen,
                        char *username, int unmaxlen,
                        char *password, int pwmaxlen);

}


//===========================================================================
// Main slave entrypoint (see kio_smb.cpp)
extern "C" 
{ 

int kdemain( int argc, char **argv ); 

}


#endif  //#endif KIO_SMB_H_INCLUDED
