From 9d25af4c5f509d861aad2f201f8033ba124ad48f Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 24 Oct 2018 15:34:35 -0400 Subject: [PATCH] 2018-10-24 Fred Gleason * Consolidated the implementation of the 'RDProfile' class into two files. * Added an rdselect_helper(1) SETUID helper program. * Removed the SETUID bit from rdselect(1). --- .gitignore | 6 + ChangeLog | 5 + configure.ac | 65 ++++-- lib/Makefile.am | 2 - lib/lib.pro | 4 - lib/librd_cs.ts | 56 +++++ lib/librd_de.ts | 56 +++++ lib/librd_es.ts | 56 +++++ lib/librd_fr.ts | 56 +++++ lib/librd_nb.ts | 56 +++++ lib/librd_nn.ts | 56 +++++ lib/librd_pt_BR.ts | 56 +++++ lib/rdconfig.cpp | 86 +++++++- lib/rdconfig.h | 20 +- lib/rdprofile.cpp | 92 +++++++- lib/rdprofile.h | 38 +++- lib/rdprofileline.cpp | 57 ----- lib/rdprofileline.h | 42 ---- lib/rdprofilesection.cpp | 65 ------ lib/rdprofilesection.h | 46 ---- rdselect/Makefile.am | 1 - rdselect/rdselect.cpp | 100 +++------ rdselect/rdselect.h | 3 - rdselect/rdselect_cs.ts | 22 +- rdselect/rdselect_de.ts | 14 +- rdselect/rdselect_es.ts | 14 +- rdselect/rdselect_fr.ts | 14 +- rdselect/rdselect_nb.ts | 14 +- rdselect/rdselect_nn.ts | 14 +- rdselect/rdselect_pt_BR.ts | 14 +- rivendell.spec.in | 3 +- utils/Makefile.am | 1 + utils/rdselect_helper/Makefile.am | 55 +++++ utils/rdselect_helper/rdselect_helper.cpp | 258 ++++++++++++++++++++++ utils/rdselect_helper/rdselect_helper.h | 49 ++++ 35 files changed, 1096 insertions(+), 400 deletions(-) delete mode 100644 lib/rdprofileline.cpp delete mode 100644 lib/rdprofileline.h delete mode 100644 lib/rdprofilesection.cpp delete mode 100644 lib/rdprofilesection.h create mode 100644 utils/rdselect_helper/Makefile.am create mode 100644 utils/rdselect_helper/rdselect_helper.cpp create mode 100644 utils/rdselect_helper/rdselect_helper.h diff --git a/.gitignore b/.gitignore index 1fa09454..3aa0a895 100644 --- a/.gitignore +++ b/.gitignore @@ -137,6 +137,12 @@ utils/rdmaint/rdmaint utils/rdgen/rdgen utils/rdrender/rdrender utils/rdrevert/rdrevert +utils/rdselect_helper/rd.h +utils/rdselect_helper/rdconfig.cpp +utils/rdselect_helper/rdconfig.h +utils/rdselect_helper/rdprofile.cpp +utils/rdselect_helper/rdprofile.h +utils/rdselect_helper/rdselect_helper utils/sas_shim/sas_shim web/rdfeed/rdfeed.xml xdg/rivendell-opsguide-html.desktop diff --git a/ChangeLog b/ChangeLog index b3953f03..d9fb0d8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17894,3 +17894,8 @@ 2018-10-23 Fred Gleason * Fixed a bug in 'configure.ac' that caused detection of FLAC support to always fail. +2018-10-24 Fred Gleason + * Consolidated the implementation of the 'RDProfile' class into + two files. + * Added an rdselect_helper(1) SETUID helper program. + * Removed the SETUID bit from rdselect(1). diff --git a/configure.ac b/configure.ac index 7dc9336b..7c1e7520 100644 --- a/configure.ac +++ b/configure.ac @@ -465,30 +465,6 @@ AC_CONFIG_FILES([rivendell.spec \ lib/Makefile \ rdhpi/Makefile \ cae/Makefile \ - utils/Makefile \ - utils/rdalsaconfig/Makefile \ - utils/rdcheckcuts/Makefile \ - utils/rdcleandirs/Makefile \ - utils/rdclilogedit/Makefile \ - utils/rdcollect/Makefile \ - utils/rdconvert/Makefile \ - utils/rddbconfig/Makefile \ - utils/rddbmgr/Makefile \ - utils/rddelete/Makefile \ - utils/rddgimport/Makefile \ - utils/rddiscimport/Makefile \ - utils/rdexport/Makefile \ - utils/rdgen/Makefile \ - utils/rdgpimon/Makefile \ - utils/rdimport/Makefile \ - utils/rdmaint/Makefile \ - utils/rdmarkerset/Makefile \ - utils/rdpopup/Makefile \ - utils/rdpurgecasts/Makefile \ - utils/rdrender/Makefile \ - utils/rdsoftkeys/Makefile \ - utils/rmlsend/Makefile \ - utils/sas_shim/Makefile \ web/Makefile \ web/rdfeed/Makefile \ web/rdcastmanager/Makefile \ @@ -532,10 +508,51 @@ AC_CONFIG_FILES([rivendell.spec \ systemd/Makefile \ systemd/rivendell.service \ tests/Makefile \ + utils/Makefile \ + utils/rdalsaconfig/Makefile \ + utils/rdcheckcuts/Makefile \ + utils/rdcleandirs/Makefile \ + utils/rdclilogedit/Makefile \ + utils/rdcollect/Makefile \ + utils/rdconvert/Makefile \ + utils/rddbconfig/Makefile \ + utils/rddbmgr/Makefile \ + utils/rddelete/Makefile \ + utils/rddgimport/Makefile \ + utils/rddiscimport/Makefile \ + utils/rdexport/Makefile \ + utils/rdgen/Makefile \ + utils/rdgpimon/Makefile \ + utils/rdimport/Makefile \ + utils/rdmaint/Makefile \ + utils/rdmarkerset/Makefile \ + utils/rdpopup/Makefile \ + utils/rdpurgecasts/Makefile \ + utils/rdrender/Makefile \ + utils/rdselect_helper/Makefile \ + utils/rdsoftkeys/Makefile \ + utils/rmlsend/Makefile \ + utils/sas_shim/Makefile \ xdg/Makefile \ ]) AC_OUTPUT() +# +# Create symlinks in 'utils/rdselect_helper/' +# +rm -f utils/rdselect_helper/rd.h +ln -s ../../lib/rd.h utils/rdselect_helper/rd.h + +rm -f utils/rdselect_helper/rdconfig.cpp +ln -s ../../lib/rdconfig.cpp utils/rdselect_helper/rdconfig.cpp +rm -f utils/rdselect_helper/rdconfig.h +ln -s ../../lib/rdconfig.h utils/rdselect_helper/rdconfig.h + +rm -f utils/rdselect_helper/rdprofile.cpp +ln -s ../../lib/rdprofile.cpp utils/rdselect_helper/rdprofile.cpp +rm -f utils/rdselect_helper/rdprofile.h +ln -s ../../lib/rdprofile.h utils/rdselect_helper/rdprofile.h + # # Configuration Results # diff --git a/lib/Makefile.am b/lib/Makefile.am index 8c33f5bf..10ef2b30 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -192,8 +192,6 @@ dist_librd_la_SOURCES = dbversion.h\ rdpeaksexport.cpp rdpeaksexport.h\ rdpodcast.cpp rdpodcast.h\ rdprofile.cpp rdprofile.h\ - rdprofileline.cpp rdprofileline.h\ - rdprofilesection.cpp rdprofilesection.h\ rdpushbutton.cpp rdpushbutton.h\ rdrecording.cpp rdrecording.h\ rdrehash.cpp rdrehash.h\ diff --git a/lib/lib.pro b/lib/lib.pro index b10be77c..4e8b7366 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -129,8 +129,6 @@ SOURCES += rdpasswd.cpp SOURCES += rdplay_deck.cpp SOURCES += rdplaymeter.cpp SOURCES += rdprofile.cpp -SOURCES += rdprofileline.cpp -SOURCES += rdprofilesection.cpp SOURCES += rdpushbutton.cpp SOURCES += rdrecording.cpp SOURCES += rdrehash.cpp @@ -264,8 +262,6 @@ HEADERS += rdpasswd.h HEADERS += rdplay_deck.h HEADERS += rdplaymeter.h HEADERS += rdprofile.h -HEADERS += rdprofileline.h -HEADERS += rdprofilesection.h HEADERS += rdpushbutton.h HEADERS += rdrecording.h HEADERS += rdrehash.h diff --git a/lib/librd_cs.ts b/lib/librd_cs.ts index 5b858274..44357432 100644 --- a/lib/librd_cs.ts +++ b/lib/librd_cs.ts @@ -613,6 +613,62 @@ Could not re-establish DB connection + + Unknown error + + + + Invalid arguments specified + + + + Specified configuration was not found + + + + One or more Rivendell modules are active + + + + No running as root + + + + systemctl(8) crashed + + + + Rivendell service shutdown failed + + + + Audio store unmount failed + + + + Audio store mount failed + + + + Rivendell service startup failed + + + + Current configuration was not found + + + + Synlink creation failed + + + + Invalid configuration name + + + + mount(8) crashed + + RDAddCart diff --git a/lib/librd_de.ts b/lib/librd_de.ts index 3bc26aa5..77e68ddc 100644 --- a/lib/librd_de.ts +++ b/lib/librd_de.ts @@ -609,6 +609,62 @@ Could not re-establish DB connection + + Unknown error + + + + Invalid arguments specified + + + + Specified configuration was not found + + + + One or more Rivendell modules are active + + + + No running as root + + + + systemctl(8) crashed + + + + Rivendell service shutdown failed + + + + Audio store unmount failed + + + + Audio store mount failed + + + + Rivendell service startup failed + + + + Current configuration was not found + + + + Synlink creation failed + + + + Invalid configuration name + + + + mount(8) crashed + + RDAddCart diff --git a/lib/librd_es.ts b/lib/librd_es.ts index 9210ac4a..7e27c9aa 100644 --- a/lib/librd_es.ts +++ b/lib/librd_es.ts @@ -609,6 +609,62 @@ Could not re-establish DB connection + + Unknown error + + + + Invalid arguments specified + + + + Specified configuration was not found + + + + One or more Rivendell modules are active + + + + No running as root + + + + systemctl(8) crashed + + + + Rivendell service shutdown failed + + + + Audio store unmount failed + + + + Audio store mount failed + + + + Rivendell service startup failed + + + + Current configuration was not found + + + + Synlink creation failed + + + + Invalid configuration name + + + + mount(8) crashed + + RDAddCart diff --git a/lib/librd_fr.ts b/lib/librd_fr.ts index 6db1562a..529e1d7d 100644 --- a/lib/librd_fr.ts +++ b/lib/librd_fr.ts @@ -579,6 +579,62 @@ Could not re-establish DB connection + + Unknown error + + + + Invalid arguments specified + + + + Specified configuration was not found + + + + One or more Rivendell modules are active + + + + No running as root + + + + systemctl(8) crashed + + + + Rivendell service shutdown failed + + + + Audio store unmount failed + + + + Audio store mount failed + + + + Rivendell service startup failed + + + + Current configuration was not found + + + + Synlink creation failed + + + + Invalid configuration name + + + + mount(8) crashed + + RDAddCart diff --git a/lib/librd_nb.ts b/lib/librd_nb.ts index 1ea65cba..bba61085 100644 --- a/lib/librd_nb.ts +++ b/lib/librd_nb.ts @@ -609,6 +609,62 @@ Could not re-establish DB connection + + Unknown error + + + + Invalid arguments specified + + + + Specified configuration was not found + + + + One or more Rivendell modules are active + + + + No running as root + + + + systemctl(8) crashed + + + + Rivendell service shutdown failed + + + + Audio store unmount failed + + + + Audio store mount failed + + + + Rivendell service startup failed + + + + Current configuration was not found + + + + Synlink creation failed + + + + Invalid configuration name + + + + mount(8) crashed + + RDAddCart diff --git a/lib/librd_nn.ts b/lib/librd_nn.ts index 1ea65cba..bba61085 100644 --- a/lib/librd_nn.ts +++ b/lib/librd_nn.ts @@ -609,6 +609,62 @@ Could not re-establish DB connection + + Unknown error + + + + Invalid arguments specified + + + + Specified configuration was not found + + + + One or more Rivendell modules are active + + + + No running as root + + + + systemctl(8) crashed + + + + Rivendell service shutdown failed + + + + Audio store unmount failed + + + + Audio store mount failed + + + + Rivendell service startup failed + + + + Current configuration was not found + + + + Synlink creation failed + + + + Invalid configuration name + + + + mount(8) crashed + + RDAddCart diff --git a/lib/librd_pt_BR.ts b/lib/librd_pt_BR.ts index 99813b30..a9740271 100644 --- a/lib/librd_pt_BR.ts +++ b/lib/librd_pt_BR.ts @@ -609,6 +609,62 @@ Could not re-establish DB connection + + Unknown error + + + + Invalid arguments specified + + + + Specified configuration was not found + + + + One or more Rivendell modules are active + + + + No running as root + + + + systemctl(8) crashed + + + + Rivendell service shutdown failed + + + + Audio store unmount failed + + + + Audio store mount failed + + + + Rivendell service startup failed + + + + Current configuration was not found + + + + Synlink creation failed + + + + Invalid configuration name + + + + mount(8) crashed + + RDAddCart diff --git a/lib/rdconfig.cpp b/lib/rdconfig.cpp index b0d50ea4..602910a1 100644 --- a/lib/rdconfig.cpp +++ b/lib/rdconfig.cpp @@ -2,7 +2,7 @@ // // A container class for a Rivendell Base Configuration // -// (C) Copyright 2002-2004,2016-2018 Fred Gleason +// (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 @@ -29,12 +29,13 @@ #include #include +#include #include #include #include -#include -#include +#include "rdconfig.h" +#include "rdprofile.h" RDConfig *RDConfiguration(void) { @@ -495,7 +496,7 @@ QString RDConfig::destination(unsigned n) } -void RDConfig::load() +bool RDConfig::load() { char sname[256]; QString client; @@ -505,7 +506,9 @@ void RDConfig::load() struct group *groups; RDProfile *profile=new RDProfile(); - profile->setSource(conf_filename); + if(!profile->setSource(conf_filename)) { + return false; + } gethostname(sname,255); QStringList list=QString(sname).split("."); // Strip domain name parts strncpy(sname,list[0],256); @@ -630,7 +633,7 @@ void RDConfig::load() int sock=-1; if((sock=socket(PF_INET,SOCK_DGRAM,IPPROTO_IP))<0) { - return; + return true; } struct ifreq ifr; int index=0; @@ -648,6 +651,8 @@ void RDConfig::load() ifr.ifr_ifindex=++index; } close(sock); + + return true; } @@ -728,3 +733,72 @@ QString RDConfig::createTablePostfix(const QString &engine) { return QString(" engine ")+engine+" "; } + + +QString RDConfig::rdselectExitCodeText(RDSelectExitCode code) +{ + QString ret=QObject::tr("Unknown error")+QString().sprintf(" [%d]",code); + + switch(code) { + case RDConfig::RDSelectOk: + ret=QObject::tr("OK"); + break; + + case RDConfig::RDSelectInvalidArguments: + ret=QObject::tr("Invalid arguments specified"); + break; + + case RDConfig::RDSelectNoSuchConfiguration: + ret=QObject::tr("Specified configuration was not found"); + break; + + case RDConfig::RDSelectModulesActive: + ret=QObject::tr("One or more Rivendell modules are active"); + break; + + case RDConfig::RDSelectNotRoot: + ret=QObject::tr("No running as root"); + break; + + case RDConfig::RDSelectSystemctlCrashed: + ret=QObject::tr("systemctl(8) crashed"); + break; + + case RDConfig::RDSelectRivendellShutdownFailed: + ret=QObject::tr("Rivendell service shutdown failed"); + break; + + case RDConfig::RDSelectAudioUnmountFailed: + ret=QObject::tr("Audio store unmount failed"); + break; + + case RDConfig::RDSelectAudioMountFailed: + ret=QObject::tr("Audio store mount failed"); + break; + + case RDConfig::RDSelectRivendellStartupFailed: + ret=QObject::tr("Rivendell service startup failed"); + break; + + case RDConfig::RDSelectNoCurrentConfig: + ret=QObject::tr("Current configuration was not found"); + break; + + case RDConfig::RDSelectSymlinkFailed: + ret=QObject::tr("Synlink creation failed"); + break; + + case RDConfig::RDSelectInvalidName: + ret=QObject::tr("Invalid configuration name"); + break; + + case RDConfig::RDSelectMountCrashed: + ret=QObject::tr("mount(8) crashed"); + break; + + case RDConfig::RDSelectLast: + break; + } + + return ret; +} diff --git a/lib/rdconfig.h b/lib/rdconfig.h index 17b2e1b8..df7d6fcc 100644 --- a/lib/rdconfig.h +++ b/lib/rdconfig.h @@ -2,7 +2,7 @@ // // A container class for a Rivendell Base Configuration // -// (C) Copyright 2002-2004,2016-2017 Fred Gleason +// (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 @@ -38,7 +38,20 @@ class RDConfig enum LogPriority {LogEmerg=LOG_EMERG,LogAlert=LOG_ALERT,LogCrit=LOG_CRIT, LogErr=LOG_ERR,LogWarning=LOG_WARNING,LogNotice=LOG_NOTICE, LogInfo=LOG_INFO,LogDebug=LOG_DEBUG}; - + enum RDSelectExitCode {RDSelectOk=0,RDSelectInvalidArguments=1, + RDSelectNoSuchConfiguration=2, + RDSelectModulesActive=3, + RDSelectNotRoot=4, + RDSelectSystemctlCrashed=5, + RDSelectRivendellShutdownFailed=6, + RDSelectAudioUnmountFailed=7, + RDSelectAudioMountFailed=8, + RDSelectRivendellStartupFailed=9, + RDSelectNoCurrentConfig=10, + RDSelectSymlinkFailed=11, + RDSelectInvalidName=12, + RDSelectMountCrashed=13, + RDSelectLast=14}; RDConfig(); RDConfig(const QString &filename); QString filename() const; @@ -105,10 +118,11 @@ class RDConfig unsigned sasBaseCart() const; QString sasTtyDevice() const; QString destination(unsigned n); - void load(); + bool load(); void clear(); static QString userAgent(const QString &modname); static QString createTablePostfix(const QString &engine); + static QString rdselectExitCodeText(RDSelectExitCode code); private: QString conf_filename; diff --git a/lib/rdprofile.cpp b/lib/rdprofile.cpp index 04c99057..689a57eb 100644 --- a/lib/rdprofile.cpp +++ b/lib/rdprofile.cpp @@ -2,7 +2,7 @@ // // A class to read an ini formatted configuration file. // -// (C) Copyright 2002-2003,2016 Fred Gleason +// (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 Library General Public License @@ -22,7 +22,95 @@ #include #include -#include +#include "rdprofile.h" + +RDProfileLine::RDProfileLine() +{ + clear(); +} + + +QString RDProfileLine::tag() const +{ + return line_tag; +} + + +void RDProfileLine::setTag(QString tag) +{ + line_tag=tag; +} + + +QString RDProfileLine::value() const +{ + return line_value; +} + + +void RDProfileLine::setValue(QString value) +{ + line_value=value; +} + + +void RDProfileLine::clear() +{ + line_tag=""; + line_value=""; +} + + + + + +RDProfileSection::RDProfileSection() +{ + clear(); +} + + +QString RDProfileSection::name() const +{ + return section_name; +} + + +void RDProfileSection::setName(QString name) +{ + section_name=name; +} + + +bool RDProfileSection::getValue(QString tag,QString *value) const +{ + for(unsigned i=0;i +// (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 Library General Public License @@ -25,7 +25,41 @@ #include -#include +class RDProfileLine +{ + public: + RDProfileLine(); + QString tag() const; + void setTag(QString tag); + QString value() const; + void setValue(QString value); + void clear(); + + private: + QString line_tag; + QString line_value; +}; + + + + +class RDProfileSection +{ + public: + RDProfileSection(); + QString name() const; + void setName(QString name); + bool getValue(QString tag,QString *value) const; + void addValue(QString tag,QString value); + void clear(); + + private: + QString section_name; + std::vector section_line; +}; + + + /** * @short Implements an ini configuration file parser. diff --git a/lib/rdprofileline.cpp b/lib/rdprofileline.cpp deleted file mode 100644 index 5e8edeec..00000000 --- a/lib/rdprofileline.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// rdprofileline.cpp -// -// A container class for profile lines. -// -// (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 Library 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 - -RDProfileLine::RDProfileLine() -{ - clear(); -} - - -QString RDProfileLine::tag() const -{ - return line_tag; -} - - -void RDProfileLine::setTag(QString tag) -{ - line_tag=tag; -} - - -QString RDProfileLine::value() const -{ - return line_value; -} - - -void RDProfileLine::setValue(QString value) -{ - line_value=value; -} - - -void RDProfileLine::clear() -{ - line_tag=""; - line_value=""; -} diff --git a/lib/rdprofileline.h b/lib/rdprofileline.h deleted file mode 100644 index 7bdc948a..00000000 --- a/lib/rdprofileline.h +++ /dev/null @@ -1,42 +0,0 @@ -// rdprofileline.h -// -// A container class for profile lines. -// -// (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 Library 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 RDPROFILELINE_H -#define RDPROFILELINE_H - -#include - -class RDProfileLine -{ - public: - RDProfileLine(); - QString tag() const; - void setTag(QString tag); - QString value() const; - void setValue(QString value); - void clear(); - - private: - QString line_tag; - QString line_value; -}; - - -#endif // RDPROFILELINE_H diff --git a/lib/rdprofilesection.cpp b/lib/rdprofilesection.cpp deleted file mode 100644 index 1043b12f..00000000 --- a/lib/rdprofilesection.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// rdprofilesection.cpp -// -// A container class for profile sections. -// -// (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 Library 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 - -RDProfileSection::RDProfileSection() -{ - clear(); -} - - -QString RDProfileSection::name() const -{ - return section_name; -} - - -void RDProfileSection::setName(QString name) -{ - section_name=name; -} - - -bool RDProfileSection::getValue(QString tag,QString *value) const -{ - for(unsigned i=0;i -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU Library 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 RDPROFILESECTION_H -#define RDPROFILESECTION_H - -#include - -#include - -#include - -class RDProfileSection -{ - public: - RDProfileSection(); - QString name() const; - void setName(QString name); - bool getValue(QString tag,QString *value) const; - void addValue(QString tag,QString value); - void clear(); - - private: - QString section_name; - std::vector section_line; -}; - - -#endif // RDPROFILESECTION_H diff --git a/rdselect/Makefile.am b/rdselect/Makefile.am index dee4049d..8d44f531 100644 --- a/rdselect/Makefile.am +++ b/rdselect/Makefile.am @@ -30,7 +30,6 @@ moc_%.cpp: %.h install-exec-hook: mkdir -p $(DESTDIR)$(prefix)/share/rivendell cp rdselect_*.qm $(DESTDIR)$(prefix)/share/rivendell - chmod 4755 $(DESTDIR)$(prefix)/bin/rdselect uninstall-local: rm -f $(DESTDIR)$(prefix)/share/rivendell/rdselect_*.qm diff --git a/rdselect/rdselect.cpp b/rdselect/rdselect.cpp index a9f63f11..946b10db 100644 --- a/rdselect/rdselect.cpp +++ b/rdselect/rdselect.cpp @@ -26,22 +26,24 @@ #include #include -#include -#include -#include +#include +#include #include +#include +#include +#include #include #include -#include -#include +#include #include #include #include +#include #include #include -#include +#include "rdselect.h" // // Icons @@ -195,13 +197,14 @@ MainWidget::MainWidget(QWidget *parent) // // Check for Root User // - + /* setuid(geteuid()); // So the SETUID bit works as expected if(getuid()!=0) { QMessageBox::information(this,tr("RDSelect"), tr("Only root can run this utility!")); exit(256); } + */ } @@ -225,28 +228,30 @@ void MainWidget::doubleClickedData(Q3ListBoxItem *item) void MainWidget::okData() { - if(RDModulesActive()) { - QMessageBox::information(this,tr("RDSelect"), - tr("One or more Rivendell modules are still open.")); - return; - } + QStringList args; + QProcess *proc=NULL; - if(!VerifyShutdown()) { + QStringList f0=select_configs[select_box->currentItem()]->filename(). + split("/",QString::SkipEmptyParts); + args.push_back(f0.last()); + proc=new QProcess(this); + proc->start(QString(RD_PREFIX)+"/bin/rdselect_helper",args); + proc->waitForFinished(); + if(proc->exitStatus()!=QProcess::NormalExit) { + QMessageBox::critical(this,"RDSelect - "+tr("Error"), + tr("RDSelect helper process crashed!")); + delete proc; return; } - if(!Shutdown(select_current_id)) { - SetSystem(-1); - QMessageBox::warning(this,tr("RDSelect"), - tr("Unable to shutdown current configuration")+ - "\n["+QString(strerror(errno))+"]."); + if(proc->exitCode()!=0) { + QMessageBox::critical(this,"RDSelect - "+tr("Error"), + tr("Unable to select configuration:")+"\n"+ + RDConfig::rdselectExitCodeText((RDConfig::RDSelectExitCode)proc->exitCode())); + delete proc; return; } - if(!Startup(select_box->currentItem())) { - SetSystem(-1); - QMessageBox::warning(this,tr("RDSelect"), - tr("Unable to start up new configuration")); - } - SetSystem(select_box->currentItem()); + delete proc; + exit(0); } @@ -267,47 +272,6 @@ void MainWidget::resizeEvent(QResizeEvent *e) } -bool MainWidget::Shutdown(int id) -{ - RDConfig *conf=select_configs[id]; - - if(system("systemctl stop rivendell")!=0) { - return false; - } - system(QString("umount ")+conf->audioRoot()); - - return true; -} - - -bool MainWidget::Startup(int id) -{ - RDConfig *conf=select_configs[id]; - - if(!conf->audioStoreMountSource().isEmpty()) { - QString cmd=QString("mount"); - if(!conf->audioStoreMountType().isEmpty()) { - cmd+=" -t "+conf->audioStoreMountType(); - } - if(!conf->audioStoreMountOptions().isEmpty()) { - cmd+=" -o "+conf->audioStoreMountOptions(); - } - cmd+=" "+conf->audioStoreMountSource()+" "+ - conf->audioRoot(); - if(system(cmd)!=0) { - return false; - } - } - unlink(RD_CONF_FILE); - symlink(select_filenames[id],RD_CONF_FILE); - if(system("systemctl start rivendell")!=0) { - return false; - } - - return true; -} - - void MainWidget::SetSystem(int id) { QString text=tr("None"); @@ -319,12 +283,6 @@ void MainWidget::SetSystem(int id) } -bool MainWidget::VerifyShutdown() const -{ - return true; -} - - void MainWidget::SetCurrentItem(int id) { QPixmap *pix=redx_map; diff --git a/rdselect/rdselect.h b/rdselect/rdselect.h index cbab3c04..025e06cd 100644 --- a/rdselect/rdselect.h +++ b/rdselect/rdselect.h @@ -52,10 +52,7 @@ class MainWidget : public QWidget void resizeEvent(QResizeEvent *e); private: - bool Shutdown(int id); - bool Startup(int id); void SetSystem(int id); - bool VerifyShutdown() const; void SetCurrentItem(int id); std::vector select_configs; QStringList select_filenames; diff --git a/rdselect/rdselect_cs.ts b/rdselect/rdselect_cs.ts index 54892ed6..532a83ff 100644 --- a/rdselect/rdselect_cs.ts +++ b/rdselect/rdselect_cs.ts @@ -9,7 +9,7 @@ RDSelect - RDSelect + RDSelect None @@ -29,19 +29,31 @@ Only root can run this utility! - Pouze superuživatel (root) může spouštět tento program! + Pouze superuživatel (root) může spouštět tento program! Unable to shutdown current configuration - Nelze vypnout nynější nastavení + Nelze vypnout nynější nastavení Unable to start up new configuration - Nelze spustit nové nastavení + Nelze spustit nové nastavení One or more Rivendell modules are still open. - Jeden nebo více modulů Rivendell je stále ještě otevřeno. + Jeden nebo více modulů Rivendell je stále ještě otevřeno. + + + Error + + + + RDSelect helper process crashed! + + + + Unable to select configuration: + diff --git a/rdselect/rdselect_de.ts b/rdselect/rdselect_de.ts index 781d5fa3..8a3137e1 100644 --- a/rdselect/rdselect_de.ts +++ b/rdselect/rdselect_de.ts @@ -7,10 +7,6 @@ &Cancel - - RDSelect - - None @@ -28,19 +24,15 @@ - Only root can run this utility! + Error - Unable to shutdown current configuration + RDSelect helper process crashed! - Unable to start up new configuration - - - - One or more Rivendell modules are still open. + Unable to select configuration: diff --git a/rdselect/rdselect_es.ts b/rdselect/rdselect_es.ts index 781d5fa3..8a3137e1 100644 --- a/rdselect/rdselect_es.ts +++ b/rdselect/rdselect_es.ts @@ -7,10 +7,6 @@ &Cancel - - RDSelect - - None @@ -28,19 +24,15 @@ - Only root can run this utility! + Error - Unable to shutdown current configuration + RDSelect helper process crashed! - Unable to start up new configuration - - - - One or more Rivendell modules are still open. + Unable to select configuration: diff --git a/rdselect/rdselect_fr.ts b/rdselect/rdselect_fr.ts index 781d5fa3..8a3137e1 100644 --- a/rdselect/rdselect_fr.ts +++ b/rdselect/rdselect_fr.ts @@ -7,10 +7,6 @@ &Cancel - - RDSelect - - None @@ -28,19 +24,15 @@ - Only root can run this utility! + Error - Unable to shutdown current configuration + RDSelect helper process crashed! - Unable to start up new configuration - - - - One or more Rivendell modules are still open. + Unable to select configuration: diff --git a/rdselect/rdselect_nb.ts b/rdselect/rdselect_nb.ts index 781d5fa3..8a3137e1 100644 --- a/rdselect/rdselect_nb.ts +++ b/rdselect/rdselect_nb.ts @@ -7,10 +7,6 @@ &Cancel - - RDSelect - - None @@ -28,19 +24,15 @@ - Only root can run this utility! + Error - Unable to shutdown current configuration + RDSelect helper process crashed! - Unable to start up new configuration - - - - One or more Rivendell modules are still open. + Unable to select configuration: diff --git a/rdselect/rdselect_nn.ts b/rdselect/rdselect_nn.ts index 781d5fa3..8a3137e1 100644 --- a/rdselect/rdselect_nn.ts +++ b/rdselect/rdselect_nn.ts @@ -7,10 +7,6 @@ &Cancel - - RDSelect - - None @@ -28,19 +24,15 @@ - Only root can run this utility! + Error - Unable to shutdown current configuration + RDSelect helper process crashed! - Unable to start up new configuration - - - - One or more Rivendell modules are still open. + Unable to select configuration: diff --git a/rdselect/rdselect_pt_BR.ts b/rdselect/rdselect_pt_BR.ts index 781d5fa3..8a3137e1 100644 --- a/rdselect/rdselect_pt_BR.ts +++ b/rdselect/rdselect_pt_BR.ts @@ -7,10 +7,6 @@ &Cancel - - RDSelect - - None @@ -28,19 +24,15 @@ - Only root can run this utility! + Error - Unable to shutdown current configuration + RDSelect helper process crashed! - Unable to start up new configuration - - - - One or more Rivendell modules are still open. + Unable to select configuration: diff --git a/rivendell.spec.in b/rivendell.spec.in index 2a93057c..90e310c1 100644 --- a/rivendell.spec.in +++ b/rivendell.spec.in @@ -465,7 +465,8 @@ rm -rf $RPM_BUILD_ROOT %files select -%attr(4755,root,root) @LOCAL_PREFIX@/bin/rdselect +@LOCAL_PREFIX@/bin/rdselect +%attr(4755,root,root) @LOCAL_PREFIX@/bin/rdselect_helper @LOCAL_PREFIX@/bin/rdmonitor /etc/X11/xinit/xinitrc.d/start-rdmonitor.sh diff --git a/utils/Makefile.am b/utils/Makefile.am index 4762b9ff..dd6dbc15 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -43,6 +43,7 @@ SUBDIRS = $(ALSACONFIG_RD_OPT)\ rdpopup\ rdpurgecasts\ rdrender\ + rdselect_helper\ rdsoftkeys\ rmlsend\ sas_shim diff --git a/utils/rdselect_helper/Makefile.am b/utils/rdselect_helper/Makefile.am new file mode 100644 index 00000000..91228e31 --- /dev/null +++ b/utils/rdselect_helper/Makefile.am @@ -0,0 +1,55 @@ +## Makefile.am +## +## (C) Copyright 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)\" @QT4_CFLAGS@ +MOC = @QT_MOC@ + +# The dependency for qt's Meta Object Compiler (moc) +moc_%.cpp: %.h + $(MOC) $< -o $@ + +install-exec-hook: + chmod 4755 $(DESTDIR)$(prefix)/bin/rdselect_helper + +bin_PROGRAMS = rdselect_helper + +dist_rdselect_helper_SOURCES = rdselect_helper.cpp rdselect_helper.h + +nodist_rdselect_helper_SOURCES = moc_rdselect_helper.cpp\ + rd.h\ + rdconfig.cpp rdconfig.h\ + rdprofile.cpp rdprofile.h + +rdselect_helper_LDADD = -lQtCore -lQtNetwork -lQt3Support + +CLEANFILES = *~\ + *.idb\ + *ilk\ + *.obj\ + *.pdb\ + *.qm\ + moc_* + +DISTCLEANFILES = rd.h\ + rdconfig.cpp rdconfig.h\ + rdprofile.cpp rdprofile.h + +MAINTAINERCLEANFILES = *~\ + Makefile.in\ + moc_* diff --git a/utils/rdselect_helper/rdselect_helper.cpp b/utils/rdselect_helper/rdselect_helper.cpp new file mode 100644 index 00000000..b5de7f5c --- /dev/null +++ b/utils/rdselect_helper/rdselect_helper.cpp @@ -0,0 +1,258 @@ +// rdselect_help.cpp +// +// SETUID helper script for rdselect(1) +// +// (C) Copyright 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 "rd.h" +#include "rdselect_helper.h" + +MainObject::MainObject(QObject *parent) + : QObject(parent) +{ + setuid(geteuid()); // So the SETUID bit works as expected + if(getuid()!=0) { + fprintf(stderr, + "rdselect_helper: this program must be installed SETUID root\n"); + exit(RDConfig::RDSelectNotRoot); + } + + // + // Process argument + // + if(qApp->argc()!=2) { + fprintf(stderr,"rdselect_helper: you must pass exactly one argument\n"); + exit(RDConfig::RDSelectInvalidArguments); + } + if(QString(qApp->argv()[1]).contains("/")|| + QString(qApp->argv()[1]).contains("..")) { + fprintf(stderr,"rdselect_helper: invalid configuration name\n"); + exit(RDConfig::RDSelectInvalidName); + } + helper_config_filename= + QString(RD_DEFAULT_RDSELECT_DIR)+"/"+QString(qApp->argv()[1]); + + // + // Load Configurations + // + helper_config=new RDConfig(); + helper_config->setFilename(helper_config_filename); + if(!helper_config->load()) { + fprintf(stderr,"rdselect_helper: no such configuration\n"); + exit(RDConfig::RDSelectNoSuchConfiguration); + } + helper_prev_config=new RDConfig(); + if(!helper_prev_config->load()) { + fprintf(stderr,"rdselect_helper: no current configuration found\n"); + exit(RDConfig::RDSelectNoCurrentConfig); + } + + // + // Check system state + // + if(ModulesActive()) { + fprintf(stderr,"rdselect_helper: one or more rivendell modules active\n"); + exit(RDConfig::RDSelectModulesActive); + } + + // + // Shutdown old setup + // + Shutdown(); + + // + // Startup new setup + // + Startup(); + + exit(RDConfig::RDSelectOk); +} + + +void MainObject::Startup() +{ + QStringList args; + QProcess *proc=NULL; + + // + // Mount the audio store + // + if(!helper_config->audioStoreMountSource().isEmpty()) { + args.clear(); + if(!helper_config->audioStoreMountType().isEmpty()) { + args.push_back("-t"); + args.push_back(helper_config->audioStoreMountType()); + } + args.push_back("-o"); + if(helper_config->audioStoreMountOptions().isEmpty()) { + args.push_back("defaults"); + } + else { + args.push_back(helper_config->audioStoreMountOptions()); + } + args.push_back(helper_config->audioStoreMountSource()); + args.push_back(helper_config->audioRoot()); + proc=new QProcess(this); + proc->start("/bin/mount",args); + proc->waitForFinished(); + if(proc->exitStatus()!=QProcess::NormalExit) { + fprintf(stderr,"rdselect_helper: mount(8) command crashed\n"); + exit(RDConfig::RDSelectMountCrashed); + } + if(proc->exitCode()!=0) { + fprintf(stderr,"rdselect_helper: mount exited with error code %d\n", + proc->exitCode()); + exit(RDConfig::RDSelectAudioMountFailed); + } + delete proc; + } + + // + // Start the rivendell service + // + unlink(RD_CONF_FILE); + if(symlink(helper_config_filename,RD_CONF_FILE)!=0) { + fprintf(stderr,"rdselect_helper: unable to create new symlink [%s]\n", + strerror(errno)); + exit(RDConfig::RDSelectSymlinkFailed); + } + args.clear(); + args.push_back("start"); + args.push_back("rivendell"); + proc=new QProcess(this); + proc->start("/bin/systemctl",args); + proc->waitForFinished(); + if(proc->exitStatus()!=QProcess::NormalExit) { + fprintf(stderr,"rdselect_helper: systemctl(8) crashed\n"); + exit(RDConfig::RDSelectSystemctlCrashed); + } + if(proc->exitCode()!=0) { + fprintf(stderr,"rdselect_helper: rivendell service start failed\n"); + exit(RDConfig::RDSelectRivendellStartupFailed); + } + delete proc; +} + + +void MainObject::Shutdown() +{ + QStringList args; + + // + // Stop Rivendell Service + // + args.push_back("stop"); + args.push_back("rivendell"); + QProcess *proc=new QProcess(this); + proc->start("/bin/systemctl",args); + proc->waitForFinished(); + if(proc->exitStatus()!=QProcess::NormalExit) { + fprintf(stderr,"rdselect_helper: systemctl(8) crashed\n"); + exit(RDConfig::RDSelectSystemctlCrashed); + } + if(proc->exitCode()!=0) { + fprintf(stderr,"rdselect_helper: rivendell service shutdown failed\n"); + exit(RDConfig::RDSelectRivendellShutdownFailed); + } + delete proc; + + // + // Unmount the audio store + // + if(umount(helper_prev_config->audioRoot())!=0) { + if(errno!=EINVAL) { // Ignore the error if we're already unmounted + fprintf(stderr,"rdselect_helper: unmount of \"%s\" failed [%s]\n", + (const char *)helper_prev_config->audioRoot(), + strerror(errno)); + exit(RDConfig::RDSelectAudioUnmountFailed); + } + } +} + + +bool MainObject::ProcessActive(const QStringList &cmds) const +{ + QStringList dirs; + QDir *proc_dir=new QDir("/proc"); + bool ok=false; + FILE *f=NULL; + char line[1024]; + QString cmdline; + + proc_dir->setFilter(QDir::Dirs); + dirs=proc_dir->entryList(); + for(int i=0;i +// +// 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 RDSELECT_HELPER_H +#define RDSELECT_HELPER_H + +#include +#include + +#include +#include + +#include "rdconfig.h" + +class MainObject : public QObject +{ + Q_OBJECT; + public: + MainObject(QObject *parent=0); + + private: + void Startup(); + void Shutdown(); + bool ProcessActive(const QStringList &cmds) const; + bool ModulesActive() const; + QString helper_config_filename; + RDConfig *helper_config; + RDConfig *helper_prev_config; +}; + + +#endif // RDSELECT_HELPER_H