|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2015 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include <config.h>
|
|
Packit |
8f70b4 |
#include <ctype.h>
|
|
Packit |
8f70b4 |
#include <stddef.h>
|
|
Packit |
8f70b4 |
#include "SleepJob.h"
|
|
Packit |
8f70b4 |
#include "CmdExec.h"
|
|
Packit |
8f70b4 |
#include "misc.h"
|
|
Packit |
8f70b4 |
#include "LocalDir.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
SleepJob::SleepJob(const TimeInterval &when,FileAccess *s,LocalDirectory *cwd,char *what)
|
|
Packit |
8f70b4 |
: SessionJob(s), Timer(when), saved_cwd(cwd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cmd.set_allocated(what);
|
|
Packit |
8f70b4 |
exit_code=0;
|
|
Packit |
8f70b4 |
done=false;
|
|
Packit |
8f70b4 |
repeat=false;
|
|
Packit |
8f70b4 |
weak=false;
|
|
Packit |
8f70b4 |
repeat_count=0;
|
|
Packit |
8f70b4 |
max_repeat_count=0;
|
|
Packit |
8f70b4 |
continue_code=-1;
|
|
Packit |
8f70b4 |
break_code=-1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
SleepJob::~SleepJob()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int SleepJob::Do()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int m=STALL;
|
|
Packit |
8f70b4 |
if(Done())
|
|
Packit |
8f70b4 |
return m;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(waiting.count()>0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
Job *j=FindDoneAwaitedJob();
|
|
Packit |
8f70b4 |
if(!j)
|
|
Packit |
8f70b4 |
return m;
|
|
Packit |
8f70b4 |
exit_code=j->ExitCode();
|
|
Packit |
8f70b4 |
if(!repeat || (++repeat_count>=max_repeat_count && max_repeat_count)
|
|
Packit |
8f70b4 |
|| exit_code==break_code || (continue_code!=-1 && exit_code!=continue_code))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
RemoveWaiting(j);
|
|
Packit |
8f70b4 |
Delete(j);
|
|
Packit |
8f70b4 |
exec=0;
|
|
Packit |
8f70b4 |
done=true;
|
|
Packit |
8f70b4 |
return MOVED;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
Reset();
|
|
Packit |
8f70b4 |
exec=(CmdExec*)j; // we are sure it is CmdExec.
|
|
Packit |
8f70b4 |
RemoveWaiting(j);
|
|
Packit |
8f70b4 |
m=MOVED;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(Stopped())
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(cmd)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!exec)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
exec=new CmdExec(session.borrow(),saved_cwd.borrow());
|
|
Packit |
8f70b4 |
exec->AllocJobno();
|
|
Packit |
8f70b4 |
exec->cmdline.vset("(",cmd.get(),")",NULL);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
exec->FeedCmd(cmd);
|
|
Packit |
8f70b4 |
exec->FeedCmd("\n");
|
|
Packit |
8f70b4 |
AddWaiting(exec.borrow());
|
|
Packit |
8f70b4 |
return MOVED;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
done=true;
|
|
Packit |
8f70b4 |
return MOVED;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return m;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *SleepJob::Status()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(Stopped() || TimeLeft().Seconds()<=1)
|
|
Packit |
8f70b4 |
return "";
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(IsInfty())
|
|
Packit |
8f70b4 |
return(_("Sleeping forever"));
|
|
Packit |
8f70b4 |
return xstring::cat(_("Sleep time left: "),
|
|
Packit |
8f70b4 |
TimeLeft().toString(TimeInterval::TO_STR_TRANSLATE),
|
|
Packit |
8f70b4 |
NULL);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
xstring& SleepJob::FormatStatus(xstring& buf,int,const char *prefix)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(repeat)
|
|
Packit |
8f70b4 |
buf.appendf(_("\tRepeat count: %d\n"),repeat_count);
|
|
Packit |
8f70b4 |
const char *s=Status();
|
|
Packit |
8f70b4 |
if(s[0])
|
|
Packit |
8f70b4 |
buf.appendf("\t%s\n",s);
|
|
Packit |
8f70b4 |
return buf;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void SleepJob::ShowRunStatus(const SMTaskRef<StatusLine>& s)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(Stopped())
|
|
Packit |
8f70b4 |
Job::ShowRunStatus(s);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
s->Show("%s",Status());
|
|
Packit |
8f70b4 |
current->TimeoutS(1);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SleepJob::lftpMovesToBackground()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(weak || IsInfty() || (repeat && cmd[0]==0))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// terminate
|
|
Packit |
8f70b4 |
done=true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define args (parent->args)
|
|
Packit |
8f70b4 |
#define eprintf parent->eprintf
|
|
Packit |
8f70b4 |
#define session (parent->session)
|
|
Packit |
8f70b4 |
Job *cmd_sleep(CmdExec *parent)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
if(args->count()!=2)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: argument required. "),op);
|
|
Packit |
8f70b4 |
err:
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),op);
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *t=args->getarg(1);
|
|
Packit |
8f70b4 |
TimeIntervalR delay(t);
|
|
Packit |
8f70b4 |
if(delay.Error())
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s: %s. ",op,t,delay.ErrorText());
|
|
Packit |
8f70b4 |
goto err;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return new SleepJob(delay);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
Job *cmd_repeat(CmdExec *parent)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *op=args->a0();
|
|
Packit |
8f70b4 |
int cmd_start=1;
|
|
Packit |
8f70b4 |
TimeIntervalR delay(1);
|
|
Packit |
8f70b4 |
int max_count=0;
|
|
Packit |
8f70b4 |
const char *delay_str=0;
|
|
Packit |
8f70b4 |
bool while_ok=false;
|
|
Packit |
8f70b4 |
bool until_ok=false;
|
|
Packit |
8f70b4 |
bool weak=false;
|
|
Packit |
8f70b4 |
int opt;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static struct option repeat_opts[]=
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
{"delay",required_argument,0,'d'},
|
|
Packit |
8f70b4 |
{"count",required_argument,0,'c'},
|
|
Packit |
8f70b4 |
{"while-ok",no_argument,0,'o'},
|
|
Packit |
8f70b4 |
{"until-ok",no_argument,0,'O'},
|
|
Packit |
8f70b4 |
{"weak",no_argument,0,'w'},
|
|
Packit |
8f70b4 |
{0},
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
args->rewind();
|
|
Packit |
8f70b4 |
while((opt=args->getopt_long("+c:d:",repeat_opts,0))!=EOF)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
switch(opt)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
case('c'):
|
|
Packit |
8f70b4 |
max_count=atoi(optarg);
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('d'):
|
|
Packit |
8f70b4 |
delay_str=optarg;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('o'):
|
|
Packit |
8f70b4 |
while_ok=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('O'):
|
|
Packit |
8f70b4 |
until_ok=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('w'):
|
|
Packit |
8f70b4 |
weak=true;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
case('?'):
|
|
Packit |
8f70b4 |
eprintf(_("Try `help %s' for more information.\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(!delay_str)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *t=args->getcurr();
|
|
Packit |
8f70b4 |
if(t && isdigit((unsigned char)t[0]))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
args->getnext();
|
|
Packit |
8f70b4 |
delay_str=t;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
cmd_start=args->getindex();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(delay_str)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
delay.Set(delay_str);
|
|
Packit |
8f70b4 |
if(delay.Error())
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf("%s: %s: %s.\n",op,delay_str,delay.ErrorText());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *cmd = (args->count()==cmd_start+1
|
|
Packit |
8f70b4 |
? args->Combine(cmd_start) : args->CombineQuoted(cmd_start));
|
|
Packit |
8f70b4 |
SleepJob *s=new SleepJob(delay,session->Clone(),parent->cwd->Clone(),cmd);
|
|
Packit |
8f70b4 |
s->Repeat(max_count);
|
|
Packit |
8f70b4 |
s->SetWeak(weak);
|
|
Packit |
8f70b4 |
if(while_ok)
|
|
Packit |
8f70b4 |
s->ContinueCode(0);
|
|
Packit |
8f70b4 |
if(until_ok)
|
|
Packit |
8f70b4 |
s->BreakCode(0);
|
|
Packit |
8f70b4 |
return s;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
extern "C" {
|
|
Packit |
8f70b4 |
#include "parse-datetime.h"
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
Job *cmd_at(CmdExec *parent)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int count=1;
|
|
Packit |
8f70b4 |
int cmd_start=0;
|
|
Packit |
8f70b4 |
xstring date;
|
|
Packit |
8f70b4 |
for(;;)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *arg=args->getnext();
|
|
Packit |
8f70b4 |
if(arg==0)
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
if(!strcmp(arg,"--"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
cmd_start=count+1;
|
|
Packit |
8f70b4 |
break;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(date)
|
|
Packit |
8f70b4 |
date.append(' ');
|
|
Packit |
8f70b4 |
date.append(arg);
|
|
Packit |
8f70b4 |
count++;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!date) {
|
|
Packit |
8f70b4 |
eprintf(_("%s: date-time specification missed\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct timespec ts;
|
|
Packit |
8f70b4 |
if(!parse_datetime(&ts,date,0))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
eprintf(_("%s: date-time parse error\n"),args->a0());
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
time_t when=ts.tv_sec;
|
|
Packit |
8f70b4 |
if(when
|
|
Packit |
8f70b4 |
when+=86400;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *cmd=0;
|
|
Packit |
8f70b4 |
if(cmd_start)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// two cases:
|
|
Packit |
8f70b4 |
// 1. at time -- "cmd; cmd..." (one argument)
|
|
Packit |
8f70b4 |
// 2. at time -- shell "cmd; cmd..." (several args)
|
|
Packit |
8f70b4 |
if(cmd_start==args->count()-1)
|
|
Packit |
8f70b4 |
cmd=args->Combine(cmd_start);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
cmd=args->CombineQuoted(cmd_start);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!cmd)
|
|
Packit |
8f70b4 |
return new SleepJob(Time(when,0)-SMTask::now);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
return new SleepJob(Time(when,0)-SMTask::now,
|
|
Packit |
8f70b4 |
session->Clone(), parent->cwd->Clone(), cmd);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
#undef args
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include "modconfig.h"
|
|
Packit |
8f70b4 |
#ifndef MODULE_CMD_SLEEP
|
|
Packit |
8f70b4 |
# define module_init cmd_sleep_module_init
|
|
Packit |
8f70b4 |
#endif
|
|
Packit |
8f70b4 |
CDECL void module_init()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
CmdExec::RegisterCommand("sleep",cmd_sleep,0,
|
|
Packit |
8f70b4 |
N_("Usage: sleep <time>[unit]\n"
|
|
Packit |
8f70b4 |
"Sleep for given amount of time. The time argument can be optionally\n"
|
|
Packit |
8f70b4 |
"followed by unit specifier: d - days, h - hours, m - minutes, s - seconds.\n"
|
|
Packit |
8f70b4 |
"By default time is assumed to be seconds.\n")
|
|
Packit |
8f70b4 |
);
|
|
Packit |
8f70b4 |
CmdExec::RegisterCommand("at",cmd_at);
|
|
Packit |
8f70b4 |
CmdExec::RegisterCommand("repeat",cmd_repeat,0,
|
|
Packit |
8f70b4 |
N_("Repeat specified command with a delay between iterations.\n"
|
|
Packit |
8f70b4 |
"Default delay is one second, default command is empty.\n"
|
|
Packit |
8f70b4 |
" -c <count> maximum number of iterations\n"
|
|
Packit |
8f70b4 |
" -d <delay> delay between iterations\n"
|
|
Packit |
8f70b4 |
" --while-ok stop when command exits with non-zero code\n"
|
|
Packit |
8f70b4 |
" --until-ok stop when command exits with zero code\n"
|
|
Packit |
8f70b4 |
" --weak stop when lftp moves to background.\n")
|
|
Packit |
8f70b4 |
);
|
|
Packit |
8f70b4 |
}
|