diff --git a/ChangeLog b/ChangeLog index cb18e308..e1c23c86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16480,3 +16480,6 @@ 2017-12-13 Fred Gleason * Added a 'Backing Up and Restoring the Database' section to the Operations Guide. +2017-12-14 Fred Gleason + * Added an 'RDTempDirectory' class. + * Fixed a race in the 'Export' Web API call. diff --git a/lib/Makefile.am b/lib/Makefile.am index ab2c2e25..669fda28 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -219,6 +219,7 @@ dist_librd_la_SOURCES = dbversion.h\ rdsvc.cpp rdsvc.h\ rdsystem.cpp rdsystem.h\ rdsystemuser.cpp rdsystemuser.h\ + rdtempdirectory.cpp rdtempdirectory.h\ rdtextfile.cpp rdtextfile.h\ rdtextvalidator.cpp rdtextvalidator.h\ rdtimeedit.cpp rdtimeedit.h\ diff --git a/lib/lib.pro b/lib/lib.pro index 8b0e91fe..46497f34 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -108,6 +108,7 @@ SOURCES += rdstation.cpp SOURCES += rdstereometer.cpp SOURCES += rdsvc.cpp SOURCES += rdsystem.cpp +SOURCES += rdtempdirectory.cpp SOURCES += rdtextfile.cpp SOURCES += rdtextvalidator.cpp SOURCES += rdtimeedit.cpp @@ -248,6 +249,7 @@ HEADERS += rdstation.h HEADERS += rdstereometer.h HEADERS += rdsvc.h HEADERS += rdsystem.h +HEADERS += rdtempdirectory.h HEADERS += rdtextfile.h HEADERS += rdtextvalidator.h HEADERS += rdtimeedit.h diff --git a/lib/rdtempdirectory.cpp b/lib/rdtempdirectory.cpp new file mode 100644 index 00000000..449fd555 --- /dev/null +++ b/lib/rdtempdirectory.cpp @@ -0,0 +1,97 @@ +// rdtempdirectory.cpp +// +// Securely create and then remove a temporary directory +// +// (C) Copyright 2017 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 "rdconfig.h" +#include "rdtempdirectory.h" + +RDTempDirectory::RDTempDirectory(const QString &base_name) +{ + temp_base_name=base_name; + temp_dir=NULL; +} + + +RDTempDirectory::~RDTempDirectory() +{ + if(temp_dir!=NULL) { + QStringList files=temp_dir->entryList(QDir::Files); + for(unsigned i=0;iremove(files[i]); + } + rmdir(temp_dir->path()); + delete temp_dir; + } +} + + +QString RDTempDirectory::path() const +{ + if(temp_dir==NULL) { + return QString(); + } + return temp_dir->path(); +} + + +bool RDTempDirectory::create(QString *err_msg) +{ + char tempdir[PATH_MAX]; + + strncpy(tempdir,RDTempDirectory::basePath(),PATH_MAX); + strncat(tempdir,"/",PATH_MAX-strlen(tempdir)); + strncat(tempdir,temp_base_name,PATH_MAX-strlen(tempdir)); + strncat(tempdir,"XXXXXX",PATH_MAX-strlen(tempdir)); + if(mkdtemp(tempdir)==NULL) { + *err_msg=strerror(errno); + return false; + } + temp_dir=new QDir(tempdir); + + return true; +} + + +QString RDTempDirectory::basePath() +{ + QString conf_temp_directory = RDConfiguration()->tempDirectory(); + if (!conf_temp_directory.isEmpty()) { + return conf_temp_directory; + } +#ifdef WIN32 + if(getenv("TEMP")!=NULL) { + return QString(getenv("TEMP")); + } + if(getenv("TMP")!=NULL) { + return QString(getenv("TMP")); + } + return QString("C:\\"); +#else + if(getenv("TMPDIR")!=NULL) { + return QString(getenv("TMPDIR")); + } + return QString("/tmp"); +#endif // WIN32 +} diff --git a/lib/rdtempdirectory.h b/lib/rdtempdirectory.h new file mode 100644 index 00000000..29aee396 --- /dev/null +++ b/lib/rdtempdirectory.h @@ -0,0 +1,42 @@ +// rdtempdirectory.h +// +// Securely create and then remove a temporary directory +// +// (C) Copyright 2017 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 RDTEMPDIRECTORY_H +#define RDTEMPDIRECTORY_H + +#include +#include + +class RDTempDirectory +{ + public: + RDTempDirectory(const QString &base_name); + ~RDTempDirectory(); + QString path() const; + bool create(QString *err_msg); + static QString basePath(); + + private: + QString temp_base_name; + QDir *temp_dir; +}; + + +#endif // RDTEMPDIRECTORY_H diff --git a/web/rdxport/export.cpp b/web/rdxport/export.cpp index 4b095b5a..85c496f1 100644 --- a/web/rdxport/export.cpp +++ b/web/rdxport/export.cpp @@ -2,7 +2,7 @@ // // Rivendell web service portal -- Export service // -// (C) Copyright 2010-2015 Fred Gleason +// (C) Copyright 2010-2017 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 @@ -24,14 +24,15 @@ #include #include -#include -#include -#include #include -#include +#include #include +#include +#include +#include +#include -#include +#include "rdxport.h" void Xport::Export() { @@ -138,8 +139,12 @@ void Xport::Export() int fd; ssize_t n; uint8_t data[2048]; - QString tmpdir=RDTempDir(); - QString tmpfile=tmpdir+"/exported_audio"; + QString err_msg; + RDTempDirectory *tempdir=new RDTempDirectory("rdxport-export"); + if(!tempdir->create(&err_msg)) { + XmlExit("unable to create temporary directory ["+err_msg+"]",500); + } + QString tmpfile=tempdir->path()+"/exported_audio"; RDAudioConvert *conv=new RDAudioConvert(xport_config->stationName()); conv->setSourceFile(RDCut::pathName(cartnum,cutnum)); conv->setDestinationFile(tmpfile); @@ -179,7 +184,8 @@ void Xport::Export() } close(fd); unlink(tmpfile); - rmdir(tmpdir); + // rmdir(tmpdir); + delete tempdir; Exit(0); break; @@ -208,8 +214,7 @@ void Xport::Export() if(wavedata!=NULL) { delete wavedata; } - unlink(tmpfile); - rmdir(tmpdir); + delete tempdir; if(resp_code==200) { Exit(200); }