/* Copyright (c) 2004 Jan Schaefer 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // NFS related #include "../nfs/nfsfile.h" #include "../nfs/nfsentry.h" #include "../nfs/nfsdialog.h" // Samba related #include "sambafile.h" #include "sambashare.h" #include "sharedlgimpl.h" #include "propertiespage.h" #define FILESHARE_DEBUG 5009 PropertiesPage::PropertiesPage(TQWidget* parent, KFileItemList items,bool enterUrl) : PropertiesPageGUI(parent), m_enterUrl(enterUrl), m_items(items), m_nfsFile(0), m_nfsEntry(0), m_sambaFile(0), m_sambaShare(0), m_sambaChanged(false), m_nfsChanged(false), m_loaded(false) { if (m_items.isEmpty()) { shareFrame->setDisabled(true); } else { shareFrame->setEnabled(true); // currently only one dir is allowed m_path = m_items.first()->url().path(1); } if (m_enterUrl) { shareChk->hide(); urlRq->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); urlRq->setURL(m_path); connect( urlRq, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(urlRqTextChanged(const TQString&))); } else { urlRq->hide(); folderLbl->hide(); } enableSamba(false,i18n("Reading Samba configuration file ...")); enableNFS(false,i18n("Reading NFS configuration file ...")); //TQTimer::singleShot(1, this, TQT_SLOT(load)); load(); } PropertiesPage::~PropertiesPage() { delete m_nfsFile; delete m_sambaFile; } void PropertiesPage::urlRqTextChanged(const TQString&) { if (!m_enterUrl) return; KURL url(urlRq->url()); if (url.isLocalFile()) { TQFileInfo info(url.path(1)); if (info.exists() && info.isDir()) { shareFrame->setEnabled(true); return; } } shareFrame->setDisabled(true); } void PropertiesPage::load() { loadNFS(); loadSamba(); bool nfsShared = KNFSShare::instance()->isDirectoryShared(m_path); bool sambaShared = KSambaShare::instance()->isDirectoryShared(m_path); nfsChk->setChecked(nfsShared); sambaChk->setChecked(sambaShared); if (!m_enterUrl) shareChk->setChecked(nfsShared || sambaShared); m_loaded = true; } void PropertiesPage::enableNFS(bool b, const TQString & message) { nfsChk->setEnabled(b); nfsGrp->setEnabled(b); TQToolTip::add(nfsChk,message); TQToolTip::add(nfsGrp,message); } void PropertiesPage::enableSamba(bool b, const TQString & message) { sambaChk->setEnabled(b); sambaGrp->setEnabled(b); TQToolTip::add(sambaChk,message); TQToolTip::add(sambaGrp,message); } bool PropertiesPage::save() { if (!hasChanged()) { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::save: nothing changed." << endl; return true; } if (!checkURL()) { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::save: url check failed." << endl; return false; } updateNFSEntry(); if (!updateSambaShare()) { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::save: updateSambaShare failed!" << endl; return false; } return save(m_nfsFile, m_sambaFile, m_nfsChanged, m_sambaChanged); } bool PropertiesPage::save(NFSFile* nfsFile, SambaFile* sambaFile, bool nfs, bool samba) { TQString nfsFileName = KNFSShare::instance()->exportsPath(); bool nfsNeedsTDEsu = false; if (nfs) { if (TQFileInfo(nfsFileName).isWritable()) { nfsFile->saveTo(nfsFileName); } else { nfsNeedsTDEsu = true; kdDebug(FILESHARE_DEBUG) << "PropertiesPage::save: nfs needs tdesu." << endl; } } else kdDebug(FILESHARE_DEBUG) << "PropertiesPage::save: nfs has not changed." << endl; TQString sambaFileName = KSambaShare::instance()->smbConfPath(); bool sambaNeedsTDEsu = false; if (samba) { if (TQFileInfo(sambaFileName).isWritable()) { sambaFile->saveTo(sambaFileName); } else { sambaNeedsTDEsu = true; kdDebug(FILESHARE_DEBUG) << "PropertiesPage::save: samba needs tdesu." << endl; } } else kdDebug(FILESHARE_DEBUG) << "PropertiesPage::save: samba has not changed." << endl; if (nfsNeedsTDEsu || sambaNeedsTDEsu) { KTempFile nfsTempFile; nfsTempFile.setAutoDelete(true); KTempFile sambaTempFile; sambaTempFile.setAutoDelete(true); KProcIO proc; TQString command; if (nfsNeedsTDEsu) { nfsFile->saveTo(nfsTempFile.name()); command += TQString("cp %1 %2;exportfs -ra;") .arg(TDEProcess::quote( nfsTempFile.name() )) .arg(TDEProcess::quote( nfsFileName )); } if (sambaNeedsTDEsu) { sambaFile->saveTo(sambaTempFile.name()); command += TQString("cp %1 %2;") .arg(TDEProcess::quote( sambaTempFile.name() )) .arg(TDEProcess::quote( sambaFileName )); } proc<<"tdesu" << "-d" << "-c"<save(); } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::saveSamba: samba has not changed." << endl; return true; } bool PropertiesPage::saveNFS() { updateNFSEntry(); if (!m_nfsChanged) { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::saveNFS: NFS did not change." << endl; return true; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::saveNFS: saving..." << endl; return m_nfsFile->save(); } bool PropertiesPage::checkURL() { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL" << endl; if (!m_enterUrl) return true; kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: enterUrl=true" << endl; KURL url(urlRq->url()); TQString path = url.path(1); kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: m_path='" << m_path << "'" << endl; kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: path='" << path << "'" << endl; if (m_path == path) { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: paths are equal" << endl; return true; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: different path" << endl; if (!url.isValid()) { KMessageBox::sorry(this,i18n("Please enter a valid path.")); urlRq->setFocus(); urlRq->lineEdit()->selectAll(); return false; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: url is valid" << endl; if (!url.isLocalFile()) { KMessageBox::sorry(this,i18n("Only local folders can be shared.")); urlRq->setFocus(); urlRq->lineEdit()->selectAll(); return false; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: url is local file" << endl; TQFileInfo info(path); if (!info.exists()) { KMessageBox::sorry(this,i18n("The folder does not exists.")); urlRq->setFocus(); urlRq->lineEdit()->selectAll(); return false; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: folder exits" << endl; if (!info.isDir()) { KMessageBox::sorry(this,i18n("Only folders can be shared.")); urlRq->setFocus(); urlRq->lineEdit()->selectAll(); return false; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: path is dir" << endl; if (KSambaShare::instance()->isDirectoryShared(path) || KNFSShare::instance()->isDirectoryShared(path)) { KMessageBox::sorry(this,i18n("The folder is already shared.")); urlRq->setFocus(); urlRq->lineEdit()->selectAll(); return false; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::checkURL: folder not shared yet" << endl; m_path = path; return true; } bool PropertiesPage::loadNFS() { if (!KFileShare::nfsEnabled()) { enableNFS(false,i18n("The administrator does not allow sharing with NFS.")); return false; } delete m_nfsFile; m_nfsFile = new NFSFile(KNFSShare::instance()->exportsPath()); if (!m_nfsFile->load()) { enableNFS(false,i18n("Error: could not read NFS configuration file.")); return false; } enableNFS(true,""); loadNFSEntry(); return true; } void PropertiesPage::loadNFSEntry() { m_nfsEntry = m_nfsFile->getEntryByPath(m_path); m_nfsChanged = false; if (!m_nfsEntry) { nfsChk->setChecked(false); return; } NFSHost* publicHost = m_nfsEntry->getPublicHost(); if (publicHost) { publicNFSChk->setChecked(true); writableNFSChk->setChecked(!publicHost->readonly); } else publicNFSChk->setChecked(false); } void PropertiesPage::updateNFSEntry() { if (shareChk->isChecked() && nfsChk->isChecked()) { if (!m_nfsEntry) { m_nfsEntry = new NFSEntry(m_path); m_nfsFile->addEntry(m_nfsEntry); m_nfsChanged = true; } NFSHost* publicHost = m_nfsEntry->getPublicHost(); if (publicNFSChk->isChecked()) { if (!publicHost) { publicHost = new NFSHost("*"); publicHost->allSquash=true; m_nfsEntry->addHost(publicHost); m_nfsChanged = true; } if (publicHost->readonly != !writableNFSChk->isChecked()) { publicHost->readonly = !writableNFSChk->isChecked(); m_nfsChanged = true; } } else { if (publicHost) { m_nfsEntry->removeHost(publicHost); m_nfsChanged = true; } } } else { // unshare if (m_nfsEntry) { m_nfsFile->removeEntry(m_nfsEntry); m_nfsEntry = 0; m_nfsChanged = true; } } } void PropertiesPage::moreNFSBtn_clicked() { updateNFSEntry(); NFSDialog* dlg = new NFSDialog(this,m_nfsEntry); if (dlg->exec()==TQDialog::Accepted && dlg->modified()) { kdDebug(FILESHARE_DEBUG) << "NFSDialog::ok" << endl; loadNFSEntry(); m_nfsChanged = true; emit changed(); } delete dlg; } bool PropertiesPage::loadSamba() { if (!KFileShare::sambaEnabled()) { enableSamba(false,i18n("The administrator does not allow sharing with Samba.")); return false; } delete m_sambaFile; m_sambaFile = new SambaFile(KSambaShare::instance()->smbConfPath(), false); if (! m_sambaFile->load()) { enableSamba(false,i18n("Error: could not read Samba configuration file.")); return false; } enableSamba(true,""); TQString shareName = m_sambaFile->findShareByPath(m_path); if (shareName.isNull()) { sambaChk->setChecked(false); kdDebug(FILESHARE_DEBUG) << "PropertiesPage::loadSamba: shareName is null!" << endl; return false; } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::loadSamba: shareName=" << shareName << endl; m_sambaShare = m_sambaFile->getShare(shareName); loadSambaShare(); return true; } void PropertiesPage::loadSambaShare() { if (! m_sambaShare) { sambaChk->setChecked(false); kdDebug(FILESHARE_DEBUG) << "PropertiesPage::loadSambaShare: no share with name " << m_sambaShare->getName() << endl; return; } if (m_sambaShare->getBoolValue("public")) { publicSambaChk->setChecked(true); writableSambaChk->setChecked(m_sambaShare->getBoolValue("writable")); } else publicSambaChk->setChecked(false); sambaNameEdit->setText(m_sambaShare->getName() ); } void PropertiesPage::sambaChkToggled( bool b ) { if (!m_loaded) return; if (sambaNameEdit->text().isEmpty()) sambaNameEdit->setText(getNewSambaName()); } bool PropertiesPage::updateSambaShare() { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::updateSambaShare" << endl; if (shareChk->isChecked() && sambaChk->isChecked()) { if (m_enterUrl) { if (m_path != urlRq->url()) { m_path = urlRq->url(); } } kdDebug(FILESHARE_DEBUG) << "PropertiesPage::updateSambaShare: m_path" << m_path << endl; if (!m_sambaShare) { createNewSambaShare(); m_sambaChanged = true; } setSambaShareBoolValue("public", publicSambaChk); setSambaShareBoolValue("writable", writableSambaChk); if (sambaNameEdit->text().isEmpty()) { KMessageBox::sorry(this, i18n("You have to enter a name for the Samba share.")); sambaNameEdit->setFocus(); return false; } if (sambaNameEdit->text() != m_sambaShare->getName()) { SambaShare* otherShare = m_sambaFile->getShare(sambaNameEdit->text()); if (otherShare && otherShare != m_sambaShare) { // There is another Share with the same name KMessageBox::sorry(this, i18n("There is already a share with the name %1.
Please choose another name.
").arg(sambaNameEdit->text())); sambaNameEdit->selectAll(); sambaNameEdit->setFocus(); return false; } m_sambaShare->setName(sambaNameEdit->text()); m_sambaChanged = true; } if (m_sambaShare->getValue("path") != m_path) { m_sambaShare->setValue("path", m_path); m_sambaChanged = true; } } else { if (m_sambaShare) { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::updateSambaShare: removing share" << endl; m_sambaFile->removeShare(m_sambaShare); m_sambaShare = 0; m_sambaChanged = true; } } return true; } void PropertiesPage::setSambaShareBoolValue(const TQString & value, TQCheckBox* chk) { bool v = m_sambaShare->getBoolValue(value); if (v == chk->isChecked()) return; m_sambaShare->setValue(value,chk->isChecked()); m_sambaChanged = true; } TQString PropertiesPage::getNewSambaName() { TQString path = m_path; if (path.isNull() && m_enterUrl) { path = urlRq->url(); } TQString shareName = KURL(path).fileName(); if (!sambaNameEdit->text().isEmpty()) shareName = sambaNameEdit->text(); // Windows could have problems with longer names shareName = shareName.left(12).upper(); if ( m_sambaFile->getShare(shareName) ) shareName = m_sambaFile->getUnusedName(shareName); return shareName; } void PropertiesPage::createNewSambaShare() { m_sambaShare = m_sambaFile->newShare(getNewSambaName(),m_path); kdDebug(FILESHARE_DEBUG) << "PropertiesPage::createNewSambaShare: " << m_sambaShare->getName() << endl; } void PropertiesPage::moreSambaBtnClicked() { kdDebug(FILESHARE_DEBUG) << "PropertiesPage::moreSambaBtnClicked()" << endl; updateSambaShare(); ShareDlgImpl* dlg = new ShareDlgImpl(this,m_sambaShare); dlg->directoryGrp->hide(); dlg->pixmapFrame->hide(); if (dlg->exec() == TQDialog::Accepted && dlg->hasChanged()) { m_sambaChanged = true; changedSlot(); loadSambaShare(); } delete dlg; } #include "propertiespage.moc"