From 5521539314d87d3432e3c5c0e74954a673a884bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Wed, 23 Jul 2008 09:33:08 +0000 Subject: Vendor import of OpenSSH 5.1p1 --- sftp.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 10 deletions(-) (limited to 'sftp.c') diff --git a/sftp.c b/sftp.c index 861c3db05031..e1aa49d0f086 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.99 2008/01/20 00:38:30 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.103 2008/07/13 22:16:03 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -25,6 +25,9 @@ #include #include #include +#ifdef HAVE_SYS_STATVFS_H +#include +#endif #include #include @@ -44,6 +47,14 @@ typedef void EditLine; #include #include +#ifdef HAVE_UTIL_H +# include +#endif + +#ifdef HAVE_LIBUTIL_H +# include +#endif + #include "xmalloc.h" #include "log.h" #include "pathnames.h" @@ -64,7 +75,7 @@ int batchmode = 0; size_t copy_buffer_len = 32768; /* Number of concurrent outstanding requests */ -size_t num_requests = 16; +size_t num_requests = 64; /* PID of ssh transport process */ static pid_t sshpid = -1; @@ -104,6 +115,7 @@ extern char *__progname; #define I_CHGRP 2 #define I_CHMOD 3 #define I_CHOWN 4 +#define I_DF 24 #define I_GET 5 #define I_HELP 6 #define I_LCHDIR 7 @@ -136,6 +148,7 @@ static const struct CMD cmds[] = { { "chgrp", I_CHGRP }, { "chmod", I_CHMOD }, { "chown", I_CHOWN }, + { "df", I_DF }, { "dir", I_LS }, { "exit", I_QUIT }, { "get", I_GET }, @@ -200,6 +213,8 @@ help(void) printf("chgrp grp path Change group of file 'path' to 'grp'\n"); printf("chmod mode path Change permissions of file 'path' to 'mode'\n"); printf("chown own path Change owner of file 'path' to 'own'\n"); + printf("df [path] Display statistics for current directory or\n"); + printf(" filesystem containing 'path'\n"); printf("help Display this help text\n"); printf("get remote-path [local-path] Download file\n"); printf("lls [ls-options [path]] Display local directory listing\n"); @@ -349,7 +364,7 @@ infer_path(const char *p, char **ifp) static int parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag) { - extern int optind, optreset, opterr; + extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; @@ -363,7 +378,7 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag) *pflag = 1; break; default: - error("%s: Invalid flag -%c", cmd, ch); + error("%s: Invalid flag -%c", cmd, optopt); return -1; } } @@ -374,7 +389,7 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag) static int parse_ls_flags(char **argv, int argc, int *lflag) { - extern int optind, optreset, opterr; + extern int opterr, optind, optopt, optreset; int ch; optind = optreset = 1; @@ -413,7 +428,34 @@ parse_ls_flags(char **argv, int argc, int *lflag) *lflag |= LS_TIME_SORT; break; default: - error("ls: Invalid flag -%c", ch); + error("ls: Invalid flag -%c", optopt); + return -1; + } + } + + return optind; +} + +static int +parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag) +{ + extern int opterr, optind, optopt, optreset; + int ch; + + optind = optreset = 1; + opterr = 0; + + *hflag = *iflag = 0; + while ((ch = getopt(argc, argv, "hi")) != -1) { + switch (ch) { + case 'h': + *hflag = 1; + break; + case 'i': + *iflag = 1; + break; + default: + error("%s: Invalid flag -%c", cmd, optopt); return -1; } } @@ -797,6 +839,56 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, return (0); } +static int +do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) +{ + struct sftp_statvfs st; + char s_used[FMT_SCALED_STRSIZE]; + char s_avail[FMT_SCALED_STRSIZE]; + char s_root[FMT_SCALED_STRSIZE]; + char s_total[FMT_SCALED_STRSIZE]; + + if (do_statvfs(conn, path, &st, 1) == -1) + return -1; + if (iflag) { + printf(" Inodes Used Avail " + "(root) %%Capacity\n"); + printf("%11llu %11llu %11llu %11llu %3llu%%\n", + (unsigned long long)st.f_files, + (unsigned long long)(st.f_files - st.f_ffree), + (unsigned long long)st.f_favail, + (unsigned long long)st.f_ffree, + (unsigned long long)(100 * (st.f_files - st.f_ffree) / + st.f_files)); + } else if (hflag) { + strlcpy(s_used, "error", sizeof(s_used)); + strlcpy(s_avail, "error", sizeof(s_avail)); + strlcpy(s_root, "error", sizeof(s_root)); + strlcpy(s_total, "error", sizeof(s_total)); + fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used); + fmt_scaled(st.f_bavail * st.f_frsize, s_avail); + fmt_scaled(st.f_bfree * st.f_frsize, s_root); + fmt_scaled(st.f_blocks * st.f_frsize, s_total); + printf(" Size Used Avail (root) %%Capacity\n"); + printf("%7sB %7sB %7sB %7sB %3llu%%\n", + s_total, s_used, s_avail, s_root, + (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / + st.f_blocks)); + } else { + printf(" Size Used Avail " + "(root) %%Capacity\n"); + printf("%12llu %12llu %12llu %12llu %3llu%%\n", + (unsigned long long)(st.f_frsize * st.f_blocks / 1024), + (unsigned long long)(st.f_frsize * + (st.f_blocks - st.f_bfree) / 1024), + (unsigned long long)(st.f_frsize * st.f_bavail / 1024), + (unsigned long long)(st.f_frsize * st.f_bfree / 1024), + (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / + st.f_blocks)); + } + return 0; +} + /* * Undo escaping of glob sequences in place. Used to undo extra escaping * applied in makeargv() when the string is destined for a function that @@ -972,7 +1064,7 @@ makeargv(const char *arg, int *argcp) } static int -parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, +parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag, unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; @@ -1016,7 +1108,7 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, } /* Get arguments and parse flags */ - *lflag = *pflag = *n_arg = 0; + *lflag = *pflag = *hflag = *n_arg = 0; *path1 = *path2 = NULL; optidx = 1; switch (cmdnum) { @@ -1068,6 +1160,18 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, if (cmdnum != I_RM) undo_glob_escape(*path1); break; + case I_DF: + if ((optidx = parse_df_flags(cmd, argv, argc, hflag, + iflag)) == -1) + return -1; + /* Default to current directory if no path specified */ + if (argc - optidx < 1) + *path1 = NULL; + else { + *path1 = xstrdup(argv[optidx]); + undo_glob_escape(*path1); + } + break; case I_LS: if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1) return(-1); @@ -1130,7 +1234,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; - int pflag, lflag, iflag, cmdnum, i; + int pflag, lflag, iflag, hflag, cmdnum, i; unsigned long n_arg; Attrib a, *aa; char path_buf[MAXPATHLEN]; @@ -1138,7 +1242,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, glob_t g; path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, + cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg, &path1, &path2); if (iflag != 0) @@ -1232,6 +1336,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, path1 = make_absolute(path1, *pwd); err = do_globbed_ls(conn, path1, tmp, lflag); break; + case I_DF: + /* Default to current directory if no path specified */ + if (path1 == NULL) + path1 = xstrdup(*pwd); + path1 = make_absolute(path1, *pwd); + err = do_df(conn, path1, hflag, iflag); + break; case I_LCHDIR: if (chdir(path1) == -1) { error("Couldn't change local directory to " -- cgit v1.2.3