You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/filesharing/simple/fileshare.cpp

444 lines
13 KiB

/*
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 &not 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 << "\nRESTRICT=";
stream << (m_restricted ? "yes" : "no");
stream << "\nSHARINGMODE=";
stream << (m_ccgui->simpleRadio->isChecked() ? "simple" : "advanced");
stream << "\nFILESHAREGROUP=";
stream << m_fileShareGroup;
stream << "\nSAMBA=";
stream << (m_ccgui->sambaChk->isChecked() ? "yes" : "no");
stream << "\nNFS=";
stream << (m_ccgui->nfsChk->isChecked() ? "yes" : "no");
stream << "\nROOTPASSNEEDED=";
stream << (m_rootPassNeeded ? "yes" : "no");
stream << "\nSMBCONF=";
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"