Logo Search packages:      
Sourcecode: kcmpureftpd version File versions  Download package

kcmpureftpdscript.cpp

/***************************************************************************
                         kcmpureftpdscript.cpp - pure-ftpd script generator
                         -------------------
    begin                : Fri Apr 13 2001
    copyright            : (C) 2001-2003 by Claudiu Costin
    email                : claudiuc@kde.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 <sys/types.h>
#include <sys/stat.h>

#include <qwhatsthis.h>
#include <qbuttongroup.h>
#include <qlabel.h>
#include <qcheckbox.h>
#include <qradiobutton.h>
#include <qtextedit.h>
#include <qtooltip.h>
#include <qtabwidget.h>
#include <qlayout.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qregexp.h>

#include <kdebug.h>
#include <kglobal.h>
#include <kapplication.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kpushbutton.h>
#include <knuminput.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <kurlrequester.h>
#include <kstddirs.h>
#include <kmessagebox.h>
#include <kglobalsettings.h>

#include "kcmpureftpdscript.h"
#include "kscriptadd.h"
#include "kscriptedit.h"


00055 KPureftpdScript::KPureftpdScript(QWidget *parent, const char *name)
        : KCModule(parent, name)  {

  config = new KConfig("kcmpureftpdscriptrc", false, false);
  scriptTemplate = new ScriptTemplate();
  script = new Script();

  QVBoxLayout *layout = new QVBoxLayout(this,0,0);
  ui = new KPureftpdScriptUI(this);
  layout->add(ui);

  itemStandalone = new KListViewItem(ui->scriptList,i18n("Standalone"),
                                    i18n("PureFTPd run as a standalone server"));
  itemStandalone->setOpen(true);
  itemSuperserver = new KListViewItem(ui->scriptList,i18n("Superserver"),
                                      i18n("PureFTPd run from xinetd or inetd-like superserver"));
  itemSuperserver->setOpen(true);
  itemOrphans = 0L;

  debug=0;
  isSettingGui=false;
  guiDataChanged=false;
  modifiedIcon = KGlobal::iconLoader()->loadIcon("filesave",KIcon::Small);

  facilitylist  << "auth"   << "authpriv" << "cron"   << "daemon" << "ftp"   << "kern"
                << "lpr"    << "mail"     << "news"   << "syslog" << "user"
                << "uucp"   << "local0"   << "local1" << "local2" << "local3"
                << "local4" << "local5"   << "local6" << "local7";
  logfmtlist    << "clf"    << "stats"    << "w3c";

  ui->facility->insertStringList(facilitylist);
  ui->facility->setCurrentItem(4);
  ui->authMethod->insertStringList(script->authMethods().keys());
  ui->authMethod->setCurrentItem(0);
  ui->logFormat->insertStringList(logfmtlist);
  ui->logFormat->setCurrentItem(0);
  ui->outputView->setFont(KGlobalSettings::fixedFont());
  ui->scriptList->setSorting(-1);
  ui->authList->setSorting(-1);


  connect(ui,SIGNAL(changed()),this,SLOT(slotConfigChanged()));
  connect(ui->authAdd,SIGNAL(clicked()),this,SLOT(slotAuthAdd()));
  connect(ui->authModify,SIGNAL(clicked()),this,SLOT(slotAuthModify()));
  connect(ui->authDelete,SIGNAL(clicked()),this,SLOT(slotAuthDelete()));
  connect(ui->authMoveUp,SIGNAL(clicked()),this,SLOT(slotAuthMoveUp()));
  connect(ui->authMoveDown,SIGNAL(clicked()),this,SLOT(slotAuthMoveDown()));
  connect(ui->authMethod,SIGNAL(activated(int)),this,SLOT(slotAuthMethodChanged(int)));

  connect(ui->authList,SIGNAL(executed(QListViewItem*)),this,SLOT(slotAuthListChanged(QListViewItem*)));
  connect(ui->authList,SIGNAL(currentChanged(QListViewItem*)),this,SLOT(slotAuthListChanged(QListViewItem*)));
  connect(ui->grpAuth,SIGNAL(clicked(int)),this,SLOT(slotAuthType(int)));

  connect(ui->scriptList,SIGNAL(currentChanged(QListViewItem*)),this,SLOT(slotScriptListChanged(QListViewItem*)));
  connect(ui->scriptList,SIGNAL(doubleClicked(QListViewItem*)),this,SLOT(slotScriptListDClicked(QListViewItem*)));
  connect(ui->scriptList,SIGNAL(contextMenuRequested(QListViewItem*, const QPoint &, int)),this,SLOT(slotScriptListRMB(QListViewItem*, const QPoint &, int)));
  connect(ui->outputSave,SIGNAL(clicked()),this,SLOT(slotOutputSave()));
  connect(ui->tab,SIGNAL(currentChanged(QWidget*)),this,SLOT(slotTabChanged(QWidget*)));

  connect(ui->scriptAdd,SIGNAL(clicked()),this,SLOT(slotScriptAdd()));
  connect(ui->scriptEdit,SIGNAL(clicked()),this,SLOT(slotScriptEdit()));
  connect(ui->scriptSave,SIGNAL(clicked()),this,SLOT(slotScriptSave()));
  connect(ui->scriptRevert,SIGNAL(clicked()),this,SLOT(slotScriptRevert()));
  connect(ui->scriptDelete,SIGNAL(clicked()),this,SLOT(slotScriptDelete()));

  loadTemplates();
  loadScripts();
  load();
  setScriptEditButtons();
}

00126 KPureftpdScript::~KPureftpdScript() {}

00128 void KPureftpdScript::slotConfigChanged() {
  if (isSettingGui) return;
  guiDataChanged=true;
  emit changed(true);
}

void KPureftpdScript::setScriptChanged(bool b) {
  KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();

  if (item != 0L) {
    if (listMap.contains(item)) {
      // it's script
      QString id=listMap[item];
      if (scriptTemplate->map().contains(script->map()[id].templateid())) {
        // it's normal script
        if (b) {
          item->setPixmap(0,modifiedIcon);
        } else {
          item->setPixmap(0,QPixmap());
        }
        script->map()[listMap[item]].setChanged(b);
      } else {
        // it's orphaned script
      }
    } else {
      // it's toplevel item or script template
    }
  }
  emit changed(b);
}

void KPureftpdScript::loadTemplates() {
  KListViewItem *parent, *item;

  scriptTemplate->loadAll();

  // create ListView items for templates
  for(ScriptTemplateItemIterator it=scriptTemplate->begin(); it!=scriptTemplate->end(); ++it) {
    parent=0L; // stop GCC complaining
    switch (it.data().runmode()) {
    case ScriptPref::Standalone:
      parent = itemStandalone;
      break;
    case ScriptPref::Superserver:
      parent = itemSuperserver;
      break;
    default:
      kdFatal() << "Bug in application. Unknown runmode=" << it.data().runmode() << endl;
    }
    item = new KListViewItem(parent, i18n(it.data().title()), i18n(it.data().description()));
    item->setOpen(true);
    it.data().setLi(item);
    // insert a "/" char to distinguish templates from scripts
    listMap[item]="/"+it.data().id();
  }
}

void KPureftpdScript::loadScripts() {
  KListViewItem *parenttpl, *item;

  script->loadAll();
  for(ScriptItemIterator it=script->begin(); it!=script->end(); ++it) {
    if (scriptTemplate->map().contains(it.data().templateid())) {
      parenttpl = scriptTemplate->map()[it.data().templateid()].li();
    } else {
      if (itemOrphans == 0L) {
        itemOrphans = new KListViewItem(ui->scriptList, i18n("Orphans"),
                                        i18n("Scripts without associated script templates"));
        itemOrphans->setOpen(true);
      }
      parenttpl=itemOrphans;
    }
    item = new KListViewItem(parenttpl, i18n(it.data().title()), i18n(it.data().description()));
    item->setOpen(true);
    it.data().setLi(item);
    listMap[item]=it.data().id();
  }
}

// ----------  SCRIPT SLOTS  BEGIN   --------------------------------- //
void KPureftpdScript::slotScriptAdd() {

    // get current template item where to add script
    KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();
    if (item != 0L) {
        if (listMap.contains(item)) {
            QString id = listMap[item];
            ScriptPref p;

            if (id.left(1) == "/") {
                p.templateid=id.mid(1);
            } else {
                p.templateid=script->map()[id].templateid();
            }
            if (!scriptTemplate->map().contains(p.templateid)) {
                // it happen if I forgot to disable "Add" for orphaned scripts
                kdFatal() << "slotScriptAdd: the associated template does not exists" << endl;
            }

            p.outputfile=scriptTemplate->map()[p.templateid].outputfile();
            p.outputfilemode=scriptTemplate->map()[p.templateid].outputfilemode();

            QString ttitle = scriptTemplate->map()[p.templateid].title();
            QString tdescription = scriptTemplate->map()[p.templateid].description();

            QString trunmode;
            switch (scriptTemplate->map()[p.templateid].runmode()) {
            case ScriptPref::Standalone:
                trunmode=i18n("Standalone");
                break;
            case ScriptPref::Superserver:
                trunmode=i18n("Superserver");
                break;
            default:
                // it happen if I forgot to update the code when a new
                // run mode is added
                kdFatal() << "slotScriptAdd: unknown runmode" << endl;
            }

            KScriptAdd dlgScriptAdd;
            dlgScriptAdd.setData(p);
            QString s = i18n("<qt><dl>\n"
                             "<dt><b>Template Name:</b></dt><dd>%1</dd>\n"
                             "<dt><b>Template Description:</b></dt><dd>%2</dd>\n"
                             "<dt><b>Run Mode:</b></dt><dd>%3</dd>\n"
                             "</dl></qt>").arg(ttitle).arg(tdescription).arg(trunmode);
            dlgScriptAdd.setInfo(s);
            connect(&dlgScriptAdd, SIGNAL(setPref(ScriptPref)),
                    this, SLOT(slotAddPref(ScriptPref)));
            if (dlgScriptAdd.exec() == QDialog::Accepted) {
                QString newid;
                int tries=0, max_tries=10;

                // try hard to generated a new unique script ID.
                do {
                    newid=KApplication::randomString(16);
                    tries++;
                } while (script->map().contains(newid) && tries<max_tries);

                if (tries==max_tries) {
                    // it happen if something *very* bad happend with random
                    // generator or KDE library code
                    kdFatal() << "slotScriptAdd: this machine have a *very* broken number generator" << endl;
                }
                // load the current GUI data; user may want this instead of defaults
                GuiData g;
                getGui(g);

                // create a new ListViewItem
                KListViewItem *parent = scriptTemplate->map()[p.templateid].li();
                KListViewItem *newitem = new KListViewItem(parent, pref.title, pref.description);
                ui->scriptList->setCurrentItem(newitem);
                // make a new script item
                script->map()[newid] = ScriptItem(newid, pref.title, pref.description,
                                                  pref.outputfile, pref.outputfilemode, p.templateid+"-"+newid+".purescr",
                                                  p.templateid, g, true);
                script->map()[newid].setLi(newitem);
                listMap[newitem]=newid;

                // check if user have permission to write the output file
                if (canWriteFile(script->map()[newid].outputfile())) {
                    ui->outputSave->setEnabled(true);
                } else {
                    ui->outputSave->setEnabled(false);
                }
                setScriptChanged(true);
                setScriptEditButtons();
                ui->outputView->setText(parseOptions(script->map()[newid]));
            }
        } else {
            // it happen if I forgot to disable "Add" for toplevel ListViewItems
            // or bug in application (listMap not in-sync)
            kdFatal() << "slotScriptAdd: the current selected item is not in listMap" << endl;
        }
    }
}

void KPureftpdScript::slotAddPref(ScriptPref data) {
    pref=data;
}

void KPureftpdScript::slotScriptEdit() {
  // get current selected item to be edited
  KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();
  if (item != 0L) {
    if (listMap.contains(item)) {
      // get the id of item and check if it's a script one
      QString id = listMap[item];
      if (id.left(1) == "/") {
        // it happen if I forgot to disable "Edit" for templates items
        kdFatal() << "slotScriptEdit: cannot edit script templates" << endl;
      } else {
        ScriptPref p;

        p.id=id;
        p.templateid=script->map()[id].templateid();
        p.outputfilemode=script->map()[id].outputfilemode();
        p.runmode=scriptTemplate->map()[p.templateid].runmode();
        p.title=script->map()[id].title();
        p.description=script->map()[id].description();
        p.outputfile=script->map()[id].outputfile();

        QString ttitle = scriptTemplate->map()[p.templateid].title();
        QString tdescription = scriptTemplate->map()[p.templateid].description();

        QString trunmode;
        switch (p.runmode) {
        case ScriptPref::Standalone:
          trunmode=i18n("Standalone");
          break;
        case ScriptPref::Superserver:
          trunmode=i18n("Superserver");
          break;
        default:
          // it happen if I forgot to update the code when a new
          // run mode is added
          kdFatal() << "slotScriptEdit: unknown runmode" << endl;
        }

        KScriptEdit dlgScriptEdit;
        dlgScriptEdit.setData(p);
        QString s = i18n("<qt><dl>\n"
                        "<dt><b>Template Name:</b></dt><dd>%1</dd>\n"
                        "<dt><b>Template Description:</b></dt><dd>%2</dd>\n"
                        "<dt><b>Run Mode:</b></dt><dd>%3</dd>\n"
                        "</dl></qt>").arg(ttitle).arg(tdescription).arg(trunmode);
        dlgScriptEdit.setInfo(s);
        connect(&dlgScriptEdit, SIGNAL(setPref(ScriptPref)),
                this, SLOT(slotEditPref(ScriptPref)));
        if (dlgScriptEdit.exec() == QDialog::Accepted) {
          KListViewItem *editem = script->map()[id].li();

          // set the GUI
          editem->setText(0,pref.title);
          editem->setText(1,pref.description);
          ui->outputFile->setText(pref.outputfile);
          // set the data
          script->map()[id].setTitle(pref.title);
          script->map()[id].setDescription(pref.description);
          script->map()[id].setOutputFile(pref.outputfile);
          script->map()[id].setOutputFileMode(pref.outputfilemode);

          setScriptChanged(true);
          setScriptEditButtons();
          ui->outputView->setText(parseOptions(script->map()[id]));
        }
      }
    } else {
      // it happen if I forgot to disable "Edit" for toplevel
      // ListViewItems or bug in application (listMap not in-sync)
      kdFatal() << "slotScriptEdit: the current selected item is not in listMap" << endl;
    }
  }
}

void KPureftpdScript::slotEditPref(ScriptPref data) {
    pref=data;
}

00387 void KPureftpdScript::slotScriptSave() {
  KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();
  if (item != 0L) {
    if (listMap.contains(item)) {
      // get the id of item and check if it's a script one
      QString id = listMap[item];
      if (id.left(1) == "/") {
        // it happen if I forgot to disable "Save" for templates items
        kdFatal() << "slotScriptSave: cannot save script templates" << endl;
      } else {
        Script::IOStatus ret;
        QString scriptfile;

        // calculate where to save script file, according to permissions
        // and KDE way
        scriptfile=script->map()[id].scriptfile();
        int pos;
        if ((pos=scriptfile.findRev("/")) == -1) {
          scriptfile=KGlobal::dirs()->saveLocation("data","kcmpureftpdscript/") + scriptfile;
        } else {
          QFileInfo fi(scriptfile);
          if (!fi.isWritable()) {
            scriptfile=KGlobal::dirs()->saveLocation("data","kcmpureftpdscript/") + scriptfile.mid(pos+1);
          }
        }

        script->map()[id].setScriptFile(scriptfile);
        ret=script->save(script->map()[id]);
        switch (ret) {
          case Script::SaveOk:
              setScriptChanged(false);
              setScriptEditButtons();
          break;
          case Script::OpenError:
              KMessageBox::detailedSorry(this,
                      i18n("There was an error trying to open the script file for writing."),
                      i18n("<qt>You may not have required permissions to open it. Please "
                           "check the \"<i>%1</i>\" file.</qt>").arg(scriptfile),
                      i18n("Save failed"));
          break;
          case Script::WriteError:
              KMessageBox::detailedSorry(this,
                      i18n("There was an error trying to write the script file."),
                      i18n("<qt>It's possible that some disk access error occured. Please "
                           "check the \"<i>%1</i>\" file</qt>").arg(scriptfile),
                      i18n("Save failed"));
          break;
          default:
            kdFatal() << "slotScriptSave: unknown IOStatus code; ret=" << ret << endl;
        }
      }
    } else {
      // it happen if I forgot to disable "Save" for toplevel
      // ListViewItems or bug in application (listMap not in-sync)
      kdFatal() << "slotScriptSave: the current selected item is not in listMap" << endl;
    }
  }
}

void KPureftpdScript::slotScriptRevert() {
  int r = KMessageBox::questionYesNo(this,
            i18n("Your script changes will be lost. Do you want to continue?"),
            i18n("Script Revert"),  KStdGuiItem::yes(),  KStdGuiItem::cancel());
  if (r != KMessageBox::Yes) return;


  KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();
  if (item != 0L) {
    if (listMap.contains(item)) {
      // get the id of item and check if it's a script one
      QString id = listMap[item];
      if (id.left(1) == "/") {
        // it happen if I forgot to disable "Revert" for templates items
        kdFatal() << "slotScriptRevert: cannot revert script templates" << endl;
      } else {
        QString scriptfile = script->map()[id].scriptfile();
        QString templateid = script->map()[id].templateid();
        QString newid;
        Script::IOStatus ret;
        ScriptItem s;

        ret=script->load(s,scriptfile,newid);
        switch (ret) {
          case Script::LoadOk:
            if (newid == id) {
              // set the new script item
              script->map()[id]=s;
              // set the GUI
              script->map()[id].setLi(item);
              item->setText(0,script->map()[id].title());
              item->setText(1,script->map()[id].description());
              ui->outputFile->setText(script->map()[id].outputfile());
              if (templateid != script->map()[id].templateid()) {
                script->map()[id].setTemplateId(templateid);
                KMessageBox::sorry(this,
                        i18n("The associated script template for the script file in the original "
                            "file is different from the in-memory loaded script. This mismatch "
                            "was reverted to the in-memory value."),
                        i18n("Revert fixed"));
              }
              setGui(script->map()[id].guidata());
              setScriptChanged(false);
              setScriptEditButtons();
              ui->outputView->setText(parseOptions(script->map()[id]));
              guiDataChanged=false;
            } else {
              // the script id changed on disk!
              script->map().remove(newid);
              KMessageBox::detailedSorry(this,
                      i18n("Unique identificator for the already loaded script is different from the one "
                           "of the script file on the disk."),
                      i18n("<qt>The ID of the original script on disk was found to be different from "
                           "the current one. You should edit the file \"<i>%1</i>\" to fix the problem or "
                           "you may want to delete the script file if you don't need it.</qt>").arg(scriptfile),
                      i18n("Revert failed"));
            }
          break;
          case Script::OpenError:
              KMessageBox::detailedSorry(this,
                      i18n("There was an error trying to open the original script file."),
                      i18n("<qt>You may not have required permissions to open it. Please "
                           "check the \"<i>%1</i>\" file.</qt>").arg(scriptfile),
                      i18n("Revert failed"));
          break;
          case Script::ReadError:
              KMessageBox::detailedSorry(this,
                      i18n("There was an error trying to read the content of original script file."),
                      i18n("<qt>It's possible that some disk access error occured. Please "
                           "check the \"<i>%1</i>\" file</qt>").arg(scriptfile),
                      i18n("Revert failed"));
          break;
          case Script::ParseError:
              KMessageBox::detailedSorry(this,
                      i18n("There was an error parsing the content of original script file."),
                      i18n("<qt>It's possible that file corruption occured and XML content is not "
                           "as expected by application. Please correct the \"<i>%1</i>\" file, "
                           "load it from backup or delete it.</qt>").arg(scriptfile),
                      i18n("Revert failed"));
          break;
          case Script::DataError:
              KMessageBox::detailedSorry(this,
                      i18n("Data in the original script file is not valid and was not reloaded."),
                      i18n("<qt>It's possible that some fields does not meet data constraints. "
                           "Please manualy review the \"<i>%1</i>\" file, and check the following tags: "
                           "<tt>id</tt>, <tt>templateid</tt>.</qt>").arg(scriptfile),
                      i18n("Revert failed"));
          break;
          default:
            kdFatal() << "slotScriptRevert: unknown IOStatus code; ret=" << ret << endl;
        }
      }
    } else {
      // it happen if I forgot to disable "Revert" for toplevel
      // ListViewItems or bug in application (listMap not in-sync)
      kdFatal() << "slotScriptRevert: the current selected item is not in listMap" << endl;
    }
  }
}

void KPureftpdScript::slotScriptDelete() {
  KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();
  if (item != 0L) {
    if (listMap.contains(item)) {
      // get the id of item and check if it's a script one
      QString id = listMap[item];
      if (id.left(1) == "/") {
        // it happen if I forgot to disable "Delete" for templates items
        kdFatal() << "slotScriptDelete: cannot revert script templates" << endl;
      } else {

        int answer = KMessageBox::questionYesNo(this,
                        i18n("<qt>Do you want to permanently delete the "
                             "<b>%1</b> script?</qt>").arg(script->map()[id].title()),
                        i18n("Delete Confirmation"),
                        KStdGuiItem::yes(), KStdGuiItem::cancel());
        if (answer == KMessageBox::Yes) {
          QString scriptfile= script->map()[id].scriptfile();
          if (scriptfile.find("/") != -1) {
            // delete the script file because it's already on disk
            if (QFile::remove(scriptfile)) {
              delete item;
              listMap.remove(item);
              script->map().remove(id);
              setScriptEditButtons();
            } else {
              KMessageBox::error(this,
                                 i18n("<qt>There was an error deleting the <b>%1</b> script. "
                                      "Maybe this is a system script and you don't have "
                                      "permissions to delete the <b>%2</b> file.</qt>").arg(id).arg(scriptfile),
                                 i18n("Delete Error"));
            }
          } else {
            // script was not yet saved on disk, so do nothing
            delete item;
            listMap.remove(item);
            script->map().remove(id);
            setScriptEditButtons();
          }
        }
      }
    } else {
      // it happen if I forgot to disable "Delete" for toplevel
      // ListViewItems or bug in application (listMap not in-sync)
      kdFatal() << "slotScriptDelete: the current selected item is not in listMap" << endl;
    }
  }
}


00596 void KPureftpdScript::slotTabChanged(QWidget *widget) {
  KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();

  if (listMap.contains(item)) {
    QString id = listMap[item];
    if (id.find("/") == -1) {
      QString tid = script->map()[id].templateid();

      if (scriptTemplate->map().contains(tid)) {
        // item is normal script
        if (widget == ui->tabScripts) {
          if (guiDataChanged) {
            GuiData g;
            getGui(g);
            script->map()[id].setGuiData(g);
            guiDataChanged=false;
            setScriptChanged(true);
            setScriptEditButtons();
            ui->outputView->setText(parseOptions(script->map()[id]));
          }
        } else if (widget == ui->tabRun) {
          ScriptPref::RunMode r = scriptTemplate->map()[tid].runmode();
          switch (r) {
            case ScriptPref::Standalone:
              ui->grpStandalone->setEnabled(true);
              QToolTip::remove(ui->grpStandalone);
            break;
            case ScriptPref::Superserver:
              ui->grpStandalone->setEnabled(false);
              QToolTip::add(ui->grpStandalone,i18n(
                "<qt><p>In the list of scripts from \"Scripts\" tab "
                "you choosed to run <b>pure-ftpd</b> from a superserver "
                "like <b>xinetd</b> or <b>inetd</b>.</p></qt>"
                ));
            break;
            default:
              kdFatal() << "slotTabChanged: unknown runmode=" << r << endl;
          }
        } else {
          // the other QTabs
          guiDataChanged=false;
        }
      } else {
        // item is orphaned script
        // nothing know about it's associated script template
        guiDataChanged=false;
      }
    } else {
      // item is script template
      guiDataChanged=false;
    }
  } else {
    // item is toplevel item
    guiDataChanged=false;
  }
}

00653 void KPureftpdScript::slotScriptListChanged(QListViewItem *item) {
    if (item == 0L) {
        // no item in the ListView?
    } else {
        if (listMap.contains((KListViewItem*)item)) {
            QString id=listMap[(KListViewItem*)item];
            if (id.left(1) == "/") {
                // it's script template
                ui->outputView->clear();
                ui->outputFile->setText(scriptTemplate->map()[id.mid(1)].outputfile());
            } else {
                // it's script
                if (scriptTemplate->map().contains(script->map()[id].templateid())) {
                    // it's normal script
                    ui->outputView->setText(parseOptions(script->map()[id]));
                } else {
                    // it's orphaned script, so clear the UI
                    ui->outputView->clear();
                }
                ui->outputFile->setText(script->map()[id].outputfile());
                setGui(script->map()[id].guidata());
            }
        } else {
            // the item is a toplevel item
            ui->outputView->clear();
            ui->outputFile->clear();
        }
    }
    setScriptEditButtons();
}

00684 void KPureftpdScript::slotScriptListDClicked(QListViewItem *item) {
  if (item == 0L) {
    // no item in the ListView?
  } else {
    if (listMap.contains((KListViewItem*)item)) {
      QString id=listMap[(KListViewItem*)item];
      if (id.left(1) == "/") {
        // it's script template
        slotScriptAdd();
      } else {
        // it's script
        slotScriptEdit();
      }
    } else {
      // the item is a toplevel item
    }
  }
}

void KPureftpdScript::slotScriptListRMB(QListViewItem *item, const QPoint &pos, int column) {
    QPoint tpos=pos;
    tpos=tpos;
    column=column;
    item=item;

}


void KPureftpdScript::setScriptEditButtons() {
    KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();

    if (item == 0L) {
        // no item in list or nothing selected yet
        ui->scriptAdd->setEnabled(false);
        ui->scriptEdit->setEnabled(false);
        ui->scriptSave->setEnabled(false);
        ui->scriptRevert->setEnabled(false);
        ui->scriptDelete->setEnabled(false);
        ui->scriptDelete->setEnabled(false);
        ui->outputSave->setEnabled(false);
    } else if ( item==itemStandalone || item==itemSuperserver ||
                (0L!=itemOrphans && item==itemOrphans)) {
        // one of toplevel items is selected
        ui->scriptAdd->setEnabled(false);
        ui->scriptEdit->setEnabled(false);
        ui->scriptSave->setEnabled(false);
        ui->scriptRevert->setEnabled(false);
        ui->scriptDelete->setEnabled(false);
        ui->outputSave->setEnabled(false);
    } else {
        // search to see if the item is in one of the
        // either scripts map or templates map
        if (listMap.contains(item)) {
            QString id=listMap[item];
            if (id.left(1) == "/") {
                // it's template
                ui->scriptAdd->setEnabled(true);
                ui->scriptEdit->setEnabled(false);
                ui->scriptSave->setEnabled(false);
                ui->scriptRevert->setEnabled(false);
                ui->scriptDelete->setEnabled(false);
                ui->outputSave->setEnabled(false);
            } else {
                // it's script
                ui->scriptDelete->setEnabled(true);
                // set the output save button
                if (scriptTemplate->map().contains(script->map()[id].templateid())) {
                    ui->scriptAdd->setEnabled(false);
                    ui->scriptEdit->setEnabled(true);
                    // check if user have permission to write the output file
                    if (canWriteFile(script->map()[id].outputfile())) {
                        ui->outputSave->setEnabled(true);
                    } else {
                        ui->outputSave->setEnabled(false);
                    }
                } else {
                    // it's orphaned script
                    ui->scriptAdd->setEnabled(false);
                    ui->scriptEdit->setEnabled(false);
                    ui->outputSave->setEnabled(false);
                }

                if (script->map()[id].isChanged()) {
                    ui->scriptSave->setEnabled(true);
                    if (script->map()[id].scriptfile().find("/") == -1) {
                      ui->scriptRevert->setEnabled(false);
                    } else {
                      ui->scriptRevert->setEnabled(true);
                    }
                } else {
                    ui->scriptSave->setEnabled(false);
                    ui->scriptRevert->setEnabled(false);
                }
            }
        } else {
            // the item is in not script or template. Strange...
            ui->scriptAdd->setEnabled(false);
            ui->scriptEdit->setEnabled(false);
            ui->scriptSave->setEnabled(false);
            ui->scriptRevert->setEnabled(false);
            ui->scriptDelete->setEnabled(false);
            ui->outputSave->setEnabled(false);
        }
    }
}

bool KPureftpdScript::canWriteFile(const QString &f) {
    if (f==QString::null) {
        return false;
    } else {
        QFileInfo fi(f);
        if (fi.isFile()) {
            if (fi.isWritable()) {
                return true;
            } else {
                return false;
            }
        } else if (!fi.exists()) {
            QFileInfo di(fi.dirPath());
            if (di.isDir() && di.isWritable()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}

void KPureftpdScript::slotOutputSave() {
  KListViewItem *item = (KListViewItem *)ui->scriptList->currentItem();

  if (item == 0L) return;
  if (!listMap.contains(item)) return;
  QString id = listMap[item];
  if (!script->map().contains(id)) return;
  QString outputfile = script->map()[id].outputfile();
  int outputfilemode = script->map()[id].outputfilemode();

  QFile f(outputfile);

  if (f.open(IO_WriteOnly)) {
    QTextStream stream(&f);
    stream << ui->outputView->text();
    if (f.status() != IO_Ok) {
      KMessageBox::error(this,i18n(
                            "<qt>Cannot write to the file \"%1\". "
                            "<p>May be the disk is full "
                            "or other write error occured.</qt>"
                        ).arg(f.name()),i18n("Write Error"));
    }
    f.close();
    ::chmod(QFile::encodeName(outputfile),outputfilemode);
  } else {
    KMessageBox::error(this,i18n(
                          "<qt>Cannot write to the file \"%1\". "
                          "<p>May be you don't have enough permissions.</qt>"
                      ).arg(f.name()),i18n("Write Error"));
  }
}
// ----------  SCRIPT SLOTS    END   --------------------------------- //


// ----------  AUTH EDIT SLOTS    BEGIN ------------------------------ //
00849 void KPureftpdScript::slotAuthType(int index) {
  if (ui->useAuthDefault->isChecked()) {
    ui->txtAuthMethod->setEnabled(false);
    ui->authMethod->setEnabled(false);
    ui->txtAuthFile->setEnabled(false);
    ui->authFile->setEnabled(false);
    ui->authList->setEnabled(false);
    ui->authAdd->setEnabled(false);
    ui->authModify->setEnabled(false);
    ui->authDelete->setEnabled(false);
    ui->authMoveUp->setEnabled(false);
    ui->authMoveDown->setEnabled(false);
  } else if (ui->useAuthCustom->isChecked()) {
    ui->txtAuthMethod->setEnabled(true);
    ui->authMethod->setEnabled(true);
    ui->txtAuthFile->setEnabled(true);
    ui->authList->setEnabled(true);
    slotAuthMethodChanged(ui->authMethod->currentItem());
    setAuthMoveButtons();
  } else {
    kdFatal() << "slotAuthType: unknown selected auth type index=" << index << endl;
  }
}

00873 void KPureftpdScript::slotAuthAdd() {
  KListViewItem *tmp = new KListViewItem(ui->authList,ui->authList->currentItem());
  tmp->setText(0,ui->authMethod->currentText());

  if (script->authMethods()[ui->authMethod->currentText()] == Script::NoPath) {
      tmp->setText(1,QString::null);
  } else if (script->authMethods()[ui->authMethod->currentText()] == Script::WithPath) {
      tmp->setText(1,ui->authFile->url());
  } else {
    kdFatal() << "slotAuthAdd: unknow AuthMethodOption" << endl;
  }

  ui->authList->setCurrentItem(tmp);
  ui->authList->setSelected(ui->authList->currentItem(),true);
  setAuthEditButtons();
  setAuthMoveButtons();
}

00891 void KPureftpdScript::slotAuthModify() {
  ui->authList->currentItem()->setText(0,ui->authMethod->currentText());

  if (script->authMethods()[ui->authMethod->currentText()] == Script::NoPath) {
      ui->authList->currentItem()->setText(1,QString::null);
  } else if (script->authMethods()[ui->authMethod->currentText()] == Script::WithPath) {
      ui->authList->currentItem()->setText(1,ui->authFile->url());
  } else {
    kdFatal() << "slotAuthModify: unknow AuthMethodOption" << endl;
  }
}

00903 void KPureftpdScript::slotAuthDelete() {
  delete ui->authList->currentItem();
  ui->authList->setSelected(ui->authList->currentItem(),true);
  setAuthEditButtons();
  setAuthMoveButtons();
}

void KPureftpdScript::slotAuthMoveUp() {
  QListViewItem *it = ui->authList->currentItem();
  if (it->itemAbove()) {
    it->itemAbove()->moveItem(it);
  }
  setAuthMoveButtons();
}

void KPureftpdScript::slotAuthMoveDown() {
  QListViewItem *it = ui->authList->currentItem();
  if (it->itemBelow()) {
    it->moveItem(it->itemBelow());
  }
  setAuthMoveButtons();
}

00926 void KPureftpdScript::slotAuthMethodChanged(int index) {
  index=index; // shup up GCC

  if (script->authMethods()[ui->authMethod->currentText()] == Script::NoPath) {
    ui->authFile->setEnabled(false);
  } else if (script->authMethods()[ui->authMethod->currentText()] == Script::WithPath) {
    ui->authFile->setEnabled(true);
  } else {
    kdFatal() << "slotAuthMethodChanged: unknow AuthMethodOption" << endl;
  }

  setAuthEditButtons();
}

00940 void KPureftpdScript::slotAuthListChanged(QListViewItem *item) {
  if (item) {
    ui->authMethod->setCurrentText(item->text(0));
    ui->authFile->setURL(item->text(1));
    slotAuthMethodChanged(ui->authMethod->currentItem());
    setAuthMoveButtons();
  }
}

void KPureftpdScript::setAuthEditButtons() {
  if (ui->authList->childCount()==0) {
    ui->authAdd->setEnabled(true);
    ui->authModify->setEnabled(false);
    ui->authDelete->setEnabled(false);
  } else {
    if (ui->authList->findItem(ui->authMethod->currentText(),0)) {
      ui->authAdd->setEnabled(false);
      if (ui->authList->currentItem()->text(0) == ui->authMethod->currentText()) {
        ui->authModify->setEnabled(true);
      } else {
        ui->authModify->setEnabled(false);
      }
    } else {
      ui->authAdd->setEnabled(true);
      ui->authModify->setEnabled(true);
    }
    ui->authDelete->setEnabled(true);
  }
}

void KPureftpdScript::setAuthMoveButtons() {
  ui->authMoveUp->setEnabled( ui->authList->currentItem() != ui->authList->firstChild() );
  ui->authMoveDown->setEnabled( ui->authList->currentItem() != ui->authList->lastItem() );
}
// ----------  AUTH EDIT SLOTS    END   ------------------------------ //

// ---------------------------------------------------------------- //

QString KPureftpdScript::parseOptions(ScriptItem &s) {
  QString tid, osep, lsep, lopt, options, output;

  tid = s.templateid();
  osep = scriptTemplate->map()[tid].optsep();
  lsep = scriptTemplate->map()[tid].linesep();
  output = scriptTemplate->map()[tid].scripttemplate();

  // --- "Security & Logging" tab (first)
  // Note: syslog() option is first to allow ensure blocking messages to "local2"
  //       syslog facility while parsing command line options
  //       when user choose to not use syslog logging
  lopt=QString::null;
  if (s.guidata().usesyslog) {
    if (s.guidata().facility!=4)
      lopt.append("-f " + facilitylist[s.guidata().facility] + osep);
    if (s.guidata().logpid) lopt.append("-1" + osep);
  } else {
    lopt.append("-f none" + osep);
  }
  if (!lopt.isEmpty()) options.append(lopt + lsep);

  // --- "Run" tab
  lopt=QString::null;
  ScriptPref::RunMode r = scriptTemplate->map()[tid].runmode();
  switch (r) {
    case ScriptPref::Standalone:
      lopt.append("-B" + osep);
      lopt.append("-S " + s.guidata().address + "," + s.guidata().port + osep);
      if (s.guidata().maxclients != 50) {
        lopt.append("-c " + QString::number(s.guidata().maxclients) + osep);
      }
      if (s.guidata().clientsperip > 0) {
        lopt.append("-C " + QString::number(s.guidata().clientsperip) + osep);
      }
    break;
    case ScriptPref::Superserver:
    break;
    default:
      kdFatal() << "parseOptions: unknown runmode=" << r << endl;
  }
  if (!lopt.isEmpty()) options.append(lopt + lsep);

  // --- "Authentication" tab
  lopt=QString::null;
  if (s.guidata().authtype==1) {
    QValueList<AuthMethod> authlist = s.guidata().authlist;
    QValueList<AuthMethod>::ConstIterator it;
    for(it=authlist.begin(); it!=authlist.end(); ++it) {
      if (script->authMethods()[(*it).method] == Script::NoPath) {
        lopt.append("-l " + (*it).method + osep);
      } else if (script->authMethods()[(*it).method] == Script::WithPath) {
        lopt.append("-l " + (*it).method + ":" + (*it).path + osep);
      } else {
        kdFatal() << "parseOptions: unknown AuthMethodOption for method=" << (*it).method << endl;
      }
    }
  }
  if (!lopt.isEmpty()) options.append(lopt + lsep);

  // --- "Users" tab
  lopt=QString::null;
  if (s.guidata().anonlogin) lopt.append("-e" + osep);
  if (s.guidata().allowmkdir) lopt.append("-M" + osep);
  if (s.guidata().ftpuserdeny) lopt.append("-s" + osep);
  if (s.guidata().denyupload) lopt.append("-i" + osep);
  if (s.guidata().anonreaddotfiles) lopt.append("-z" + osep);
  if (s.guidata().nonanonlogin) lopt.append("-E" + osep);
  if (s.guidata().readdotfiles) lopt.append("-X" + osep);
  if (s.guidata().writedotfiles) lopt.append("-x" + osep);
  if (s.guidata().restrictedip && !s.guidata().loginip.isEmpty())
    lopt.append("-V " + s.guidata().loginip + osep);
  if (!lopt.isEmpty()) options.append(lopt + lsep);

  // --- "Security & Logging" tab
  lopt=QString::null;
  if (s.guidata().disablechmod) lopt.append("-R" + osep);
  if (s.guidata().usechrootall) lopt.append("-A" + osep);
  if (s.guidata().usechroot) lopt.append("-a " + QString::number(s.guidata().chrootgid) + osep);
  if (s.guidata().useuidlogin) lopt.append("-u " + QString::number(s.guidata().uidlogin) + osep);
  if (s.guidata().idletime != 15) lopt.append("-I " + QString::number(s.guidata().idletime) + osep);
  if (s.guidata().maxfiles!=2000 || s.guidata().maxdepth!=5)
    lopt.append("-L " + QString::number(s.guidata().maxfiles) + ":" + QString::number(s.guidata().maxdepth) + osep);
  if (s.guidata().filesumask!=0133 || s.guidata().dirsumask!=0022)
    lopt.append("-U " + QString::number(s.guidata().filesumask,8) + ":" + QString::number(s.guidata().dirsumask,8) + osep);
  switch (s.guidata().debug) {
    case 1:
      lopt.append("-d" + osep);
    break;
    case 2:
      lopt.append("-d" + osep + "-d" + osep);
    break;
    default:
      ;
  }
  if (s.guidata().usefilelog) {
    lopt.append("-O " + logfmtlist[s.guidata().logformat] + ":" + s.guidata().pathlog + osep);
  }
  if (s.guidata().resolve) lopt.append("-H" + osep);
  if (!lopt.isEmpty()) options.append(lopt + lsep);

  // --- "Limits" tab
  lopt=QString::null;
  if (s.guidata().useportrange)
    lopt.append("-p " + QString::number(s.guidata().portlow) + ":" + QString::number(s.guidata().porthigh) + osep);
  if (s.guidata().usequota)
    lopt.append("-n " + QString::number(s.guidata().quotamaxfiles) + ":" + QString::number(s.guidata().quotamaxsize) + osep);
  if (s.guidata().usedisklimit)
    lopt.append("-k " + QString::number(s.guidata().diskpercent) + osep);
  if (s.guidata().useloadlimit)
    lopt.append("-m " + QString::number(s.guidata().systemload,'f',2) + osep);
  switch (s.guidata().grpbandwidth) {
    case 1:
      lopt.append("-t " + QString::number(s.guidata().bandupload) + ":" + QString::number(s.guidata().banddownload) + osep);
    break;
    case 2:
      lopt.append("-T " + QString::number(s.guidata().bandupload) + ":" + QString::number(s.guidata().banddownload) + osep);
    break;
    default:
      ;
  }
  switch (s.guidata().grpratio) {
    case 1:
      lopt.append("-q " + QString::number(s.guidata().ratioupload) + ":" + QString::number(s.guidata().ratiodownload) + osep);
    break;
    case 2:
      lopt.append("-Q " + QString::number(s.guidata().ratioupload) + ":" + QString::number(s.guidata().ratiodownload) + osep);
    break;
    default:
      ;
  }
  if (!lopt.isEmpty()) options.append(lopt + lsep);

  // --- "Miscellanous" tab
  lopt=QString::null;
  if (s.guidata().onlyipv4) lopt.append("-4" + osep);
  if (s.guidata().activeftp) lopt.append("-N" + osep);
  if (s.guidata().usepassiveip) lopt.append("-P " + s.guidata().passiveip + osep);
  if (s.guidata().useuploadscript) lopt.append("-o" + osep);
  if (s.guidata().allowresume) lopt.append("-K" + osep);
  if (s.guidata().createhomedir) lopt.append("-j" + osep);
  if (s.guidata().usefortunes) lopt.append("-F " + s.guidata().fortunesfile + osep);
  if (s.guidata().neveroverwrite) lopt.append("-r" + osep);
  if (s.guidata().norename) lopt.append("-G" + osep);
  if (s.guidata().customerproof) lopt.append("-Z" + osep);
  if (s.guidata().enableworkarounds) lopt.append("-b" + osep);
  if (s.guidata().fxpeveryone) lopt.append("-W" + osep);
  if (s.guidata().fxpnonanonym) lopt.append("-w" + osep);
  if (!lopt.isEmpty()) options.append(lopt);

  output.replace(QRegExp("@PUREFTPD@"), s.guidata().pureftpd);
  output.replace(QRegExp("@PUREFTPWHO@"), s.guidata().pureftpwho);
  output.replace(QRegExp("@PUREMRTGINFO@"), s.guidata().puremrtginfo);
  output.replace(QRegExp("@PUREAUTHD@"), s.guidata().pureauthd);
  output.replace(QRegExp("@PUREQUOTACHECK@"), s.guidata().purequotacheck);
  output.replace(QRegExp("@PUREUPLOADSCRIPT@"), s.guidata().pureuploadscript);
  output.replace(QRegExp("@PUREPW@"), s.guidata().purepw);
  output.replace(QRegExp("@PUREPWCONVERT@"), s.guidata().purepwconvert);
  output.replace(QRegExp("@PURESTATSDECODE@"), s.guidata().purestatsdecode);
  output.replace(QRegExp("@ID@"), s.id());
  output.replace(QRegExp("@TITLE@"), s.title());
  output.replace(QRegExp("@DESCRIPTION@"), s.description());
  output.replace(QRegExp("@OUTPUTFILE@"), s.outputfile());
  output.replace(QRegExp("@OUTPUTFILEMODE@"), "0"+QString::number(s.outputfilemode(),8));
  output.replace(QRegExp("@RUNMODE@"), QString::number(scriptTemplate->map()[tid].runmode()));
  output.replace(QRegExp("@OPTSEP@"), osep);
  output.replace(QRegExp("@LINESEP@"), lsep);
  output.replace(QRegExp("@OPTIONS@"), options);

  return output;
}

void KPureftpdScript::getGui(GuiData &g) {
  // "Scripts" tab

  // "Run" tab
  g.address = ui->address->text();
  g.port = ui->port->text();
  g.maxclients = ui->maxClients->value();
  g.clientsperip = ui->clientsPerIp->value();
  g.pidfile = ui->pidFile->url();
  g.pureftpd = ui->pureftpd->url();
  g.pureftpwho = ui->pureftpwho->url();
  g.puremrtginfo = ui->puremrtginfo->url();
  g.pureauthd = ui->pureauthd->url();
  g.purequotacheck = ui->purequotacheck->url();
  g.pureuploadscript = ui->pureuploadscript->url();
  g.purepw = ui->purepw->url();
  g.purepwconvert = ui->purepwconvert->url();
  g.purestatsdecode = ui->purestatsdecode->url();

  // "Authentication" tab
  g.authtype = ui->grpAuth->id(ui->grpAuth->selected());
  g.authlist.clear();
  QListViewItem *it = ui->authList->firstChild();
  while (it != 0L) {
    AuthMethod am;
    am.method=it->text(0);
    am.path=it->text(1);
    g.authlist.append(am);
    it = it->nextSibling();
  }

  // "Users" tab
  g.anonlogin = ui->anonLogin->isChecked();
  g.allowmkdir = ui->allowMkdir->isChecked();
  g.ftpuserdeny = ui->ftpUserDeny->isChecked();
  g.denyupload = ui->denyUpload->isChecked();
  g.anonreaddotfiles = ui->anonReadDotFiles->isChecked();
  g.nonanonlogin = ui->nonAnonLogin->isChecked();
  g.readdotfiles = ui->readDotFiles->isChecked();
  g.writedotfiles = ui->writeDotFiles->isChecked();
  g.restrictedip = ui->restrictedIp->isChecked();
  g.loginip = ui->loginIp->text();

  // "Security & Logging" tab
  g.disablechmod = ui->disableChmod->isChecked();
  g.usechrootall = ui->useChrootAll->isChecked();
  g.usechroot = ui->useChroot->isChecked();
  g.chrootgid = ui->chrootGid->value();
  g.useuidlogin = ui->useUidLogin->isChecked();
  g.uidlogin = ui->uidLogin->value();
  g.idletime = ui->idleTime->value();
  g.maxfiles = ui->maxFiles->value();
  g.maxdepth = ui->maxDepth->value();
  g.filesumask = ui->filesUmask->value();
  g.dirsumask = ui->dirsUmask->value();
  g.debug = ui->debug->currentItem();
  g.usesyslog = ui->useSyslog->isChecked();
  g.facility = ui->facility->currentItem();
  g.logpid = ui->logPid->isChecked();
  g.usefilelog = ui->useFilelog->isChecked();
  g.logformat = ui->logFormat->currentItem();
  g.pathlog = ui->pathLog->url();
  g.resolve = ui->resolve->isChecked();

  // "Limits" tab
  g.useportrange = ui->usePortRange->isChecked();
  g.portlow = ui->portLow->value();
  g.porthigh = ui->portHigh->value();
  g.usequota = ui->useQuota->isChecked();
  g.quotamaxfiles = ui->quotaMaxFiles->value();
  g.quotamaxsize = ui->quotaMaxSize->value();
  g.usedisklimit = ui->useDiskLimit->isChecked();
  g.diskpercent = ui->diskPercent->value();
  g.useloadlimit = ui->useLoadLimit->isChecked();
  g.systemload = ui->systemLoad->value();
  g.grpbandwidth = ui->grpBandwidth->id(ui->grpBandwidth->selected());
  g.bandupload = ui->bandUpload->value();
  g.banddownload = ui->bandDownload->value();
  g.grpratio = ui->grpRatio->id(ui->grpRatio->selected());
  g.ratioupload = ui->ratioUpload->value();
  g.ratiodownload = ui->ratioDownload->value();

  // "Miscellaneous" tab
  g.onlyipv4 = ui->onlyIpv4->isChecked();
  g.activeftp = ui->activeFtp->isChecked();
  g.usepassiveip = ui->usePassiveIp->isChecked();
  g.passiveip = ui->passiveIp->text();
  g.useuploadscript = ui->useUploadScript->isChecked();
  g.allowresume = ui->allowResume->isChecked();
  g.createhomedir = ui->createHomeDir->isChecked();
  g.usefortunes = ui->useFortunes->isChecked();
  g.fortunesfile = ui->fortunesFile->url();
  g.neveroverwrite = ui->neverOverwrite->isChecked();
  g.norename = ui->noRename->isChecked();
  g.customerproof = ui->customerProof->isChecked();
  g.enableworkarounds = ui->enableWorkarounds->isChecked();
  g.fxpeveryone = ui->fxpEveryone->isChecked();
  g.fxpnonanonym = ui->fxpNonAnonym->isChecked();

}

void KPureftpdScript::setGui(const GuiData &g) {
  isSettingGui=true;
  // "Scripts" tab

  // "Run" tab
  ui->address->setText(g.address);
  ui->port->setText(g.port);
  ui->maxClients->setValue(g.maxclients);
  ui->clientsPerIp->setValue(g.clientsperip);
  ui->pidFile->setURL(g.pidfile);
  ui->pureftpd->setURL(g.pureftpd);
  ui->pureftpwho->setURL(g.pureftpwho);
  ui->puremrtginfo->setURL(g.puremrtginfo);
  ui->pureauthd->setURL(g.pureauthd);
  ui->purequotacheck->setURL(g.purequotacheck);
  ui->pureuploadscript->setURL(g.pureuploadscript);
  ui->purepw->setURL(g.purepw);
  ui->purepwconvert->setURL(g.purepwconvert);
  ui->purestatsdecode->setURL(g.purestatsdecode);

  // "Authentication" tab
  ui->authList->clear();
  for (QValueList<AuthMethod>::ConstIterator it=g.authlist.begin(); it!=g.authlist.end(); ++it) {
    KListViewItem *tmp = new KListViewItem(ui->authList,ui->authList->currentItem());
    tmp->setText(0,(*it).method);
    tmp->setText(1,(*it).path);
    ui->authList->setCurrentItem(tmp);
  }
  ui->grpAuth->setButton(g.authtype);
  slotAuthType(g.authtype);

  // "Users" tab
  ui->anonLogin->setChecked(g.anonlogin);
  ui->allowMkdir->setChecked(g.allowmkdir);
  ui->ftpUserDeny->setChecked(g.ftpuserdeny);
  ui->denyUpload->setChecked(g.denyupload);
  ui->anonReadDotFiles->setChecked(g.anonreaddotfiles);
  ui->nonAnonLogin->setChecked(g.nonanonlogin);
  ui->readDotFiles->setChecked(g.readdotfiles);
  ui->writeDotFiles->setChecked(g.writedotfiles);
  ui->restrictedIp->setChecked(g.restrictedip);
  ui->loginIp->setText(g.loginip);

  // "Security & Logging" tab
  ui->disableChmod->setChecked(g.disablechmod);
  ui->useChrootAll->setChecked(g.usechrootall);
  ui->useChroot->setChecked(g.usechroot);
  ui->chrootGid->setValue(g.chrootgid);
  ui->useUidLogin->setChecked(g.useuidlogin);
  ui->uidLogin->setValue(g.uidlogin);
  ui->idleTime->setValue(g.idletime);
  ui->maxFiles->setValue(g.maxfiles);
  ui->maxDepth->setValue(g.maxdepth);
  ui->filesUmask->setValue(g.filesumask);
  ui->dirsUmask->setValue(g.dirsumask);
  ui->debug->setCurrentItem(g.debug);
  ui->useSyslog->setChecked(g.usesyslog);
  ui->facility->setCurrentItem(g.facility);
  ui->logPid->setChecked(g.logpid);
  ui->useFilelog->setChecked(g.usefilelog);
  ui->logFormat->setCurrentItem(g.logformat);
  ui->pathLog->setURL(g.pathlog);
  ui->resolve->setChecked(g.resolve);

  // "Limits" tab
  ui->usePortRange->setChecked(g.useportrange);
  ui->portLow->setValue(g.portlow);
  ui->portHigh->setValue(g.porthigh);
  ui->useQuota->setChecked(g.usequota);
  ui->quotaMaxFiles->setValue(g.quotamaxfiles);
  ui->quotaMaxSize->setValue(g.quotamaxsize);
  ui->useDiskLimit->setChecked(g.usedisklimit);
  ui->diskPercent->setValue(g.diskpercent);
  ui->useLoadLimit->setChecked(g.useloadlimit);
  ui->systemLoad->setValue(g.systemload);
  ui->grpBandwidth->setButton(g.grpbandwidth);
  ui->slotBand(g.grpbandwidth);
  ui->bandUpload->setValue(g.bandupload);
  ui->bandDownload->setValue(g.banddownload);
  ui->grpRatio->setButton(g.grpratio);
  ui->slotRatio(g.grpratio);
  ui->ratioUpload->setValue(g.ratioupload);
  ui->ratioDownload->setValue(g.ratiodownload);

  // "Miscellaneous" tab
  ui->onlyIpv4->setChecked(g.onlyipv4);
  ui->activeFtp->setChecked(g.activeftp);
  ui->usePassiveIp->setChecked(g.usepassiveip);
  ui->passiveIp->setText(g.passiveip);
  ui->useUploadScript->setChecked(g.useuploadscript);
  ui->allowResume->setChecked(g.allowresume);
  ui->createHomeDir->setChecked(g.createhomedir);
  ui->useFortunes->setChecked(g.usefortunes);
  ui->fortunesFile->setURL(g.fortunesfile);
  ui->neverOverwrite->setChecked(g.neveroverwrite);
  ui->noRename->setChecked(g.norename);
  ui->customerProof->setChecked(g.customerproof);
  ui->enableWorkarounds->setChecked(g.enableworkarounds);
  ui->fxpEveryone->setChecked(g.fxpeveryone);
  ui->fxpNonAnonym->setChecked(g.fxpnonanonym);

  isSettingGui=false;
}


// ----------  KCMMODULE METHODS  BEGIN ------------------------------ //
01357 void KPureftpdScript::load() {
  // application options
  config->setGroup("Options");
  debug=config->readUnsignedNumEntry("Debug",0);

  // save the default GUI in a fake script
  QString scriptfile, id;
  ScriptItem s;
  scriptfile = KGlobal::dirs()->findResource("data","kcmpureftpdscript/guidata");
  if (script->load(s,scriptfile,id) == Script::LoadOk) {
    setGui(s.guidata());
  } else {
    // set some safe defaults defined in GuiData class
    GuiData g;
    setGui(g);
  }

  emit changed(false);
}

01377 void KPureftpdScript::save() {
  // application options
  config->setGroup("Options");
  config->writeEntry("Debug",debug);
  config->sync();

  // save the default GUI in a fake script
  GuiData g;
  getGui(g);
  ScriptItem s;
  s.setGuiData(g);
  s.setId("dummy-unused-id");
  s.setTemplateId("dummy-unused-templateid");
  QString dir = KGlobal::dirs()->saveLocation("data","kcmpureftpdscript/");
  s.setScriptFile(dir+"guidata");
  script->save(s);

  // save the GUI modified data back in current script
  slotTabChanged(ui->tabScripts);
  // save all modified scripts
  ScriptItemIterator it;
  for (it=script->begin(); it!=script->end(); ++it) {
    if ((*it).isChanged()) {
      (void)script->save((*it));
    }
  }

  emit changed(false);
}

01407 void KPureftpdScript::defaults() {
  // here set the GUI to some sane, safe and secure pure-ftpd values
  GuiData g;
  setGui(g);
  emit changed(true);
}

01414 int KPureftpdScript::buttons() {
    return KCModule::Apply | KCModule::Help;
}

01418 QString KPureftpdScript::quickHelp() const {
    return i18n("<h1>PureFTPd Script Generator</h1> <p>This module allow you to generate <b>PureFTPd</b> "
                "configuration files and startup shell scripts. These are made based on script templates "
                "and settings you choose in the graphical interface. For system administrators which manage "
                "many FTP servers, the \"Script Manager\" is a very handy tool to keep things organized.</p>"
                "<p>As with every program which act as server, you should be very carefull when set options "
                "that can compromise system security where FTP server is running.</p>"
               );
}

01428 const KAboutData *KPureftpdScript::aboutData() const {
    KAboutData *myAboutData = new KAboutData(
                                  "kcmpureftpdscript", I18N_NOOP("KCM PureFtpd"),
                                  VERSION, I18N_NOOP("KControl module for PureFtpd startup scripts generation"),
                                  KAboutData::License_GPL, "(c) 2001-2003 Claudiu Costin",0,
                                  "http://www.ro.kde.org/kcmpureftpd/",
                                  "claudiuc@kde.org");
    myAboutData->addAuthor("Claudiu Costin",I18N_NOOP("Original author"),"claudiuc@kde.org");
    myAboutData->addAuthor("Frank Denis",I18N_NOOP("Tooltips from manual pages"),"j@pureftpd.org");
    myAboutData->addCredit("Iuliana Costin",
                           I18N_NOOP("My lovely wife who allowed me to spend countless hours in "
                                     "front of computer."),QString::null);
    myAboutData->addCredit("Bernard Lheureux",
                           I18N_NOOP("Very helpfull to track down compilation\n"
                                     "and installation problems on Mandrake 7.2."),
                           "bernard.lheureux@bbsoft4.org");
    myAboutData->addCredit("Frank Denis",
                           I18N_NOOP("Pureftpd FTP server author. "
                                     "Many thanks for such great piece of code."),
                           "j@pureftpd.org");
    return myAboutData;
}
// ----------  KCMMODULE METHODS    END ------------------------------ //

extern "C" {
    KCModule *create_pureftpdscript(QWidget *parent, const char *name) {
        QString dummy=name;
        KGlobal::locale()->insertCatalogue("kcmpureftpd");
        return new KPureftpdScript(parent,"kcmpureftpdscript");
    };

    void init_pureftpd() {
        kapp->startServiceByDesktopName("kcmpureftpdscript");
    };
}

Generated by  Doxygen 1.6.0   Back to index