From 63cf33574cab5ed709d12ecf9c0eac7dbe9340d3 Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Sun, 7 Oct 2018 09:28:10 -0700 Subject: [PATCH 1/9] Initial Commit --- configure.ac | 1 + utils/rddbconfig/Makefile.am | 49 ++++ utils/rddbconfig/createdb.cpp | 116 ++++++++ utils/rddbconfig/createdb.h | 47 ++++ utils/rddbconfig/db.cpp | 78 ++++++ utils/rddbconfig/db.h | 43 +++ utils/rddbconfig/mysql_login.cpp | 174 ++++++++++++ utils/rddbconfig/mysql_login.h | 58 ++++ utils/rddbconfig/opendb.cpp | 436 +++++++++++++++++++++++++++++++ utils/rddbconfig/opendb.h | 33 +++ utils/rddbconfig/rddbconfig.cpp | 380 +++++++++++++++++++++++++++ utils/rddbconfig/rddbconfig.h | 79 ++++++ 12 files changed, 1494 insertions(+) create mode 100644 utils/rddbconfig/Makefile.am create mode 100644 utils/rddbconfig/createdb.cpp create mode 100644 utils/rddbconfig/createdb.h create mode 100644 utils/rddbconfig/db.cpp create mode 100644 utils/rddbconfig/db.h create mode 100644 utils/rddbconfig/mysql_login.cpp create mode 100644 utils/rddbconfig/mysql_login.h create mode 100644 utils/rddbconfig/opendb.cpp create mode 100644 utils/rddbconfig/opendb.h create mode 100644 utils/rddbconfig/rddbconfig.cpp create mode 100644 utils/rddbconfig/rddbconfig.h diff --git a/configure.ac b/configure.ac index fc660fde..77838ec6 100644 --- a/configure.ac +++ b/configure.ac @@ -494,6 +494,7 @@ AC_CONFIG_FILES([rivendell.spec \ utils/rdclilogedit/Makefile \ utils/rdcollect/Makefile \ utils/rdconvert/Makefile \ + utils/rddbconfig/Makefile \ utils/rddbmgr/Makefile \ utils/rddelete/Makefile \ utils/rddgimport/Makefile \ diff --git a/utils/rddbconfig/Makefile.am b/utils/rddbconfig/Makefile.am new file mode 100644 index 00000000..3b69e250 --- /dev/null +++ b/utils/rddbconfig/Makefile.am @@ -0,0 +1,49 @@ +## Makefile.am +## +## (C) Copyright 2009,2016-2018 Fred Gleason +## +## 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. +## +## Use automake to process this into a Makefile.in +## + +AM_CPPFLAGS = -Wall -DPREFIX=\"$(prefix)\" -I$(top_srcdir)/lib -I$(top_srcdir)/rdhpi @QT4_CFLAGS@ -DQT3_SUPPORT -I/usr/include/Qt3Support +LIBS = -L$(top_srcdir)/lib -L$(top_srcdir)/rdhpi +MOC = @QT_MOC@ + +# The dependency for qt's Meta Object Compiler (moc) +moc_%.cpp: %.h + $(MOC) $< -o $@ + +bin_PROGRAMS = rddbconfig + +dist_rddbconfig_SOURCES = rddbconfig.cpp rddbconfig.h mysql_login.cpp mysql_login.h \ + db.cpp db.h createdb.cpp createdb.h + +nodist_rddbconfig_SOURCES = moc_rddbconfig.cpp moc_mysql_login.cpp + +rddbconfig_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @LIBALSA@ @QT4_LIBS@ -lQt3Support + +EXTRA_DIST = rddbconfig.pro + +CLEANFILES = *~\ + *.qm\ + moc_* + +MAINTAINERCLEANFILES = *~\ + *.tar.gz\ + aclocal.m4\ + configure\ + Makefile.in\ + moc_* diff --git a/utils/rddbconfig/createdb.cpp b/utils/rddbconfig/createdb.cpp new file mode 100644 index 00000000..0c03ec51 --- /dev/null +++ b/utils/rddbconfig/createdb.cpp @@ -0,0 +1,116 @@ +// createdb.cpp +// +// Create Rivendell MySQL database RDDbConfig +// +// (C) Copyright 2002-2018 Fred Gleason +// +// 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 +#include + +#include +#include + +#include "createdb.h" + +CreateDb::CreateDb(QString host,QString database,QString username,QString password) +{ + db_host=host; + db_name=database; + db_user=username; + db_pass=password; +} + +bool CreateDb::create(QObject *parent,QString *err_str,RDConfig *config) +{ + QString sql; + + // + // Open Database + // + if (!db.isOpen()){ + db=QSqlDatabase::addDatabase(config->mysqlDriver(),"createDb"); + if(!db.isValid()) { + *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!")); + return true; + } + db.setHostName(db_host); + db.setDatabaseName("mysql"); + db.setUserName(db_user); + db.setPassword(db_pass); + if(!db.open()) { + *err_str+=QString(QObject::tr("Couldn't open MySQL connection on"))+ + " \""+db_host+"\"."; + db.removeDatabase(db.connectionName()); + db.close(); + return true; + } + + QSqlQuery *q; + + sql=QString().sprintf("drop database if exists `%s`",(const char *)db_name); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString(QObject::tr("Could not remove database")); + return true; + } + delete q; + + sql=QString().sprintf("create database if not exists `%s`",(const char *)db_name); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString(QObject::tr("Could not create database")); + return true; + } + delete q; + + sql=QString().sprintf("grant all on * to %s identified by \"%s\"",(const char *)db_user,(const char *)db_pass); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString().sprintf("Could not set permissions: %s",(const char *)sql); + return true; + } + delete q; + + QProcess rddbmgrProcess(parent); + QStringList args; + args << QString("--create"); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + rddbmgrProcess.start(QString(RD_PREFIX)+"/sbin/rddbmgr",args); + rddbmgrProcess.waitForFinished(); + QApplication::restoreOverrideCursor(); + if (rddbmgrProcess.exitCode()) { + fprintf(stderr,"Exit Code=%d\n",rddbmgrProcess.exitCode()); + return true; + } + } + + return false; +} + +CreateDb::~CreateDb() +{ + if(db.isOpen()) { + db.removeDatabase(db_name); + db.close(); + } +} + +bool CreateDb::isOpen() +{ + return db.isOpen(); +} + diff --git a/utils/rddbconfig/createdb.h b/utils/rddbconfig/createdb.h new file mode 100644 index 00000000..7cbddfcf --- /dev/null +++ b/utils/rddbconfig/createdb.h @@ -0,0 +1,47 @@ +// createdb.h +// +// Create a Rivendell Database +// +// (C) Copyright 2002-2018 Fred Gleason +// +// 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. +// + +#ifndef CREATEDB_H +#define CREATEDB_H + +#include +#include + +#include + +class CreateDb +{ + public: + CreateDb(QString host,QString database,QString username,QString password); + ~CreateDb(); + bool create(QObject *parent,QString *err_str, RDConfig *config); + bool isOpen(); + + private: + QString db_host; + QString db_name; + QString db_user; + QString db_pass; + QSqlDatabase db; +}; + +#endif // CREATEDB_H + + diff --git a/utils/rddbconfig/db.cpp b/utils/rddbconfig/db.cpp new file mode 100644 index 00000000..d712b366 --- /dev/null +++ b/utils/rddbconfig/db.cpp @@ -0,0 +1,78 @@ +// db.cpp +// +// Create Rivendell MySQL database RDDbConfig +// +// (C) Copyright 2002-2018 Fred Gleason +// +// 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 +#include + +#include "db.h" + +Db::Db(QString *err_str,RDConfig *config) +{ + QSqlQuery *q; + db_schema=0; + + // + // Open Database + // + if (!db.isOpen()){ + db=QSqlDatabase::addDatabase(config->mysqlDriver()); + if(!db.isValid()) { + *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!")); + return; + } + db.setHostName(config->mysqlHostname()); + db.setDatabaseName(config->mysqlDbname()); + db.setUserName(config->mysqlUsername()); + db.setPassword(config->mysqlPassword()); + if(!db.open()) { + *err_str+=QString(QObject::tr("Couldn't open MySQL connection on"))+ + " \""+config->mysqlHostname()+"\"."; + db.removeDatabase(config->mysqlDbname()); + db.close(); + return; + } + + q=new QSqlQuery("select DB from VERSION"); + if(q->first()) { + db_schema=q->value(0).toUInt(); + } + delete q; + } +} + + +Db::~Db() +{ + if(db.isOpen()) { +// db.removeDatabase(config->mysqlDbname()); + db.close(); + } +} + +bool Db::isOpen() +{ + return db.isOpen(); +} + +unsigned Db::schema() +{ + return db_schema; +} + diff --git a/utils/rddbconfig/db.h b/utils/rddbconfig/db.h new file mode 100644 index 00000000..dfc086e2 --- /dev/null +++ b/utils/rddbconfig/db.h @@ -0,0 +1,43 @@ +// db.h +// +// Create a Rivendell Database +// +// (C) Copyright 2002-2018 Fred Gleason +// +// 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. +// + +#ifndef DB_H +#define DB_H + +#include + +#include + +class Db +{ + public: + Db(QString *err_str,RDConfig *config); + ~Db(); + bool isOpen(); + unsigned schema(); + + private: + QSqlDatabase db; + unsigned db_schema; +}; + +#endif // DB_H + + diff --git a/utils/rddbconfig/mysql_login.cpp b/utils/rddbconfig/mysql_login.cpp new file mode 100644 index 00000000..1b1adc9f --- /dev/null +++ b/utils/rddbconfig/mysql_login.cpp @@ -0,0 +1,174 @@ +// mysql_login.cpp +// +// mySQL Administrative Login widget for RDDbConfig +// +// (C) Copyright 2002-2018 Fred Gleason +// +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mysql_login.h" + +MySqlLogin::MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *username,QString *password, + QWidget *parent) + : QDialog(parent,"",true) +{ + setCaption(tr("mySQL Admin")); + login_host=hostname; + login_dbname=dbname; + login_name=username; + login_password=password; + + // + // Create Fonts + // + QFont font=QFont("Helvetica",12,QFont::Normal); + font.setPixelSize(12); + + // + // Message Label + // + RDLabel *label=new RDLabel(msg,this); + label->setFont(font); + label->setGeometry(10,10,sizeHint().width()-20,sizeHint().height()-130); + label->setAlignment(Qt::AlignCenter); + + + // + // MySql Host Name + // + login_host_edit=new QLineEdit(this); + login_host_edit->setFont(font); + login_host_edit->setGeometry(100,sizeHint().height()-150,200,19); + login_host_edit->setMaxLength(64); + login_host_edit->setText(*login_host); + login_host_edit->setFocus(); + QLabel *login_host_label=new QLabel(login_host_edit,tr("&Hostname:"),this); + login_host_label->setFont(font); + login_host_label->setGeometry(10,sizeHint().height()-150,85,19); + login_host_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); + + // + // MySql Database Name + // + login_dbname_edit=new QLineEdit(this); + login_dbname_edit->setFont(font); + login_dbname_edit->setGeometry(100,sizeHint().height()-130,200,19); + login_dbname_edit->setMaxLength(64); + login_dbname_edit->setText(*login_dbname); + login_dbname_edit->setFocus(); + QLabel *login_dbname_label=new QLabel(login_dbname_edit,tr("&Database:"),this); + login_dbname_label->setFont(font); + login_dbname_label->setGeometry(10,sizeHint().height()-130,85,19); + login_dbname_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); + + // + // MySql Login Name + // + login_name_edit=new QLineEdit(this); + login_name_edit->setFont(font); + login_name_edit->setGeometry(100,sizeHint().height()-110,100,19); + login_name_edit->setMaxLength(16); + login_name_edit->setFocus(); + QLabel *login_name_label=new QLabel(login_name_edit,tr("User&name:"),this); + login_name_label->setFont(font); + login_name_label->setGeometry(10,sizeHint().height()-109,85,19); + login_name_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); + + // + // MySql Login Password + // + login_password_edit=new QLineEdit(this); + login_password_edit->setFont(font); + login_password_edit->setGeometry(100,sizeHint().height()-90,100,19); + login_password_edit->setMaxLength(16); + login_password_edit->setEchoMode(QLineEdit::Password); + QLabel *login_password_label=new QLabel(login_password_edit,tr("&Password:"),this); + login_password_label->setFont(font); + login_password_label->setGeometry(10,sizeHint().height()-88,85,19); + login_password_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); + + // + // OK Button + // + QPushButton *ok_button=new QPushButton(this); + ok_button->setGeometry(sizeHint().width()-180,sizeHint().height()-60,80,50); + ok_button->setFont(font); + ok_button->setText(tr("&OK")); + ok_button->setDefault(true); + connect(ok_button,SIGNAL(clicked()),this,SLOT(okData())); + + // + // Cancel Button + // + QPushButton *cancel_button=new QPushButton(this); + cancel_button->setGeometry(sizeHint().width()-90,sizeHint().height()-60, + 80,50); + cancel_button->setFont(font); + cancel_button->setText(tr("&Cancel")); + connect(cancel_button,SIGNAL(clicked()),this,SLOT(cancelData())); +} + + +MySqlLogin::~MySqlLogin() +{ + delete login_name_edit; + delete login_password_edit; +} + + +QSize MySqlLogin::sizeHint() const +{ + return QSize(360,210); +} + + +QSizePolicy MySqlLogin::sizePolicy() const +{ + return QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); +} + + +void MySqlLogin::okData() +{ + *login_host=login_host_edit->text(); + *login_dbname=login_dbname_edit->text(); + *login_name=login_name_edit->text(); + *login_password=login_password_edit->text(); + + done(0); +} + + +void MySqlLogin::cancelData() +{ + done(1); +} + diff --git a/utils/rddbconfig/mysql_login.h b/utils/rddbconfig/mysql_login.h new file mode 100644 index 00000000..e36ad663 --- /dev/null +++ b/utils/rddbconfig/mysql_login.h @@ -0,0 +1,58 @@ +// mysql_login.h +// +// mySQL Administrative Login Widget for RDAdmin. +// +// (C) Copyright 2002-2003,2016 Fred Gleason +// +// 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. +// + +#ifndef MYSQL_LOGIN_H +#define MYSQL_LOGIN_H + +#include +#include +#include +#include +#include + +class MySqlLogin : public QDialog +{ + Q_OBJECT + public: + MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *username,QString *password, + QWidget *parent=0); + ~MySqlLogin(); + QSize sizeHint() const; + QSizePolicy sizePolicy() const; + + private slots: + void okData(); + void cancelData(); + + private: + QString *login_host; + QLineEdit *login_host_edit; + QString *login_dbname; + QLineEdit *login_dbname_edit; + QString *login_name; + QLineEdit *login_name_edit; + QString *login_password; + QLineEdit *login_password_edit; +}; + + +#endif + + diff --git a/utils/rddbconfig/opendb.cpp b/utils/rddbconfig/opendb.cpp new file mode 100644 index 00000000..ecbcacbe --- /dev/null +++ b/utils/rddbconfig/opendb.cpp @@ -0,0 +1,436 @@ +// opendb.cpp +// +// Open a Rivendell Database +// +// (C) Copyright 2002-2004,2016 Fred Gleason +// +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Includes used for netmask and remote server detection. +#include +#include +#include +#include + +#include + +/** + * Get the netmask of an interface and return it via an in_addr struct pointer. + * + * Note: uses linux IOCTL call SIOCGIFNETMASK to retrieve the netmask from a + * temporary socket. + * + * @param interface String with the interface to query. + * @param netmask Pointer to struct in_addr that will be populated with the netmask. + * @return true on success + **/ +bool get_netmask(const char * interface, struct in_addr * netmask) +{ + int fd; + struct ifreq ifr; + struct sockaddr_in *nmask; + + fd=socket(AF_INET, SOCK_DGRAM, 0); + ifr.ifr_addr.sa_family=AF_INET; + strncpy(ifr.ifr_name, interface, IFNAMSIZ-1); + ioctl(fd, SIOCGIFNETMASK, &ifr); + close(fd); + nmask=(struct sockaddr_in *)&ifr.ifr_netmask; + netmask->s_addr=nmask->sin_addr.s_addr; + return true; +} + + +/** + * Check if creating the database on the local machine or on a remote server in + * the same subnet. + * + * @param host QString with the hostname of machine to create the database. + * @return true if database is to be created on a remote server. + **/ +bool check_remote_server(QString host) { + char local_hostname[256]; + int rc; + struct hostent *temp_hostent; + struct hostent local_hostent; + struct hostent host_hostent; + struct in_addr local_ip; + struct in_addr host_ip; + struct in_addr local_netmask; + + // check if host is 'localhost' + if (0==strncasecmp("localhost", (const char *)host, 255)) + return false; + + rc=gethostname(local_hostname, 255); + // compare hostnames + if ((0==rc) && (0!=strncasecmp(local_hostname, (const char *)host, 255))) { + if ((temp_hostent=gethostbyname(local_hostname))) + local_hostent=*temp_hostent; + else + return false; + local_ip=*(struct in_addr *)temp_hostent->h_addr; + + if ((temp_hostent=gethostbyname((const char *)host))) + host_hostent=*temp_hostent; + else + return false; + host_ip=*(struct in_addr *)temp_hostent->h_addr; + + // compare IPs + if ((local_hostent.h_addrtype == AF_INET) && + (host_hostent.h_addrtype == AF_INET) && + (local_ip.s_addr != host_ip.s_addr)) { + // FIXME: ideally do something smarter than just testing eth0 (note use + // below in format_remote_host() also) + // get list of interfaces if_nameindex() + // loop through list of interfaces, get IP, see if it matches local IP + // once have good interface, get netmask + rc=get_netmask("eth0", &local_netmask); + + // compare if IPs are on same subnet. note: use of bitwise sum + if ( (local_ip.s_addr & local_netmask.s_addr) == + (host_ip.s_addr & local_netmask.s_addr) ) + return true; + } // endif compare IPs + } // endif compare hostnames + return false; +} + + +/** + * Format a QString with the MySQL host portion for a remote host. The + * resulting string will use the local subnet and mask to generate something + * like "192.168.1.0/255.255.255.0" . + * + * @param host string with the hostname to use for the subnet and mask. + * @return QString with formated result. + **/ +QString format_remote_host(const char *hostname) { + struct in_addr local_netmask; + struct hostent *temp_hostent; + struct in_addr local_ip; + struct in_addr local_subnet; + + temp_hostent=gethostbyname(hostname); + local_ip=*(struct in_addr *)temp_hostent->h_addr; + // FIXME: ideally do something smarter than just testing eth0 (see above in check_remote_server() also) + get_netmask("eth0", &local_netmask); + local_subnet.s_addr=(local_ip.s_addr & local_netmask.s_addr); + return QString().sprintf("%s/%s", strdupa(inet_ntoa(local_subnet)), strdupa(inet_ntoa(local_netmask)) ); +} + + +bool OpenDb(QString dbname,QString login,QString pwd, + QString host,QString stationname,bool interactive,RDConfig *config) +{ + // + // Yeesh, this whole method really needs a rewrite! + // They shoot horses, don't they?? + // + + int db_ver; + QString admin_name; + QString admin_pwd; + QString sql; + QSqlQuery *q; + QString msg; + MySqlLogin *mysql_login; + QString str; + int err=0; + QString err_str=""; + + // + // Open Database + // + QSqlDatabase *db=QSqlDatabase::addDatabase(admin_config->mysqlDriver()); + if(!db) { + return false; + } + db->setDatabaseName(dbname); + db->setUserName(login); + db->setPassword(pwd); + db->setHostName(host); + if(!db->open()) { + /* + if(!interactive) { + return false; + } + */ + RDKillDaemons(); + if(interactive) { + msg=QObject::tr("Unable to access the Rivendell Database!\n\ +Please enter a login for an account with\n\ +administrative rights on the mySQL server,\n\ +and we will try to get this straightened out."); + mysql_login=new MySqlLogin(msg,&admin_name,&admin_pwd); + if(mysql_login->exec()!=0) { + delete mysql_login; + db->removeDatabase(dbname); + return false; + } + delete mysql_login; + } + else { + admin_name=admin_admin_username; + admin_pwd=admin_admin_password; + if(!admin_admin_hostname.isEmpty()) { + db->setHostName(admin_admin_hostname); + } + } + db->setUserName(admin_name); + db->setPassword(admin_pwd); + if(db->open()) { // Fixup DB Access Permsissions + PrintError(QObject::tr("Wrong access permissions for accessing mySQL!"), + interactive); + db->removeDatabase("mysql"); + return false; + } + else { + db->setDatabaseName("mysql"); + if(!db->open()) { // mySQL is hosed -- scream and die. + PrintError(QObject::tr("Unable to connect to mySQL!"),interactive); + db->removeDatabase("mysql"); + return false; + } + else { // Create a new Rivendell Database + sql=QString().sprintf("create database %s",(const char *)dbname); + q=new QSqlQuery(sql); + if(!q->isActive()) { // Can't create DB. + delete q; + PrintError(QObject::tr("Unable to create a Rivendell Database!"), + interactive); + db->removeDatabase("mysql"); + return false; + } + delete q; + + // Check if creating the database on the local machine or on a remote + // server in the same subnet. If creating on a remote server, set the + // host portion of the MySQL user to the subnet that is common between + // the local workstation and the server. + if (check_remote_server(host)) { + host=format_remote_host(host); + } + sql=QString().sprintf("create user %s@'%s' identified by '%s'", + (const char *)login, (const char *)host, (const char *)pwd); + q=new QSqlQuery(sql); + delete q; + sql=QString().sprintf("grant SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,\ + INDEX, ALTER, LOCK TABLES on %s.* to %s@'%s'", + (const char *)dbname, (const char *)login, (const char *)host); + q=new QSqlQuery(sql); + delete q; + q=new QSqlQuery("flush privileges"); + delete q; + db->close(); // Relinquish admin perms + if(!admin_admin_dbname.isEmpty()) { + dbname=admin_admin_dbname; + } + db->setDatabaseName(dbname); + db->setUserName(login); + db->setPassword(pwd); + db->setHostName(host); + if(!db->open()) { // Can't open new database + PrintError(QObject::tr("Unable to connect to new Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + if(!CreateDb(login,pwd,config)) { // Can't create tables. + PrintError(QObject::tr("Unable to create Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + db->close(); + db->setDatabaseName(dbname); + db->setUserName(login); + db->setPassword(pwd); + if(!db->open()) { + PrintError(QObject::tr("Unable to connect to Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + if(!InitDb(login,pwd,stationname,config)) { // Can't initialize tables. + PrintError(QObject::tr("Unable to initialize Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + if(interactive) { + QMessageBox::information(NULL,QObject::tr("RDAdmin"), + QObject::tr("New Rivendell Database Created!")); + } + return true; + } + } + return false; + } + if((db_ver=RDCheckVersion())exec()!=0) { + delete mysql_login; + db->removeDatabase(dbname); + return false; + } + delete mysql_login; + } + else { + admin_name=admin_admin_username; + admin_pwd=admin_admin_password; + } + RDKillDaemons(); + db->close(); + db->setDatabaseName("mysql"); + db->setUserName(admin_name); + db->setPassword(admin_pwd); + if(!db->open()) { + PrintError(QObject::tr("Unable to log into Administrator account!"), + interactive); + db->removeDatabase(dbname); + return false; + } + q=new QSqlQuery(QString().sprintf ("drop database %s",(const char *)dbname)); + delete q; + q=new QSqlQuery(QString().sprintf("create database %s",(const char *)dbname)); + if(!q->isActive()) { // Can't create DB. + delete q; + PrintError(QObject::tr("Unable to create a Rivendell Database!"), + interactive); + db->removeDatabase("mysql"); + return false; + } + delete q; + sql=QString(). + sprintf("grant all on %s to %s identified by \"%s\"", + (const char *)dbname,(const char *)login,(const char *)pwd); + q=new QSqlQuery(sql); + if(!q->isActive()) { // Can't authorize DB. + PrintError(QObject::tr("Unable to authorize a Rivendell Database!"), + interactive); + db->removeDatabase("mysql"); + return false; + } + db->close(); // Relinquish admin perms + db->setDatabaseName(dbname); + db->setUserName(login); + db->setPassword(pwd); + if(!db->open()) { // Can't open new database + PrintError(QObject::tr("Unable to connect to new Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + if(!CreateDb(login,pwd,config)) { // Can't create tables. + PrintError(QObject::tr("Unable to create Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + db->close(); + db->setDatabaseName(dbname); + db->setUserName(login); + db->setPassword(pwd); + if(!db->open()) { + PrintError(QObject::tr("Unable to connect to Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + if(!InitDb(login,pwd,stationname,config)) { // Can't initialize tables. + PrintError(QObject::tr("Unable to initialize Rivendell Database!"), + interactive); + db->removeDatabase(dbname); + return false; + } + } + else { // Out-of-date version + if(interactive) { + if(QMessageBox::warning(NULL,QObject::tr("Update Needed"), + QObject::tr("The Rivendell Database needs to be updated.\n\ +All audio and settings will be preserved, but\n\ +this will STOP any audio playout or recording\n\ +on this machine for a few seconds. Continue?"), + QMessageBox::Yes,QMessageBox::No)!= + QMessageBox::Yes) { + db->removeDatabase(dbname); + return false; + } + } + RDKillDaemons(); + if((err=UpdateDb(db_ver,config))!=UPDATEDB_SUCCESS) { + err_str=QObject::tr("Unable to update Rivendell Database:"); + switch(err) { + case UPDATEDB_BACKUP_FAILED: + err_str+=QObject::tr("\nDatabase backup failed!"); + break; + + case UPDATEDB_QUERY_FAILED: + err_str+=QObject::tr("\nSchema modification failed!"); + break; + + default: + err_str+=QObject::tr("\nUnknown/unspecified error!"); + break; + } + PrintError(err_str,interactive); + db->removeDatabase(dbname); + return false; + } + str=QString( + QObject::tr("The Rivendell Database has been updated to version")); + msg=QString(). + sprintf("%s %d",(const char *)str,RD_VERSION_DATABASE); + if(!admin_skip_backup) { + msg+=QObject::tr("\nand a backup of the original database saved in "); + msg+=admin_backup_filename; + } + msg+="."; + if(interactive) { + QMessageBox::information(NULL,QObject::tr("Database Updated"),msg); + } + } + } + + return true; +} + diff --git a/utils/rddbconfig/opendb.h b/utils/rddbconfig/opendb.h new file mode 100644 index 00000000..133a7b65 --- /dev/null +++ b/utils/rddbconfig/opendb.h @@ -0,0 +1,33 @@ +// opendb.h +// +// Open a Rivendell Database +// +// (C) Copyright 2002-2003,2016 Fred Gleason +// +// 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. +// + +#ifndef OPENDB_H +#define OPENDB_H + +#include + +#include + +bool OpenDb(QString dbname,QString username,QString password,QString hostname, + QString stationname,bool interactive,RDConfig *config); + + +#endif // OPENDB_H + diff --git a/utils/rddbconfig/rddbconfig.cpp b/utils/rddbconfig/rddbconfig.cpp new file mode 100644 index 00000000..d7ef1716 --- /dev/null +++ b/utils/rddbconfig/rddbconfig.cpp @@ -0,0 +1,380 @@ +// rddbconfig.cpp +// +// A Qt-based application to configure, backup, and restore +// the Rivendell database. +// +// (C) Copyright 2009-2018 Fred Gleason +// +// 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. +// + +#define LINE fprintf(stderr,"%s:%d\n",__FILE__,__LINE__); + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../../icons/rivendell-22x22.xpm" + +#include + +#include "db.h" +#include "createdb.h" +#include "mysql_login.h" + +// +// Globals +// +MainWidget::MainWidget(QWidget *parent) + : QWidget(parent) +{ + QString err_msg; + + db_daemon_start_needed=false; + db=NULL; + + // + // Open rd.conf(5) + // + rd_config=new RDConfig(); + rd_config->load(); + rd_config->setModuleName("rddbconfig"); + + setWindowTitle(tr("RDDbConfig")+" v"+VERSION); + + // + // Create And Set Icon + // + setWindowIcon(QPixmap(rivendell_22x22_xpm)); + + // + // Fix the Window Size + // + setMinimumWidth(sizeHint().width()); + setMinimumHeight(sizeHint().height()); + + // + // Generate Fonts + // + QFont font("Helvetica",12,QFont::Normal); + font.setPixelSize(12); + QFont label_font("Helvetica",12,QFont::Bold); + label_font.setPixelSize(12); + QFont day_font=QFont("Helvetica",12,QFont::Normal); + day_font.setPixelSize(12); + + // + // Labels + // + QLabel *label=new QLabel(tr("Select an operation:"),this); + label->setGeometry(0,90,sizeHint().width(),16); + label->setFont(label_font); + label->setAlignment(Qt::AlignCenter); + + label_hostname=new QLabel(QString().sprintf("SQL Server: %s", + (const char *)rd_config->mysqlHostname()),this); + label_hostname->setGeometry(0,5,sizeHint().width(),16); + label_hostname->setFont(day_font); + label_hostname->setAlignment(Qt::AlignCenter); + + label_username=new QLabel(QString().sprintf("SQL Usename: %s", + (const char *)rd_config->mysqlUsername()),this); + label_username->setGeometry(0,20,sizeHint().width(),16); + label_username->setFont(day_font); + label_username->setAlignment(Qt::AlignCenter); + + label_dbname=new QLabel(QString().sprintf("SQL Database: %s", + (const char *)rd_config->mysqlDbname()),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(label_font); + connect(db_create_button,SIGNAL(clicked()),this,SLOT(createData())); + + // + // Backup Button + // + db_backup_button=new QPushButton(tr("Backup"),this); + db_backup_button->setFont(label_font); + connect(db_backup_button,SIGNAL(clicked()),this,SLOT(backupData())); + + // + // Restore Button + // + db_restore_button=new QPushButton(tr("Restore"),this); + db_restore_button->setFont(label_font); + connect(db_restore_button,SIGNAL(clicked()),this,SLOT(restoreData())); + + // + // Close Button + // + db_close_button=new QPushButton(tr("Close"),this); + db_close_button->setFont(label_font); + connect(db_close_button,SIGNAL(clicked()),this,SLOT(closeData())); + + updateLabels(); +} + + +MainWidget::~MainWidget() +{ +} + + +QSize MainWidget::sizeHint() const +{ + return QSize(280,330); +} + + +QSizePolicy MainWidget::sizePolicy() const +{ + return QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); +} + +void MainWidget::updateLabels() +{ + QString err_msg=""; + + if(db!=NULL) { + delete db; + } + db = new Db(&err_msg,rd_config); + + if (!db->isOpen()) { + QMessageBox::critical(this,tr("Cannot Open Database"),tr("Unable to open database. The connection parameters of the [Mysql] section of rd.conf may be incorrect or you may need to create a new database.")); + label_schema->setVisible(false); + db_backup_button->setEnabled(false); + db_restore_button->setEnabled(false); + } + else { + label_schema->setText(QString().sprintf("DB Version: %d",db->schema())); + label_schema->setVisible(true); + db_backup_button->setEnabled(true); + db_restore_button->setEnabled(true); + } +} + +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 msg="Message"; + QString err_str; + + if(geteuid()!=0) { + QMessageBox::warning(this,tr("RDDbConfig error"), + tr("Create requires root permissions.")); + return; + } + + 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(msg,&hostname,&dbname,&admin_name,&admin_pwd); + + mysql_login->exec(); + + delete mysql_login; + + if(admin_name.isEmpty()||admin_pwd.isEmpty()||hostname.isEmpty()||dbname.isEmpty()) { + return; + } + + stopDaemons(); + + CreateDb *db_create=new CreateDb(hostname,dbname,admin_name,admin_pwd); + + if(db_create->create(this,&err_str,rd_config)) { + fprintf(stderr,"err_str: %s\n",(const char *)err_str); + } + + delete db_create; + + startDaemons(); +} + + +void MainWidget::backupData() +{ + QString filename; + + if (!db->isOpen()) { + QMessageBox::critical(this,tr("RDDbConfig Error"), + QString().sprintf("Could not open %s database.", + (const char *)rd_config->mysqlDbname())); + return; + } + + filename=Q3FileDialog::getSaveFileName("rivendell.sql", + "MySQL (*.sql)",this,"open file dialog","Enter the MySQL Backup Filename"); + + if (!filename.isEmpty()) { + QProcess backupProcess(this); + QStringList args; + args << QString().sprintf("--user=%s",(const char *)rd_config->mysqlUsername()) + << QString().sprintf("--password=%s",(const char *)rd_config->mysqlPassword()) + << QString().sprintf("--host=%s",(const char *)rd_config->mysqlHostname()) + << rd_config->mysqlDbname(); + backupProcess.setStandardOutputFile(filename); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + backupProcess.start("mysqldump", args); + backupProcess.waitForFinished(); + QApplication::restoreOverrideCursor(); + if (backupProcess.exitCode()) { + fprintf(stderr,"Exit Code=%d\n",backupProcess.exitCode()); + QMessageBox::critical(this,tr("RDDbConfig error"), + QString(backupProcess.readAllStandardError())); + } + else { + QMessageBox::information(this,"Database Backed Up Successfully", + QString().sprintf("Backed up %s database to %s", + (const char *)rd_config->mysqlDbname(), + (const char *)filename)); + rd_config->log("rddbconfig",RDConfig::LogInfo, + QString().sprintf("Backed up %s database to %s", + (const char *)rd_config->mysqlDbname(), + (const char *)filename)); + } + } +} + + +void MainWidget::restoreData() +{ + QString filename; + + if(geteuid()!=0) { + QMessageBox::warning(this,tr("RDDbConfig error"), + tr("Restore requires root permissions.")); + return; + } + + if (!db->isOpen()) { + QMessageBox::critical(this,tr("RDDbConfig error"), + tr("Could not open Rivendell database.")); + return; + } + + filename=Q3FileDialog::getOpenFileName("", + "MySQL (*.sql);;All Files(*)",this,"open file dialog", + "Choose the MySQL Backup File to Restore"); + + 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; + } + QProcess restoreProcess(this); + QStringList args; + args << QString().sprintf("--user=%s",(const char *)rd_config->mysqlUsername()) + << QString().sprintf("--password=%s",(const char *)rd_config->mysqlPassword()) + << QString().sprintf("--host=%s",(const char *)rd_config->mysqlHostname()) + << rd_config->mysqlDbname(); + restoreProcess.setStandardInputFile(filename); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + stopDaemons(); + restoreProcess.start("mysql", args); + restoreProcess.waitForFinished(); + QApplication::restoreOverrideCursor(); + if (restoreProcess.exitCode()) { + QMessageBox::critical(this,tr("RDDbConfig error"), + QString(restoreProcess.readAllStandardError())); + } + else { + QMessageBox::information(this,"Database Restored Successfully", + QString().sprintf("Restored %s database from %s", + (const char *)rd_config->mysqlDbname(), + (const char *)filename)); + rd_config->log("rddbconfig",RDConfig::LogInfo, + QString().sprintf("Restored %s database from %s", + (const char *)rd_config->mysqlDbname(), + (const char *)filename)); + } + 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); +} + + +void MainWidget::stopDaemons() +{ + if(system("/usr/bin/systemctl status rivendell")==0) { + system("/usr/bin/systemctl stop rivendell"); + db_daemon_start_needed=true; + } +} + + +void MainWidget::startDaemons() +{ + if(db_daemon_start_needed) { + system("/usr/bin/systemctl start rivendell"); + } +} + + +int main(int argc,char *argv[]) +{ + // + // Start GUI + // + QApplication::setStyle(RD_GUI_STYLE); + QApplication a(argc,argv); + MainWidget *w=new MainWidget(); + a.setMainWidget(w); + w->setGeometry(QRect(QPoint(0,0),w->sizeHint())); + w->move(250,250); + w->show(); + return a.exec(); +} diff --git a/utils/rddbconfig/rddbconfig.h b/utils/rddbconfig/rddbconfig.h new file mode 100644 index 00000000..74e05946 --- /dev/null +++ b/utils/rddbconfig/rddbconfig.h @@ -0,0 +1,79 @@ +// rddbconfig.h +// +// A Qt-based application to configure, backup, and restore +// the Rivendell database. +// +// (C) Copyright 2009-2018 Fred Gleason +// +// 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. +// + +#ifndef RDDBCONFIG_H +#define RDDBCONFIG_H + +#include +#include +#include +#include + +#include + +#include +#include + +#include "db.h" + +#define RDDBCONFIG_USAGE "\n\n"; + +class MainWidget : public QWidget +{ + Q_OBJECT + public: + MainWidget(QWidget *parent=0); + ~MainWidget(); + QSize sizeHint() const; + QSizePolicy sizePolicy() const; + + private slots: + void stopDaemons(); + void startDaemons(); + void createData(); + void backupData(); + void restoreData(); + void closeData(); + + protected: + void resizeEvent(QResizeEvent *e); + + private: + void updateLabels(); + RDConfig *rd_config; + bool db_manage_daemons; + bool db_daemon_start_needed; + QFont label_font; + QFont day_font; + QPushButton *db_create_button; + QPushButton *db_backup_button; + QPushButton *db_restore_button; + QPushButton *db_close_button; + QLabel *label_hostname; + QLabel *label_username; + QLabel *label_dbname; + QLabel *label_schema; + + Db *db; + bool db_open; +}; + +#endif // RDDBCONFIG_H From b89e38e52b4b2751a26ed121f3fe43e30f0e6442 Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Mon, 8 Oct 2018 15:11:20 -0700 Subject: [PATCH 2/9] Added rddbconfig to SUBDIRS --- utils/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/Makefile.am b/utils/Makefile.am index 13293606..4762b9ff 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -30,6 +30,7 @@ SUBDIRS = $(ALSACONFIG_RD_OPT)\ rdclilogedit\ rdcollect\ rdconvert\ + rddbconfig\ rddbmgr\ rddelete\ rddiscimport\ From a62d13b14b33b9dec7cb603695d5c2c22121dba2 Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Mon, 8 Oct 2018 16:40:05 -0700 Subject: [PATCH 3/9] Requires root privileges Improved error detection and reporting --- utils/rddbconfig/createdb.cpp | 13 ++++++++----- utils/rddbconfig/mysql_login.cpp | 4 ++-- utils/rddbconfig/rddbconfig.cpp | 32 +++++++++++++++----------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/utils/rddbconfig/createdb.cpp b/utils/rddbconfig/createdb.cpp index 0c03ec51..ab6cde05 100644 --- a/utils/rddbconfig/createdb.cpp +++ b/utils/rddbconfig/createdb.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -34,7 +35,7 @@ CreateDb::CreateDb(QString host,QString database,QString username,QString passwo db_pass=password; } -bool CreateDb::create(QObject *parent,QString *err_str,RDConfig *config) +bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *config) { QString sql; @@ -64,7 +65,7 @@ bool CreateDb::create(QObject *parent,QString *err_str,RDConfig *config) sql=QString().sprintf("drop database if exists `%s`",(const char *)db_name); q=new QSqlQuery(sql,db); if (!q->isActive()) { - *err_str+=QString(QObject::tr("Could not remove database")); + *err_str+=QString(QObject::tr("Could not remove old database")); return true; } delete q; @@ -72,12 +73,13 @@ bool CreateDb::create(QObject *parent,QString *err_str,RDConfig *config) sql=QString().sprintf("create database if not exists `%s`",(const char *)db_name); q=new QSqlQuery(sql,db); if (!q->isActive()) { - *err_str+=QString(QObject::tr("Could not create database")); + *err_str+=QString(QObject::tr("Could not create new database")); return true; } delete q; - sql=QString().sprintf("grant all on * to %s identified by \"%s\"",(const char *)db_user,(const char *)db_pass); + sql=QString().sprintf("grant all on * to %s identified by \"%s\"", + (const char *)db_user,(const char *)db_pass); q=new QSqlQuery(sql,db); if (!q->isActive()) { *err_str+=QString().sprintf("Could not set permissions: %s",(const char *)sql); @@ -93,7 +95,8 @@ bool CreateDb::create(QObject *parent,QString *err_str,RDConfig *config) rddbmgrProcess.waitForFinished(); QApplication::restoreOverrideCursor(); if (rddbmgrProcess.exitCode()) { - fprintf(stderr,"Exit Code=%d\n",rddbmgrProcess.exitCode()); + *err_str+=QString().sprintf("Failed to create %s database. Rddbmgr exit code=%d", + (const char *)db_name,rddbmgrProcess.exitCode()); return true; } } diff --git a/utils/rddbconfig/mysql_login.cpp b/utils/rddbconfig/mysql_login.cpp index 1b1adc9f..5caaced3 100644 --- a/utils/rddbconfig/mysql_login.cpp +++ b/utils/rddbconfig/mysql_login.cpp @@ -65,11 +65,11 @@ MySqlLogin::MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *us // MySql Host Name // login_host_edit=new QLineEdit(this); + login_host_edit->setReadOnly(true); login_host_edit->setFont(font); login_host_edit->setGeometry(100,sizeHint().height()-150,200,19); login_host_edit->setMaxLength(64); login_host_edit->setText(*login_host); - login_host_edit->setFocus(); QLabel *login_host_label=new QLabel(login_host_edit,tr("&Hostname:"),this); login_host_label->setFont(font); login_host_label->setGeometry(10,sizeHint().height()-150,85,19); @@ -79,11 +79,11 @@ MySqlLogin::MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *us // MySql Database Name // login_dbname_edit=new QLineEdit(this); + login_dbname_edit->setReadOnly(true); login_dbname_edit->setFont(font); login_dbname_edit->setGeometry(100,sizeHint().height()-130,200,19); login_dbname_edit->setMaxLength(64); login_dbname_edit->setText(*login_dbname); - login_dbname_edit->setFocus(); QLabel *login_dbname_label=new QLabel(login_dbname_edit,tr("&Database:"),this); login_dbname_label->setFont(font); login_dbname_label->setGeometry(10,sizeHint().height()-130,85,19); diff --git a/utils/rddbconfig/rddbconfig.cpp b/utils/rddbconfig/rddbconfig.cpp index d7ef1716..85a25693 100644 --- a/utils/rddbconfig/rddbconfig.cpp +++ b/utils/rddbconfig/rddbconfig.cpp @@ -51,6 +51,12 @@ MainWidget::MainWidget(QWidget *parent) 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) // @@ -170,7 +176,7 @@ void MainWidget::updateLabels() db = new Db(&err_msg,rd_config); if (!db->isOpen()) { - QMessageBox::critical(this,tr("Cannot Open Database"),tr("Unable to open database. The connection parameters of the [Mysql] section of rd.conf may be incorrect or you may need to create a new database.")); + QMessageBox::information(this,tr("Cannot Open Database"),tr("Unable to open database. The connection parameters of the [Mysql] section of rd.conf may be incorrect or you may need to create a new database.")); label_schema->setVisible(false); db_backup_button->setEnabled(false); db_restore_button->setEnabled(false); @@ -198,12 +204,6 @@ void MainWidget::createData() QString msg="Message"; QString err_str; - if(geteuid()!=0) { - QMessageBox::warning(this,tr("RDDbConfig error"), - tr("Create requires root permissions.")); - return; - } - 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; @@ -217,6 +217,7 @@ void MainWidget::createData() delete mysql_login; if(admin_name.isEmpty()||admin_pwd.isEmpty()||hostname.isEmpty()||dbname.isEmpty()) { + QMessageBox::critical(this,tr("RDDbConfig Error"),tr("Did not specify username and/or password.")); return; } @@ -225,7 +226,10 @@ void MainWidget::createData() CreateDb *db_create=new CreateDb(hostname,dbname,admin_name,admin_pwd); if(db_create->create(this,&err_str,rd_config)) { - fprintf(stderr,"err_str: %s\n",(const char *)err_str); + QMessageBox::critical(this,tr("RDDbConfig Error"),err_str); + } + else { + QMessageBox::information(this,tr("Success"),tr("A new database has been successfully created.")); } delete db_create; @@ -262,7 +266,7 @@ void MainWidget::backupData() QApplication::restoreOverrideCursor(); if (backupProcess.exitCode()) { fprintf(stderr,"Exit Code=%d\n",backupProcess.exitCode()); - QMessageBox::critical(this,tr("RDDbConfig error"), + QMessageBox::critical(this,tr("RDDbConfig Error"), QString(backupProcess.readAllStandardError())); } else { @@ -283,14 +287,8 @@ void MainWidget::restoreData() { QString filename; - if(geteuid()!=0) { - QMessageBox::warning(this,tr("RDDbConfig error"), - tr("Restore requires root permissions.")); - return; - } - if (!db->isOpen()) { - QMessageBox::critical(this,tr("RDDbConfig error"), + QMessageBox::critical(this,tr("RDDbConfig Error"), tr("Could not open Rivendell database.")); return; } @@ -316,7 +314,7 @@ void MainWidget::restoreData() restoreProcess.waitForFinished(); QApplication::restoreOverrideCursor(); if (restoreProcess.exitCode()) { - QMessageBox::critical(this,tr("RDDbConfig error"), + QMessageBox::critical(this,tr("RDDbConfig Error"), QString(restoreProcess.readAllStandardError())); } else { From 2e8819dfa8ccf4ae8c53b2202e82c419deb60f17 Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Mon, 8 Oct 2018 18:09:45 -0700 Subject: [PATCH 4/9] Fixed problems with MySQL user management --- utils/rddbconfig/createdb.cpp | 45 ++++++++++++++++++++++++++++++--- utils/rddbconfig/rddbconfig.cpp | 7 ++++- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/utils/rddbconfig/createdb.cpp b/utils/rddbconfig/createdb.cpp index ab6cde05..d049410a 100644 --- a/utils/rddbconfig/createdb.cpp +++ b/utils/rddbconfig/createdb.cpp @@ -35,7 +35,7 @@ CreateDb::CreateDb(QString host,QString database,QString username,QString passwo db_pass=password; } -bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *config) +bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *rd_config) { QString sql; @@ -43,7 +43,7 @@ bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *config) // Open Database // if (!db.isOpen()){ - db=QSqlDatabase::addDatabase(config->mysqlDriver(),"createDb"); + db=QSqlDatabase::addDatabase(rd_config->mysqlDriver(),"createDb"); if(!db.isValid()) { *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!")); return true; @@ -78,8 +78,41 @@ bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *config) } delete q; - sql=QString().sprintf("grant all on * to %s identified by \"%s\"", - (const char *)db_user,(const char *)db_pass); + // + // Drop any existing 'rduser'@'%' and 'rduser'@'localhost' users + // + sql=QString().sprintf("drop user '%s'@'%%'",(const char *)rd_config->mysqlUsername()); + q=new QSqlQuery(sql,db); + delete q; + sql=QString().sprintf("drop user '%s'@'localhost'",(const char *)rd_config->mysqlUsername()); + q=new QSqlQuery(sql,db); + delete q; + + sql=QString("flush privileges"); + q=new QSqlQuery(sql,db); + delete q; + + sql=QString().sprintf("create user '%s'@'%%' identified by \"%s\"", + (const char *)rd_config->mysqlUsername(),(const char *)rd_config->mysqlPassword()); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString().sprintf("Could not create user: '%s'@'%%'",(const char *)sql); + return true; + } + delete q; + + sql=QString().sprintf("create user '%s'@'localhost' identified by \"%s\"", + (const char *)rd_config->mysqlUsername(),(const char *)rd_config->mysqlPassword()); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString().sprintf("Could not create user: '%s'@'localhost'",(const char *)sql); + return true; + } + delete q; + + sql=QString().sprintf("grant SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,\ + INDEX, ALTER, LOCK TABLES on %s.* to %s", + (const char *)db_name, (const char *)rd_config->mysqlUsername()); q=new QSqlQuery(sql,db); if (!q->isActive()) { *err_str+=QString().sprintf("Could not set permissions: %s",(const char *)sql); @@ -87,6 +120,10 @@ bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *config) } delete q; + sql=QString("flush privileges"); + q=new QSqlQuery(sql,db); + delete q; + QProcess rddbmgrProcess(parent); QStringList args; args << QString("--create"); diff --git a/utils/rddbconfig/rddbconfig.cpp b/utils/rddbconfig/rddbconfig.cpp index 85a25693..e09f54ee 100644 --- a/utils/rddbconfig/rddbconfig.cpp +++ b/utils/rddbconfig/rddbconfig.cpp @@ -176,7 +176,6 @@ void MainWidget::updateLabels() db = new Db(&err_msg,rd_config); if (!db->isOpen()) { - QMessageBox::information(this,tr("Cannot Open Database"),tr("Unable to open database. The connection parameters of the [Mysql] section of rd.conf may be incorrect or you may need to create a new database.")); label_schema->setVisible(false); db_backup_button->setEnabled(false); db_restore_button->setEnabled(false); @@ -234,6 +233,8 @@ void MainWidget::createData() delete db_create; + updateLabels(); + startDaemons(); } @@ -348,7 +349,9 @@ void MainWidget::resizeEvent(QResizeEvent *e) void MainWidget::stopDaemons() { if(system("/usr/bin/systemctl status rivendell")==0) { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); system("/usr/bin/systemctl stop rivendell"); + QApplication::restoreOverrideCursor(); db_daemon_start_needed=true; } } @@ -357,7 +360,9 @@ void MainWidget::stopDaemons() void MainWidget::startDaemons() { if(db_daemon_start_needed) { + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); system("/usr/bin/systemctl start rivendell"); + QApplication::restoreOverrideCursor(); } } From 7336e5cf496eb6327c2b1d0788cc85b7d70e490f Mon Sep 17 00:00:00 2001 From: Deltec Enterprises Date: Mon, 8 Oct 2018 18:12:02 -0700 Subject: [PATCH 5/9] Delete opendb.h --- utils/rddbconfig/opendb.h | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 utils/rddbconfig/opendb.h diff --git a/utils/rddbconfig/opendb.h b/utils/rddbconfig/opendb.h deleted file mode 100644 index 133a7b65..00000000 --- a/utils/rddbconfig/opendb.h +++ /dev/null @@ -1,33 +0,0 @@ -// opendb.h -// -// Open a Rivendell Database -// -// (C) Copyright 2002-2003,2016 Fred Gleason -// -// 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. -// - -#ifndef OPENDB_H -#define OPENDB_H - -#include - -#include - -bool OpenDb(QString dbname,QString username,QString password,QString hostname, - QString stationname,bool interactive,RDConfig *config); - - -#endif // OPENDB_H - From bfa62cd96ef4df41d833ffdff305a51fe96b6540 Mon Sep 17 00:00:00 2001 From: Deltec Enterprises Date: Mon, 8 Oct 2018 18:12:29 -0700 Subject: [PATCH 6/9] Delete opendb.cpp --- utils/rddbconfig/opendb.cpp | 436 ------------------------------------ 1 file changed, 436 deletions(-) delete mode 100644 utils/rddbconfig/opendb.cpp diff --git a/utils/rddbconfig/opendb.cpp b/utils/rddbconfig/opendb.cpp deleted file mode 100644 index ecbcacbe..00000000 --- a/utils/rddbconfig/opendb.cpp +++ /dev/null @@ -1,436 +0,0 @@ -// opendb.cpp -// -// Open a Rivendell Database -// -// (C) Copyright 2002-2004,2016 Fred Gleason -// -// 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Includes used for netmask and remote server detection. -#include -#include -#include -#include - -#include - -/** - * Get the netmask of an interface and return it via an in_addr struct pointer. - * - * Note: uses linux IOCTL call SIOCGIFNETMASK to retrieve the netmask from a - * temporary socket. - * - * @param interface String with the interface to query. - * @param netmask Pointer to struct in_addr that will be populated with the netmask. - * @return true on success - **/ -bool get_netmask(const char * interface, struct in_addr * netmask) -{ - int fd; - struct ifreq ifr; - struct sockaddr_in *nmask; - - fd=socket(AF_INET, SOCK_DGRAM, 0); - ifr.ifr_addr.sa_family=AF_INET; - strncpy(ifr.ifr_name, interface, IFNAMSIZ-1); - ioctl(fd, SIOCGIFNETMASK, &ifr); - close(fd); - nmask=(struct sockaddr_in *)&ifr.ifr_netmask; - netmask->s_addr=nmask->sin_addr.s_addr; - return true; -} - - -/** - * Check if creating the database on the local machine or on a remote server in - * the same subnet. - * - * @param host QString with the hostname of machine to create the database. - * @return true if database is to be created on a remote server. - **/ -bool check_remote_server(QString host) { - char local_hostname[256]; - int rc; - struct hostent *temp_hostent; - struct hostent local_hostent; - struct hostent host_hostent; - struct in_addr local_ip; - struct in_addr host_ip; - struct in_addr local_netmask; - - // check if host is 'localhost' - if (0==strncasecmp("localhost", (const char *)host, 255)) - return false; - - rc=gethostname(local_hostname, 255); - // compare hostnames - if ((0==rc) && (0!=strncasecmp(local_hostname, (const char *)host, 255))) { - if ((temp_hostent=gethostbyname(local_hostname))) - local_hostent=*temp_hostent; - else - return false; - local_ip=*(struct in_addr *)temp_hostent->h_addr; - - if ((temp_hostent=gethostbyname((const char *)host))) - host_hostent=*temp_hostent; - else - return false; - host_ip=*(struct in_addr *)temp_hostent->h_addr; - - // compare IPs - if ((local_hostent.h_addrtype == AF_INET) && - (host_hostent.h_addrtype == AF_INET) && - (local_ip.s_addr != host_ip.s_addr)) { - // FIXME: ideally do something smarter than just testing eth0 (note use - // below in format_remote_host() also) - // get list of interfaces if_nameindex() - // loop through list of interfaces, get IP, see if it matches local IP - // once have good interface, get netmask - rc=get_netmask("eth0", &local_netmask); - - // compare if IPs are on same subnet. note: use of bitwise sum - if ( (local_ip.s_addr & local_netmask.s_addr) == - (host_ip.s_addr & local_netmask.s_addr) ) - return true; - } // endif compare IPs - } // endif compare hostnames - return false; -} - - -/** - * Format a QString with the MySQL host portion for a remote host. The - * resulting string will use the local subnet and mask to generate something - * like "192.168.1.0/255.255.255.0" . - * - * @param host string with the hostname to use for the subnet and mask. - * @return QString with formated result. - **/ -QString format_remote_host(const char *hostname) { - struct in_addr local_netmask; - struct hostent *temp_hostent; - struct in_addr local_ip; - struct in_addr local_subnet; - - temp_hostent=gethostbyname(hostname); - local_ip=*(struct in_addr *)temp_hostent->h_addr; - // FIXME: ideally do something smarter than just testing eth0 (see above in check_remote_server() also) - get_netmask("eth0", &local_netmask); - local_subnet.s_addr=(local_ip.s_addr & local_netmask.s_addr); - return QString().sprintf("%s/%s", strdupa(inet_ntoa(local_subnet)), strdupa(inet_ntoa(local_netmask)) ); -} - - -bool OpenDb(QString dbname,QString login,QString pwd, - QString host,QString stationname,bool interactive,RDConfig *config) -{ - // - // Yeesh, this whole method really needs a rewrite! - // They shoot horses, don't they?? - // - - int db_ver; - QString admin_name; - QString admin_pwd; - QString sql; - QSqlQuery *q; - QString msg; - MySqlLogin *mysql_login; - QString str; - int err=0; - QString err_str=""; - - // - // Open Database - // - QSqlDatabase *db=QSqlDatabase::addDatabase(admin_config->mysqlDriver()); - if(!db) { - return false; - } - db->setDatabaseName(dbname); - db->setUserName(login); - db->setPassword(pwd); - db->setHostName(host); - if(!db->open()) { - /* - if(!interactive) { - return false; - } - */ - RDKillDaemons(); - if(interactive) { - msg=QObject::tr("Unable to access the Rivendell Database!\n\ -Please enter a login for an account with\n\ -administrative rights on the mySQL server,\n\ -and we will try to get this straightened out."); - mysql_login=new MySqlLogin(msg,&admin_name,&admin_pwd); - if(mysql_login->exec()!=0) { - delete mysql_login; - db->removeDatabase(dbname); - return false; - } - delete mysql_login; - } - else { - admin_name=admin_admin_username; - admin_pwd=admin_admin_password; - if(!admin_admin_hostname.isEmpty()) { - db->setHostName(admin_admin_hostname); - } - } - db->setUserName(admin_name); - db->setPassword(admin_pwd); - if(db->open()) { // Fixup DB Access Permsissions - PrintError(QObject::tr("Wrong access permissions for accessing mySQL!"), - interactive); - db->removeDatabase("mysql"); - return false; - } - else { - db->setDatabaseName("mysql"); - if(!db->open()) { // mySQL is hosed -- scream and die. - PrintError(QObject::tr("Unable to connect to mySQL!"),interactive); - db->removeDatabase("mysql"); - return false; - } - else { // Create a new Rivendell Database - sql=QString().sprintf("create database %s",(const char *)dbname); - q=new QSqlQuery(sql); - if(!q->isActive()) { // Can't create DB. - delete q; - PrintError(QObject::tr("Unable to create a Rivendell Database!"), - interactive); - db->removeDatabase("mysql"); - return false; - } - delete q; - - // Check if creating the database on the local machine or on a remote - // server in the same subnet. If creating on a remote server, set the - // host portion of the MySQL user to the subnet that is common between - // the local workstation and the server. - if (check_remote_server(host)) { - host=format_remote_host(host); - } - sql=QString().sprintf("create user %s@'%s' identified by '%s'", - (const char *)login, (const char *)host, (const char *)pwd); - q=new QSqlQuery(sql); - delete q; - sql=QString().sprintf("grant SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,\ - INDEX, ALTER, LOCK TABLES on %s.* to %s@'%s'", - (const char *)dbname, (const char *)login, (const char *)host); - q=new QSqlQuery(sql); - delete q; - q=new QSqlQuery("flush privileges"); - delete q; - db->close(); // Relinquish admin perms - if(!admin_admin_dbname.isEmpty()) { - dbname=admin_admin_dbname; - } - db->setDatabaseName(dbname); - db->setUserName(login); - db->setPassword(pwd); - db->setHostName(host); - if(!db->open()) { // Can't open new database - PrintError(QObject::tr("Unable to connect to new Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - if(!CreateDb(login,pwd,config)) { // Can't create tables. - PrintError(QObject::tr("Unable to create Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - db->close(); - db->setDatabaseName(dbname); - db->setUserName(login); - db->setPassword(pwd); - if(!db->open()) { - PrintError(QObject::tr("Unable to connect to Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - if(!InitDb(login,pwd,stationname,config)) { // Can't initialize tables. - PrintError(QObject::tr("Unable to initialize Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - if(interactive) { - QMessageBox::information(NULL,QObject::tr("RDAdmin"), - QObject::tr("New Rivendell Database Created!")); - } - return true; - } - } - return false; - } - if((db_ver=RDCheckVersion())exec()!=0) { - delete mysql_login; - db->removeDatabase(dbname); - return false; - } - delete mysql_login; - } - else { - admin_name=admin_admin_username; - admin_pwd=admin_admin_password; - } - RDKillDaemons(); - db->close(); - db->setDatabaseName("mysql"); - db->setUserName(admin_name); - db->setPassword(admin_pwd); - if(!db->open()) { - PrintError(QObject::tr("Unable to log into Administrator account!"), - interactive); - db->removeDatabase(dbname); - return false; - } - q=new QSqlQuery(QString().sprintf ("drop database %s",(const char *)dbname)); - delete q; - q=new QSqlQuery(QString().sprintf("create database %s",(const char *)dbname)); - if(!q->isActive()) { // Can't create DB. - delete q; - PrintError(QObject::tr("Unable to create a Rivendell Database!"), - interactive); - db->removeDatabase("mysql"); - return false; - } - delete q; - sql=QString(). - sprintf("grant all on %s to %s identified by \"%s\"", - (const char *)dbname,(const char *)login,(const char *)pwd); - q=new QSqlQuery(sql); - if(!q->isActive()) { // Can't authorize DB. - PrintError(QObject::tr("Unable to authorize a Rivendell Database!"), - interactive); - db->removeDatabase("mysql"); - return false; - } - db->close(); // Relinquish admin perms - db->setDatabaseName(dbname); - db->setUserName(login); - db->setPassword(pwd); - if(!db->open()) { // Can't open new database - PrintError(QObject::tr("Unable to connect to new Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - if(!CreateDb(login,pwd,config)) { // Can't create tables. - PrintError(QObject::tr("Unable to create Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - db->close(); - db->setDatabaseName(dbname); - db->setUserName(login); - db->setPassword(pwd); - if(!db->open()) { - PrintError(QObject::tr("Unable to connect to Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - if(!InitDb(login,pwd,stationname,config)) { // Can't initialize tables. - PrintError(QObject::tr("Unable to initialize Rivendell Database!"), - interactive); - db->removeDatabase(dbname); - return false; - } - } - else { // Out-of-date version - if(interactive) { - if(QMessageBox::warning(NULL,QObject::tr("Update Needed"), - QObject::tr("The Rivendell Database needs to be updated.\n\ -All audio and settings will be preserved, but\n\ -this will STOP any audio playout or recording\n\ -on this machine for a few seconds. Continue?"), - QMessageBox::Yes,QMessageBox::No)!= - QMessageBox::Yes) { - db->removeDatabase(dbname); - return false; - } - } - RDKillDaemons(); - if((err=UpdateDb(db_ver,config))!=UPDATEDB_SUCCESS) { - err_str=QObject::tr("Unable to update Rivendell Database:"); - switch(err) { - case UPDATEDB_BACKUP_FAILED: - err_str+=QObject::tr("\nDatabase backup failed!"); - break; - - case UPDATEDB_QUERY_FAILED: - err_str+=QObject::tr("\nSchema modification failed!"); - break; - - default: - err_str+=QObject::tr("\nUnknown/unspecified error!"); - break; - } - PrintError(err_str,interactive); - db->removeDatabase(dbname); - return false; - } - str=QString( - QObject::tr("The Rivendell Database has been updated to version")); - msg=QString(). - sprintf("%s %d",(const char *)str,RD_VERSION_DATABASE); - if(!admin_skip_backup) { - msg+=QObject::tr("\nand a backup of the original database saved in "); - msg+=admin_backup_filename; - } - msg+="."; - if(interactive) { - QMessageBox::information(NULL,QObject::tr("Database Updated"),msg); - } - } - } - - return true; -} - From bec85018a36b188bae31ff7b9fef4caef6496f90 Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Mon, 8 Oct 2018 18:15:38 -0700 Subject: [PATCH 7/9] No changes... I have no idea why git thinks there are changes. --- utils/rddbconfig/createdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/rddbconfig/createdb.h b/utils/rddbconfig/createdb.h index 7cbddfcf..2c293218 100644 --- a/utils/rddbconfig/createdb.h +++ b/utils/rddbconfig/createdb.h @@ -31,7 +31,7 @@ class CreateDb public: CreateDb(QString host,QString database,QString username,QString password); ~CreateDb(); - bool create(QObject *parent,QString *err_str, RDConfig *config); + bool create(QWidget *parent,QString *err_str, RDConfig *config); bool isOpen(); private: From 74739cad2e9cab8015e995f283512c9233046e88 Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Mon, 8 Oct 2018 22:03:56 -0700 Subject: [PATCH 8/9] Fixed QSqlDatabase warnings --- utils/rddbconfig/createdb.cpp | 170 ++++++++++++++++---------------- utils/rddbconfig/createdb.h | 1 - utils/rddbconfig/db.cpp | 48 +++++---- utils/rddbconfig/db.h | 1 - utils/rddbconfig/rddbconfig.cpp | 48 +++++++-- utils/rddbconfig/rddbconfig.h | 1 + 6 files changed, 147 insertions(+), 122 deletions(-) diff --git a/utils/rddbconfig/createdb.cpp b/utils/rddbconfig/createdb.cpp index d049410a..d920a9f9 100644 --- a/utils/rddbconfig/createdb.cpp +++ b/utils/rddbconfig/createdb.cpp @@ -42,100 +42,96 @@ bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *rd_config) // // Open Database // - if (!db.isOpen()){ - db=QSqlDatabase::addDatabase(rd_config->mysqlDriver(),"createDb"); - if(!db.isValid()) { - *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!")); - return true; - } - db.setHostName(db_host); - db.setDatabaseName("mysql"); - db.setUserName(db_user); - db.setPassword(db_pass); - if(!db.open()) { - *err_str+=QString(QObject::tr("Couldn't open MySQL connection on"))+ - " \""+db_host+"\"."; - db.removeDatabase(db.connectionName()); - db.close(); - return true; - } + QSqlDatabase db=QSqlDatabase::addDatabase(rd_config->mysqlDriver(),"createDb"); + if(!db.isValid()) { + *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!")); + return true; + } - QSqlQuery *q; + db.setHostName(db_host); + db.setDatabaseName("mysql"); + db.setUserName(db_user); + db.setPassword(db_pass); + if(!db.open()) { + *err_str+=QString().sprintf("Couldn't open MySQL connection on %s",(const char *)db_host); + return true; + } - sql=QString().sprintf("drop database if exists `%s`",(const char *)db_name); - q=new QSqlQuery(sql,db); - if (!q->isActive()) { - *err_str+=QString(QObject::tr("Could not remove old database")); - return true; - } - delete q; + QSqlQuery *q; - sql=QString().sprintf("create database if not exists `%s`",(const char *)db_name); - q=new QSqlQuery(sql,db); - if (!q->isActive()) { - *err_str+=QString(QObject::tr("Could not create new database")); - return true; - } - delete q; + sql=QString().sprintf("drop database if exists `%s`",(const char *)db_name); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString(QObject::tr("Could not remove old database")); + return true; + } + delete q; - // - // Drop any existing 'rduser'@'%' and 'rduser'@'localhost' users - // - sql=QString().sprintf("drop user '%s'@'%%'",(const char *)rd_config->mysqlUsername()); - q=new QSqlQuery(sql,db); - delete q; - sql=QString().sprintf("drop user '%s'@'localhost'",(const char *)rd_config->mysqlUsername()); - q=new QSqlQuery(sql,db); - delete q; + sql=QString().sprintf("create database if not exists `%s`",(const char *)db_name); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString(QObject::tr("Could not create new database")); + return true; + } + delete q; - sql=QString("flush privileges"); - q=new QSqlQuery(sql,db); - delete q; + // + // Drop any existing 'rduser'@'%' and 'rduser'@'localhost' users + // + sql=QString().sprintf("drop user '%s'@'%%'",(const char *)rd_config->mysqlUsername()); + q=new QSqlQuery(sql,db); + delete q; + sql=QString().sprintf("drop user '%s'@'localhost'",(const char *)rd_config->mysqlUsername()); + q=new QSqlQuery(sql,db); + delete q; - sql=QString().sprintf("create user '%s'@'%%' identified by \"%s\"", - (const char *)rd_config->mysqlUsername(),(const char *)rd_config->mysqlPassword()); - q=new QSqlQuery(sql,db); - if (!q->isActive()) { - *err_str+=QString().sprintf("Could not create user: '%s'@'%%'",(const char *)sql); - return true; - } - delete q; + sql=QString("flush privileges"); + q=new QSqlQuery(sql,db); + delete q; - sql=QString().sprintf("create user '%s'@'localhost' identified by \"%s\"", - (const char *)rd_config->mysqlUsername(),(const char *)rd_config->mysqlPassword()); - q=new QSqlQuery(sql,db); - if (!q->isActive()) { - *err_str+=QString().sprintf("Could not create user: '%s'@'localhost'",(const char *)sql); - return true; - } - delete q; + sql=QString().sprintf("create user '%s'@'%%' identified by \"%s\"", + (const char *)rd_config->mysqlUsername(),(const char *)rd_config->mysqlPassword()); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString().sprintf("Could not create user: '%s'@'%%'",(const char *)sql); + return true; + } + delete q; - sql=QString().sprintf("grant SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,\ - INDEX, ALTER, LOCK TABLES on %s.* to %s", - (const char *)db_name, (const char *)rd_config->mysqlUsername()); - q=new QSqlQuery(sql,db); - if (!q->isActive()) { - *err_str+=QString().sprintf("Could not set permissions: %s",(const char *)sql); - return true; - } - delete q; + sql=QString().sprintf("create user '%s'@'localhost' identified by \"%s\"", + (const char *)rd_config->mysqlUsername(),(const char *)rd_config->mysqlPassword()); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString().sprintf("Could not create user: '%s'@'localhost'",(const char *)sql); + return true; + } + delete q; - sql=QString("flush privileges"); - q=new QSqlQuery(sql,db); - delete q; + sql=QString().sprintf("grant SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,\ + INDEX, ALTER, LOCK TABLES on %s.* to %s", + (const char *)db_name, (const char *)rd_config->mysqlUsername()); + q=new QSqlQuery(sql,db); + if (!q->isActive()) { + *err_str+=QString().sprintf("Could not set permissions: %s",(const char *)sql); + return true; + } + delete q; - QProcess rddbmgrProcess(parent); - QStringList args; - args << QString("--create"); - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - rddbmgrProcess.start(QString(RD_PREFIX)+"/sbin/rddbmgr",args); - rddbmgrProcess.waitForFinished(); - QApplication::restoreOverrideCursor(); - if (rddbmgrProcess.exitCode()) { - *err_str+=QString().sprintf("Failed to create %s database. Rddbmgr exit code=%d", - (const char *)db_name,rddbmgrProcess.exitCode()); - return true; - } + sql=QString("flush privileges"); + q=new QSqlQuery(sql,db); + delete q; + + QProcess rddbmgrProcess(parent); + QStringList args; + args << QString("--create"); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + rddbmgrProcess.start(QString(RD_PREFIX)+"/sbin/rddbmgr",args); + rddbmgrProcess.waitForFinished(); + QApplication::restoreOverrideCursor(); + if (rddbmgrProcess.exitCode()) { + *err_str+=QString().sprintf("Failed to create %s database. Rddbmgr exit code=%d", + (const char *)db_name,rddbmgrProcess.exitCode()); + return true; } return false; @@ -143,14 +139,16 @@ bool CreateDb::create(QWidget *parent,QString *err_str,RDConfig *rd_config) CreateDb::~CreateDb() { - if(db.isOpen()) { - db.removeDatabase(db_name); + { + QSqlDatabase db=QSqlDatabase::database("createDb"); db.close(); } + QSqlDatabase::removeDatabase("createDb"); } bool CreateDb::isOpen() { + QSqlDatabase db=QSqlDatabase::database("createDb"); return db.isOpen(); } diff --git a/utils/rddbconfig/createdb.h b/utils/rddbconfig/createdb.h index 2c293218..5b8c1efb 100644 --- a/utils/rddbconfig/createdb.h +++ b/utils/rddbconfig/createdb.h @@ -39,7 +39,6 @@ class CreateDb QString db_name; QString db_user; QString db_pass; - QSqlDatabase db; }; #endif // CREATEDB_H diff --git a/utils/rddbconfig/db.cpp b/utils/rddbconfig/db.cpp index d712b366..ab1037a0 100644 --- a/utils/rddbconfig/db.cpp +++ b/utils/rddbconfig/db.cpp @@ -31,43 +31,41 @@ Db::Db(QString *err_str,RDConfig *config) // // Open Database // - if (!db.isOpen()){ - db=QSqlDatabase::addDatabase(config->mysqlDriver()); - if(!db.isValid()) { - *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!")); - return; - } - db.setHostName(config->mysqlHostname()); - db.setDatabaseName(config->mysqlDbname()); - db.setUserName(config->mysqlUsername()); - db.setPassword(config->mysqlPassword()); - if(!db.open()) { - *err_str+=QString(QObject::tr("Couldn't open MySQL connection on"))+ - " \""+config->mysqlHostname()+"\"."; - db.removeDatabase(config->mysqlDbname()); - db.close(); - return; - } - - q=new QSqlQuery("select DB from VERSION"); - if(q->first()) { - db_schema=q->value(0).toUInt(); - } - delete q; + QSqlDatabase db=QSqlDatabase::addDatabase(config->mysqlDriver(),"Rivendell"); + if(!db.isValid()) { + *err_str+= QString(QObject::tr("Couldn't initialize MySql driver!")); + return; } + db.setHostName(config->mysqlHostname()); + db.setDatabaseName(config->mysqlDbname()); + db.setUserName(config->mysqlUsername()); + db.setPassword(config->mysqlPassword()); + if(!db.open()) { + *err_str+=QString().sprintf("Couldn't open MySQL connection on %s", + (const char *)config->mysqlHostname()); + return; + } + + q=new QSqlQuery("select DB from VERSION",db); + if(q->first()) { + db_schema=q->value(0).toUInt(); + } + delete q; } Db::~Db() { - if(db.isOpen()) { -// db.removeDatabase(config->mysqlDbname()); + { + QSqlDatabase db=QSqlDatabase::database("Rivendell"); db.close(); } + QSqlDatabase::removeDatabase("Rivendell"); } bool Db::isOpen() { + QSqlDatabase db=QSqlDatabase::database("Rivendell"); return db.isOpen(); } diff --git a/utils/rddbconfig/db.h b/utils/rddbconfig/db.h index dfc086e2..71adbf54 100644 --- a/utils/rddbconfig/db.h +++ b/utils/rddbconfig/db.h @@ -34,7 +34,6 @@ class Db unsigned schema(); private: - QSqlDatabase db; unsigned db_schema; }; diff --git a/utils/rddbconfig/rddbconfig.cpp b/utils/rddbconfig/rddbconfig.cpp index e09f54ee..be0f7ebe 100644 --- a/utils/rddbconfig/rddbconfig.cpp +++ b/utils/rddbconfig/rddbconfig.cpp @@ -176,13 +176,12 @@ void MainWidget::updateLabels() db = new Db(&err_msg,rd_config); if (!db->isOpen()) { - label_schema->setVisible(false); + label_schema->setText("DB Version: unknown"); db_backup_button->setEnabled(false); db_restore_button->setEnabled(false); } else { label_schema->setText(QString().sprintf("DB Version: %d",db->schema())); - label_schema->setVisible(true); db_backup_button->setEnabled(true); db_restore_button->setEnabled(true); } @@ -211,7 +210,10 @@ void MainWidget::createData() mysql_login=new MySqlLogin(msg,&hostname,&dbname,&admin_name,&admin_pwd); - mysql_login->exec(); + if(mysql_login->exec()) { + delete mysql_login; + return; + } delete mysql_login; @@ -231,11 +233,11 @@ void MainWidget::createData() QMessageBox::information(this,tr("Success"),tr("A new database has been successfully created.")); } - delete db_create; + startDaemons(); updateLabels(); - startDaemons(); + delete db_create; } @@ -346,24 +348,52 @@ void MainWidget::resizeEvent(QResizeEvent *e) } +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(); +#if 0 if(system("/usr/bin/systemctl status rivendell")==0) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); system("/usr/bin/systemctl stop rivendell"); QApplication::restoreOverrideCursor(); db_daemon_start_needed=true; } +#endif } void MainWidget::startDaemons() { - if(db_daemon_start_needed) { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - system("/usr/bin/systemctl start rivendell"); - QApplication::restoreOverrideCursor(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + if(statusDaemons("rivendell")) { + QProcess startProcess(this); + QStringList args; + args << "start" << "rivendell"; + startProcess.start("systemctl", args); + startProcess.waitForFinished(); } + QApplication::restoreOverrideCursor(); } diff --git a/utils/rddbconfig/rddbconfig.h b/utils/rddbconfig/rddbconfig.h index 74e05946..741c9fce 100644 --- a/utils/rddbconfig/rddbconfig.h +++ b/utils/rddbconfig/rddbconfig.h @@ -46,6 +46,7 @@ class MainWidget : public QWidget QSizePolicy sizePolicy() const; private slots: + int statusDaemons(QString service); void stopDaemons(); void startDaemons(); void createData(); From cf91daa25453cdf1f91d5b7e7de589668c4b1304 Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Tue, 9 Oct 2018 06:55:29 -0700 Subject: [PATCH 9/9] Cleaned up MySQL login dialog --- utils/rddbconfig/mysql_login.cpp | 56 +++++++------------------------- utils/rddbconfig/mysql_login.h | 7 +--- utils/rddbconfig/rddbconfig.cpp | 5 ++- 3 files changed, 14 insertions(+), 54 deletions(-) diff --git a/utils/rddbconfig/mysql_login.cpp b/utils/rddbconfig/mysql_login.cpp index 5caaced3..e895c358 100644 --- a/utils/rddbconfig/mysql_login.cpp +++ b/utils/rddbconfig/mysql_login.cpp @@ -36,13 +36,10 @@ #include "mysql_login.h" -MySqlLogin::MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *username,QString *password, - QWidget *parent) +MySqlLogin::MySqlLogin(QString *username,QString *password, QWidget *parent) : QDialog(parent,"",true) { setCaption(tr("mySQL Admin")); - login_host=hostname; - login_dbname=dbname; login_name=username; login_password=password; @@ -55,51 +52,22 @@ MySqlLogin::MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *us // // Message Label // - RDLabel *label=new RDLabel(msg,this); + RDLabel *label=new RDLabel(tr("Enter your MySQL administrator username and password\nThe Hostname and Database are found in /etc/rd.conf"),this); label->setFont(font); - label->setGeometry(10,10,sizeHint().width()-20,sizeHint().height()-130); + label->setGeometry(10,10,sizeHint().width()-20,30); label->setAlignment(Qt::AlignCenter); - - // - // MySql Host Name - // - login_host_edit=new QLineEdit(this); - login_host_edit->setReadOnly(true); - login_host_edit->setFont(font); - login_host_edit->setGeometry(100,sizeHint().height()-150,200,19); - login_host_edit->setMaxLength(64); - login_host_edit->setText(*login_host); - QLabel *login_host_label=new QLabel(login_host_edit,tr("&Hostname:"),this); - login_host_label->setFont(font); - login_host_label->setGeometry(10,sizeHint().height()-150,85,19); - login_host_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); - - // - // MySql Database Name - // - login_dbname_edit=new QLineEdit(this); - login_dbname_edit->setReadOnly(true); - login_dbname_edit->setFont(font); - login_dbname_edit->setGeometry(100,sizeHint().height()-130,200,19); - login_dbname_edit->setMaxLength(64); - login_dbname_edit->setText(*login_dbname); - QLabel *login_dbname_label=new QLabel(login_dbname_edit,tr("&Database:"),this); - login_dbname_label->setFont(font); - login_dbname_label->setGeometry(10,sizeHint().height()-130,85,19); - login_dbname_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); - // // MySql Login Name // login_name_edit=new QLineEdit(this); login_name_edit->setFont(font); - login_name_edit->setGeometry(100,sizeHint().height()-110,100,19); + login_name_edit->setGeometry(sizeHint().width()/2-125+90,50,140,19); login_name_edit->setMaxLength(16); login_name_edit->setFocus(); - QLabel *login_name_label=new QLabel(login_name_edit,tr("User&name:"),this); + QLabel *login_name_label=new QLabel(login_name_edit,tr("&Username:"),this); login_name_label->setFont(font); - login_name_label->setGeometry(10,sizeHint().height()-109,85,19); + login_name_label->setGeometry(sizeHint().width()/2-125,50,85,19); login_name_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); // @@ -107,19 +75,19 @@ MySqlLogin::MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *us // login_password_edit=new QLineEdit(this); login_password_edit->setFont(font); - login_password_edit->setGeometry(100,sizeHint().height()-90,100,19); + login_password_edit->setGeometry(sizeHint().width()/2-125+90,70,140,19); login_password_edit->setMaxLength(16); login_password_edit->setEchoMode(QLineEdit::Password); QLabel *login_password_label=new QLabel(login_password_edit,tr("&Password:"),this); login_password_label->setFont(font); - login_password_label->setGeometry(10,sizeHint().height()-88,85,19); + login_password_label->setGeometry(sizeHint().width()/2-125,70,85,19); login_password_label->setAlignment(Qt::AlignRight|Qt::ShowPrefix); // // OK Button // QPushButton *ok_button=new QPushButton(this); - ok_button->setGeometry(sizeHint().width()-180,sizeHint().height()-60,80,50); + ok_button->setGeometry(sizeHint().width()/2-90,sizeHint().height()-60,80,50); ok_button->setFont(font); ok_button->setText(tr("&OK")); ok_button->setDefault(true); @@ -129,7 +97,7 @@ MySqlLogin::MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *us // Cancel Button // QPushButton *cancel_button=new QPushButton(this); - cancel_button->setGeometry(sizeHint().width()-90,sizeHint().height()-60, + cancel_button->setGeometry(sizeHint().width()/2+10,sizeHint().height()-60, 80,50); cancel_button->setFont(font); cancel_button->setText(tr("&Cancel")); @@ -146,7 +114,7 @@ MySqlLogin::~MySqlLogin() QSize MySqlLogin::sizeHint() const { - return QSize(360,210); + return QSize(340,160); } @@ -158,8 +126,6 @@ QSizePolicy MySqlLogin::sizePolicy() const void MySqlLogin::okData() { - *login_host=login_host_edit->text(); - *login_dbname=login_dbname_edit->text(); *login_name=login_name_edit->text(); *login_password=login_password_edit->text(); diff --git a/utils/rddbconfig/mysql_login.h b/utils/rddbconfig/mysql_login.h index e36ad663..cfc4fcd5 100644 --- a/utils/rddbconfig/mysql_login.h +++ b/utils/rddbconfig/mysql_login.h @@ -31,8 +31,7 @@ class MySqlLogin : public QDialog { Q_OBJECT public: - MySqlLogin(QString msg,QString *hostname,QString *dbname,QString *username,QString *password, - QWidget *parent=0); + MySqlLogin(QString *username,QString *password, QWidget *parent=0); ~MySqlLogin(); QSize sizeHint() const; QSizePolicy sizePolicy() const; @@ -42,10 +41,6 @@ class MySqlLogin : public QDialog void cancelData(); private: - QString *login_host; - QLineEdit *login_host_edit; - QString *login_dbname; - QLineEdit *login_dbname_edit; QString *login_name; QLineEdit *login_name_edit; QString *login_password; diff --git a/utils/rddbconfig/rddbconfig.cpp b/utils/rddbconfig/rddbconfig.cpp index be0f7ebe..4df81655 100644 --- a/utils/rddbconfig/rddbconfig.cpp +++ b/utils/rddbconfig/rddbconfig.cpp @@ -199,7 +199,6 @@ void MainWidget::createData() QString dbname=rd_config->mysqlDbname(); QString admin_name; QString admin_pwd; - QString msg="Message"; QString err_str; if (db->isOpen()) { @@ -208,7 +207,7 @@ void MainWidget::createData() } } - mysql_login=new MySqlLogin(msg,&hostname,&dbname,&admin_name,&admin_pwd); + mysql_login=new MySqlLogin(&admin_name,&admin_pwd); if(mysql_login->exec()) { delete mysql_login; @@ -217,7 +216,7 @@ void MainWidget::createData() delete mysql_login; - if(admin_name.isEmpty()||admin_pwd.isEmpty()||hostname.isEmpty()||dbname.isEmpty()) { + if(admin_name.isEmpty()||admin_pwd.isEmpty()) { QMessageBox::critical(this,tr("RDDbConfig Error"),tr("Did not specify username and/or password.")); return; }