mirror of
				https://github.com/ElvishArtisan/rivendell.git
				synced 2025-11-04 16:14:03 +01:00 
			
		
		
		
	* Cleaned up deprecation warnings for 'QString::sprintf()'. Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
		
			
				
	
	
		
			453 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			453 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// rddbconfig.cpp
 | 
						|
//
 | 
						|
// A Qt-based application to configure, backup, and restore
 | 
						|
// the Rivendell database.
 | 
						|
//
 | 
						|
//   (C) Copyright 2009-2021 Fred Gleason <fredg@paravelsystems.com>
 | 
						|
//
 | 
						|
//   This program is free software; you can redistribute it and/or modify
 | 
						|
//   it under the terms of the GNU General Public License version 2 as
 | 
						|
//   published by the Free Software Foundation.
 | 
						|
//
 | 
						|
//   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., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
//
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <syslog.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <sys/types.h>
 | 
						|
 | 
						|
#include <QApplication>
 | 
						|
#include <QFileDialog>
 | 
						|
#include <QProcess>
 | 
						|
 | 
						|
#include <dbversion.h>
 | 
						|
#include <rdapplication.h>
 | 
						|
#include <rdconf.h>
 | 
						|
#include <rdconfig.h>
 | 
						|
#include <rdpaths.h>
 | 
						|
 | 
						|
#include "../../icons/rivendell-22x22.xpm"
 | 
						|
 | 
						|
#include "rddbconfig.h"
 | 
						|
#include "db.h"
 | 
						|
#include "createdb.h"
 | 
						|
#include "mysql_login.h"
 | 
						|
 | 
						|
//
 | 
						|
// Globals
 | 
						|
//
 | 
						|
MainWidget::MainWidget(RDConfig *c,QWidget *parent)
 | 
						|
  : RDWidget(c,parent)
 | 
						|
{
 | 
						|
  QString err_msg;
 | 
						|
 | 
						|
  db_daemon_start_needed=false;
 | 
						|
  db=NULL;
 | 
						|
 | 
						|
  if(geteuid()!=0) {
 | 
						|
    QMessageBox::critical(this,tr("RDDbConfig Error"),
 | 
						|
      tr("This application requires root permissions."));
 | 
						|
      exit(256);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Open rd.conf(5)
 | 
						|
  //
 | 
						|
  rd_config=new RDConfig();
 | 
						|
  rd_config->load();
 | 
						|
  rd_config->setModuleName("rddbconfig");
 | 
						|
 | 
						|
 | 
						|
  //
 | 
						|
  // Create And Set Icon
 | 
						|
  //
 | 
						|
  setWindowIcon(QPixmap(rivendell_22x22_xpm));
 | 
						|
  setWindowTitle(tr("RDDbConfig")+" v"+VERSION);
 | 
						|
 | 
						|
  //
 | 
						|
  // Fix the Window Size
 | 
						|
  //
 | 
						|
  setMinimumSize(sizeHint());
 | 
						|
 | 
						|
  //
 | 
						|
  // Labels
 | 
						|
  //
 | 
						|
  QLabel *label=new QLabel(tr("Select an operation:"),this);
 | 
						|
  label->setGeometry(0,90,sizeHint().width(),16);
 | 
						|
  label->setFont(labelFont());
 | 
						|
  label->setAlignment(Qt::AlignCenter);
 | 
						|
 | 
						|
  label_hostname=new QLabel(QString::asprintf("SQL Server: %s",
 | 
						|
	 rd_config->mysqlHostname().toUtf8().constData()),this);
 | 
						|
  label_hostname->setGeometry(0,5,sizeHint().width(),16);
 | 
						|
  label_hostname->setFont(day_font);
 | 
						|
  label_hostname->setAlignment(Qt::AlignCenter);
 | 
						|
 | 
						|
  label_username=new QLabel(QString::asprintf("SQL Usename: %s",
 | 
						|
	 rd_config->mysqlUsername().toUtf8().constData()),this);
 | 
						|
  label_username->setGeometry(0,20,sizeHint().width(),16);
 | 
						|
  label_username->setFont(day_font);
 | 
						|
  label_username->setAlignment(Qt::AlignCenter);
 | 
						|
 | 
						|
  label_dbname=new QLabel(QString::asprintf("SQL Database: %s",
 | 
						|
	 rd_config->mysqlDbname().toUtf8().constData()),this);
 | 
						|
  label_dbname->setGeometry(0,35,sizeHint().width(),16);
 | 
						|
  label_dbname->setFont(day_font);
 | 
						|
  label_dbname->setAlignment(Qt::AlignCenter);
 | 
						|
 | 
						|
  label_schema=new QLabel(this);
 | 
						|
  label_schema->setGeometry(0,50,sizeHint().width(),16);
 | 
						|
  label_schema->setFont(day_font);
 | 
						|
  label_schema->setAlignment(Qt::AlignCenter);
 | 
						|
 | 
						|
  //
 | 
						|
  // Create Button
 | 
						|
  //
 | 
						|
  db_create_button=new QPushButton(tr("Create"),this);
 | 
						|
  db_create_button->setFont(buttonFont());
 | 
						|
  connect(db_create_button,SIGNAL(clicked()),this,SLOT(createData()));
 | 
						|
 | 
						|
  //
 | 
						|
  // Backup Button
 | 
						|
  //
 | 
						|
  db_backup_button=new QPushButton(tr("Backup"),this);
 | 
						|
  db_backup_button->setFont(buttonFont());
 | 
						|
  connect(db_backup_button,SIGNAL(clicked()),this,SLOT(backupData()));
 | 
						|
 | 
						|
  //
 | 
						|
  // Restore Button
 | 
						|
  //
 | 
						|
  db_restore_button=new QPushButton(tr("Restore"),this);
 | 
						|
  db_restore_button->setFont(buttonFont());
 | 
						|
  connect(db_restore_button,SIGNAL(clicked()),this,SLOT(restoreData()));
 | 
						|
 | 
						|
  //
 | 
						|
  // Close Button
 | 
						|
  //
 | 
						|
  db_close_button=new QPushButton(tr("Close"),this);
 | 
						|
  db_close_button->setFont(buttonFont());
 | 
						|
  connect(db_close_button,SIGNAL(clicked()),this,SLOT(closeData()));
 | 
						|
 | 
						|
  //
 | 
						|
  // Signals
 | 
						|
  //
 | 
						|
  connect(this,SIGNAL(dbChanged()),this,SLOT(updateLabels()));
 | 
						|
  connect(this,SIGNAL(dbMismatch()),this,SLOT(mismatchData()));
 | 
						|
 | 
						|
  this->show();
 | 
						|
 | 
						|
  emit dbChanged();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
MainWidget::~MainWidget()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
QSize MainWidget::sizeHint() const
 | 
						|
{
 | 
						|
  return QSize(280,330);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
QSizePolicy MainWidget::sizePolicy() const
 | 
						|
{
 | 
						|
  return QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
 | 
						|
}
 | 
						|
 | 
						|
void MainWidget::mismatchData()
 | 
						|
{
 | 
						|
  if (!db->schema()) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (QMessageBox::question(this,tr("Database Mismatch"),QString::asprintf("Your database is version %d. Your Rivendell %s installation requires version %d. Would you like to modify your database to the current version?",db->schema(),VERSION,RD_VERSION_DATABASE),(QMessageBox::No|QMessageBox::Yes)) != QMessageBox::Yes) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  QProcess modifyProcess(this);
 | 
						|
  QStringList args;
 | 
						|
  args << QString("--modify");
 | 
						|
  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 | 
						|
  modifyProcess.start(QString("%1/sbin/rddbmgr").arg(RD_PREFIX), args);
 | 
						|
  bool r=modifyProcess.waitForFinished(-1);
 | 
						|
  QApplication::restoreOverrideCursor();
 | 
						|
  if(r) {
 | 
						|
    QString stderr=modifyProcess.readAllStandardError();
 | 
						|
    if (modifyProcess.exitCode()) {
 | 
						|
      QMessageBox::critical(this,tr("RDDbConfig Error"),stderr);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      if(!stderr.isEmpty()) {
 | 
						|
        QMessageBox::information(this,"Database Modified with Warnings",
 | 
						|
          QString::asprintf("Modified database to version %d with warnings:\n\n%s",
 | 
						|
			    RD_VERSION_DATABASE,stderr.toUtf8().constData()));
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        QMessageBox::information(this,"Database Modified Successfully",
 | 
						|
          QString::asprintf("Modified database to version %d",
 | 
						|
			    RD_VERSION_DATABASE));
 | 
						|
      }
 | 
						|
      RDApplication::syslog(rd_config,LOG_INFO,
 | 
						|
			    "modified database to version %d",
 | 
						|
			    RD_VERSION_DATABASE);
 | 
						|
 | 
						|
      emit dbChanged();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    QMessageBox::critical(this,tr("Database Update Error"),
 | 
						|
      QString("Error starting rddbmgr: code=%1").arg(modifyProcess.error()));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void MainWidget::updateLabels()
 | 
						|
{
 | 
						|
  QString err_msg="";
 | 
						|
 | 
						|
  if(db!=NULL) {
 | 
						|
    delete db;
 | 
						|
  }
 | 
						|
  db = new Db(&err_msg,rd_config);
 | 
						|
 | 
						|
  if (!db->isOpen()) {
 | 
						|
    label_schema->setText("DB Version: unknown");
 | 
						|
    db_backup_button->setEnabled(false);
 | 
						|
    db_restore_button->setEnabled(false);
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    label_schema->setText(QString::asprintf("DB Version: %d",db->schema()));
 | 
						|
    db_backup_button->setEnabled(true);
 | 
						|
    db_restore_button->setEnabled(true);
 | 
						|
 | 
						|
    if(db->schema()!=RD_VERSION_DATABASE) {
 | 
						|
      emit dbMismatch();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void MainWidget::closeData()
 | 
						|
{
 | 
						|
  exit(0);
 | 
						|
}
 | 
						|
 | 
						|
void MainWidget::createData()
 | 
						|
{
 | 
						|
  MySqlLogin *mysql_login;
 | 
						|
  QString hostname=rd_config->mysqlHostname();
 | 
						|
  QString dbname=rd_config->mysqlDbname();
 | 
						|
  QString admin_name;
 | 
						|
  QString admin_pwd;
 | 
						|
  QString err_str;
 | 
						|
 | 
						|
  if (db->isOpen()) {
 | 
						|
    if (QMessageBox::question(this,tr("Create Database"),tr("Creating a new database will erase all of your data. Are you sure you want to create a new database?"),(QMessageBox::No|QMessageBox::Yes)) != QMessageBox::Yes) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  mysql_login=new MySqlLogin(&admin_name,&admin_pwd,rd_config,this);
 | 
						|
 | 
						|
  if(mysql_login->exec()) {
 | 
						|
    delete mysql_login;
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  delete mysql_login;
 | 
						|
 | 
						|
  if(admin_name.isEmpty()||admin_pwd.isEmpty()) {
 | 
						|
    QMessageBox::critical(this,tr("RDDbConfig Error"),tr("Did not specify username and/or password."));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  stopDaemons();
 | 
						|
 | 
						|
  CreateDb *db_create=new CreateDb(hostname,dbname,admin_name,admin_pwd);
 | 
						|
 | 
						|
  if(db_create->create(this,&err_str,rd_config)) {
 | 
						|
    QMessageBox::critical(this,tr("RDDbConfig Error"),err_str);
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    QMessageBox::information(this,tr("Success"),tr("A new database has been successfully created."));
 | 
						|
  }
 | 
						|
 | 
						|
  startDaemons();
 | 
						|
 | 
						|
  emit updateLabels();
 | 
						|
 | 
						|
  delete db_create;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void MainWidget::backupData()
 | 
						|
{
 | 
						|
  QString filename;
 | 
						|
 | 
						|
  if (!db->isOpen()) {
 | 
						|
    QMessageBox::critical(this,tr("RDDbConfig Error"),
 | 
						|
      QString::asprintf("Could not open %s database.",
 | 
						|
			rd_config->mysqlDbname().toUtf8().constData()));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  filename=QFileDialog::getSaveFileName(this,"RDDbConfig - "+
 | 
						|
					tr("Enter the MySQL Backup Filename"),
 | 
						|
					RDHomeDir(),
 | 
						|
					"MySQL files (*.sql);;All files (*.*)");
 | 
						|
 | 
						|
  if (!filename.isEmpty()) {
 | 
						|
    QProcess backupProcess(this);
 | 
						|
    QStringList args;
 | 
						|
    args << QString::asprintf("--user=%s",rd_config->mysqlUsername().toUtf8().constData())
 | 
						|
	 << QString::asprintf("--password=%s",rd_config->mysqlPassword().toUtf8().constData())
 | 
						|
	 << QString::asprintf("--host=%s",rd_config->mysqlHostname().toUtf8().constData())
 | 
						|
      << rd_config->mysqlDbname();
 | 
						|
    backupProcess.setStandardOutputFile(filename);
 | 
						|
    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 | 
						|
    backupProcess.start("mysqldump", args);
 | 
						|
    backupProcess.waitForFinished(-1);
 | 
						|
    QApplication::restoreOverrideCursor();
 | 
						|
    if (backupProcess.exitCode()) {
 | 
						|
      QMessageBox::critical(this,tr("RDDbConfig Error"),
 | 
						|
        QString(backupProcess.readAllStandardError()));
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      QMessageBox::information(this,"Database Backed Up Successfully",
 | 
						|
        QString::asprintf("Backed up %s database to %s",
 | 
						|
			  rd_config->mysqlDbname().toUtf8().constData(),
 | 
						|
			  filename.toUtf8().constData()));
 | 
						|
      RDApplication::syslog(rd_config,LOG_INFO,"backed up %s database to %s",
 | 
						|
			    rd_config->mysqlDbname().toUtf8().constData(),
 | 
						|
			    filename.toUtf8().constData());
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void MainWidget::restoreData()
 | 
						|
{
 | 
						|
  QString filename;
 | 
						|
 | 
						|
  if (!db->isOpen()) {
 | 
						|
    QMessageBox::critical(this,tr("RDDbConfig Error"),
 | 
						|
      tr("Could not open Rivendell database."));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  filename=
 | 
						|
    QFileDialog::getOpenFileName(this,"RDDbConfig - "+
 | 
						|
				 tr("Choose the MySQL Backup File to Restore"),
 | 
						|
				 RDHomeDir(),
 | 
						|
				 "MySQL files (*.sql);;All files (*.*)");
 | 
						|
 | 
						|
  if(!filename.isEmpty()) {
 | 
						|
    if (QMessageBox::question(this,tr("Restore Entire Database"),tr("Are you sure you want to restore your entire Rivendell database?"),(QMessageBox::No|QMessageBox::Yes)) != QMessageBox::Yes) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    db->clearDatabase(rd_config->mysqlDbname());
 | 
						|
 | 
						|
    QProcess restoreProcess(this);
 | 
						|
    QStringList args;
 | 
						|
    args << QString::asprintf("--user=%s",rd_config->mysqlUsername().toUtf8().constData())
 | 
						|
	 << QString::asprintf("--password=%s",rd_config->mysqlPassword().toUtf8().constData())
 | 
						|
	 << QString::asprintf("--host=%s",rd_config->mysqlHostname().toUtf8().constData())
 | 
						|
      << rd_config->mysqlDbname();
 | 
						|
    restoreProcess.setStandardInputFile(filename);
 | 
						|
    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 | 
						|
    stopDaemons();
 | 
						|
    restoreProcess.start("mysql", args);
 | 
						|
    restoreProcess.waitForFinished(-1);
 | 
						|
    QApplication::restoreOverrideCursor();
 | 
						|
    if (restoreProcess.exitCode()) {
 | 
						|
      QMessageBox::critical(this,tr("RDDbConfig Error"),
 | 
						|
      QString(restoreProcess.readAllStandardError()));
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      QMessageBox::information(this,"Database Restored Successfully",
 | 
						|
        QString::asprintf("Restored %s database from %s",
 | 
						|
			  rd_config->mysqlDbname().toUtf8().constData(),
 | 
						|
			  filename.toUtf8().constData()));
 | 
						|
      RDApplication::syslog(rd_config,LOG_INFO,"restored %s database from %s",
 | 
						|
			    rd_config->mysqlDbname().toUtf8().constData(),
 | 
						|
			    filename.toUtf8().constData());
 | 
						|
    }
 | 
						|
    emit updateLabels();
 | 
						|
    startDaemons();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void MainWidget::resizeEvent(QResizeEvent *e)
 | 
						|
{
 | 
						|
  db_create_button->
 | 
						|
    setGeometry(size().width()/2-80,110,160,50);
 | 
						|
  db_backup_button->
 | 
						|
    setGeometry(size().width()/2-80,165,160,50);
 | 
						|
  db_restore_button->
 | 
						|
    setGeometry(size().width()/2-80,220,160,50);
 | 
						|
  db_close_button->
 | 
						|
    setGeometry(size().width()/2-80,275,160,50);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int MainWidget::statusDaemons(QString service)
 | 
						|
{
 | 
						|
  QProcess statusProcess(this);
 | 
						|
  QStringList args;
 | 
						|
  args << "status" << service;
 | 
						|
  statusProcess.start("systemctl", args);
 | 
						|
  statusProcess.waitForFinished();
 | 
						|
  return statusProcess.exitCode();
 | 
						|
}
 | 
						|
 | 
						|
void MainWidget::stopDaemons()
 | 
						|
{
 | 
						|
  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 | 
						|
  if(!statusDaemons("rivendell")) {
 | 
						|
    QProcess stopProcess(this);
 | 
						|
    QStringList args;
 | 
						|
    args << "stop" << "rivendell";
 | 
						|
    stopProcess.start("systemctl", args);
 | 
						|
    stopProcess.waitForFinished();
 | 
						|
    if (!stopProcess.exitCode()) {
 | 
						|
      db_daemon_start_needed=true;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  QApplication::restoreOverrideCursor();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void MainWidget::startDaemons()
 | 
						|
{
 | 
						|
  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 | 
						|
  if(statusDaemons("rivendell")) {
 | 
						|
    QProcess startProcess(this);
 | 
						|
    QStringList args;
 | 
						|
    args << "start" << "rivendell";
 | 
						|
    startProcess.start("systemctl", args);
 | 
						|
    startProcess.waitForFinished();
 | 
						|
  }
 | 
						|
  QApplication::restoreOverrideCursor();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int main(int argc,char *argv[])
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Start GUI
 | 
						|
  //
 | 
						|
  RDConfig *config=new RDConfig();
 | 
						|
  config->load();
 | 
						|
  QApplication a(argc,argv);
 | 
						|
  new MainWidget(config);
 | 
						|
  return a.exec();
 | 
						|
}
 |