version 1.219, 2022/09/16 03:13:34 |
version 1.220, 2022/09/16 03:33:14 |
|
|
struct CMD { |
struct CMD { |
const char *c; |
const char *c; |
const int n; |
const int n; |
const int t; |
const int t; /* Completion type for the first argument */ |
|
const int t2; /* completion type for the optional second argument */ |
}; |
}; |
|
|
/* Type of completion */ |
/* Type of completion */ |
|
|
#define LOCAL 2 |
#define LOCAL 2 |
|
|
static const struct CMD cmds[] = { |
static const struct CMD cmds[] = { |
{ "bye", I_QUIT, NOARGS }, |
{ "bye", I_QUIT, NOARGS, NOARGS }, |
{ "cd", I_CHDIR, REMOTE }, |
{ "cd", I_CHDIR, REMOTE, NOARGS }, |
{ "chdir", I_CHDIR, REMOTE }, |
{ "chdir", I_CHDIR, REMOTE, NOARGS }, |
{ "chgrp", I_CHGRP, REMOTE }, |
{ "chgrp", I_CHGRP, REMOTE, NOARGS }, |
{ "chmod", I_CHMOD, REMOTE }, |
{ "chmod", I_CHMOD, REMOTE, NOARGS }, |
{ "chown", I_CHOWN, REMOTE }, |
{ "chown", I_CHOWN, REMOTE, NOARGS }, |
{ "copy", I_COPY, REMOTE }, |
{ "copy", I_COPY, REMOTE, LOCAL }, |
{ "cp", I_COPY, REMOTE }, |
{ "cp", I_COPY, REMOTE, LOCAL }, |
{ "df", I_DF, REMOTE }, |
{ "df", I_DF, REMOTE, NOARGS }, |
{ "dir", I_LS, REMOTE }, |
{ "dir", I_LS, REMOTE, NOARGS }, |
{ "exit", I_QUIT, NOARGS }, |
{ "exit", I_QUIT, NOARGS, NOARGS }, |
{ "get", I_GET, REMOTE }, |
{ "get", I_GET, REMOTE, LOCAL }, |
{ "help", I_HELP, NOARGS }, |
{ "help", I_HELP, NOARGS, NOARGS }, |
{ "lcd", I_LCHDIR, LOCAL }, |
{ "lcd", I_LCHDIR, LOCAL, NOARGS }, |
{ "lchdir", I_LCHDIR, LOCAL }, |
{ "lchdir", I_LCHDIR, LOCAL, NOARGS }, |
{ "lls", I_LLS, LOCAL }, |
{ "lls", I_LLS, LOCAL, NOARGS }, |
{ "lmkdir", I_LMKDIR, LOCAL }, |
{ "lmkdir", I_LMKDIR, LOCAL, NOARGS }, |
{ "ln", I_LINK, REMOTE }, |
{ "ln", I_LINK, REMOTE, REMOTE }, |
{ "lpwd", I_LPWD, LOCAL }, |
{ "lpwd", I_LPWD, LOCAL, NOARGS }, |
{ "ls", I_LS, REMOTE }, |
{ "ls", I_LS, REMOTE, NOARGS }, |
{ "lumask", I_LUMASK, NOARGS }, |
{ "lumask", I_LUMASK, NOARGS, NOARGS }, |
{ "mkdir", I_MKDIR, REMOTE }, |
{ "mkdir", I_MKDIR, REMOTE, NOARGS }, |
{ "mget", I_GET, REMOTE }, |
{ "mget", I_GET, REMOTE, LOCAL }, |
{ "mput", I_PUT, LOCAL }, |
{ "mput", I_PUT, LOCAL, REMOTE }, |
{ "progress", I_PROGRESS, NOARGS }, |
{ "progress", I_PROGRESS, NOARGS, NOARGS }, |
{ "put", I_PUT, LOCAL }, |
{ "put", I_PUT, LOCAL, REMOTE }, |
{ "pwd", I_PWD, REMOTE }, |
{ "pwd", I_PWD, REMOTE, NOARGS }, |
{ "quit", I_QUIT, NOARGS }, |
{ "quit", I_QUIT, NOARGS, NOARGS }, |
{ "reget", I_REGET, REMOTE }, |
{ "reget", I_REGET, REMOTE, LOCAL }, |
{ "rename", I_RENAME, REMOTE }, |
{ "rename", I_RENAME, REMOTE, REMOTE }, |
{ "reput", I_REPUT, LOCAL }, |
{ "reput", I_REPUT, LOCAL, REMOTE }, |
{ "rm", I_RM, REMOTE }, |
{ "rm", I_RM, REMOTE, NOARGS }, |
{ "rmdir", I_RMDIR, REMOTE }, |
{ "rmdir", I_RMDIR, REMOTE, NOARGS }, |
{ "symlink", I_SYMLINK, REMOTE }, |
{ "symlink", I_SYMLINK, REMOTE, REMOTE }, |
{ "version", I_VERSION, NOARGS }, |
{ "version", I_VERSION, NOARGS, NOARGS }, |
{ "!", I_SHELL, NOARGS }, |
{ "!", I_SHELL, NOARGS, NOARGS }, |
{ "?", I_HELP, NOARGS }, |
{ "?", I_HELP, NOARGS, NOARGS }, |
{ NULL, -1, -1 } |
{ NULL, -1, -1, -1 } |
}; |
}; |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
|
|
} |
} |
|
|
/* |
/* |
* Determine whether a particular sftp command's arguments (if any) |
* Determine whether a particular sftp command's arguments (if any) represent |
* represent local or remote files. |
* local or remote files. The "cmdarg" argument specifies the actual argument |
|
* and accepts values 1 or 2. |
*/ |
*/ |
static int |
static int |
complete_is_remote(char *cmd) { |
complete_is_remote(char *cmd, int cmdarg) { |
int i; |
int i; |
|
|
if (cmd == NULL) |
if (cmd == NULL) |
return -1; |
return -1; |
|
|
for (i = 0; cmds[i].c; i++) { |
for (i = 0; cmds[i].c; i++) { |
if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) |
if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c))) { |
return cmds[i].t; |
if (cmdarg == 1) |
|
return cmds[i].t; |
|
else if (cmdarg == 2) |
|
return cmds[i].t2; |
|
break; |
|
} |
} |
} |
|
|
return -1; |
return -1; |
|
|
ret = CC_REDISPLAY; |
ret = CC_REDISPLAY; |
} else if (carg >= 1) { |
} else if (carg >= 1) { |
/* Handle file parsing */ |
/* Handle file parsing */ |
int remote = complete_is_remote(argv[0]); |
int remote = 0; |
|
int i = 0, cmdarg = 0; |
char *filematch = NULL; |
char *filematch = NULL; |
|
|
if (carg > 1 && line[cursor-1] != ' ') |
if (carg > 1 && line[cursor-1] != ' ') |
filematch = argv[carg - 1]; |
filematch = argv[carg - 1]; |
|
|
|
for (i = 1; i < carg; i++) { |
|
/* Skip flags */ |
|
if (argv[i][0] != '-') |
|
cmdarg++; |
|
} |
|
|
|
/* |
|
* If previous argument is complete, then offer completion |
|
* on the next one. |
|
*/ |
|
if (line[cursor - 1] == ' ') |
|
cmdarg++; |
|
|
|
remote = complete_is_remote(argv[0], cmdarg); |
|
|
if ((remote == REMOTE || remote == LOCAL) && |
if ((remote == REMOTE || remote == LOCAL) && |
complete_match(el, complete_ctx->conn, |
complete_match(el, complete_ctx->conn, |