]> andersk Git - gssapi-openssh.git/blobdiff - openssh/sftp.c
merged OpenSSH 5.1p1 to trunk
[gssapi-openssh.git] / openssh / sftp.c
index 861c3db05031c20f239b578705b958671707ecbe..e1aa49d0f0863eefdacf7b24b8685842c8159188 100644 (file)
@@ -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 <djm@openbsd.org>
  *
@@ -25,6 +25,9 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
 
 #include <ctype.h>
 #include <errno.h>
@@ -44,6 +47,14 @@ typedef void EditLine;
 #include <unistd.h>
 #include <stdarg.h>
 
+#ifdef HAVE_UTIL_H
+# include <util.h>
+#endif
+
+#ifdef HAVE_LIBUTIL_H
+# include <libutil.h>
+#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 "
This page took 0.098395 seconds and 4 git commands to generate.