|
Packit Service |
a2489d |
/*
|
|
Packit Service |
a2489d |
* lftp - file transfer program
|
|
Packit Service |
a2489d |
*
|
|
Packit Service |
a2489d |
* Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit Service |
a2489d |
*
|
|
Packit Service |
a2489d |
* This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
a2489d |
* it under the terms of the GNU General Public License as published by
|
|
Packit Service |
a2489d |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit Service |
a2489d |
* (at your option) any later version.
|
|
Packit Service |
a2489d |
*
|
|
Packit Service |
a2489d |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
a2489d |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
a2489d |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
a2489d |
* GNU General Public License for more details.
|
|
Packit Service |
a2489d |
*
|
|
Packit Service |
a2489d |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
a2489d |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
a2489d |
*/
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
#include <config.h>
|
|
Packit Service |
a2489d |
#include <stdlib.h>
|
|
Packit Service |
a2489d |
#include <errno.h>
|
|
Packit Service |
a2489d |
#include <assert.h>
|
|
Packit Service |
a2489d |
#include "Job.h"
|
|
Packit Service |
a2489d |
#include "misc.h"
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xlist_head<Job> Job::all_jobs;
|
|
Packit Service |
a2489d |
#define waiting_num waiting.count()
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Job::Job()
|
|
Packit Service |
a2489d |
: all_jobs_node(this), children_jobs_node(this)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
all_jobs.add(all_jobs_node);
|
|
Packit Service |
a2489d |
parent=0;
|
|
Packit Service |
a2489d |
jobno=-1;
|
|
Packit Service |
a2489d |
fg=false;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::SetParent(Job *j)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(children_jobs_node.listed())
|
|
Packit Service |
a2489d |
children_jobs_node.remove();
|
|
Packit Service |
a2489d |
parent=j;
|
|
Packit Service |
a2489d |
if(j)
|
|
Packit Service |
a2489d |
j->children_jobs.add(children_jobs_node);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::AllocJobno()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
jobno=0;
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
if(scan!=this && scan->jobno>=jobno)
|
|
Packit Service |
a2489d |
jobno=scan->jobno+1;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::PrepareToDie()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
// reparent or kill children (hm, that's sadistic)
|
|
Packit Service |
a2489d |
xlist_for_each_safe(Job,children_jobs,child_node,child,next) {
|
|
Packit Service |
a2489d |
child_node->remove();
|
|
Packit Service |
a2489d |
if(child->jobno!=-1 && this->parent) {
|
|
Packit Service |
a2489d |
child->parent=this->parent;
|
|
Packit Service |
a2489d |
this->parent->children_jobs.add(child_node);
|
|
Packit Service |
a2489d |
} else {
|
|
Packit Service |
a2489d |
child->parent=0;
|
|
Packit Service |
a2489d |
child->DeleteLater();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
// if parent waits for the job, make it stop
|
|
Packit Service |
a2489d |
if(parent)
|
|
Packit Service |
a2489d |
parent->RemoveWaiting(this);
|
|
Packit Service |
a2489d |
fg_data=0;
|
|
Packit Service |
a2489d |
waiting.unset();
|
|
Packit Service |
a2489d |
if(children_jobs_node.listed())
|
|
Packit Service |
a2489d |
children_jobs_node.remove();
|
|
Packit Service |
a2489d |
all_jobs_node.remove();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Job::~Job()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
assert(!all_jobs_node.listed());
|
|
Packit Service |
a2489d |
assert(!children_jobs_node.listed());
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Job *Job::FindJob(int n)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(scan->jobno==n)
|
|
Packit Service |
a2489d |
return scan;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
return 0;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Job *Job::FindWhoWaitsFor(Job *j)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(scan->WaitsFor(j))
|
|
Packit Service |
a2489d |
return scan;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
return 0;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool Job::WaitsFor(Job *j)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
return waiting.search(j)>=0;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Job *Job::FindDoneAwaitedJob()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(waiting[i]->Done())
|
|
Packit Service |
a2489d |
return waiting[i];
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
return 0;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::WaitForAllChildren()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xlist_for_each(Job,children_jobs,node,scan)
|
|
Packit Service |
a2489d |
AddWaiting(scan);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::AllWaitingFg()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
waiting[i]->Fg();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::ReplaceWaiting(Job *from,Job *to)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
int i=waiting.search(from);
|
|
Packit Service |
a2489d |
if(i>=0)
|
|
Packit Service |
a2489d |
waiting[i]=to;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::AddWaiting(Job *j)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(j==0 || this->WaitsFor(j))
|
|
Packit Service |
a2489d |
return;
|
|
Packit Service |
a2489d |
assert(FindWhoWaitsFor(j)==0);
|
|
Packit Service |
a2489d |
j->SetParentFg(this);
|
|
Packit Service |
a2489d |
waiting.append(j);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::RemoveWaiting(const Job *j)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
int i=waiting.search(const_cast<Job*>(j));
|
|
Packit Service |
a2489d |
if(i>=0)
|
|
Packit Service |
a2489d |
waiting.remove(i);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
class KilledJob : public Job
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
public:
|
|
Packit Service |
a2489d |
int Do() { return STALL; }
|
|
Packit Service |
a2489d |
int Done() { return 1; }
|
|
Packit Service |
a2489d |
int ExitCode() { return 255; }
|
|
Packit Service |
a2489d |
};
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::Kill(Job *j)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(j->AcceptSig(SIGTERM)!=WANTDIE)
|
|
Packit Service |
a2489d |
return;
|
|
Packit Service |
a2489d |
if(j->parent && j->parent->WaitsFor(j))
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
// someone waits for termination of this job, so
|
|
Packit Service |
a2489d |
// we have to simulate normal death...
|
|
Packit Service |
a2489d |
Job *r=new KilledJob();
|
|
Packit Service |
a2489d |
r->parent=j->parent;
|
|
Packit Service |
a2489d |
j->parent->children_jobs.add(r->children_jobs_node);
|
|
Packit Service |
a2489d |
j->children_jobs_node.remove();
|
|
Packit Service |
a2489d |
r->cmdline.set(j->cmdline);
|
|
Packit Service |
a2489d |
r->waiting.move_here(j->waiting);
|
|
Packit Service |
a2489d |
j->parent->ReplaceWaiting(j,r);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
assert(FindWhoWaitsFor(j)==0);
|
|
Packit Service |
a2489d |
j->DeleteLater();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::Kill(int n)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
Job *j=FindJob(n);
|
|
Packit Service |
a2489d |
if(j)
|
|
Packit Service |
a2489d |
Kill(j);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::KillAll()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
// Job::Kill may remove more than a single job from all_jobs list,
|
|
Packit Service |
a2489d |
// collect list of jobs beforehand.
|
|
Packit Service |
a2489d |
xarray<Job*> to_kill;
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
if(scan->jobno>=0)
|
|
Packit Service |
a2489d |
to_kill.append(scan);
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
Kill(to_kill[i]);
|
|
Packit Service |
a2489d |
CollectGarbage();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::Cleanup()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xarray<Job*> to_kill;
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
to_kill.append(scan);
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
Kill(to_kill[i]);
|
|
Packit Service |
a2489d |
CollectGarbage();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::SendSig(int n,int sig)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
Job *j=FindJob(n);
|
|
Packit Service |
a2489d |
if(j)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
int res=j->AcceptSig(sig);
|
|
Packit Service |
a2489d |
if(res==WANTDIE)
|
|
Packit Service |
a2489d |
Kill(n);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
int Job::NumberOfJobs()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
int count=0;
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
if(!scan->Done())
|
|
Packit Service |
a2489d |
count++;
|
|
Packit Service |
a2489d |
return count;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
int Job::NumberOfChildrenJobs()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
int count=0;
|
|
Packit Service |
a2489d |
xlist_for_each(Job,children_jobs,node,scan)
|
|
Packit Service |
a2489d |
if(!scan->Done())
|
|
Packit Service |
a2489d |
count++;
|
|
Packit Service |
a2489d |
return count;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static int jobno_compare(Job *const*a,Job *const*b)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
return (*a)->jobno-(*b)->jobno;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::SortJobs()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xarray<Job*> arr;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xlist_for_each_safe(Job,all_jobs,node,scan,next) {
|
|
Packit Service |
a2489d |
arr.append(scan);
|
|
Packit Service |
a2489d |
node->remove();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
arr.qsort(jobno_compare);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
int count=arr.count();
|
|
Packit Service |
a2489d |
while(count--)
|
|
Packit Service |
a2489d |
all_jobs.add(arr[count]->all_jobs_node);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan_waiting)
|
|
Packit Service |
a2489d |
scan_waiting->waiting.qsort(jobno_compare);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static xstring print_buf("");
|
|
Packit Service |
a2489d |
void Job::PrintJobTitle(int indent,const char *suffix)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
print_buf.truncate();
|
|
Packit Service |
a2489d |
printf("%s",FormatJobTitle(print_buf,indent,suffix).get());
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::ListOneJob(int verbose,int indent,const char *suffix)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
print_buf.truncate();
|
|
Packit Service |
a2489d |
printf("%s",FormatOneJob(print_buf,verbose,indent,suffix).get());
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::ListOneJobRecursively(int verbose,int indent)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
print_buf.truncate();
|
|
Packit Service |
a2489d |
printf("%s",FormatOneJobRecursively(print_buf,verbose,indent).get());
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::PrintStatus(int v,const char *prefix)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
print_buf.truncate();
|
|
Packit Service |
a2489d |
printf("%s",FormatStatus(print_buf,v,prefix).get());
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::ListDoneJobs()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
SortJobs();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
FILE *f=stdout;
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(scan->jobno>=0 && (scan->parent==this || scan->parent==0)
|
|
Packit Service |
a2489d |
&& scan->Done())
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
fprintf(f,_("[%d] Done (%s)"),scan->jobno,scan->GetCmdLine().get());
|
|
Packit Service |
a2489d |
const char *this_url=this->GetConnectURL();
|
|
Packit Service |
a2489d |
this_url=alloca_strdup(this_url); // save it from overwriting.
|
|
Packit Service |
a2489d |
const char *that_url=scan->GetConnectURL();
|
|
Packit Service |
a2489d |
if(this_url && that_url && strcmp(this_url,that_url))
|
|
Packit Service |
a2489d |
fprintf(f," (wd: %s)",that_url);
|
|
Packit Service |
a2489d |
fprintf(f,"\n");
|
|
Packit Service |
a2489d |
scan->PrintStatus(0);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xstring& Job::FormatJobTitle(xstring& s,int indent,const char *suffix)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(jobno<0 && !cmdline)
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
s.append_padding(indent,' ');
|
|
Packit Service |
a2489d |
if(jobno>=0)
|
|
Packit Service |
a2489d |
s.appendf("[%d] ",jobno);
|
|
Packit Service |
a2489d |
s.append(GetCmdLine());
|
|
Packit Service |
a2489d |
if(suffix) {
|
|
Packit Service |
a2489d |
s.append(' ');
|
|
Packit Service |
a2489d |
s.append(suffix);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
if(waiting.count()>0) {
|
|
Packit Service |
a2489d |
size_t len=s.length();
|
|
Packit Service |
a2489d |
FormatShortStatus(s.append(" -- "));
|
|
Packit Service |
a2489d |
if(s.length()<=len+4)
|
|
Packit Service |
a2489d |
s.truncate(len);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
s.append('\n');
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xstring& Job::FormatOneJob(xstring& s,int verbose,int indent,const char *suffix)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
FormatJobTitle(s,indent,suffix);
|
|
Packit Service |
a2489d |
FormatStatus(s,verbose);
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(waiting[i]->jobno<0 && waiting[i]!=this && !waiting[i]->cmdline)
|
|
Packit Service |
a2489d |
waiting[i]->FormatOneJob(s,verbose,indent+1,"");
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xstring& Job::FormatOneJobRecursively(xstring& s,int verbose,int indent)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
FormatJobTitle(s,indent,"");
|
|
Packit Service |
a2489d |
FormatStatus(s,verbose);
|
|
Packit Service |
a2489d |
FormatJobs(s,verbose,indent+1);
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xstring& Job::FormatJobs(xstring& s,int verbose,int indent)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(indent==0)
|
|
Packit Service |
a2489d |
SortJobs();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
// list the foreground job first.
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(waiting[i]!=this && waiting[i]->parent==this)
|
|
Packit Service |
a2489d |
waiting[i]->FormatOneJobRecursively(s,verbose,indent);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xlist_for_each(Job,children_jobs,node,scan)
|
|
Packit Service |
a2489d |
if(!scan->Done() && !this->WaitsFor(scan))
|
|
Packit Service |
a2489d |
scan->FormatOneJobRecursively(s,verbose,indent);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::BuryDoneJobs()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xlist_for_each_safe(Job,all_jobs,node,scan,next)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if((scan->parent==this || scan->parent==0) && scan->jobno>=0
|
|
Packit Service |
a2489d |
&& scan->Done())
|
|
Packit Service |
a2489d |
scan->DeleteLater();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
CollectGarbage();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::fprintf(FILE *file,const char *fmt,...)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
va_list v;
|
|
Packit Service |
a2489d |
va_start(v,fmt);
|
|
Packit Service |
a2489d |
vfprintf(file,fmt,v);
|
|
Packit Service |
a2489d |
va_end(v);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::printf(const char *fmt,...)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
va_list v;
|
|
Packit Service |
a2489d |
va_start(v,fmt);
|
|
Packit Service |
a2489d |
vfprintf(stdout,fmt,v);
|
|
Packit Service |
a2489d |
va_end(v);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::eprintf(const char *fmt,...)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
va_list v;
|
|
Packit Service |
a2489d |
va_start(v,fmt);
|
|
Packit Service |
a2489d |
vfprintf(stderr,fmt,v);
|
|
Packit Service |
a2489d |
va_end(v);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xstring& SessionJob::FormatStatus(xstring& s,int v,const char *prefix)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(v<2 || !session)
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
const char *url=session->GetConnectURL();
|
|
Packit Service |
a2489d |
if(url && *url) {
|
|
Packit Service |
a2489d |
s.append(prefix);
|
|
Packit Service |
a2489d |
s.append(url);
|
|
Packit Service |
a2489d |
s.append('\n');
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
const char *last_dc=session->GetLastDisconnectCause();
|
|
Packit Service |
a2489d |
if(last_dc && !session->IsConnected()) {
|
|
Packit Service |
a2489d |
s.append(prefix);
|
|
Packit Service |
a2489d |
s.appendf("Last disconnect cause: %s\n",last_dc);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void SessionJob::Fg()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(session)
|
|
Packit Service |
a2489d |
session->SetPriority(1);
|
|
Packit Service |
a2489d |
Job::Fg();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void SessionJob::Bg()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
Job::Bg();
|
|
Packit Service |
a2489d |
if(session)
|
|
Packit Service |
a2489d |
session->SetPriority(0);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::vfprintf(FILE *file,const char *fmt,va_list v)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(file!=stdout && file!=stderr)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
::vfprintf(file,fmt,v);
|
|
Packit Service |
a2489d |
return;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
if(parent)
|
|
Packit Service |
a2489d |
parent->vfprintf(file,fmt,v);
|
|
Packit Service |
a2489d |
else
|
|
Packit Service |
a2489d |
top_vfprintf(file,fmt,v);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::top_vfprintf(FILE *file,const char *fmt,va_list v)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
::vfprintf(file,fmt,v);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::perror(const char *f)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(f)
|
|
Packit Service |
a2489d |
eprintf("%s: %s\n",f,strerror(errno));
|
|
Packit Service |
a2489d |
else
|
|
Packit Service |
a2489d |
eprintf("%s\n",strerror(errno));
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::puts(const char *s)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
printf("%s\n",s);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::Bg()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(!fg)
|
|
Packit Service |
a2489d |
return;
|
|
Packit Service |
a2489d |
fg=false;
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(waiting[i]!=this)
|
|
Packit Service |
a2489d |
waiting[i]->Bg();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
if(fg_data)
|
|
Packit Service |
a2489d |
fg_data->Bg();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void Job::Fg()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
Resume();
|
|
Packit Service |
a2489d |
if(fg)
|
|
Packit Service |
a2489d |
return;
|
|
Packit Service |
a2489d |
fg=true;
|
|
Packit Service |
a2489d |
if(fg_data)
|
|
Packit Service |
a2489d |
fg_data->Fg();
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(waiting[i]!=this)
|
|
Packit Service |
a2489d |
waiting[i]->Fg();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
int Job::AcceptSig(int s)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(waiting[i]==this)
|
|
Packit Service |
a2489d |
continue;
|
|
Packit Service |
a2489d |
if(waiting[i]->AcceptSig(s)==WANTDIE)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
while(waiting[i]->waiting_num>0)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
Job *new_waiting=waiting[i]->waiting[0];
|
|
Packit Service |
a2489d |
waiting[i]->RemoveWaiting(new_waiting);
|
|
Packit Service |
a2489d |
AddWaiting(new_waiting);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
Job *j=waiting[i];
|
|
Packit Service |
a2489d |
RemoveWaiting(j);
|
|
Packit Service |
a2489d |
Delete(j);
|
|
Packit Service |
a2489d |
i--;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
return WANTDIE;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::ShowRunStatus(const SMTaskRef<StatusLine>& sl)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(waiting_num==0)
|
|
Packit Service |
a2489d |
return;
|
|
Packit Service |
a2489d |
Job *j=waiting[0];
|
|
Packit Service |
a2489d |
if(waiting_num>1)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
j=waiting[(now/3)%waiting_num];
|
|
Packit Service |
a2489d |
current->TimeoutS(3);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
if(j!=this)
|
|
Packit Service |
a2489d |
j->ShowRunStatus(sl);
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Job *Job::FindAnyChild()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xlist_for_each(Job,children_jobs,node,scan)
|
|
Packit Service |
a2489d |
if(scan->jobno>=0)
|
|
Packit Service |
a2489d |
return scan;
|
|
Packit Service |
a2489d |
return 0;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::lftpMovesToBackground_ToAll()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
xlist_for_each(Job,all_jobs,node,scan)
|
|
Packit Service |
a2489d |
scan->lftpMovesToBackground();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool Job::CheckForWaitLoop(Job *parent)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
if(parent==this)
|
|
Packit Service |
a2489d |
return true;
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
if(waiting[i]->CheckForWaitLoop(parent))
|
|
Packit Service |
a2489d |
return true;
|
|
Packit Service |
a2489d |
return false;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Job::WaitDone()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
IncRefCount(); // keep me in memory
|
|
Packit Service |
a2489d |
for(;;)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
SMTask::Schedule();
|
|
Packit Service |
a2489d |
if(Deleted() || Done())
|
|
Packit Service |
a2489d |
break;
|
|
Packit Service |
a2489d |
SMTask::Block();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
DecRefCount();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
off_t Job::GetBytesCount()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
off_t sum=0;
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
sum+=waiting[i]->GetBytesCount();
|
|
Packit Service |
a2489d |
return sum;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
double Job::GetTimeSpent()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
return 0;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
double Job::GetTransferRate()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
double sum=0;
|
|
Packit Service |
a2489d |
for(int i=0; i
|
|
Packit Service |
a2489d |
sum+=waiting[i]->GetTransferRate();
|
|
Packit Service |
a2489d |
return sum;
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
xstring& Job::FormatShortStatus(xstring& s)
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
double rate=GetTransferRate();
|
|
Packit Service |
a2489d |
if(rate>=1)
|
|
Packit Service |
a2489d |
s.append(Speedometer::GetStrProper(rate));
|
|
Packit Service |
a2489d |
return s;
|
|
Packit Service |
a2489d |
}
|