version 1.148, 2013/07/25 00:56:52 |
version 1.149, 2013/08/06 23:03:49 |
|
|
#define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) |
#define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) |
|
|
/* Commands for interactive mode */ |
/* Commands for interactive mode */ |
#define I_CHDIR 1 |
enum sftp_command { |
#define I_CHGRP 2 |
I_CHDIR = 1, |
#define I_CHMOD 3 |
I_CHGRP, |
#define I_CHOWN 4 |
I_CHMOD, |
#define I_DF 24 |
I_CHOWN, |
#define I_GET 5 |
I_DF, |
#define I_HELP 6 |
I_GET, |
#define I_LCHDIR 7 |
I_HELP, |
#define I_LINK 25 |
I_LCHDIR, |
#define I_LLS 8 |
I_LINK, |
#define I_LMKDIR 9 |
I_LLS, |
#define I_LPWD 10 |
I_LMKDIR, |
#define I_LS 11 |
I_LPWD, |
#define I_LUMASK 12 |
I_LS, |
#define I_MKDIR 13 |
I_LUMASK, |
#define I_PUT 14 |
I_MKDIR, |
#define I_PWD 15 |
I_PUT, |
#define I_QUIT 16 |
I_PWD, |
#define I_RENAME 17 |
I_QUIT, |
#define I_RM 18 |
I_RENAME, |
#define I_RMDIR 19 |
I_RM, |
#define I_SHELL 20 |
I_RMDIR, |
#define I_SYMLINK 21 |
I_SHELL, |
#define I_VERSION 22 |
I_SYMLINK, |
#define I_PROGRESS 23 |
I_VERSION, |
#define I_REGET 26 |
I_PROGRESS, |
|
I_REGET, |
|
}; |
|
|
struct CMD { |
struct CMD { |
const char *c; |
const char *c; |
|
|
error("stat %s: %s", g.gl_pathv[i], strerror(errno)); |
error("stat %s: %s", g.gl_pathv[i], strerror(errno)); |
continue; |
continue; |
} |
} |
|
|
tmp = xstrdup(g.gl_pathv[i]); |
tmp = xstrdup(g.gl_pathv[i]); |
if ((filename = basename(tmp)) == NULL) { |
if ((filename = basename(tmp)) == NULL) { |
error("basename %s: %s", tmp, strerror(errno)); |
error("basename %s: %s", tmp, strerror(errno)); |
|
|
* |
* |
* If "lastquote" is not NULL, the quoting character used for the last |
* If "lastquote" is not NULL, the quoting character used for the last |
* argument is placed in *lastquote ("\0", "'" or "\""). |
* argument is placed in *lastquote ("\0", "'" or "\""). |
* |
* |
* If "terminated" is not NULL, *terminated will be set to 1 when the |
* If "terminated" is not NULL, *terminated will be set to 1 when the |
* last argument's quote has been properly terminated or 0 otherwise. |
* last argument's quote has been properly terminated or 0 otherwise. |
* This parameter is only of use if "sloppy" is set. |
* This parameter is only of use if "sloppy" is set. |
|
|
state = q; |
state = q; |
if (lastquote != NULL) |
if (lastquote != NULL) |
*lastquote = arg[i]; |
*lastquote = arg[i]; |
} else if (state == MA_UNQUOTED) |
} else if (state == MA_UNQUOTED) |
state = q; |
state = q; |
else if (state == q) |
else if (state == q) |
state = MA_UNQUOTED; |
state = MA_UNQUOTED; |
|
|
char *tmp; |
char *tmp; |
|
|
/* Count entries for sort and find longest */ |
/* Count entries for sort and find longest */ |
for (y = 0; list[y]; y++) |
for (y = 0; list[y]; y++) |
m = MAX(m, strlen(list[y])); |
m = MAX(m, strlen(list[y])); |
|
|
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) |
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) |
|
|
for (y = 1; list[y]; y++) { |
for (y = 1; list[y]; y++) { |
u_int x; |
u_int x; |
|
|
for (x = 0; x < matchlen; x++) |
for (x = 0; x < matchlen; x++) |
if (list[0][x] != list[y][x]) |
if (list[0][x] != list[y][x]) |
break; |
break; |
|
|
matchlen = x; |
matchlen = x; |
|
|
tmp[matchlen] = '\0'; |
tmp[matchlen] = '\0'; |
return tmp; |
return tmp; |
} |
} |
} |
} |
|
|
return xstrdup(word); |
return xstrdup(word); |
} |
} |
|
|
if (cmd == NULL) { |
if (cmd == NULL) { |
for (y = 0; cmds[y].c; y++) |
for (y = 0; cmds[y].c; y++) |
list[count++] = xstrdup(cmds[y].c); |
list[count++] = xstrdup(cmds[y].c); |
|
|
list[count] = NULL; |
list[count] = NULL; |
complete_display(list, 0); |
complete_display(list, 0); |
|
|
for (y = 0; list[y] != NULL; y++) |
for (y = 0; list[y] != NULL; y++) |
free(list[y]); |
free(list[y]); |
free(list); |
free(list); |
return count; |
return count; |
} |
} |
|
|
/* Prepare subset of commands that start with "cmd" */ |
/* Prepare subset of commands that start with "cmd" */ |
cmdlen = strlen(cmd); |
cmdlen = strlen(cmd); |
for (y = 0; cmds[y].c; y++) { |
for (y = 0; cmds[y].c; y++) { |
if (!strncasecmp(cmd, cmds[y].c, cmdlen)) |
if (!strncasecmp(cmd, cmds[y].c, cmdlen)) |
list[count++] = xstrdup(cmds[y].c); |
list[count++] = xstrdup(cmds[y].c); |
} |
} |
list[count] = NULL; |
list[count] = NULL; |
|
|
if (count > 1) |
if (count > 1) |
complete_display(list, 0); |
complete_display(list, 0); |
|
|
for (y = 0; list[y]; y++) |
for (y = 0; list[y]; y++) |
free(list[y]); |
free(list[y]); |
free(list); |
free(list); |
|
|
if (tmp != NULL) { |
if (tmp != 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; |
return cmds[i].t; |
} |
} |
|
|
|
|
u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; |
u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; |
int clen; |
int clen; |
const LineInfo *lf; |
const LineInfo *lf; |
|
|
/* Glob from "file" location */ |
/* Glob from "file" location */ |
if (file == NULL) |
if (file == NULL) |
tmp = xstrdup("*"); |
tmp = xstrdup("*"); |
|
|
if (remote != LOCAL) { |
if (remote != LOCAL) { |
tmp = make_absolute(tmp, remote_path); |
tmp = make_absolute(tmp, remote_path); |
remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); |
remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); |
} else |
} else |
glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); |
glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g); |
|
|
/* Determine length of pwd so we can trim completion display */ |
/* Determine length of pwd so we can trim completion display */ |
for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { |
for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) { |
/* Terminate counting on first unescaped glob metacharacter */ |
/* Terminate counting on first unescaped glob metacharacter */ |
|
|
} |
} |
free(tmp); |
free(tmp); |
|
|
if (g.gl_matchc == 0) |
if (g.gl_matchc == 0) |
goto out; |
goto out; |
|
|
if (g.gl_matchc > 1) |
if (g.gl_matchc > 1) |
|
|
|
|
if (tmplen > (filelen - cesc)) { |
if (tmplen > (filelen - cesc)) { |
tmp2 = tmp + filelen - cesc; |
tmp2 = tmp + filelen - cesc; |
len = strlen(tmp2); |
len = strlen(tmp2); |
/* quote argument on way out */ |
/* quote argument on way out */ |
for (i = 0; i < len; i += clen) { |
for (i = 0; i < len; i += clen) { |
if ((clen = mblen(tmp2 + i, len - i)) < 0 || |
if ((clen = mblen(tmp2 + i, len - i)) < 0 || |
|
|
static unsigned char |
static unsigned char |
complete(EditLine *el, int ch) |
complete(EditLine *el, int ch) |
{ |
{ |
char **argv, *line, quote; |
char **argv, *line, quote; |
int argc, carg; |
int argc, carg; |
u_int cursor, len, terminated, ret = CC_ERROR; |
u_int cursor, len, terminated, ret = CC_ERROR; |
const LineInfo *lf; |
const LineInfo *lf; |
|
|
} else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { |
} else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') { |
/* Handle the command parsing */ |
/* Handle the command parsing */ |
if (complete_cmd_parse(el, argv[0], argc == carg, |
if (complete_cmd_parse(el, argv[0], argc == carg, |
quote, terminated) != 0) |
quote, terminated) != 0) |
ret = CC_REDISPLAY; |
ret = CC_REDISPLAY; |
} else if (carg >= 1) { |
} else if (carg >= 1) { |
/* Handle file parsing */ |
/* Handle file parsing */ |
|
|
if (remote != 0 && |
if (remote != 0 && |
complete_match(el, complete_ctx->conn, |
complete_match(el, complete_ctx->conn, |
*complete_ctx->remote_pathp, filematch, |
*complete_ctx->remote_pathp, filematch, |
remote, carg == argc, quote, terminated) != 0) |
remote, carg == argc, quote, terminated) != 0) |
ret = CC_REDISPLAY; |
ret = CC_REDISPLAY; |
} |
} |
|
|
free(line); |
free(line); |
return ret; |
return ret; |
} |
} |
|
|
|
|
el_source(el, NULL); |
el_source(el, NULL); |
|
|
/* Tab Completion */ |
/* Tab Completion */ |
el_set(el, EL_ADDFN, "ftp-complete", |
el_set(el, EL_ADDFN, "ftp-complete", |
"Context sensitive argument completion", complete); |
"Context sensitive argument completion", complete); |
complete_ctx.conn = conn; |
complete_ctx.conn = conn; |
complete_ctx.remote_pathp = &remote_path; |
complete_ctx.remote_pathp = &remote_path; |
|
|
extern char *__progname; |
extern char *__progname; |
|
|
fprintf(stderr, |
fprintf(stderr, |
"usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" |
"usage: %s [-1246Capqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" |
" [-D sftp_server_path] [-F ssh_config] " |
" [-D sftp_server_path] [-F ssh_config] " |
"[-i identity_file] [-l limit]\n" |
"[-i identity_file] [-l limit]\n" |
" [-o ssh_option] [-P port] [-R num_requests] " |
" [-o ssh_option] [-P port] [-R num_requests] " |