/***************************************************************************
                          klprfax_config.cpp  -  description
                             -------------------
    begin                : Sun May 27 2001
    copyright            : (C) 2001 by Hans Dijkema
    email                : hdijkema@hum.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 "klprfax_config.h"

#include <klocale.h>
#include <kmessagebox.h>
#include <kaboutapplication.h>

#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

#ifndef max
#define max(a,b) ((a>b) ? a : b)
#endif

klprfax_config::klprfax_config(KApplication *_app,KConfigBase *conf,QWidget *parent, const char *name ) : QWidget(parent,name)
{
  // ROOT privileges needed to:
  //
  // /etc/printcap can be updated if the user has root privileges.
  // Also the fax printername can be set.
  // The user with root privileges also sets the modem device to use (/etc/klprfax).
  //
  // --> these options are grayed if the owner of this process isn't root.
  //
  // THIS can be done by users.
  //
  // Users default X display to display klprfax on is set in $HOME/.klprfax.
  // Header lines can be set, i.e. the From line (normally name).
  // and the own fax number line.
  //

  app=_app;
  config=conf;
  rootConf=conf;
  rootConf->setGroup("devices");

  dlg=new QGrid(5,QGrid::Vertical,this);
  dlg->setMargin(10);
  dlg->setSpacing(10);

  // Now work from top to down.

  rootGroup=new QLabel(dlg);
  rootGroup->setText(i18n("Device settings (root privileges needed)"));

  // root privileges

  rootCanvas=new QGrid(3,dlg);
  rootCanvas->setSpacing(10);
  rootCanvas->setMargin(10);
  rootCanvas->setFrameStyle(QFrame::Box|QFrame::Raised);

  explainPtrName=new QLabel(rootCanvas);
  explainPtrName->setText(i18n("printer name: "));

  printerName=new QLineEdit(rootCanvas);
  printerName->setText(rootConf->readEntry("printername","<not defined>"));
  printerName->setEnabled(isRoot());

  editPrintCap=new QPushButton(rootCanvas);editPrintCap->setText(i18n("&edit /etc/printcap"));
  connect(editPrintCap,SIGNAL(clicked()), SLOT(EditPrintCap()));
  editPrintCap->setEnabled(isRoot());

  explainModem=new QLabel(rootCanvas);
  explainModem->setText(i18n("modem device: "));

  modemDevice=new QLineEdit(rootCanvas);
  {QString dev;
     dev=rootConf->readEntry("device","modem");
     dev="/dev/"+dev;
     modemDevice->setText(dev);
  }
  modemDevice->setEnabled(isRoot());
  modemDevice->adjustSize();
  modemDevice->setMinimumWidth(200);

  setModemDevice=new QPushButton(rootCanvas);
  setModemDevice->setText(i18n("set modem device"));
  connect(setModemDevice,SIGNAL(clicked()), SLOT(setDevice()));
  setModemDevice->setEnabled(isRoot());

  // user settings

  conf->setGroup("klprfax");

  userGroup=new QLabel(dlg);
  userGroup->setText(i18n("User settings"));

  canvas=new QGrid(2,dlg);
  canvas->setSpacing(10);
  canvas->setMargin(10);
  canvas->setFrameStyle(QFrame::Box|QFrame::Raised);

  lxDisplay=new QLabel(canvas);
  lxDisplay->setText(i18n("X DISPLAY Variable: "));
  xDisplay=new QLineEdit(canvas);
  xDisplay->adjustSize();
  xDisplay->setText(conf->readEntry("xdisplay",":0"));

  lfrom=new QLabel(canvas);
  lfrom->setText(i18n("your header :"));
  from=new QLineEdit(canvas);
  from->setText(conf->readEntry("from",""));

  lfromFax=new QLabel(canvas);
  lfromFax->setText(i18n("your fax :"));
  fromFax=new QLineEdit(canvas);
  fromFax->setText(conf->readEntry("fromFax",""));

  lprefix=new QLabel(canvas);
  lprefix->setText(i18n("dial prefix :"));
  prefix=new QLineEdit(canvas);
  prefix->setText(conf->readEntry("dialprefix",""));

  // Add the cancel and ok buttons

  buttons=new QGrid(4,dlg);
  buttons->setSpacing(10);

  new QLabel(buttons);

  about=new QPushButton(buttons);
  about->setText(i18n("&About"));
  connect(about,SIGNAL(clicked()),SLOT(doAbout()));

  cancel=new QPushButton(buttons);
  cancel->setText(i18n("&Cancel"));
  connect(cancel,SIGNAL(clicked()),SLOT(close()));

  ok=new QPushButton(buttons);
  ok->setText(i18n("&Ok"));
  connect(ok,SIGNAL(clicked()),SLOT(set()));

  // Now adjust the dialog size

  dlg->adjustSize();

  setFixedSize(dlg->width(),dlg->height());
}

klprfax_config::~klprfax_config()
{
}

/** No descriptions */
void klprfax_config::EditPrintCap()
{
  createLPD();
}

/** No descriptions */
bool klprfax_config::isRoot(void)
{
uid_t r=getuid();
return r==0;
}
/** No descriptions */

#define klprfaxLPD 	KDE_BINDIR "/klprfax_lpd"
#define PCAPMV		"/etc/printcap.klprfax"
#define PCAPMV1 	"/etc/printcap.klprfax.old"
#define PCAP		"/etc/printcap"
#define STARTCAP 	"#### start of klprfax section - don't touch!\n"
#define ENDCAP   	"#### end of klprfax section\n"

void klprfax_config::createLPD()
{
FILE *fin;
FILE *fout;
char line[4096];
bool skip=false;

   // first check the printername

   QString _name=printerName->text().stripWhiteSpace();
   char name[1024];
   strcpy(name,_name.latin1());

   int i,N;
   for(i=0,N=_name.length();i<N && isalpha(name[i]);i++);
   if (i!=N) {
      KMessageBox::error(this,i18n("The name of the LPD fax printer definition can only consist\n"
                                    "of a-z or A-Z characters."
                                   )
                        );
      return;
   }
   else if (N==0) {
      KMessageBox::error(this,i18n("The name of the LPD fax printer definition can not be empty."));
      return;
   }

   // Go on, make the printcap definition.

   // first move /etc/printcap --> /etc/printcap.klprfax

   rename(PCAPMV,PCAPMV1);
   if (rename(PCAP,PCAPMV)==-1) {
     KMessageBox::error(this,i18n("Can't rename " PCAP " to " PCAPMV ".\n"
                                   "Check distribution!"
                                  )
                        );
     rename(PCAPMV1,PCAPMV);
     return;
   }
   unlink(PCAPMV1);

   fin=fopen(PCAPMV,"rb");
   fout=fopen(PCAP,"wb");

   while(fgets(line,4096,fin)!=NULL) {
     if (strcmp(line,STARTCAP)==0) { skip=true; }
     else if (strcmp(line,ENDCAP)==0) { skip=false; }
     else if (!skip) {
       fprintf(fout,"%s",line);
     }
   }

   // add printcap section to /etc/printcap

   fprintf(fout,STARTCAP
                "%s:\\\n"
                "        :lp=/dev/null:\\\n"
                "        :sd=/var/spool/lpd/klprfax:\\\n"
                "        :lf=/var/spool/lpd/klprfax/log:\\\n"
                "        :af=/var/spool/lpd/klprfax/acct:\\\n"
                "        :if=%s/klprfax_filter:\\\n"
                "        :mx#0:\\\n"
                "        :sh:\n"
	        ENDCAP
               ,name,KDE_BINDIR
          );

   fclose(fin);
   fclose(fout);

   // And, if not exists make the lpd directory stucture accordingly

   int k=system(klprfaxLPD);
   k>>=8;

   if (k==0) {
     KMessageBox::information(this,i18n("/etc/printcap section successfully made, and\n"
                                         "klprfax LPD spool directory too."
                                        )
                             );
   }
   else if (k==1) {
     KMessageBox::information(this,i18n("/etc/printcap section successfully made.\n"
                                         "klprfax LPD spool directory already exists :-)."
                                        )
                             );
   }
   else if (k==2) {
     KMessageBox::information(this,i18n("/etc/printcap section successfully made.\n"
                                         "klprfax LPD spool directory made, but LPD daemon\n"
                                         "can't be started :-(. Please check the LPD daemon."
                                        )
                             );
   }
   else {
     KMessageBox::error(this,i18n("/etc/printcap section successfully made.\n"
                                         "klprfax LPD spool directory couldn't be made :-(.\n"
                                         "This won't work, please make spool directory by hand."
                                        )
                             );
   }


   rootConf->setGroup("devices");
   rootConf->writeEntry("printername",_name);
}

/** No descriptions */
void klprfax_config::setDevice()
{
QString dev=modemDevice->text().stripWhiteSpace();
  if (dev.left(5)=="/dev/") {
    dev=dev.mid(5);
  }

  rootConf->setGroup("devices");
  rootConf->writeEntry("device",dev);

  FILE *f=fopen("/etc/klprfax","wb");
  if (f==NULL) {
    KMessageBox::error(this,i18n("Unexpected: Can't open /etc/klprfax!"));
  }
  else {
    fprintf(f,"%s\n",dev.latin1());
    fclose(f);
  }
}

void klprfax_config::set()
{
  config->setGroup("klprfax");
  config->writeEntry("xdisplay",xDisplay->text().stripWhiteSpace());
  config->writeEntry("from",from->text());
  config->writeEntry("fromFax",fromFax->text());
  config->writeEntry("dialprefix",prefix->text().stripWhiteSpace());

  QString file;
  file.sprintf("%s/.klprfax",getenv("HOME"));

  FILE *f;
  f=fopen(file.latin1(),"wb");
  if (f==NULL) {
    KMessageBox::error(this,i18n("Unexpected: Can't write $HOME/.klprfax!"));
  }
  else {QString d=xDisplay->text().stripWhiteSpace();
    fprintf(f,"DISPLAY=\"%s\";export DISPLAY\n",d.latin1());
    fclose(f);
  }
  close();
}
/** No descriptions */
void klprfax_config::doAbout()
{
  KAboutApplication(this).exec();
}
