diff options
Diffstat (limited to 'filesharing/advanced/nfs')
-rw-r--r-- | filesharing/advanced/nfs/Makefile.am | 13 | ||||
-rw-r--r-- | filesharing/advanced/nfs/hostprops.ui | 558 | ||||
-rw-r--r-- | filesharing/advanced/nfs/hostprops.ui.h | 13 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsdialog.cpp | 216 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsdialog.h | 58 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsdialoggui.ui | 156 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsdialoggui.ui.h | 18 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsentry.cpp | 381 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsentry.h | 120 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsfile.cpp | 261 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfsfile.h | 59 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfshostdlg.cpp | 226 | ||||
-rw-r--r-- | filesharing/advanced/nfs/nfshostdlg.h | 59 |
13 files changed, 2138 insertions, 0 deletions
diff --git a/filesharing/advanced/nfs/Makefile.am b/filesharing/advanced/nfs/Makefile.am new file mode 100644 index 00000000..f9395529 --- /dev/null +++ b/filesharing/advanced/nfs/Makefile.am @@ -0,0 +1,13 @@ +METASOURCES = AUTO +AM_CPPFLAGS= $(all_includes) + +noinst_LTLIBRARIES = libfilesharenfs.la + +libfilesharenfs_la_SOURCES = \ + nfsdialog.cpp \ + nfshostdlg.cpp \ + hostprops.ui \ + nfsdialoggui.ui \ + nfsfile.cpp \ + nfsentry.cpp + diff --git a/filesharing/advanced/nfs/hostprops.ui b/filesharing/advanced/nfs/hostprops.ui new file mode 100644 index 00000000..4ff97e28 --- /dev/null +++ b/filesharing/advanced/nfs/hostprops.ui @@ -0,0 +1,558 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>HostProps</class> +<widget class="QWidget"> + <property name="name"> + <cstring>HostProps</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>333</width> + <height>332</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>propertiesGrp</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>180</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="title"> + <string>Host Properties</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>&Name/address:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nameEdit</cstring> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>nameEdit</cstring> + </property> + <property name="frameShape"> + <enum>LineEditPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Name / Address field</b> +<p> +Here you can enter the host name or address.<br> +The host may be specified in a number of ways: +<p> +<i>single host</i> +<p> + This is the most common format. You may specify a host either by an abbreviated name recognized by the resolver, the fully qualified domain name, or an IP address. +</p> + +<i>netgroups</i> +<p> + NIS netgroups may be given as @group. Only the host part of each netgroup members is consider in checking for membership. Empty host parts or those containing a single dash (-) are ignored. +</p> + +<i>wildcards</i> +<p> + Machine names may contain the wildcard characters * and ?. This can be used to make the exports file more compact; for instance, *.cs.foo.edu matches all hosts in the domain cs.foo.edu. However, these wildcard characters do not match the dots in a domain name, so the above pattern does not include hosts such as a.b.cs.foo.edu. +</p> + +<i>IP networks</i> +<p> + You can also export directories to all hosts on an IP (sub-) network simultaneously. This is done by specifying an IP address and netmask pair as address/netmask where the netmask can be specified in dotted-decimal format, or as a contiguous mask length (for example, either `/255.255.252.0' or `/22' appended to the network base address result in identical subnetworks with 10 bits of host). +</p></string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>publicChk</cstring> + </property> + <property name="text"> + <string>&Public access</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Public access</b> +<p> +If you check this, the host address will be a single wildcard , which means public access. +This is just the same as if you would enter a wildcard in the address field. +</p></string> + </property> + </widget> + </vbox> + </widget> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>GroupBox7</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Options</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>readOnlyChk</cstring> + </property> + <property name="text"> + <string>&Writable</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Writable</b> +<p> +Allow both read and write requests on this NFS volume. +</p> +<p> +The default is to disallow any request which changes the filesystem +</p></string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>secureChk</cstring> + </property> + <property name="text"> + <string>&Insecure</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Insecure</b> +<p> +If this option is checked, it is not required that requests originate on an internet port less than IPPORT_RESERVED (1024). +</p> +<p> +If unsure leave it unchecked. +</p></string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>syncChk</cstring> + </property> + <property name="text"> + <string>&Sync</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Sync</b> +<p> +This option requests that all file writes be committed to disk before the write request completes. This is required for complete safety of data in the face of a server crash, but incurs a performance hit. +</p> +<p> +The default is to allow the server to write the data out whenever it is ready. +</p></string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="0"> + <property name="name"> + <cstring>wdelayChk</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>No w&delay</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>No wdelay</b> +<p> +This option only has effect if sync is also set. The NFS server will normally delay committing a write request to disk slightly if it suspects that another related write request may be in progress or may arrive soon. This allows multiple write requests to be committed to disk with the one operation which can improve performance. If an NFS server received mainly small unrelated requests, this behavior could actually reduce performance, so no wdelay is available to turn it off. </p></string> + </property> + </widget> + <widget class="QCheckBox" row="4" column="0"> + <property name="name"> + <cstring>hideChk</cstring> + </property> + <property name="text"> + <string>No &hide</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>No hide</b> +<p> +This option is based on the option of the same name provided in IRIX NFS. Normally, if a server exports two filesystems one of which is mounted on the other, then the client will have to mount both filesystems explicitly to get access to them. If it just mounts the parent, it will see an empty directory at the place where the other filesystem is mounted. That filesystem is "hidden". +</p> +<p> +Setting the nohide option on a filesystem causes it not to be hidden, and an appropriately authorized client will be able to move from the parent to that filesystem without noticing the change. +</p> +<p> +However, some NFS clients do not cope well with this situation as, for instance, it is then possible for two files in the one apparent filesystem to have the same inode number. +</p> +<p> +The nohide option is currently only effective on single host exports. It does not work reliably with netgroup, subnet, or wildcard exports. +</p> +<p> +This option can be very useful in some situations, but it should be used with due care, and only after confirming that the client system copes with the situation effectively. +</p></string> + </property> + </widget> + <widget class="QCheckBox" row="5" column="0"> + <property name="name"> + <cstring>subtreeChk</cstring> + </property> + <property name="text"> + <string>No su&btree check</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>No subtree check</b> +<p> +This option disables subtree checking, which has mild security implications, but can improve reliability is some circumstances. +</p> +<p> +If a subdirectory of a filesystem is exported, but the whole filesystem is not, then whenever a NFS request arrives, the server must check not only that the accessed file is in the appropriate filesystem (which is easy) but also that it is in the exported tree (which is harder). This check is called the subtree_check. +</p> +<p> +In order to perform this check, the server must include some information about the location of the file in the "filehandle" that is given to the client. This can cause problems with accessing files that are renamed while a client has them open (though in many simple cases it will still work). +</p> +<p> +subtree checking is also used to make sure that files inside directories to which only root has access can only be accessed if the filesystem is exported with no_root_squash (see below), even the file itself allows more general access. +</p> +<p> +As a general guide, a home directory filesystem, which is normally exported at the root and may see lots of file renames, should be exported with subtree checking disabled. A filesystem which is mostly read-only, and at least does not see many file renames (e.g. /usr or /var) and for which subdirectories may be exported, should probably be exported with subtree checks enabled. +</p></string> + </property> + </widget> + <widget class="QCheckBox" row="6" column="0"> + <property name="name"> + <cstring>secureLocksChk</cstring> + </property> + <property name="text"> + <string>Insecure loc&ks</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Insecure locks</b> +<p> +This option tells the NFS server not to require authentication of locking requests (i.e. requests which use the NLM protocol). Normally the NFS server will require a lock request to hold a credential for a user who has read access to the file. With this flag no access checks will be performed. +</p> +<p> +Early NFS client implementations did not send credentials with lock requests, and many current NFS clients still exist which are based on the old implementations. Use this flag if you find that you can only lock files which are world readable. +</p></string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="1" column="1"> + <property name="name"> + <cstring>GroupBox3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>User Mapping</string> + </property> + <property name="alignment"> + <set>AlignAuto</set> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>allSquashChk</cstring> + </property> + <property name="text"> + <string>All s&quash</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>All squash</b> +<p> +Map all uids and gids to the anonymous user. Useful for NFS-exported public FTP directories, news spool directories, etc. </p></string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>rootSquashChk</cstring> + </property> + <property name="text"> + <string>No &root squash</string> + </property> + <property name="whatsThis" stdset="0"> + <string><b>No root squash</b> +<p> +Turn of root squashing. This option is mainly useful for diskless clients. +</p> +<i>root squashing</i> +<p> +Map requests from uid/gid 0 to the anonymous uid/gid. Note that this does not apply to any other uids that might be equally sensitive, such as user bin. +</p></string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout15</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>Anonym. &UID:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>anonuidEdit</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Anonym. UID/GID</b> <p> These options explicitly set the uid and gid of the anonymous account. This option is primarily useful for PC/NFS clients, where you might want all requests appear to be from one user. </p></string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>anonuidEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>100</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>FF</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout16</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Anonym. &GID:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>anongidEdit</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string><b>Anonym. UID/GID</b> <p> These options explicitly set the uid and gid of the anonymous account. This option is primarily useful for PC/NFS clients, where you might want all requests appear to be from one user. </p></string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>anongidEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>FF</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>publicChk</sender> + <signal>toggled(bool)</signal> + <receiver>nameEdit</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>readOnlyChk</sender> + <signal>clicked()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>secureChk</sender> + <signal>clicked()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>syncChk</sender> + <signal>clicked()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>wdelayChk</sender> + <signal>pressed()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>subtreeChk</sender> + <signal>pressed()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>secureLocksChk</sender> + <signal>pressed()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>allSquashChk</sender> + <signal>pressed()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>rootSquashChk</sender> + <signal>pressed()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>nameEdit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>hideChk</sender> + <signal>clicked()</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>syncChk</sender> + <signal>toggled(bool)</signal> + <receiver>wdelayChk</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>anonuidEdit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> + <connection> + <sender>anongidEdit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostProps</receiver> + <slot>setModified()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">hostprops.ui.h</include> +</includes> +<signals> + <signal>modified()</signal> +</signals> +<slots> + <slot>setModified()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/filesharing/advanced/nfs/hostprops.ui.h b/filesharing/advanced/nfs/hostprops.ui.h new file mode 100644 index 00000000..5d456a22 --- /dev/null +++ b/filesharing/advanced/nfs/hostprops.ui.h @@ -0,0 +1,13 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + + +void HostProps::setModified() +{ + emit modified(); +} diff --git a/filesharing/advanced/nfs/nfsdialog.cpp b/filesharing/advanced/nfs/nfsdialog.cpp new file mode 100644 index 00000000..7e88f2be --- /dev/null +++ b/filesharing/advanced/nfs/nfsdialog.cpp @@ -0,0 +1,216 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + +#include <qradiobutton.h> +#include <qpushbutton.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qbuttongroup.h> +#include <qlayout.h> + +#include <kdebug.h> +#include <kmessagebox.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <klistview.h> +#include <kaccel.h> + +#include "nfsdialog.h" +#include "nfsentry.h" +#include "nfshostdlg.h" +#include "nfsfile.h" +#include "nfsdialoggui.h" + +NFSDialog::NFSDialog(QWidget * parent, NFSEntry* entry) + : KDialogBase(Plain, i18n("NFS Options"), Ok|Cancel, Ok, parent), + m_nfsEntry(entry), + m_modified(false) +{ + if (m_nfsEntry) + m_workEntry = m_nfsEntry->copy(); + else + kdWarning() << "NFSDialog::NFSDialog: entry is null!" << endl; + + initGUI(); + initSlots(); + initListView(); +} + +NFSDialog::~NFSDialog() +{ + delete m_workEntry; +} + +void NFSDialog::initGUI() { + QWidget* page = plainPage(); + m_gui = new NFSDialogGUI(page); + + QVBoxLayout *layout = new QVBoxLayout( page ); + layout->addWidget( m_gui ); + + KAccel* accel = new KAccel( m_gui->listView ); + accel->insert( "Delete", Qt::Key_Delete, this, SLOT(slotRemoveHost())); +} + +void NFSDialog::initSlots() +{ + connect( m_gui->removeHostBtn, SIGNAL(clicked()), this, SLOT( slotRemoveHost())); + connect( m_gui->addHostBtn, SIGNAL(clicked()), this, SLOT( slotAddHost())); + connect( m_gui->modifyHostBtn, SIGNAL(clicked()), this, SLOT( slotModifyHost())); + connect( m_gui->listView, SIGNAL(doubleClicked(QListViewItem*)), + this, SLOT( slotModifyHost())); + +} + +void NFSDialog::initListView() +{ + if (m_workEntry) { + HostIterator it = m_workEntry->getHosts(); + + NFSHost* host; + while ( (host = it.current()) != 0 ) { + ++it; + createItemFromHost(host); + } + } +} + +QListViewItem* NFSDialog::createItemFromHost(NFSHost* host) +{ + if (!host) + return 0; + + QListViewItem* item = new QListViewItem(m_gui->listView); + updateItem(item, host); + return item; +} + +void NFSDialog::updateItem(QListViewItem* item, NFSHost* host) +{ + item->setText(0,host->name); + item->setText(1,host->paramString()); +} + +void NFSDialog::slotAddHost() +{ + NFSHost *host = new NFSHost(); + + // Set some secure parameters + //host->allSquash=true; + host->readonly=true; + + HostList hostList; + hostList.append(host); + + NFSHostDlg *dlg = new NFSHostDlg(this, &hostList, m_workEntry); + dlg->exec(); + + + if (dlg->result()==QDialog::Accepted) { + m_workEntry->addHost(host); + createItemFromHost(host); + setModified(); + } else { + delete host; + } + + delete dlg; +} + +void NFSDialog::slotOk() { + if (m_modified) { + m_nfsEntry->copyFrom(m_workEntry); + } + KDialogBase::slotOk(); +} + +void NFSDialog::slotRemoveHost() +{ + QPtrList<QListViewItem> items = m_gui->listView->selectedItems(); + if (items.count()==0) + return; + + QListViewItem *item; + for ( item = items.first(); item; item = items.next() ) { + QString name = item->text(0); + m_gui->listView->takeItem(item); + + NFSHost* host = m_workEntry->getHostByName(name); + if (host) { + m_workEntry->removeHost(host); + } else { + kdWarning() << "NFSDialog::slotRemoveHost: no host " + << name << " << found!" << endl; + } + + } + + m_gui->modifyHostBtn->setDisabled(true); + m_gui->removeHostBtn->setDisabled(true); + setModified(); +} + +void NFSDialog::slotModifyHost() +{ + QPtrList<QListViewItem> items = m_gui->listView->selectedItems(); + if (items.count()==0) + return; + + HostList hostList; + + QListViewItem *item; + for ( item = items.first(); item; item = items.next() ) { + + NFSHost* host = m_workEntry->getHostByName(item->text(0)); + if (host) + hostList.append(host); + else + kdWarning() << "NFSDialog::slogModifyHost: host " + << item->text(0) << " is null!" << endl; + } + + NFSHostDlg *dlg = new NFSHostDlg(this, &hostList, m_workEntry); + if (dlg->exec() == QDialog::Accepted && + dlg->isModified()) + { + setModified(); + } + + delete dlg; + + NFSHost* host = hostList.first(); + for ( item = items.first(); item; item = items.next() ) { + if (item && host) + updateItem( item,host); + host = hostList.next(); + } +} + +void NFSDialog::setModified() +{ + m_modified = true; +} + +bool NFSDialog::modified() { + return m_modified; +} + +#include "nfsdialog.moc" + diff --git a/filesharing/advanced/nfs/nfsdialog.h b/filesharing/advanced/nfs/nfsdialog.h new file mode 100644 index 00000000..f6128230 --- /dev/null +++ b/filesharing/advanced/nfs/nfsdialog.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef NFSDIALOG_H +#define NFSDIALOG_H + +#include <kdialogbase.h> + +class NFSEntry; +class NFSHost; +class QListViewItem; +class NFSFile; +class NFSDialogGUI; + +class NFSDialog : public KDialogBase +{ +Q_OBJECT +public: + NFSDialog(QWidget * parent, NFSEntry* entry); + ~NFSDialog(); + bool modified(); +protected: + NFSEntry * m_nfsEntry; + NFSEntry * m_workEntry; + NFSDialogGUI* m_gui; + + bool m_modified; + QListViewItem* createItemFromHost(NFSHost* host); + void updateItem(QListViewItem* item, NFSHost* host); + void initGUI(); + void initListView(); + void initSlots(); + void initWorkEntry(); +protected slots: + void slotAddHost(); + void slotRemoveHost(); + void slotModifyHost(); + virtual void slotOk(); + void setModified(); +}; + +#endif diff --git a/filesharing/advanced/nfs/nfsdialoggui.ui b/filesharing/advanced/nfs/nfsdialoggui.ui new file mode 100644 index 00000000..002ae30a --- /dev/null +++ b/filesharing/advanced/nfs/nfsdialoggui.ui @@ -0,0 +1,156 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>NFSDialogGUI</class> +<widget class="QWidget"> + <property name="name"> + <cstring>NFSDialogGUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>466</width> + <height>338</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Allowed &Hosts</string> + </property> + <property name="toolTip" stdset="0"> + <string>A list of allowed hosts</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Here you can see a list of hosts which are allowed to access this directory via NFS. +The first column shows the name or address of the host, the second column shows the access parameters. The name '*' donates public access.</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>addHostBtn</cstring> + </property> + <property name="text"> + <string>&Add Host...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>modifyHostBtn</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Mo&dify Host...</string> + </property> + </widget> + <widget class="QPushButton" row="2" column="1"> + <property name="name"> + <cstring>removeHostBtn</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>&Remove Host</string> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + <widget class="KListView" row="0" column="0" rowspan="4" colspan="1"> + <column> + <property name="text"> + <string>Name/Address</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Parameters</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listView</cstring> + </property> + <property name="selectionMode" stdset="0"> + <enum>Extended</enum> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>listView</sender> + <signal>selectionChanged()</signal> + <receiver>NFSDialogGUI</receiver> + <slot>listView_selectionChanged()</slot> + </connection> +</connections> +<tabstops> + <tabstop>addHostBtn</tabstop> + <tabstop>modifyHostBtn</tabstop> + <tabstop>removeHostBtn</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">nfsdialoggui.ui.h</include> +</includes> +<slots> + <slot>listView_selectionChanged()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/filesharing/advanced/nfs/nfsdialoggui.ui.h b/filesharing/advanced/nfs/nfsdialoggui.ui.h new file mode 100644 index 00000000..85894340 --- /dev/null +++ b/filesharing/advanced/nfs/nfsdialoggui.ui.h @@ -0,0 +1,18 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + + + + + +void NFSDialogGUI::listView_selectionChanged() +{ + bool empty = listView->selectedItems().isEmpty(); + modifyHostBtn->setDisabled(empty); + removeHostBtn->setDisabled(empty); +} diff --git a/filesharing/advanced/nfs/nfsentry.cpp b/filesharing/advanced/nfs/nfsentry.cpp new file mode 100644 index 00000000..4144cc7c --- /dev/null +++ b/filesharing/advanced/nfs/nfsentry.cpp @@ -0,0 +1,381 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include <kdebug.h> + +#include "nfsentry.h" + +NFSHost::NFSHost(const QString & hostString) +{ + readonly = true; + + QString s = hostString; + + int l = s.find('('); + int r = s.find(')'); + + initParams(); + + // get hostname + if (l>=0) + name = s.left(l); + else + name = s; + + kdDebug(5009) << "NFSHost: name='" << name << "'" << endl; + + if (l>=0 && r>=0) + { + QString params = s.mid(l+1,r-l-1); + + parseParamsString(params); + } +} + +NFSHost::NFSHost() { + initParams(); + name=""; +} + +NFSHost::~NFSHost() +{ +} + +/** + * Set the parameters to their default values + */ +void NFSHost::initParams() +{ + readonly = true; + sync = false; + secure = true; + wdelay = true; + hide = true; + subtreeCheck = true; + secureLocks = true; + allSquash = false; + rootSquash = true; + + anonuid = 65534; + anongid = 65534; +} + + +void NFSHost::parseParamsString(const QString & s) +{ + + if (s.isEmpty()) + return; + + int i; + + QString rest = s; + QString p; + + do + { + i = rest.find(",",0); + + if (i==-1) + p = rest; + else + { + p = rest.left( i ); + rest = rest.mid(i+1); + } + + setParam(p); + } + while (i>-1); + +} + +QString NFSHost::paramString() const +{ + QString s; + + if (!readonly) s+="rw,"; + if (!rootSquash) s+="no_root_squash,"; + if (!secure) s+="insecure,"; + if (!secureLocks) s+="insecure_locks,"; + if (!subtreeCheck) s+="no_subtree_check,"; + if (sync) + s+="sync,"; + else + s+="async,"; + + if (!wdelay) s+="wdelay,"; + if (allSquash) s+="all_squash,"; + if (!hide) s+="nohide,"; + + if (anongid!=65534) + s+=QString("anongid=%1,").arg(anongid); + + if (anonuid!=65534) + s+=QString("anonuid=%1,").arg(anonuid); + + // get rid of the last ',' + s.truncate(s.length()-1); + + return s; +} + +QString NFSHost::toString() const +{ + QString s = name; + + s+='('; + s+=paramString(); + s+=')'; + + return s; + +} + +NFSHost* NFSHost::copy() const { + NFSHost* result = new NFSHost(); + + result->name = name; + + result->readonly = readonly; + result->sync = sync; + result->secure = secure; + result->wdelay = wdelay; + result->hide = hide; + result->subtreeCheck = subtreeCheck; + result->secureLocks = secureLocks; + result->allSquash = allSquash; + result->rootSquash = rootSquash; + + result->anonuid = anonuid; + result->anongid = anongid; + + return result; +} + +bool NFSHost::isPublic() const { + return name == "*"; +} + +void NFSHost::setParam(const QString & s) +{ + QString p = s.lower(); + + if (p=="ro") { + readonly = true; + return; } + + if (p=="rw") { + readonly = false; + return; } + + if (p=="sync") { + sync = true; + return; } + + if (p=="async") { + sync = false; + return; } + + if (p=="secure") { + secure = true; + return; } + + if (p=="insecure") { + secure = false; + return; } + + if (p=="wdelay") { + wdelay = true; + return; } + + if (p=="no_wdelay") { + wdelay = false; + return; } + + if (p=="hide") { + hide = true; + return; } + + if (p=="nohide") { + hide = false; + return; } + + if (p=="subtree_check") { + subtreeCheck = true; + return; } + + if (p=="no_subtree_check") { + subtreeCheck = false; + return; } + + if (p=="secure_locks" || + p=="auth_nlm") { + secureLocks = true; + return; } + + if (p=="insecure_locks" || + p=="no_auth_nlm" ) { + secureLocks = true; + return; } + + if (p=="all_squash") { + allSquash = true; + return; } + + if (p=="no_all_squash") { + allSquash = false; + return; } + + if (p=="root_squash") { + rootSquash = true; + return; } + + if (p=="no_root_squash") { + rootSquash = false; + return; } + + int i = p.find("=",0); + + // get anongid or anonuid + if (i>-1) + { + QString name = p.left(i).lower(); + kdDebug(5009) << name << endl; + + QString value = p.mid(i+1); + kdDebug(5009) << value << endl; + + if (name=="anongid") + anongid = value.toInt(); + + if (name=="anonuid") + anonuid = value.toInt(); + } + +} + +NFSEntry::NFSEntry(const QString & path) +{ + _hosts.setAutoDelete(true); + setPath(path); +} + +NFSEntry::~NFSEntry() +{ +} + +void NFSEntry::clear() { + _hosts.clear(); +} + +NFSEntry* NFSEntry::copy() { + NFSEntry* result = new NFSEntry(path()); + result->copyFrom(this); + return result; +} + +void NFSEntry::copyFrom(NFSEntry* entry) { + clear(); + HostIterator it = entry->getHosts(); + + NFSHost* host; + while ( (host = it.current()) != 0 ) { + ++it; + addHost(host->copy()); + } +} + +QString NFSEntry::toString() const +{ + QString s = _path.stripWhiteSpace(); + + if (_path.find(' ') > -1) { + s = '"'+s+'"'; + } + + s += ' '; + + HostIterator it = getHosts(); + + NFSHost* host; + + while ( (host = it.current()) != 0 ) + { + ++it; + s+= host->toString() ; + if (it.current()) + s+= " \\\n\t "; + } + + + return s; +} + +void NFSEntry::addHost(NFSHost * host) +{ + _hosts.append(host); +} + +void NFSEntry::removeHost(NFSHost * host) +{ + _hosts.remove(host); +} + +NFSHost* NFSEntry::getHostByName(const QString & name) const +{ + HostIterator it = getHosts(); + NFSHost* host; + + while ( (host = it.current()) != 0 ) + { + ++it; + + if (host->name==name) + return host; + } + + return 0; +} + +NFSHost* NFSEntry::getPublicHost() const +{ + NFSHost* result = getHostByName("*"); + if (result) + return result; + + return getHostByName(QString::null); +} + + +HostIterator NFSEntry::getHosts() const +{ + return HostIterator(_hosts); +} + +QString NFSEntry::path() const +{ + return _path; +} + +void NFSEntry::setPath(const QString & path) +{ + _path = path; +} + diff --git a/filesharing/advanced/nfs/nfsentry.h b/filesharing/advanced/nfs/nfsentry.h new file mode 100644 index 00000000..6003412d --- /dev/null +++ b/filesharing/advanced/nfs/nfsentry.h @@ -0,0 +1,120 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef NFSENTRY_H +#define NFSENTRY_H + + +#include <qstring.h> +#include <qptrlist.h> + + +class NFSHost +{ +public: + NFSHost(const QString & hostString); + ~NFSHost(); + NFSHost(); + + bool readonly; + bool sync; + bool secure; + bool wdelay; + bool hide; + bool subtreeCheck; + bool secureLocks; + bool allSquash; + bool rootSquash; + + int anonuid; + int anongid; + + QString name; + + QString paramString() const; + QString toString() const; + bool isPublic() const; + + /** returns a copy of this host */ + NFSHost* copy() const; +protected: + void parseParamsString(const QString &); + void setParam(const QString &); + void initParams(); +}; + + + +typedef QPtrList<NFSHost> HostList; +typedef QPtrListIterator<NFSHost> HostIterator; + +class NFSLine { +public: + virtual QString toString() const = 0; +}; + +typedef QPtrList<NFSLine> NFSLineList; +typedef QPtrListIterator<NFSLine> NFSLineIterator; + +class NFSEmptyLine : public NFSLine { +public: + virtual QString toString() const { return QString::fromLatin1("\n"); } + virtual ~NFSEmptyLine() {}; +}; + +class NFSComment : public NFSLine { +public: + NFSComment(const QString & s) { comment = s; } + virtual ~NFSComment() {}; + QString comment; + virtual QString toString() const { return comment; } +}; + +class NFSEntry : public NFSLine { +public: + NFSEntry(const QString & path); + virtual ~NFSEntry(); + + void addHost(NFSHost * host); + void removeHost(NFSHost * host); + NFSHost* getHostByName(const QString & name) const; + NFSHost* getPublicHost() const; + HostIterator getHosts() const; + + /** Creates a deep copy of this entry */ + NFSEntry * copy(); + + /** clears all hosts and makes a deep copy of + * the given entry + */ + void copyFrom(NFSEntry* entry); + + /** removes all hosts */ + void clear(); + QString path() const; + void setPath(const QString &); + + virtual QString toString() const; + +protected: + HostList _hosts; + QString _path; +}; + +#endif diff --git a/filesharing/advanced/nfs/nfsfile.cpp b/filesharing/advanced/nfs/nfsfile.cpp new file mode 100644 index 00000000..229eb983 --- /dev/null +++ b/filesharing/advanced/nfs/nfsfile.cpp @@ -0,0 +1,261 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include <pwd.h> +#include <time.h> +#include <unistd.h> + +#include <qfileinfo.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qstringlist.h> + +#include <kdebug.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <knfsshare.h> +#include <ktempfile.h> +#include <kprocio.h> + +#include "nfsfile.h" + +NFSFile::NFSFile(const KURL & url, bool readonly) +{ + _lines.setAutoDelete(true); + _entries.setAutoDelete(false); + _url = url; + _readonly = readonly; +} + +NFSFile::~NFSFile() +{ +} + +void NFSFile::addEntry(NFSEntry *entry) +{ + _lines.append(entry); + _entries.append(entry); +} + +void NFSFile::removeEntry(NFSEntry *entry) +{ + _entries.remove(entry); + _lines.remove(entry); +} + +bool NFSFile::hasEntry(NFSEntry *entry) +{ + return 0 < _entries.contains(entry); +} + + +NFSEntry* NFSFile::getEntryByPath(const QString & path) +{ + QString testPath = path.stripWhiteSpace(); + if ( testPath[testPath.length()-1] != '/' ) + testPath += '/'; + + for (NFSEntry* entry = _entries.first(); entry; entry = _entries.next()) + { + if (entry->path()==testPath) + return entry; + } + + return 0L; +} + +bool NFSFile::removeEntryByPath(const QString & path) { + NFSEntry* entry = getEntryByPath(path); + if (!entry) + return false; + + removeEntry(entry); + return true; +} + +EntryIterator NFSFile::getEntries() +{ + return EntryIterator(_entries); +} + + + + +bool NFSFile::load() +{ + QFile f(_url.path()); + + if ( !f.open(IO_ReadOnly) ) { + kdError() << "NFSFile::load: Could not open " << _url.path() << endl; + return false; + } + + _entries.clear(); + _lines.clear(); + + QTextStream s( &f ); + + bool continuedLine = false; // is true if the line before ended with a backslash + QString completeLine; + + while ( !s.eof() ) + { + QString currentLine = s.readLine().stripWhiteSpace(); + + if (continuedLine) { + completeLine += currentLine; + continuedLine = false; + } + else + completeLine = currentLine; + + // is the line continued in the next line ? + if ( completeLine[completeLine.length()-1] == '\\' ) + { + continuedLine = true; + // remove the ending backslash + completeLine.truncate( completeLine.length()-1 ); + continue; + } + + // empty lines + if (completeLine.isEmpty()) { + _lines.append(new NFSEmptyLine()); + continue; + } + + // comments + if ('#' == completeLine[0]) { + _lines.append(new NFSComment(completeLine)); + continue; + } + + QString path; + QString hosts; + + // Handle quotation marks + if ( completeLine[0] == '"' ) { + int i = completeLine.find('"',1); + if (i == -1) { + kdError() << "NFSFile: Parse error: Missing quotation mark: " + << completeLine << endl; + continue; + } + path = completeLine.mid(1,i-1); + hosts = completeLine.mid(i+1); + + } else { // no quotation marks + int i = completeLine.find(' '); + if (i == -1) + i = completeLine.find('\t'); + + if (i == -1) + path = completeLine; + else { + path = completeLine.left(i); + hosts = completeLine.mid(i+1).stripWhiteSpace(); + } + } + + // normalize path + if ( path[path.length()-1] != '/' ) + path += '/'; + + kdDebug(5009) << "KNFSShare: Found path: '" << path << "'" << endl; + NFSEntry *entry = new NFSEntry(path); + QStringList hostList = QStringList::split(' ', hosts); + + if (hostList.isEmpty()) { + NFSHost* host = new NFSHost("*"); + entry->addHost(host); + } else { + QStringList::iterator it; + for ( it = hostList.begin(); it != hostList.end(); ++it ) { + NFSHost* host = new NFSHost((*it).stripWhiteSpace()); + entry->addHost(host); + kdDebug(5009) << "KNFSShare: Found host: " << (*it) << " name='" + << host->name << "'" << endl; + } + } + + kdDebug(5009) << "KNFSShare: Found hosts: " << hosts << "'" << endl; + this->addEntry(entry); + } + + f.close(); + + + return true; + +} + +void NFSFile::saveTo(QTextStream * stream) { + QPtrListIterator<NFSLine> it(_lines); + + NFSLine *line; + while ( (line = it.current()) != 0 ) { + ++it; + *stream << line->toString() << endl; + } +} + +bool NFSFile::saveTo(const QString& fileName) { + QFile file(fileName); + if (!file.open(IO_WriteOnly)) + return false; + + QTextStream stream(&file); + saveTo(&stream); + file.close(); + return true; +} + +bool NFSFile::save() +{ + if (QFileInfo(_url.path()).isWritable() ) { + saveTo(_url.path()); + } else + { + + KTempFile tempFile; + saveTo(tempFile.name()); + tempFile.close(); + tempFile.setAutoDelete( true ); + + KProcIO proc; + + QString command = QString("cp %1 %2") + .arg(KProcess::quote( tempFile.name() )) + .arg(KProcess::quote( _url.path() )); + + if (restartNFSServer) + command +=";exportfs -ra"; + + if (!QFileInfo(_url.path()).isWritable() ) + proc<<"kdesu" << "-d" << "-c"<<command; + + if (!proc.start(KProcess::Block, true)) { + return false; + } + + + } + return true; +} + diff --git a/filesharing/advanced/nfs/nfsfile.h b/filesharing/advanced/nfs/nfsfile.h new file mode 100644 index 00000000..3d493a04 --- /dev/null +++ b/filesharing/advanced/nfs/nfsfile.h @@ -0,0 +1,59 @@ +/* + Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef NFSFILE_H +#define NFSFILE_H + + +#include <kurl.h> +#include "nfsentry.h" + +typedef QPtrList<NFSEntry> EntryList; +typedef QPtrListIterator<NFSEntry> EntryIterator; + +class QTextStream; + +class NFSFile { +public: + NFSFile(const KURL & , bool readonly = true); + ~NFSFile(); + + void addEntry(NFSEntry *); + void removeEntry(NFSEntry *); + bool hasEntry(NFSEntry *); + NFSEntry* getEntryByPath(const QString &); + bool removeEntryByPath(const QString &); + EntryIterator getEntries(); + + bool save(); + bool saveTo(const QString& fileName); + void saveTo(QTextStream * stream); + bool load(); + + bool restartNFSServer; + + +protected: + KURL _url; + bool _readonly; + EntryList _entries; + NFSLineList _lines; +}; + +#endif diff --git a/filesharing/advanced/nfs/nfshostdlg.cpp b/filesharing/advanced/nfs/nfshostdlg.cpp new file mode 100644 index 00000000..073170d6 --- /dev/null +++ b/filesharing/advanced/nfs/nfshostdlg.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** + nfshostdlg.cpp - description + ------------------- + begin : Mon Apr 29 2002 + copyright : (C) 2002 by Jan Sch�er + email : janschaefer@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <qcheckbox.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qwhatsthis.h> +#include <qgroupbox.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kmessagebox.h> + +#include <assert.h> + +#include "nfshostdlg.h" +#include "hostprops.h" +#include "nfsentry.h" + + +NFSHostDlg::NFSHostDlg(QWidget* parent, HostList* hosts, NFSEntry* entry) + : KDialogBase(Plain, i18n("Host Properties"), Ok|Cancel, Ok, parent), + m_hosts(hosts), m_nfsEntry(entry), m_modified(false) +{ + + QWidget* page = plainPage(); + + m_gui = new HostProps(page); + + QVBoxLayout *layout = new QVBoxLayout( page, 0, 6 ); + layout->addWidget( m_gui ); + + connect( m_gui, SIGNAL(modified()), this, SLOT(setModified())); + + init(); + +} + +NFSHostDlg::~NFSHostDlg() +{ +} + +void NFSHostDlg::init() +{ + if (m_hosts->count()==1) { + NFSHost* host = m_hosts->first(); + assert(host); + m_gui->nameEdit->setText(host->name); + m_gui->publicChk->setChecked(host->isPublic()); + + setHostValues(host); + + m_gui->nameEdit->setFocus(); + } else { + m_gui->nameEdit->setDisabled(true); + m_gui->publicChk->setDisabled(true); + + m_gui->readOnlyChk->setTristate(); + m_gui->allSquashChk->setTristate(); + m_gui->rootSquashChk->setTristate(); + m_gui->hideChk->setTristate(); + m_gui->secureChk->setTristate(); + m_gui->secureLocksChk->setTristate(); + m_gui->subtreeChk->setTristate(); + m_gui->syncChk->setTristate(); + m_gui->wdelayChk->setTristate(); + + for (NFSHost* host = m_hosts->first(); host; host = m_hosts->next()) { + setHostValues(host); + } + } +} + +void NFSHostDlg::setHostValues(NFSHost* host) { + setCheckBoxValue(m_gui->readOnlyChk, ! host->readonly); + setCheckBoxValue(m_gui->allSquashChk, host->allSquash); + setCheckBoxValue(m_gui->rootSquashChk, ! host->rootSquash); + setCheckBoxValue(m_gui->hideChk, ! host->hide); + setCheckBoxValue(m_gui->secureChk, ! host->secure); + setCheckBoxValue(m_gui->secureLocksChk, ! host->secureLocks); + setCheckBoxValue(m_gui->subtreeChk, ! host->subtreeCheck); + setCheckBoxValue(m_gui->syncChk, host->sync); + setCheckBoxValue(m_gui->wdelayChk, ! host->wdelay); + + setEditValue(m_gui->anonuidEdit,QString::number(host->anonuid)); + setEditValue(m_gui->anongidEdit,QString::number(host->anongid)); +} + +void NFSHostDlg::setEditValue(QLineEdit* edit, const QString & value) { + if (edit->text().isEmpty()) + return; + + if (edit->text() == "FF") + edit->setText(value); + else + if (edit->text() != value) + edit->setText(QString::null); +} + +void NFSHostDlg::setCheckBoxValue(QCheckBox* chk, bool value) { + if (chk->state() == QButton::NoChange) + return; + + if (chk->isChecked()) { + if (! value) + chk->setNoChange(); + } else { + if (value) + chk->setChecked(true); + } +} + + +void NFSHostDlg::slotOk() +{ + if (m_hosts->count()==1) { + NFSHost* host = m_hosts->first(); + if (! saveName(host)) + return; + + saveValues(host); + } else { + for (NFSHost* host = m_hosts->first(); host; host = m_hosts->next()) { + saveValues(host); + } + } + + KDialogBase::slotOk(); +} + +bool NFSHostDlg::saveName(NFSHost* host) { + if (m_gui->publicChk->isChecked()) { + NFSHost* publicHost = m_nfsEntry->getPublicHost(); + if (publicHost && publicHost != host) { + KMessageBox::sorry(this,i18n("There already exists a public entry."), + i18n("Host Already Exists")); + m_gui->publicChk->setChecked(false); + return false; + } + host->name="*"; + } else { + QString name = m_gui->nameEdit->text().stripWhiteSpace(); + if (name.isEmpty()) { + KMessageBox::sorry(this, + i18n("Please enter a hostname or an IP address.").arg(name), + i18n("No Hostname/IP-Address")); + m_gui->nameEdit->setFocus(); + return false; + } else { + NFSHost* host2 = m_nfsEntry->getHostByName(name); + if (host2 && host2 != host) { + KMessageBox::sorry(this,i18n("The host '%1' already exists.").arg(name), + i18n("Host Already Exists")); + m_gui->nameEdit->setFocus(); + return false; + } + } + host->name=name; + } + + return true; +} + + +void NFSHostDlg::saveValues(NFSHost* host) { + + saveCheckBoxValue(host->readonly,m_gui->readOnlyChk,true); + saveCheckBoxValue(host->allSquash,m_gui->allSquashChk,false); + saveCheckBoxValue(host->rootSquash,m_gui->rootSquashChk,true); + saveCheckBoxValue(host->hide,m_gui->hideChk,true); + saveCheckBoxValue(host->secure,m_gui->secureChk,true); + saveCheckBoxValue(host->secureLocks,m_gui->secureLocksChk,true); + saveCheckBoxValue(host->subtreeCheck,m_gui->subtreeChk,true); + saveCheckBoxValue(host->sync,m_gui->syncChk,false); + saveCheckBoxValue(host->wdelay,m_gui->wdelayChk,true); + + saveEditValue(host->anonuid,m_gui->anonuidEdit); + saveEditValue(host->anongid,m_gui->anongidEdit); +} + +void NFSHostDlg::saveEditValue(int & value, QLineEdit* edit) { + if ( edit->text().isEmpty()) + return; + + value = edit->text().toInt(); +} + +void NFSHostDlg::saveCheckBoxValue(bool & value, QCheckBox* chk, bool neg) { + if (chk->state() == QButton::NoChange) + return; + + if (neg) + value = ! chk->isChecked(); + else + value = chk->isChecked(); +} + + + +bool NFSHostDlg::isModified() { + return m_modified; +} + + +void NFSHostDlg::setModified() +{ + m_modified = true; +} + +#include "nfshostdlg.moc" + + diff --git a/filesharing/advanced/nfs/nfshostdlg.h b/filesharing/advanced/nfs/nfshostdlg.h new file mode 100644 index 00000000..6580b2bd --- /dev/null +++ b/filesharing/advanced/nfs/nfshostdlg.h @@ -0,0 +1,59 @@ +/*************************************************************************** + nfshostdlg.h - description + ------------------- + begin : Mon Apr 29 2002 + copyright : (C) 2002 by Jan Schäfer + email : janschaefer@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef NFSHOSTDLG_H +#define NFSHOSTDLG_H + +#include <kdialogbase.h> +#include "nfsentry.h" + +class NFSHost; +class HostProps; +class NFSEntry; +class QCheckBox; +class QLineEdit; + + +class NFSHostDlg : public KDialogBase +{ +Q_OBJECT +public: + NFSHostDlg(QWidget* parent, HostList* hosts, NFSEntry* entry); + virtual ~NFSHostDlg(); + bool isModified(); +protected: + HostList* m_hosts; + NFSEntry* m_nfsEntry; + HostProps* m_gui; + bool m_modified; + + void init(); +protected slots: + virtual void slotOk(); + void setModified(); + +private: + void setHostValues(NFSHost* host); + void setEditValue(QLineEdit* edit, const QString & value); + void setCheckBoxValue(QCheckBox* chk, bool value); + bool saveName(NFSHost* host); + void saveValues(NFSHost* host); + void saveEditValue(int & value, QLineEdit* edit); + void saveCheckBoxValue(bool & value, QCheckBox* chk, bool neg); +}; + +#endif |