kfilesharedlg.cpp
00001 /* This file is part of the KDE project 00002 Copyright (c) 2001 David Faure <david@mandrakesoft.com> 00003 Copyright (c) 2001 Laurent Montel <lmontel@mandrakesoft.com> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License version 2 as published by the Free Software Foundation. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kfilesharedlg.h" 00021 #include <qvbox.h> 00022 #include <qlabel.h> 00023 #include <qdir.h> 00024 #include <qradiobutton.h> 00025 #include <qbuttongroup.h> 00026 #include <qlayout.h> 00027 #include <kprocess.h> 00028 #include <kprocio.h> 00029 #include <klocale.h> 00030 #include <kglobalsettings.h> 00031 #include <kstandarddirs.h> 00032 #include <kdebug.h> 00033 #include <stdio.h> 00034 #include <stdlib.h> 00035 #include <errno.h> 00036 #include <kio/kfileshare.h> 00037 #include <kseparator.h> 00038 #include <qpushbutton.h> 00039 #include <kapplication.h> 00040 #include <ksimpleconfig.h> 00041 #include <kmessagebox.h> 00042 00043 class KFileSharePropsPlugin::Private 00044 { 00045 public: 00046 QVBox *m_vBox; 00047 KProcess *m_configProc; 00048 bool m_bAllShared; 00049 bool m_bAllUnshared; 00050 }; 00051 00052 KFileSharePropsPlugin::KFileSharePropsPlugin( KPropertiesDialog *_props ) 00053 : KPropsDlgPlugin( _props ) 00054 { 00055 d = new Private; 00056 d->m_vBox = _props->addVBoxPage( i18n("&Share") ); 00057 d->m_configProc = 0; 00058 properties->setFileSharingPage(d->m_vBox); 00059 m_widget = 0L; 00060 init(); 00061 } 00062 00063 KFileSharePropsPlugin::~KFileSharePropsPlugin() 00064 { 00065 if (d->m_configProc) 00066 d->m_configProc->detach(); // Detach to prevent that we kill the process 00067 delete d; 00068 } 00069 00070 bool KFileSharePropsPlugin::supports( const KFileItemList& items ) 00071 { 00072 // Do not show dialog if in advanced mode, 00073 // because the advanced dialog is shown already. 00074 if (KFileShare::shareMode() == KFileShare::Advanced) { 00075 kdDebug() << "KFileSharePropsPlugin::supports: false because sharemode is advanced" << endl; 00076 return false; 00077 } 00078 00079 KFileItemListIterator it( items ); 00080 for ( ; it.current(); ++it ) 00081 { 00082 bool isLocal = ( *it )->isLocalFile(); 00083 // We only support local dirs 00084 if ( !(*it)->isDir() || !isLocal ) 00085 return false; 00086 // And sharing the trash doesn't make sense 00087 if ( isLocal && (*it)->url().path( 1 ) == KGlobalSettings::trashPath() ) 00088 return false; 00089 } 00090 return true; 00091 } 00092 00093 void KFileSharePropsPlugin::init() 00094 { 00095 // We store the main widget, so that it's possible (later) to call init() 00096 // more than once, to update the page if something changed (e.g. after 00097 // the user has been authorized) 00098 delete m_widget; 00099 m_rbShare = 0L; 00100 m_rbUnShare = 0L; 00101 m_widget = new QWidget( d->m_vBox ); 00102 QVBoxLayout * vbox = new QVBoxLayout( m_widget ); 00103 00104 switch ( KFileShare::authorization() ) { 00105 case KFileShare::Authorized: 00106 { 00107 // Check if all selected dirs are in $HOME 00108 QString home = QDir::homeDirPath(); 00109 if ( home[home.length()-1] != '/' ) 00110 home += '/'; 00111 bool ok = true; 00112 KFileItemList items = properties->items(); 00113 // We have 3 possibilities: all shared, all unshared, or mixed. 00114 d->m_bAllShared = true; 00115 d->m_bAllUnshared = true; 00116 KFileItemListIterator it( items ); 00117 for ( ; it.current() && ok; ++it ) { 00118 QString path = (*it)->url().path(); 00119 if ( !path.startsWith( home ) ) 00120 ok = false; 00121 if ( KFileShare::isDirectoryShared( path ) ) 00122 d->m_bAllUnshared = false; 00123 else 00124 d->m_bAllShared = false; 00125 } 00126 if ( !ok ) 00127 { 00128 vbox->addWidget( new QLabel( i18n( "Only folders in your home folder can be shared."), 00129 m_widget ), 0 ); 00130 } 00131 else 00132 { 00133 // Everything ok, show the share/unshare GUI 00134 vbox->setSpacing( KDialog::spacingHint() ); 00135 vbox->setMargin( KDialog::marginHint() ); 00136 00137 QButtonGroup *rbGroup = new QButtonGroup( m_widget ); 00138 rbGroup->hide(); 00139 m_rbUnShare = new QRadioButton( i18n("Not shared"), m_widget ); 00140 connect( m_rbUnShare, SIGNAL( toggled(bool) ), SIGNAL( changed() ) ); 00141 vbox->addWidget( m_rbUnShare, 0 ); 00142 rbGroup->insert( m_rbUnShare ); 00143 00144 m_rbShare = new QRadioButton( i18n("Shared"), m_widget ); 00145 connect( m_rbShare, SIGNAL( toggled(bool) ), SIGNAL( changed() ) ); 00146 vbox->addWidget( m_rbShare, 0 ); 00147 rbGroup->insert( m_rbShare ); 00148 00149 // Activate depending on status 00150 if ( d->m_bAllShared ) 00151 m_rbShare->setChecked(true); 00152 if ( d->m_bAllUnshared ) 00153 m_rbUnShare->setChecked(true); 00154 00155 // Some help text 00156 QLabel *label = new QLabel( i18n("Sharing this folder makes it available under Linux/UNIX (NFS) and Windows (Samba).") , m_widget ); 00157 label->setAlignment( Qt::AlignAuto | Qt::AlignVCenter | Qt::WordBreak ); 00158 vbox->addWidget( label, 0 ); 00159 00160 KSeparator* sep=new KSeparator(m_widget); 00161 vbox->addWidget( sep, 0 ); 00162 label = new QLabel( i18n("You can also reconfigure file sharing authorization.") , m_widget ); 00163 label->setAlignment( Qt::AlignAuto | Qt::AlignVCenter | Qt::WordBreak ); 00164 vbox->addWidget( label, 0 ); 00165 m_pbConfig = new QPushButton( i18n("Configure File Sharing..."), m_widget ); 00166 connect( m_pbConfig, SIGNAL( clicked() ), SLOT( slotConfigureFileSharing() ) ); 00167 vbox->addWidget( m_pbConfig, 0, Qt::AlignHCenter ); 00168 00169 vbox->addStretch( 10 ); 00170 } 00171 } 00172 break; 00173 case KFileShare::ErrorNotFound: 00174 vbox->addWidget( new QLabel( i18n("Error running 'filesharelist'. Check if installed and in $PATH or /usr/sbin."), 00175 m_widget ), 0 ); 00176 break; 00177 case KFileShare::UserNotAllowed: 00178 { 00179 vbox->setSpacing( 10 ); 00180 if (KFileShare::sharingEnabled()) { 00181 vbox->addWidget( new QLabel( i18n("You need to be authorized to share folders."), 00182 m_widget ), 0 ); 00183 } else { 00184 vbox->addWidget( new QLabel( i18n("File sharing is disabled."), 00185 m_widget ), 0 ); 00186 } 00187 QHBoxLayout* hBox = new QHBoxLayout( (QWidget *)0L ); 00188 vbox->addLayout( hBox, 0 ); 00189 m_pbConfig = new QPushButton( i18n("Configure File Sharing..."), m_widget ); 00190 connect( m_pbConfig, SIGNAL( clicked() ), SLOT( slotConfigureFileSharing() ) ); 00191 hBox->addWidget( m_pbConfig, 0, Qt::AlignHCenter ); 00192 vbox->addStretch( 10 ); // align items on top 00193 break; 00194 } 00195 case KFileShare::NotInitialized: 00196 kdWarning() << "KFileShare Authorization still NotInitialized after calling authorization() - impossible" << endl; 00197 break; 00198 } 00199 m_widget->show(); // In case the dialog was shown already. 00200 } 00201 00202 void KFileSharePropsPlugin::slotConfigureFileSharing() 00203 { 00204 if (d->m_configProc) return; 00205 00206 d->m_configProc = new KProcess(this); 00207 (*d->m_configProc) << KStandardDirs::findExe("kdesu") << locate("exe", "kcmshell") << "fileshare"; 00208 if (!d->m_configProc->start( KProcess::NotifyOnExit )) 00209 { 00210 delete d->m_configProc; 00211 d->m_configProc = 0; 00212 return; 00213 } 00214 connect(d->m_configProc, SIGNAL(processExited(KProcess *)), 00215 this, SLOT(slotConfigureFileSharingDone())); 00216 m_pbConfig->setEnabled(false); 00217 } 00218 00219 void KFileSharePropsPlugin::slotConfigureFileSharingDone() 00220 { 00221 delete d->m_configProc; 00222 d->m_configProc = 0; 00223 KFileShare::readConfig(); 00224 KFileShare::readShareList(); 00225 init(); 00226 } 00227 00228 void KFileSharePropsPlugin::applyChanges() 00229 { 00230 kdDebug() << "KFileSharePropsPlugin::applyChanges" << endl; 00231 if ( m_rbShare && m_rbUnShare ) 00232 { 00233 bool share = m_rbShare->isChecked(); 00234 00235 if (share && d->m_bAllShared) 00236 return; // Nothing to do 00237 if (!share && d->m_bAllUnshared) 00238 return; // Nothing to do 00239 00240 KFileItemList items = properties->items(); 00241 KFileItemListIterator it( items ); 00242 bool ok = true; 00243 for ( ; it.current() && ok; ++it ) { 00244 QString path = (*it)->url().path(); 00245 ok = setShared( path, share ); 00246 if (!ok) { 00247 if (share) 00248 KMessageBox::detailedError(properties, 00249 i18n("Sharing folder '%1' failed.").arg(path), 00250 i18n("An error occurred while trying to share folder '%1'. " 00251 "Make sure that the Perl script 'fileshareset' is set suid root.") 00252 .arg(path)); 00253 else 00254 KMessageBox::error(properties, 00255 i18n("Unsharing folder '%1' failed.").arg(path), 00256 i18n("An error occurred while trying to unshare folder '%1'. " 00257 "Make sure that the Perl script 'fileshareset' is set suid root.") 00258 .arg(path)); 00259 00260 properties->abortApplying(); 00261 break; 00262 } 00263 } 00264 00265 // Get the change back into our cached info 00266 KFileShare::readShareList(); 00267 } 00268 } 00269 00270 bool KFileSharePropsPlugin::setShared( const QString& path, bool shared ) 00271 { 00272 kdDebug() << "KFileSharePropsPlugin::setShared " << path << "," << shared << endl; 00273 return KFileShare::setShared( path, shared ); 00274 } 00275 00276 QWidget* KFileSharePropsPlugin::page() const 00277 { 00278 return d->m_vBox; 00279 } 00280 00281 #include "kfilesharedlg.moc" 00282 00283 //TODO: do we need to monitor /etc/security/fileshare.conf ? 00284 // if the user is added to the 'fileshare' group, we wouldn't be notified 00285 // Of course the config module can notify us. 00286 // TODO: listen to such notifications ;)