/*
Copyright ( c ) 2002 Laurent Montel < lmontel @ mandrakesoft . com >
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 .
*/
# include <unistd.h>
# include <tqlayout.h>
# include <tqvbuttongroup.h>
# include <tqvgroupbox.h>
# include <tqlabel.h>
# include <tqdir.h>
# include <tqradiobutton.h>
# include <tqcheckbox.h>
# include <tqtooltip.h>
# include <tqvbox.h>
# include <kpushbutton.h>
# include <kdebug.h>
# include <kdialog.h>
# include <kdialogbase.h>
# include <kgenericfactory.h>
# include <klistview.h>
# include <kiconloader.h>
# include <knfsshare.h>
# include <ksambashare.h>
# include <kfileshare.h>
# include <kstandarddirs.h>
# include <ksimpleconfig.h>
# include <kmessagebox.h>
# include <kapplication.h>
# include <kuser.h>
# include <kurl.h>
# include <kprocess.h>
# include <krichtextlabel.h>
# include "../advanced/propsdlgplugin/propertiespage.h"
# include "../advanced/nfs/nfsfile.h"
# include "../advanced/kcm_sambaconf/sambafile.h"
# include "controlcenter.h"
# include "fileshare.h"
# include "groupconfigdlg.h"
typedef KGenericFactory < KFileShareConfig , TQWidget > ShareFactory ;
K_EXPORT_COMPONENT_FACTORY ( kcm_fileshare , ShareFactory ( " kcmfileshare " ) )
# define FILESHARECONF " / etc / security / fileshare.conf"
# define FILESHARE_DEBUG 5009
KFileShareConfig : : KFileShareConfig ( TQWidget * tqparent , const char * name , const TQStringList & ) :
KCModule ( ShareFactory : : instance ( ) , tqparent , name )
{
KGlobal : : locale ( ) - > insertCatalogue ( " kfileshare " ) ;
TQBoxLayout * tqlayout = new TQVBoxLayout ( this , 0 ,
KDialog : : spacingHint ( ) ) ;
/*
TQVButtonGroup * box = new TQVButtonGroup ( i18n ( " File Sharing " ) , this ) ;
box - > tqlayout ( ) - > setSpacing ( KDialog : : spacingHint ( ) ) ;
tqlayout - > addWidget ( box ) ;
noSharing = new TQRadioButton ( i18n ( " Do ¬ allow users to share files " ) , box ) ;
sharing = new TQRadioButton ( i18n ( " &Allow users to share files from their HOME folder " ) , box ) ;
*/
m_ccgui = new ControlCenterGUI ( this ) ;
connect ( m_ccgui , TQT_SIGNAL ( changed ( ) ) , this , TQT_SLOT ( configChanged ( ) ) ) ;
connect ( m_ccgui - > allowedUsersBtn , TQT_SIGNAL ( clicked ( ) ) ,
this , TQT_SLOT ( allowedUsersBtnClicked ( ) ) ) ;
TQString path = TQString : : fromLocal8Bit ( getenv ( " PATH " ) ) ;
path + = TQString : : tqfromLatin1 ( " :/usr/sbin " ) ;
TQString sambaExec = KStandardDirs : : findExe ( TQString : : tqfromLatin1 ( " smbd " ) , path ) ;
TQString nfsExec = KStandardDirs : : findExe ( TQString : : tqfromLatin1 ( " rpc.nfsd " ) , path ) ;
if ( nfsExec . isEmpty ( ) & & sambaExec . isEmpty ( ) )
{
TQMessageBox : : critical ( 0 , " File Sharing " , TQString ( " SMB and NFS servers are not installed on this machine, to enable this module the servers must be installed. " ) ) ;
m_ccgui - > shareGrp - > setDisabled ( true ) ;
m_ccgui - > sharedFoldersGroupBox - > setDisabled ( true ) ;
}
else
{
if ( nfsExec . isEmpty ( ) ) {
m_ccgui - > nfsChk - > setDisabled ( true ) ;
m_ccgui - > nfsChk - > setChecked ( false ) ;
TQToolTip : : add ( m_ccgui - > nfsChk , i18n ( " No NFS server installed on this system " ) ) ;
}
if ( sambaExec . isEmpty ( ) ) {
m_ccgui - > sambaChk - > setDisabled ( true ) ;
m_ccgui - > sambaChk - > setChecked ( false ) ;
TQToolTip : : add ( m_ccgui - > sambaChk , i18n ( " No Samba server installed on this system " ) ) ;
}
m_ccgui - > infoLbl - > hide ( ) ;
tqlayout - > addWidget ( m_ccgui ) ;
updateShareListView ( ) ;
connect ( KNFSShare : : instance ( ) , TQT_SIGNAL ( changed ( ) ) ,
this , TQT_SLOT ( updateShareListView ( ) ) ) ;
connect ( KSambaShare : : instance ( ) , TQT_SIGNAL ( changed ( ) ) ,
this , TQT_SLOT ( updateShareListView ( ) ) ) ;
}
if ( ( getuid ( ) = = 0 ) | |
( ( KFileShare : : shareMode ( ) = = KFileShare : : Advanced ) & &
( KFileShare : : authorization ( ) = = KFileShare : : Authorized ) ) )
{
connect ( m_ccgui - > addShareBtn , TQT_SIGNAL ( clicked ( ) ) ,
this , TQT_SLOT ( addShareBtnClicked ( ) ) ) ;
connect ( m_ccgui - > changeShareBtn , TQT_SIGNAL ( clicked ( ) ) ,
this , TQT_SLOT ( changeShareBtnClicked ( ) ) ) ;
connect ( m_ccgui - > removeShareBtn , TQT_SIGNAL ( clicked ( ) ) ,
this , TQT_SLOT ( removeShareBtnClicked ( ) ) ) ;
m_ccgui - > listView - > setSelectionMode ( TQListView : : Extended ) ;
m_ccgui - > shareBtnPnl - > setEnabled ( true ) ;
}
if ( getuid ( ) = = 0 ) {
setButtons ( Help | Apply ) ;
} else {
setButtons ( Help ) ;
m_ccgui - > shareGrp - > setDisabled ( true ) ;
}
load ( ) ;
}
void KFileShareConfig : : updateShareListView ( )
{
m_ccgui - > listView - > clear ( ) ;
KNFSShare * nfs = KNFSShare : : instance ( ) ;
KSambaShare * samba = KSambaShare : : instance ( ) ;
TQStringList dirs = nfs - > sharedDirectories ( ) ;
TQStringList sambaDirs = samba - > sharedDirectories ( ) ;
for ( TQStringList : : ConstIterator it = sambaDirs . begin ( ) ; it ! = sambaDirs . end ( ) ; + + it ) {
// Do not insert duplicates
if ( nfs - > isDirectoryShared ( * it ) )
continue ;
dirs + = * it ;
}
TQPixmap folderPix = SmallIcon ( " folder " , 0 , KIcon : : ShareOverlay ) ;
TQPixmap okPix = SmallIcon ( " button_ok " ) ;
TQPixmap cancelPix = SmallIcon ( " button_cancel " ) ;
for ( TQStringList : : Iterator it = dirs . begin ( ) ; it ! = dirs . end ( ) ; + + it ) {
KListViewItem * item = new KListViewItem ( m_ccgui - > listView ) ;
item - > setText ( 0 , * it ) ;
item - > setPixmap ( 0 , folderPix ) ;
if ( samba - > isDirectoryShared ( * it ) )
item - > setPixmap ( 1 , okPix ) ;
else
item - > setPixmap ( 1 , cancelPix ) ;
if ( nfs - > isDirectoryShared ( * it ) )
item - > setPixmap ( 2 , okPix ) ;
else
item - > setPixmap ( 2 , cancelPix ) ;
}
}
void KFileShareConfig : : allowedUsersBtnClicked ( ) {
GroupConfigDlg dlg ( this , m_fileShareGroup , m_restricted , m_rootPassNeeded ,
m_ccgui - > simpleRadio - > isChecked ( ) ) ;
if ( dlg . exec ( ) = = TQDialog : : Accepted ) {
m_fileShareGroup = dlg . fileShareGroup ( ) . name ( ) ;
m_restricted = dlg . restricted ( ) ;
m_rootPassNeeded = dlg . rootPassNeeded ( ) ;
configChanged ( ) ;
}
}
void KFileShareConfig : : load ( )
{
KSimpleConfig config ( TQString : : tqfromLatin1 ( FILESHARECONF ) , true ) ;
m_ccgui - > shareGrp - > setChecked ( config . readEntry ( " FILESHARING " , " yes " ) = = " yes " ) ;
m_restricted = config . readEntry ( " RESTRICT " , " yes " ) = = " yes " ;
if ( config . readEntry ( " SHARINGMODE " , " simple " ) = = " simple " )
m_ccgui - > simpleRadio - > setChecked ( true ) ;
else
m_ccgui - > advancedRadio - > setChecked ( true ) ;
m_fileShareGroup = config . readEntry ( " FILESHAREGROUP " , " fileshare " ) ;
m_ccgui - > sambaChk - > setChecked (
config . readEntry ( " SAMBA " , " yes " ) = = " yes " ) ;
m_ccgui - > nfsChk - > setChecked (
config . readEntry ( " NFS " , " yes " ) = = " yes " ) ;
m_rootPassNeeded = config . readEntry ( " ROOTPASSNEEDED " , " yes " ) = = " yes " ;
m_smbConf = KSambaShare : : instance ( ) - > smbConfPath ( ) ;
}
bool KFileShareConfig : : addGroupAccessesToFile ( const TQString & file ) {
KProcess chgrp ;
chgrp < < " chgrp " < < m_fileShareGroup < < file ;
KProcess chmod ;
chmod < < " chmod " < < " g=rw " < < file ;
if ( ! chgrp . start ( KProcess : : Block ) & & chgrp . normalExit ( ) ) {
kdDebug ( FILESHARE_DEBUG ) < < " KFileShareConfig::addGroupAccessesToFile: chgrp failed " < < endl ;
return false ;
}
if ( ! chmod . start ( KProcess : : Block ) & & chmod . normalExit ( ) ) {
kdDebug ( FILESHARE_DEBUG ) < < " KFileShareConfig::addGroupAccessesToFile: chmod failed " < < endl ;
return false ;
}
return true ;
}
bool KFileShareConfig : : removeGroupAccessesFromFile ( const TQString & file ) {
KProcess chgrp ;
chgrp < < " chgrp " < < " root " < < file ;
KProcess chmod ;
chmod < < " chmod " < < " g=r " < < file ;
if ( ! chgrp . start ( KProcess : : Block ) & & chgrp . normalExit ( ) ) {
kdDebug ( FILESHARE_DEBUG ) < < " KFileShareConfig::removeGroupAccessesFromFile: chgrp failed " < < endl ;
return false ;
}
if ( ! chmod . start ( KProcess : : Block ) & & chmod . normalExit ( ) ) {
kdDebug ( FILESHARE_DEBUG ) < < " KFileShareConfig::removeGroupAccessesFromFile: chmod failed " < < endl ;
return false ;
}
return true ;
}
bool KFileShareConfig : : setGroupAccesses ( ) {
if ( m_rootPassNeeded | | ! m_ccgui - > sambaChk - > isChecked ( ) ) {
if ( ! removeGroupAccessesFromFile ( KSambaShare : : instance ( ) - > smbConfPath ( ) ) )
return false ;
}
if ( m_rootPassNeeded | | ! m_ccgui - > nfsChk - > isChecked ( ) ) {
if ( ! removeGroupAccessesFromFile ( KNFSShare : : instance ( ) - > exportsPath ( ) ) )
return false ;
}
if ( ! m_rootPassNeeded & & m_ccgui - > sambaChk - > isChecked ( ) ) {
if ( ! addGroupAccessesToFile ( KSambaShare : : instance ( ) - > smbConfPath ( ) ) )
return false ;
}
if ( ! m_rootPassNeeded & & m_ccgui - > nfsChk - > isChecked ( ) ) {
if ( ! addGroupAccessesToFile ( KNFSShare : : instance ( ) - > exportsPath ( ) ) )
return false ;
}
return true ;
}
void KFileShareConfig : : save ( )
{
setGroupAccesses ( ) ;
TQDir dir ( " /etc/security " ) ;
if ( ! dir . exists ( ) )
dir . mkdir ( " /etc/security " ) ;
TQFile file ( FILESHARECONF ) ;
if ( ! file . open ( IO_WriteOnly ) ) {
KMessageBox : : detailedError ( this ,
i18n ( " Could not save settings. " ) ,
i18n ( " Could not open file '%1' for writing: %2 " ) . tqarg ( FILESHARECONF ) . tqarg (
file . errorString ( ) ) ,
i18n ( " Saving Failed " ) ) ;
return ;
}
TQTextStream stream ( & file ) ;
stream < < " FILESHARING= " ;
stream < < ( m_ccgui - > shareGrp - > isChecked ( ) ? " yes " : " no " ) ;
stream < < " \n RESTRICT= " ;
stream < < ( m_restricted ? " yes " : " no " ) ;
stream < < " \n SHARINGMODE= " ;
stream < < ( m_ccgui - > simpleRadio - > isChecked ( ) ? " simple " : " advanced " ) ;
stream < < " \n FILESHAREGROUP= " ;
stream < < m_fileShareGroup ;
stream < < " \n SAMBA= " ;
stream < < ( m_ccgui - > sambaChk - > isChecked ( ) ? " yes " : " no " ) ;
stream < < " \n NFS= " ;
stream < < ( m_ccgui - > nfsChk - > isChecked ( ) ? " yes " : " no " ) ;
stream < < " \n ROOTPASSNEEDED= " ;
stream < < ( m_rootPassNeeded ? " yes " : " no " ) ;
stream < < " \n SMBCONF= " ;
stream < < m_smbConf ;
file . close ( ) ;
}
void KFileShareConfig : : defaults ( )
{
m_ccgui - > shareGrp - > setChecked ( false ) ;
}
TQString KFileShareConfig : : quickHelp ( ) const
{
return i18n ( " <h1>File Sharing</h1><p>This module can be used "
" to enable file sharing over the network using "
" the \" Network File System \" (NFS) or SMB in Konqueror. "
" The latter enables you to share your files with Windows(R) "
" computers on your network.</p> " ) ;
}
void KFileShareConfig : : addShareBtnClicked ( ) {
showShareDialog ( KFileItemList ( ) ) ;
}
PropertiesPageDlg : : PropertiesPageDlg ( TQWidget * tqparent , KFileItemList files )
: KDialogBase ( tqparent , " sharedlg " , true ,
i18n ( " Share Folder " ) , Ok | Cancel , Ok , true )
{
TQVBox * vbox = makeVBoxMainWidget ( ) ;
m_page = new PropertiesPage ( vbox , files , true ) ;
}
bool PropertiesPageDlg : : hasChanged ( ) {
return m_page - > hasChanged ( ) ;
}
void PropertiesPageDlg : : slotOk ( ) {
if ( hasChanged ( ) ) {
if ( ! m_page - > save ( ) )
return ;
}
KDialogBase : : slotOk ( ) ;
}
void KFileShareConfig : : showShareDialog ( const KFileItemList & files ) {
PropertiesPageDlg * dlg = new PropertiesPageDlg ( this , files ) ;
if ( dlg - > exec ( ) = = TQDialog : : Accepted ) {
if ( dlg - > hasChanged ( ) ) {
updateShareListView ( ) ;
}
}
delete dlg ;
}
void KFileShareConfig : : changeShareBtnClicked ( ) {
KFileItemList files ;
TQPtrList < TQListViewItem > items = m_ccgui - > listView - > selectedItems ( ) ;
TQListViewItem * item ;
for ( item = items . first ( ) ; item ; item = items . next ( ) ) {
files . append ( new KFileItem ( KURL : : fromPathOrURL ( item - > text ( 0 ) ) , " " , 0 ) ) ;
}
showShareDialog ( files ) ;
}
void KFileShareConfig : : removeShareBtnClicked ( ) {
TQPtrList < TQListViewItem > items = m_ccgui - > listView - > selectedItems ( ) ;
TQListViewItem * item ;
bool nfs = false ;
bool samba = false ;
for ( item = items . first ( ) ; item ; item = items . next ( ) ) {
if ( KNFSShare : : instance ( ) - > isDirectoryShared ( item - > text ( 0 ) ) )
nfs = true ;
if ( KSambaShare : : instance ( ) - > isDirectoryShared ( item - > text ( 0 ) ) )
samba = true ;
}
NFSFile nfsFile ( KNFSShare : : instance ( ) - > exportsPath ( ) ) ;
if ( nfs ) {
kdDebug ( FILESHARE_DEBUG ) < < " KFileShareConfig::removeShareBtnClicked: nfs = true " < < endl ;
nfsFile . load ( ) ;
for ( item = items . first ( ) ; item ; item = items . next ( ) ) {
nfsFile . removeEntryByPath ( item - > text ( 0 ) ) ;
}
}
SambaFile smbFile ( KSambaShare : : instance ( ) - > smbConfPath ( ) , false ) ;
if ( samba ) {
kdDebug ( FILESHARE_DEBUG ) < < " KFileShareConfig::removeShareBtnClicked: samba = true " < < endl ;
smbFile . load ( ) ;
for ( item = items . first ( ) ; item ; item = items . next ( ) ) {
smbFile . removeShareByPath ( item - > text ( 0 ) ) ;
}
}
PropertiesPage : : save ( & nfsFile , & smbFile , nfs , samba ) ;
updateShareListView ( ) ;
}
# include "fileshare.moc"