|
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 |
#ifndef CMDEXEC_H
|
|
Packit Service |
a2489d |
#define CMDEXEC_H
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
#include <stdarg.h>
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
#include "Job.h"
|
|
Packit Service |
a2489d |
#include "ArgV.h"
|
|
Packit Service |
a2489d |
#include "Filter.h"
|
|
Packit Service |
a2489d |
#include "alias.h"
|
|
Packit Service |
a2489d |
#include "History.h"
|
|
Packit Service |
a2489d |
#include "bookmark.h"
|
|
Packit Service |
a2489d |
#include "FileGlob.h"
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
class QueueFeeder;
|
|
Packit Service |
a2489d |
class LocalDirectory;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
extern History cwd_history;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
#define CMD(name) Job *cmd_##name(CmdExec *parent)
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
typedef Job * (*cmd_creator_t)(class CmdExec *parent);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
class CmdFeeder
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
public:
|
|
Packit Service |
a2489d |
xstring_c saved_buf;
|
|
Packit Service |
a2489d |
CmdFeeder *prev;
|
|
Packit Service |
a2489d |
virtual const char *NextCmd(class CmdExec *exec,const char *prompt) = 0;
|
|
Packit Service |
a2489d |
virtual ~CmdFeeder() {}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
virtual void clear() {}
|
|
Packit Service |
a2489d |
virtual bool RealEOF() { return true; }
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
virtual void Fg() {}
|
|
Packit Service |
a2489d |
virtual void Bg() {}
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
virtual bool IsInteractive() const { return false; }
|
|
Packit Service |
a2489d |
};
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
extern CmdFeeder *lftp_feeder; // feeder to use after 'lftp' command
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
class CmdExec : public SessionJob, public ResClient
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
public:
|
|
Packit Service |
a2489d |
// current command data
|
|
Packit Service |
a2489d |
Ref<ArgV> args;
|
|
Packit Service |
a2489d |
Ref<FDStream> output;
|
|
Packit Service |
a2489d |
bool background;
|
|
Packit Service |
a2489d |
int exit_code;
|
|
Packit Service |
a2489d |
int prev_exit_code;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
private:
|
|
Packit Service |
a2489d |
CmdExec *parent_exec;
|
|
Packit Service |
a2489d |
Buffer cmd_buf;
|
|
Packit Service |
a2489d |
bool partial_cmd;
|
|
Packit Service |
a2489d |
int alias_field; // length of expanded alias (and ttl for used_aliases)
|
|
Packit Service |
a2489d |
int failed_exit_code;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
TouchedAlias *used_aliases;
|
|
Packit Service |
a2489d |
void free_used_aliases();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void skip_cmd(int len);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
enum
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
COND_ANY,
|
|
Packit Service |
a2489d |
COND_AND,
|
|
Packit Service |
a2489d |
COND_OR
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
condition;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
struct cmd_rec
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
const char *name;
|
|
Packit Service |
a2489d |
cmd_creator_t creator;
|
|
Packit Service |
a2489d |
const char *short_desc;
|
|
Packit Service |
a2489d |
const char *long_desc;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static int cmp(const CmdExec::cmd_rec *a,const CmdExec::cmd_rec *b);
|
|
Packit Service |
a2489d |
};
|
|
Packit Service |
a2489d |
static const cmd_rec static_cmd_table[];
|
|
Packit Service |
a2489d |
static const int static_cmd_table_length;
|
|
Packit Service |
a2489d |
static xarray<cmd_rec> dyn_cmd_table;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static int find_cmd(const char *cmd_name,const cmd_rec **ret);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void exec_parsed_command();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
enum parse_result
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
PARSE_OK,
|
|
Packit Service |
a2489d |
PARSE_ERR,
|
|
Packit Service |
a2489d |
PARSE_AGAIN
|
|
Packit Service |
a2489d |
};
|
|
Packit Service |
a2489d |
parse_result parse_one_cmd();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
CmdFeeder *feeder;
|
|
Packit Service |
a2489d |
bool feeder_called;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool fed_at_finish;
|
|
Packit Service |
a2489d |
void AtFinish();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
enum builtins
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
BUILTIN_NONE=0,
|
|
Packit Service |
a2489d |
BUILTIN_OPEN,
|
|
Packit Service |
a2489d |
BUILTIN_CD,
|
|
Packit Service |
a2489d |
BUILTIN_EXEC_RESTART,
|
|
Packit Service |
a2489d |
BUILTIN_GLOB
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
builtin;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
FileAccess::Path old_cwd;
|
|
Packit Service |
a2489d |
xstring_c old_lcwd;
|
|
Packit Service |
a2489d |
xstring_c slot;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Ref<GlobURL> glob;
|
|
Packit Service |
a2489d |
Ref<ArgV> args_glob;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
int redirections;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static CmdExec *chain;
|
|
Packit Service |
a2489d |
CmdExec *next;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
QueueFeeder *queue_feeder;
|
|
Packit Service |
a2489d |
CmdExec *GetQueue(bool create = true);
|
|
Packit Service |
a2489d |
bool SameQueueParameters(CmdExec *,const char *);
|
|
Packit Service |
a2489d |
int max_waiting;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
FileAccessRef saved_session;
|
|
Packit Service |
a2489d |
void ReuseSavedSession();
|
|
Packit Service |
a2489d |
void RevertToSavedSession();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void init(LocalDirectory *c);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
public:
|
|
Packit Service |
a2489d |
void FeedCmd(const char *c);
|
|
Packit Service |
a2489d |
void FeedArgV(const ArgV *,int start=0);
|
|
Packit Service |
a2489d |
void PrependCmd(const char *c);
|
|
Packit Service |
a2489d |
void ExecParsed(ArgV *a,FDStream *o=0,bool b=false);
|
|
Packit Service |
a2489d |
static bool needs_quotation(const char *buf,int len);
|
|
Packit Service |
a2489d |
static bool needs_quotation(const char *buf) { return needs_quotation(buf,strlen(buf)); }
|
|
Packit Service |
a2489d |
static bool quotable(char c,char in_quotes);
|
|
Packit Service |
a2489d |
static bool is_space(char c) { return c==' ' || c=='\t'; }
|
|
Packit Service |
a2489d |
static bool is_quote(char c) { return c=='"' || c=='\''; }
|
|
Packit Service |
a2489d |
void FeedQuoted(const char *c);
|
|
Packit Service |
a2489d |
void Exit(int);
|
|
Packit Service |
a2489d |
void AtExit();
|
|
Packit Service |
a2489d |
void AtExitBg();
|
|
Packit Service |
a2489d |
void AtExitFg();
|
|
Packit Service |
a2489d |
void AtBackground();
|
|
Packit Service |
a2489d |
void AtTerminate();
|
|
Packit Service |
a2489d |
void EmptyCmds();
|
|
Packit Service |
a2489d |
bool WriteCmds(int fd) const;
|
|
Packit Service |
a2489d |
bool ReadCmds(int fd); // does not clear queue before reading (appends)
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void AddNewJob(Job *new_job);
|
|
Packit Service |
a2489d |
void SuspendJob(Job *j);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
CmdExec(FileAccess *s,LocalDirectory *c);
|
|
Packit Service |
a2489d |
CmdExec(CmdExec *parent);
|
|
Packit Service |
a2489d |
~CmdExec();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool Idle(); // when we have no command running and command buffer is empty
|
|
Packit Service |
a2489d |
int Done();
|
|
Packit Service |
a2489d |
int ExitCode() { return failed_exit_code ? failed_exit_code : exit_code; }
|
|
Packit Service |
a2489d |
int Do();
|
|
Packit Service |
a2489d |
xstring& FormatStatus(xstring&,int,const char *prefix="\t");
|
|
Packit Service |
a2489d |
void ShowRunStatus(const SMTaskRef<StatusLine>& s);
|
|
Packit Service |
a2489d |
int AcceptSig(int sig);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
const char *FormatPrompt(const char *scan);
|
|
Packit Service |
a2489d |
const char *MakePrompt();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool interactive;
|
|
Packit Service |
a2489d |
bool show_status;
|
|
Packit Service |
a2489d |
bool top_level;
|
|
Packit Service |
a2489d |
bool verbose;
|
|
Packit Service |
a2489d |
bool auto_terminate_in_bg;
|
|
Packit Service |
a2489d |
SMTaskRef<StatusLine> status_line;
|
|
Packit Service |
a2489d |
void SetCmdFeeder(CmdFeeder *new_feeder);
|
|
Packit Service |
a2489d |
void RemoveFeeder();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
friend char *command_generator(char *,int); // readline completor
|
|
Packit Service |
a2489d |
static const char *GetFullCommandName(const char *);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool remote_completion;
|
|
Packit Service |
a2489d |
int long_running;
|
|
Packit Service |
a2489d |
bool csh_history;
|
|
Packit Service |
a2489d |
bool verify_host;
|
|
Packit Service |
a2489d |
bool verify_path;
|
|
Packit Service |
a2489d |
bool verify_path_cached;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void Reconfig(const char *name=0);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void beep_if_long();
|
|
Packit Service |
a2489d |
time_t start_time;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static CmdExec *cwd_owner;
|
|
Packit Service |
a2489d |
Ref<LocalDirectory> cwd;
|
|
Packit Service |
a2489d |
void SaveCWD();
|
|
Packit Service |
a2489d |
int RestoreCWD();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
FDStream *default_output;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void top_vfprintf(FILE *file,const char *f,va_list v);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void SetInteractive(bool i);
|
|
Packit Service |
a2489d |
void SetInteractive();
|
|
Packit Service |
a2489d |
void SetTopLevel()
|
|
Packit Service |
a2489d |
{
|
|
Packit Service |
a2489d |
top_level=true;
|
|
Packit Service |
a2489d |
Reconfig(0);
|
|
Packit Service |
a2489d |
SetInteractive();
|
|
Packit Service |
a2489d |
}
|
|
Packit Service |
a2489d |
void SetStatusLine(StatusLine *s) { status_line=s; }
|
|
Packit Service |
a2489d |
void SetAutoTerminateInBackground(bool b) { auto_terminate_in_bg=b; }
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static void RegisterCommand(const char *name,cmd_creator_t creator,
|
|
Packit Service |
a2489d |
const char *short_name=0,const char *long_name=0);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
Job *builtin_lcd();
|
|
Packit Service |
a2489d |
Job *builtin_cd();
|
|
Packit Service |
a2489d |
Job *builtin_open();
|
|
Packit Service |
a2489d |
Job *builtin_exit();
|
|
Packit Service |
a2489d |
Job *builtin_lftp();
|
|
Packit Service |
a2489d |
Job *builtin_restart();
|
|
Packit Service |
a2489d |
Job *builtin_glob();
|
|
Packit Service |
a2489d |
Job *builtin_queue();
|
|
Packit Service |
a2489d |
Job *builtin_queue_edit();
|
|
Packit Service |
a2489d |
Job *builtin_local();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool load_cmd_module(const char *op);
|
|
Packit Service |
a2489d |
Job *default_cmd();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void ChangeSession(FileAccess *new_session);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
bool print_cmd_help(const char *cmd);
|
|
Packit Service |
a2489d |
void print_cmd_index();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static const char *CmdByIndex(int i);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void enable_debug(const char *opt=0);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
int last_bg;
|
|
Packit Service |
a2489d |
bool wait_all;
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void pre_stdout();
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
void ChangeSlot(const char *n);
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
static JobRef<CmdExec> top;
|
|
Packit Service |
a2489d |
};
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
extern const char * const bookmark_subcmd[];
|
|
Packit Service |
a2489d |
extern const char * const cache_subcmd[];
|
|
Packit Service |
a2489d |
|
|
Packit Service |
a2489d |
#endif//CMDEXEC_H
|