Blame src/Job.cc

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
}