2022-11-16 Fred Gleason <fredg@paravelsystems.com>

* Added a 'QString *err_msg' argument to 'RDDownload::runDownload()'.
	* Added a 'QString *err_msg' argument to 'RDDownload::runUpload()'.
	* Fixed regression in rdcatch(1) that caused upload and download
	events to fail to show exit status correctly.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason 2022-11-16 15:31:40 -05:00
parent 63121ab15d
commit 7beec8dba1
13 changed files with 126 additions and 187 deletions

View File

@ -23691,3 +23691,8 @@
* Fixed a typo in 'lib/rdcut.cpp' that broke cut copy/pasting.
2022-11-15 Fred Gleason <fredg@paravelsystems.com>
* Fixed a regression in rdcatchd(8) that broke download events.
2022-11-16 Fred Gleason <fredg@paravelsystems.com>
* Added a 'QString *err_msg' argument to 'RDDownload::runDownload()'.
* Added a 'QString *err_msg' argument to 'RDDownload::runUpload()'.
* Fixed regression in rdcatch(1) that caused upload and download
events to fail to show exit status correctly.

View File

@ -2,7 +2,7 @@
//
// Download a File
//
// (C) Copyright 2010-2021 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2010-2022 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -116,6 +116,7 @@ RDDownload::ErrorCode RDDownload::runDownload(const QString &username,
const QString &password,
const QString &id_filename,
bool use_id_filename,
QString *curl_err_msg,
bool log_debug)
{
CURL *curl=NULL;
@ -231,6 +232,7 @@ RDDownload::ErrorCode RDDownload::runDownload(const QString &username,
curl_err,curl_easy_strerror(curl_err));
ret=RDDownload::ErrorUnspecified;
}
*curl_err_msg=curl_easy_strerror(curl_err);
if(user!=NULL) {
RDCheckExitCode("RDDownload::runDownload seteuid",seteuid(getuid()));
RDCheckExitCode("RDDownload::runDownload getgid",setegid(getgid()));

View File

@ -2,7 +2,7 @@
//
// Download a File
//
// (C) Copyright 2010-2020 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2010-2022 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -45,6 +45,7 @@ class RDDownload : public RDTransfer
const QString &password,
const QString &id_filename,
bool use_id_filename,
QString *curl_err_msg,
bool log_debug);
bool aborting() const;
static QString errorText(RDDownload::ErrorCode err);

View File

@ -116,6 +116,7 @@ RDUpload::ErrorCode RDUpload::runUpload(const QString &username,
const QString &password,
const QString &id_filename,
bool use_id_filename,
QString *err_msg,
bool log_debug)
{
CURL *curl=NULL;
@ -238,6 +239,7 @@ RDUpload::ErrorCode RDUpload::runUpload(const QString &username,
ret=RDUpload::ErrorUnspecified;
break;
}
*err_msg=curl_easy_strerror(curl_err);
if(user!=NULL) {
RDCheckExitCode("RDUpload::runUpload seteuid",seteuid(getuid()));
RDCheckExitCode("RDUpload::runUpload setegid",setegid(getgid()));

View File

@ -44,6 +44,7 @@ class RDUpload : public RDTransfer
const QString &password,
const QString &id_filename,
bool use_id_filename,
QString *err_msg,
bool log_debug);
bool aborting() const;
static QString errorText(RDUpload::ErrorCode err);

View File

@ -306,8 +306,8 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
catch_recordings_model->setFont(defaultFont());
catch_recordings_model->setPalette(palette());
connect(rda->ripc(),SIGNAL(notificationReceived(RDNotification *)),
catch_recordings_model
,SLOT(notificationReceivedData(RDNotification *)));
catch_recordings_model,
SLOT(notificationReceivedData(RDNotification *)));
catch_recordings_view->setModel(catch_recordings_model);
catch_recordings_view->setSortingEnabled(true);
catch_recordings_view->sortByColumn(2,Qt::AscendingOrder);
@ -654,7 +654,7 @@ void MainWidget::ripcUserData()
void MainWidget::catchEventReceivedData(RDCatchEvent *evt)
{
// printf("catchEventReceivedData()\n");
// printf("%s\n",evt->dump().toUtf8().constData());
// printf("CatchEvent: %s\n",evt->dump().toUtf8().constData());
switch(evt->operation()) {
case RDCatchEvent::DeckStatusResponseOp:

View File

@ -57,8 +57,15 @@
void MainObject::userChangedData()
{
QString err_msg;
disconnect(rda,SIGNAL(userChanged()),this,SLOT(userChangedData()));
//
// Create RDCatchConf
//
catch_conf=new RDCatchConf(rda->config()->stationName());
//
// Dispatch Handler
//
@ -70,13 +77,27 @@ void MainObject::userChangedData()
break;
case RDRecording::Download:
RunDownload(batch_event);
SendNotification(RDNotification::CartType,RDNotification::ModifyAction,
RDCut::cartNumber(batch_event->cutName()));
if(RunDownload(batch_event,&err_msg)) {
WriteExitCode(batch_event,RDRecording::Ok,"OK");
SendEventResponse(0,RDDeck::Idle,batch_event->id(),"");
SendNotification(RDNotification::CartType,RDNotification::ModifyAction,
RDCut::cartNumber(batch_event->cutName()));
}
else {
WriteExitCode(batch_event,RDRecording::ServerError,err_msg);
SendEventResponse(0,RDDeck::Offline,batch_event->id(),"");
}
break;
case RDRecording::Upload:
RunUpload(batch_event);
if(RunUpload(batch_event,&err_msg)) {
WriteExitCode(batch_event,RDRecording::Ok,"OK");
SendEventResponse(0,RDDeck::Idle,batch_event->id(),"");
}
else {
WriteExitCode(batch_event,RDRecording::ServerError,err_msg);
SendEventResponse(0,RDDeck::Offline,batch_event->id(),"");
}
break;
default:
@ -159,13 +180,15 @@ void MainObject::RunBatch(RDCmdSwitch *cmd)
void MainObject::RunImport(CatchEvent *evt)
{
QString err_msg;
evt->setTempName(GetTempRecordingName(evt->id()));
evt->setDeleteTempFile(true);
Import(evt);
Import(evt,&err_msg);
}
void MainObject::RunDownload(CatchEvent *evt)
bool MainObject::RunDownload(CatchEvent *evt,QString *err_msg)
{
RDDownload::ErrorCode conv_err;
@ -196,54 +219,45 @@ void MainObject::RunDownload(CatchEvent *evt)
url_username=RD_ANON_FTP_USERNAME;
url_password=QString(RD_ANON_FTP_PASSWORD)+"-"+VERSION;
}
switch((conv_err=conv->runDownload(url_username,url_password,id_filename,
evt->useSshIdentity(),
rda->config()->logXloadDebugData()))) {
case RDDownload::ErrorOk:
conv_err=conv->runDownload(url_username,url_password,id_filename,
evt->useSshIdentity(),err_msg,
rda->config()->logXloadDebugData());
if(conv_err==RDDownload::ErrorOk) {
rda->syslog(LOG_INFO,"finished download of %s to %s, id=%d",
(const char *)evt->tempName().toUtf8(),
(const char *)evt->resolvedUrl().toUtf8(),
evt->tempName().toUtf8().constData(),
evt->resolvedUrl().toUtf8().constData(),
evt->id());
break;
case RDDownload::ErrorInternal:
qApp->processEvents();
}
else {
rda->syslog(LOG_WARNING,"download of %s returned an error: \"%s\", id=%d",
(const char *)evt->tempName().toUtf8(),
(const char *)RDDownload::errorText(conv_err).toUtf8(),
evt->tempName().toUtf8().constData(),
RDDownload::errorText(conv_err).toUtf8().constData(),
evt->id());
delete conv;
unlink(evt->tempName().toUtf8());
exit(0);
default:
WriteExitCode(evt,RDRecording::ServerError,RDDownload::errorText(conv_err));
qApp->processEvents();
rda->syslog(LOG_WARNING,"download of %s returned an error: \"%s\", id=%d",
(const char *)evt->tempName().toUtf8(),
(const char *)RDDownload::errorText(conv_err).toUtf8(),
evt->id());
delete conv;
unlink(evt->tempName().toUtf8());
exit(0);
return false;
}
delete conv;
//
// Execute Import
//
if(Import(evt)) {
WriteExitCode(evt,RDRecording::Ok,tr("OK"));
qApp->processEvents();
bool imported=Import(evt,err_msg);
if(imported) {
rda->syslog(LOG_NOTICE,"HERE1!");
}
else {
rda->syslog(LOG_NOTICE,"HERE2!");
}
rda->syslog(LOG_INFO,"deleting file %s, id=%d",
(const char *)evt->tempName().toUtf8(),evt->id());
evt->tempName().toUtf8().constData(),evt->id());
unlink(evt->tempName().toUtf8());
WriteExitCode(evt,RDRecording::Ok,"OK");
return imported;
}
void MainObject::RunUpload(CatchEvent *evt)
bool MainObject::RunUpload(CatchEvent *evt,QString *err_msg)
{
RDUpload::ErrorCode conv_err;
@ -261,26 +275,24 @@ void MainObject::RunUpload(CatchEvent *evt)
evt->setTempName(BuildTempName(evt,"upload"));
evt->setDeleteTempFile(true);
rda->syslog(LOG_INFO,"started export of cut %s to %s, id=%d",
(const char *)evt->cutName().toUtf8(),
(const char *)evt->tempName().toUtf8(),evt->id());
if(!Export(evt)) {
evt->cutName().toUtf8().constData(),
evt->tempName().toUtf8().constData(),evt->id());
if(!Export(evt,err_msg)) {
rda->syslog(LOG_WARNING,"export of cut %s returned an error, id=%d",
(const char *)evt->cutName().toUtf8(),
evt->cutName().toUtf8().constData(),
evt->id());
WriteExitCode(batch_event,RDRecording::InternalError,tr("Export Error"));
qApp->processEvents();
return;
return false;
}
rda->syslog(LOG_INFO,"finished export of cut %s to %s, id=%d",
(const char *)evt->cutName().toUtf8(),
(const char *)evt->tempName().toUtf8(),evt->id());
evt->cutName().toUtf8().constData(),
evt->tempName().toUtf8().constData(),evt->id());
//
// Execute Upload
//
rda->syslog(LOG_INFO,"starting upload of %s to %s, id=%d",
(const char *)evt->tempName().toUtf8(),
(const char *)evt->resolvedUrl().toUtf8(),
evt->tempName().toUtf8().constData(),
evt->resolvedUrl().toUtf8().constData(),
evt->id());
RDUpload *conv=new RDUpload(rda->config(),this);
@ -297,38 +309,23 @@ void MainObject::RunUpload(CatchEvent *evt)
conv_err=conv->runUpload(url_username,url_password,id_filename,
evt->useSshIdentity(),
evt->useSshIdentity(),err_msg,
rda->config()->logXloadDebugData());
rda->syslog(LOG_NOTICE,"CONV_ERR: %u",conv_err);
switch(conv_err) {
case RDUpload::ErrorOk:
WriteExitCode(batch_event,RDRecording::Ok,tr("Ok"));
qApp->processEvents();
if(conv_err==RDUpload::ErrorOk) {
rda->syslog(LOG_INFO,"finished upload of %s to %s, id=%d",
(const char *)evt->tempName().toUtf8(),
(const char *)evt->resolvedUrl().toUtf8(),
evt->id());
break;
case RDUpload::ErrorInternal:
WriteExitCode(batch_event,RDRecording::InternalError,
RDUpload::errorText(conv_err));
qApp->processEvents();
}
else {
rda->syslog(LOG_WARNING,"upload of %s returned an error: \"%s\", id=%d",
(const char *)evt->tempName().toUtf8(),
(const char *)RDUpload::errorText(conv_err).toUtf8(),
evt->id());
break;
default:
WriteExitCode(batch_event,RDRecording::ServerError,
RDUpload::errorText(conv_err));
qApp->processEvents();
rda->syslog(LOG_WARNING,"upload of %s returned an error: \"%s\", id=%d",
(const char *)evt->tempName().toUtf8(),
(const char *)RDUpload::errorText(conv_err).toUtf8(),
evt->id());
break;
delete conv;
return false;
}
delete conv;
@ -361,23 +358,22 @@ void MainObject::RunUpload(CatchEvent *evt)
feed->keyName().toUtf8().constData(),
RDFeed::errorString(feed_err).toUtf8().constData(),
evt->id());
WriteExitCode(batch_event,RDRecording::ServerError,
RDFeed::errorString(feed_err));
// WriteExitCode(batch_event,RDRecording::ServerError,
// RDFeed::errorString(feed_err));
delete feed;
return;
return false;
}
rda->syslog(LOG_INFO,"post of %s to cast id %u successful, id=%d",
evt->tempName().toUtf8().constData(),
cast_id,
evt->id());
WriteExitCode(batch_event,RDRecording::Ok,tr("Ok"));
// catch_connect->setExitCode(evt->id(),RDRecording::Ok,tr("Ok"));
delete feed;
}
return true;
}
bool MainObject::Export(CatchEvent *evt)
bool MainObject::Export(CatchEvent *evt,QString *err_msg)
{
bool ret=false;
RDAudioConvert::ErrorCode conv_err;
@ -432,7 +428,7 @@ bool MainObject::Export(CatchEvent *evt)
}
bool MainObject::Import(CatchEvent *evt)
bool MainObject::Import(CatchEvent *evt,QString *err_msg)
{
bool ret=false;
RDAudioConvert::ErrorCode conv_err;
@ -441,8 +437,7 @@ bool MainObject::Import(CatchEvent *evt)
if(!cut->exists()) {
rda->syslog(LOG_WARNING,"cut not found: %s, id: %d",
(const char *)evt->cutName().toUtf8(),evt->id());
WriteExitCode(batch_event,RDRecording::NoCut,tr("No such cut"));
qApp->processEvents();
*err_msg=tr("Cut not found");
delete cut;
return false;
}
@ -450,8 +445,7 @@ bool MainObject::Import(CatchEvent *evt)
if(!wave->openWave()) {
rda->syslog(LOG_ERR,"unknown file format: %s, id: %d",
(const char *)evt->cutName().toUtf8(),evt->id());
WriteExitCode(batch_event,RDRecording::UnknownFormat,tr("Unknown Format"));
qApp->processEvents();
*err_msg=tr("Unknown file format");
delete wave;
return false;
}
@ -482,9 +476,7 @@ bool MainObject::Import(CatchEvent *evt)
rda->syslog(LOG_WARNING,"import error: %s, id: %d",
(const char *)RDAudioConvert::errorText(conv_err).toUtf8(),
evt->id());
WriteExitCode(batch_event,RDRecording::UnknownFormat,
RDAudioConvert::errorText(conv_err));
qApp->processEvents();
*err_msg=RDAudioConvert::errorText(conv_err);
ret=false;
break;
@ -492,9 +484,6 @@ bool MainObject::Import(CatchEvent *evt)
rda->syslog(LOG_WARNING,"import error: %s, id: %d",
(const char *)RDAudioConvert::errorText(conv_err).toUtf8(),
evt->id());
WriteExitCode(batch_event,RDRecording::InternalError,
RDAudioConvert::errorText(conv_err));
qApp->processEvents();
ret=false;
break;
}

View File

@ -583,6 +583,8 @@ void MainObject::engineData(int id)
catch_events[event].channel(),
catch_events[event].id());
WriteExitCode(event,RDRecording::DeviceBusy);
SendEventResponse(catch_events[event].channel(),RDDeck::Idle,
catch_events[event].id(),"");
return;
}
}
@ -597,6 +599,8 @@ void MainObject::engineData(int id)
catch_events[event].channel()-128,
catch_events[event].id());
WriteExitCode(event,RDRecording::DeviceBusy);
SendEventResponse(catch_events[event].channel(),RDDeck::Idle,
catch_events[event].id(),"");
return;
}
}
@ -1059,6 +1063,7 @@ void MainObject::eventFinishedData(int id)
return;
}
catch_events[event].setStatus(RDDeck::Idle);
rda->syslog(LOG_NOTICE,"HERE1");
SendEventResponse(0,RDDeck::Idle,catch_macro_event_id[id],"");
if(catch_events[event].oneShot()) {
PurgeEvent(event);
@ -1086,17 +1091,15 @@ void MainObject::updateXloadsData()
std::vector<int>::iterator it;
for(unsigned i=0;i<catch_active_xloads.size();i++) {
switch(ReadExitCode(catch_active_xloads[i])) {
case RDRecording::Ok:
case RDRecording::ServerError:
case RDRecording::InternalError:
it=catch_active_xloads.begin()+i;
SendEventResponse(0,RDDeck::Idle,
catch_events[catch_active_xloads[i]].id(),"");
catch_active_xloads.erase(it,it+1);
break;
case RDRecording::Ok:
case RDRecording::ServerError:
case RDRecording::InternalError:
it=catch_active_xloads.begin()+i;
catch_active_xloads.erase(it,it+1);
break;
default:
break;
default:
break;
}
}
if(catch_active_xloads.size()==0) {
@ -2050,54 +2053,13 @@ RDRecording::ExitCode MainObject::ReadExitCode(int event)
void MainObject::WriteExitCode(int event,RDRecording::ExitCode code,
const QString &err_text)
{
RDDeck::Status status=RDDeck::Offline;
QString err_txt=err_text;
if(err_text.isEmpty()) {
err_txt=RDRecording::exitString(code);
}
QString sql=QString("update `RECORDINGS` set ")+
QString::asprintf("`EXIT_CODE`=%d,",code)+
"`EXIT_TEXT`='"+RDEscapeString(err_txt)+"' where "+
QString::asprintf("`ID`=%d",catch_events[event].id());
RDSqlQuery::apply(sql);
switch(code) {
case RDRecording::Ok:
status=RDDeck::Idle;
break;
case RDRecording::Downloading:
case RDRecording::Uploading:
case RDRecording::RecordActive:
case RDRecording::PlayActive:
status=RDDeck::Recording;
break;
case RDRecording::Waiting:
status=RDDeck::Waiting;
break;
case RDRecording::ServerError:
case RDRecording::InternalError:
ExecuteErrorRml(&catch_events[event],
RDRecording::exitString(code)+": "+err_text,
catch_conf->errorRml());
status=RDDeck::Offline;
break;
default:
ExecuteErrorRml(&catch_events[event],RDRecording::exitString(code),
catch_conf->errorRml());
status=RDDeck::Offline;
break;
}
SendEventResponse(0,status,catch_events[event].id(),"");
WriteExitCode(&(catch_events[event]),code,err_text);
}
void MainObject::WriteExitCode(CatchEvent *ce,RDRecording::ExitCode code,
const QString &err_text)
{
RDDeck::Status status=RDDeck::Offline;
QString err_txt=err_text;
if(err_text.isEmpty()) {
err_txt=RDRecording::exitString(code);
@ -2107,35 +2069,6 @@ void MainObject::WriteExitCode(CatchEvent *ce,RDRecording::ExitCode code,
"`EXIT_TEXT`='"+RDEscapeString(err_txt)+"' where "+
QString::asprintf("`ID`=%d",ce->id());
RDSqlQuery::apply(sql);
switch(code) {
case RDRecording::Ok:
status=RDDeck::Idle;
break;
case RDRecording::Downloading:
case RDRecording::Uploading:
case RDRecording::RecordActive:
case RDRecording::PlayActive:
status=RDDeck::Recording;
break;
case RDRecording::Waiting:
status=RDDeck::Waiting;
break;
case RDRecording::ServerError:
case RDRecording::InternalError:
ExecuteErrorRml(ce,RDRecording::exitString(code)+": "+err_text,
catch_conf->errorRml());
status=RDDeck::Offline;
break;
default:
ExecuteErrorRml(ce,RDRecording::exitString(code),catch_conf->errorRml());
status=RDDeck::Offline;
break;
}
SendEventResponse(0,status,ce->id(),"");
}

View File

@ -96,12 +96,12 @@ class MainObject : public QObject
//
void RunBatch(RDCmdSwitch *cmd);
void RunImport(CatchEvent *evt);
void RunDownload(CatchEvent *evt);
void RunUpload(CatchEvent *evt);
bool RunDownload(CatchEvent *evt,QString *err_msg);
bool RunUpload(CatchEvent *evt,QString *err_msg);
CatchEvent *batch_event;
bool Export(CatchEvent *evt);
bool Export(CatchEvent *evt,QString *err_msg);
QString GetExportCmd(CatchEvent *evt,QString *tempname);
bool Import(CatchEvent *evt);
bool Import(CatchEvent *evt,QString *err_msg);
QString GetImportCmd(CatchEvent *evt,QString *tempname);
//

View File

@ -2,7 +2,7 @@
//
// Replicator implementation for the Citadel XDS Portal
//
// (C) Copyright 2010-2021 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2010-2022 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -365,6 +365,7 @@ bool CitadelXds::PostCut(const QString &cutname,const QString &filename)
//
// Upload File
//
QString err_msg;
RDUpload *upload=new RDUpload(rda->config());
upload->setSourceFile(tempfile);
upload->setDestinationUrl(config()->url()+"/"+filename);
@ -372,14 +373,14 @@ bool CitadelXds::PostCut(const QString &cutname,const QString &filename)
// FIXME: Finish implementing ssh(1) id keys!
//
switch(upload_err=upload->runUpload(config()->urlUsername(),
config()->urlPassword(),"",false,
config()->urlPassword(),"",false,&err_msg,
rda->config()->logXloadDebugData())) {
case RDUpload::ErrorOk:
break;
default:
rda->syslog(LOG_WARNING,"CitadelXds: audio upload failed: %s",
(const char *)RDUpload::errorText(upload_err).toUtf8());
err_msg.toUtf8().constData());
unlink(tempfile.toUtf8());
delete upload;
return false;

View File

@ -31,6 +31,7 @@ MainObject::MainObject(QObject *parent)
:QObject(parent)
{
QString err_msg;
QString curl_err_msg;
username="";
password="";
@ -102,8 +103,9 @@ MainObject::MainObject(QObject *parent)
printf("Downloading...\n");
conv_err=conv->
runDownload(username,password,ssh_identity_filename,use_identity_file,
rda->config()->logXloadDebugData());
&curl_err_msg,rda->config()->logXloadDebugData());
printf("Result: %s\n",RDDownload::errorText(conv_err).toUtf8().constData());
printf("CURL Msg: %s\n",curl_err_msg.toUtf8().constData());
delete conv;
exit(0);

View File

@ -2,7 +2,7 @@
//
// Test Rivendell file uploading.
//
// (C) Copyright 2010-2021 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2010-2022 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -96,14 +96,16 @@ MainObject::MainObject(QObject *parent)
//
// Run the Test
//
err_msg="";
RDUpload *conv=new RDUpload(rda->config(),this);
conv->setSourceFile(source_filename);
conv->setDestinationUrl(destination_url);
printf("Uploading...\n");
conv_err=conv->
runUpload(username,password,ssh_identity_filename,use_identity_file,
rda->config()->logXloadDebugData());
printf("Result: %s\n",RDUpload::errorText(conv_err).toUtf8().constData());
&err_msg,rda->config()->logXloadDebugData());
printf("Result: %s [%s]\n",RDUpload::errorText(conv_err).toUtf8().constData(),
err_msg.toUtf8().constData());
delete conv;
exit(0);

View File

@ -2,7 +2,7 @@
//
// Rivendell web service portal -- Podcast services
//
// (C) Copyright 2010-2021 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2010-2022 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -271,12 +271,13 @@ void Xport::PostPodcast()
if((upload_err=upload->
runUpload(feed->purgeUsername(),feed->purgePassword(),
rda->station()->sshIdentityFile(),feed->purgeUseIdFile(),
rda->config()->logXloadDebugData()))!=RDUpload::ErrorOk) {
&err_msg,rda->config()->logXloadDebugData()))!=
RDUpload::ErrorOk) {
delete upload;
delete feed;
delete cast;
XmlExit(QString("Upload to \"")+desturl+"\" failed ["+
RDUpload::errorText(upload_err)+"]",500,"podcasts.cpp",LINE_NUMBER);
XmlExit(QString("Upload to \"")+desturl+"\" failed ["+err_msg+"]",500,
"podcasts.cpp",LINE_NUMBER);
}
delete upload;