Bugzilla – Attachment 749 Details for
Bug 520
Recursive operations for sftp
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Add recurse mode to sftp put command via fts.
sftp-recursive-put.diff (text/plain), 20.20 KB, created by
Chase Phillips
on 2004-12-07 17:28:14 AEDT
(
hide
)
Description:
Add recurse mode to sftp put command via fts.
Filename:
MIME Type:
Creator:
Chase Phillips
Created:
2004-12-07 17:28:14 AEDT
Size:
20.20 KB
patch
obsolete
>diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/configure.ac openssh/openssh_sftp_mod-src/configure.ac >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/configure.ac 2004-01-26 21:03:39.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/configure.ac 2004-02-03 22:43:01.000000000 -0600 >@@ -469,7 +469,7 @@ > > # Checks for header files. > AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \ >- getopt.h glob.h ia.h lastlog.h limits.h login.h \ >+ fts.h getopt.h glob.h ia.h lastlog.h limits.h login.h \ > login_cap.h maillock.h netdb.h netgroup.h \ > netinet/in_systm.h pam/pam_appl.h paths.h pty.h readpassphrase.h \ > rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \ >@@ -754,7 +754,8 @@ > dnl Checks for library functions. Please keep in alphabetical order > AC_CHECK_FUNCS(\ > arc4random __b64_ntop b64_ntop __b64_pton b64_pton \ >- bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \ >+ bcopy bindresvport_sa calloc clock fchmod fchown freeaddrinfo \ >+ fts_close fts_open fts_read futimes \ > getaddrinfo getcwd getgrouplist getnameinfo getopt \ > getpeereid _getpty getrlimit getttyent glob inet_aton \ > inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \ >diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/includes.h openssh/openssh_sftp_mod-src/includes.h >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/includes.h 2004-01-26 21:03:39.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/includes.h 2004-02-03 22:43:01.000000000 -0600 >@@ -33,6 +33,7 @@ > #include <grp.h> > #include <time.h> > #include <dirent.h> >+#include <fts.h> > > #ifdef HAVE_LIMITS_H > # include <limits.h> /* For PATH_MAX */ >diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-common.c openssh/openssh_sftp_mod-src/sftp-common.c >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-common.c 2003-11-17 04:18:23.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/sftp-common.c 2004-02-03 22:43:01.000000000 -0600 >@@ -164,6 +164,8 @@ > return("Connection lost"); > case SSH2_FX_OP_UNSUPPORTED: > return("Operation unsupported"); >+ case SSH2_FX_FILE_ALREADY_EXISTS: >+ return("Already exists"); > default: > return("Unknown status"); > } >diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-int.c openssh/openssh_sftp_mod-src/sftp-int.c >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-int.c 2004-01-27 04:20:11.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/sftp-int.c 2004-02-03 22:43:01.000000000 -0600 >@@ -282,7 +282,7 @@ > } > > static int >-parse_getput_flags(const char **cpp, int *pflag) >+parse_getput_flags(const char **cpp, int *pflag, int *recursive_flag) > { > const char *cp = *cpp; > >@@ -293,6 +293,10 @@ > case 'P': > *pflag = 1; > break; >+ case 'r': >+ case 'R': >+ *recursive_flag = 1; >+ break; > default: > error("Invalid flag -%c", cp[1]); > return(-1); >@@ -420,6 +424,30 @@ > } > > static int >+is_symlink(char *path) >+{ >+ struct stat sb; >+ >+ if (stat(path, &sb) == -1) >+ fatal("stat %s: %s", path, strerror(errno)); >+ >+ return(S_ISLNK(sb.st_mode)); >+} >+ >+static int >+remote_file_exists(struct sftp_conn *conn, char *path) >+{ >+ Attrib *a; >+ >+ /* XXX: report errors? */ >+ if ((a = do_stat(conn, path, 1)) == NULL) >+ return(0); >+ if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) >+ return(0); >+ return(1); >+} >+ >+static int > remote_is_dir(struct sftp_conn *conn, char *path) > { > Attrib *a; >@@ -433,7 +461,312 @@ > } > > static int >-process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) >+remote_is_reg(struct sftp_conn *conn, char *path) >+{ >+ Attrib *a; >+ >+ /* XXX: report errors? */ >+ if ((a = do_stat(conn, path, 1)) == NULL) >+ return(0); >+ if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) >+ return(0); >+ return(a->perm & S_IFREG); >+} >+ >+static int >+remote_is_symlink(struct sftp_conn *conn, char *path) >+{ >+ Attrib *a; >+ >+ /* XXX: report errors? */ >+ if ((a = do_stat(conn, path, 1)) == NULL) >+ return(0); >+ if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) >+ return(0); >+ return(a->perm & S_IFLNK); >+} >+ >+char * >+str_replace(char *string, char *target, char *replacement) >+{ >+ char *strloc_p; >+ char *new_buffer; >+ int len; >+ >+ new_buffer = NULL; >+ new_buffer = xrealloc(new_buffer, 1); >+ new_buffer[0] = NULL; >+ >+ /* Search for the target string */ >+ >+ if ( NULL != (strloc_p = strstr(string, target)) ) { >+ /* Test for wherein the string we found the target. */ >+ >+ if (strloc_p != string) { >+ /* In the middle of the string */ >+ len = 0; >+ len += strlen(new_buffer); >+ len += strloc_p - string; >+ len += 1; /* for NULL byte */ >+ new_buffer = xrealloc(new_buffer, len); >+ new_buffer = strncpy(new_buffer, string, len); >+ } >+ >+ /* Put the replacement in place. */ >+ >+ len = 0; >+ len += strlen(new_buffer); >+ len += ( replacement == NULL ) ? 0 : strlen(replacement); >+ len += 1; /* for NULL byte added by strcat */ >+ new_buffer = xrealloc(new_buffer, len); >+ new_buffer = strcat(new_buffer, replacement); >+ >+ /* Advance the pointer past the target string. */ >+ >+ len = 0; >+ len += ( target == NULL ) ? 0 : strlen(target); >+ strloc_p += len; >+ >+ /* Add the rest of the old string to the new string. */ >+ >+ len = 0; >+ len += strlen(new_buffer); >+ len += ( strloc_p == NULL ) ? 0 : strlen(strloc_p); >+ len += 1; /* for NULL byte added by strcat */ >+ new_buffer = xrealloc(new_buffer, len); >+ new_buffer = strcat(new_buffer, strloc_p); >+ } >+ >+ return(new_buffer); >+} >+ >+static int >+do_recursive_upload(struct sftp_conn *conn, char *local_path, >+ char *remote_path, int pflag, char *pwd) >+{ >+ int this_rc = 1; /* our return value */ >+ int rc, len; /* internal return values, stores length values */ >+ >+ Attrib a; >+ >+ char link[MAXPATHLEN]; /* stores contents of symbolic links */ >+ char *remote_tmp; >+ char *tmp_path; >+ char **local_paths; /* for fts_open string array */ >+ >+ FTS *local_tree; /* for fts_open/fts_read */ >+ FTSENT *local_fsent; /* for fts_read */ >+ >+ /* Create the string array needed for fts_open. */ >+ >+ local_paths = calloc(2, sizeof(char *)); >+ local_paths[0] = local_path; >+ local_paths[1] = NULL; >+ >+ if ( NULL == (local_tree = fts_open(local_paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) ) { >+ fatal("do_recursive_upload: fts_open() returned null: %s", strerror(errno)); >+ } >+ >+ xfree(local_paths); >+ local_paths = NULL; >+ >+ /* Loop over all the fs entries in the tree. */ >+ >+ while ( NULL != (local_fsent = fts_read(local_tree)) ) { >+ switch (local_fsent->fts_info) { >+ case FTS_ERR: >+ case FTS_DNR: >+ case FTS_NS: >+ /* Fatal error generated from fts_read. */ >+ fatal("fts_read error: %s: %s", local_fsent->fts_path, strerror(local_fsent->fts_errno)); >+ case FTS_DOT: >+ /* We should *not* see dot directories since we're not using FTS_SEEDOT. */ >+ fatal("do_recursive_upload: fts_read returned dot directory but FTS_SEEDOT wasn't used! See fts(3) for more information."); >+ case FTS_D: >+ debug3("FTS_D: Will make the directory %s\n", local_fsent->fts_path); >+ >+ /* Create the directory on the remote machine. */ >+ attrib_clear(&a); >+ a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; >+ a.perm = 0777; >+ >+ if ( NULL != remote_path ) { >+ remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path); >+ } else { >+ remote_tmp = xstrdup(local_fsent->fts_path); >+ remote_tmp = make_absolute(remote_tmp, pwd); >+ } >+ >+ /* If the directory we plan to use is already in place, move on. */ >+ >+ if ( remote_is_dir(conn, remote_tmp) ) { >+ printf("%s already exists as directory\n", remote_tmp); >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ break; >+ } else if ( remote_file_exists(conn, remote_tmp) ) { >+ printf("%s already exists as non-directory... removing\n", remote_tmp); >+ >+ if ( -1 == do_rm(conn, remote_tmp) ) >+ { >+ error("Couldn't remove \"%s\"", remote_tmp); >+ this_rc = -1; >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ goto END; >+ } >+ } >+ >+ if ( -1 == do_mkdir(conn, remote_tmp, &a) ) { >+ error("Couldn't create remote directory \"%s\"", remote_tmp); >+ this_rc = -1; >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ goto END; >+ } else >+ printf("Created directory %s\n", remote_tmp); >+ >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ >+ break; >+ case FTS_F: >+ debug3("FTS_F: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path); >+ >+ /* Upload the file. */ >+ >+ if ( NULL != remote_path ) { >+ remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path); >+ } else { >+ remote_tmp = xstrdup(local_fsent->fts_path); >+ remote_tmp = make_absolute(remote_tmp, pwd); >+ } >+ >+ /* If the file we plan to upload is already in place, remove it. */ >+ >+ if ( remote_is_dir(conn, remote_tmp) ) { >+ printf("%s already exists as directory\n", remote_tmp); >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ break; >+ } else if ( remote_file_exists(conn, remote_tmp) ) { >+ printf("%s already exists as non-directory... removing\n", remote_tmp); >+ >+ if ( -1 == do_rm(conn, remote_tmp) ) >+ { >+ error("Couldn't remove \"%s\"", remote_tmp); >+ this_rc = -1; >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ goto END; >+ } >+ } >+ >+ if ( -1 == do_upload(conn, local_fsent->fts_accpath, remote_tmp, pflag) ) { >+ error("Couldn't upload \"%s\"", remote_tmp); >+ this_rc = -1; >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ goto END; >+ } >+ >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ >+ break; >+ case FTS_SL: >+ case FTS_SLNONE: >+ debug3("FTS_SL: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path); >+ >+ /* Read the fts_statp information and create a link on the remote machine. */ >+ >+ if ( -1 == (len = readlink(local_fsent->fts_accpath, link, sizeof(link) - 1)) ) { >+ error("Couldn't readlink \"%s\"", local_fsent->fts_accpath); >+ this_rc = -1; >+ goto END; >+ } >+ >+ link[len] = '\0'; >+ >+ if ( NULL != remote_path ) { >+ remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path); >+ } else { >+ remote_tmp = xstrdup(local_fsent->fts_path); >+ remote_tmp = make_absolute(remote_tmp, pwd); >+ } >+ >+ /* If the symlink we plan to make is already in place, remove it. */ >+ >+ if ( remote_is_dir(conn, remote_tmp) ) { >+ printf("%s already exists as directory\n", remote_tmp); >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ >+ if ( -1 == fts_set(local_tree, local_fsent, FTS_SKIP) ) { >+ fatal("fts_set error: %s: %s", local_fsent->fts_path, strerror(errno)); >+ } >+ >+ break; >+ } else if ( remote_file_exists(conn, remote_tmp) ) { >+ printf("%s already exists as non-directory... removing\n", remote_tmp); >+ >+ if ( -1 == do_rm(conn, remote_tmp) ) >+ { >+ error("Couldn't remove \"%s\"", remote_tmp); >+ this_rc = -1; >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ goto END; >+ } >+ } >+ >+ if ( -1 == do_symlink(conn, link, remote_tmp) ) { >+ error("Couldn't symlink \"%s\"", remote_tmp); >+ this_rc = -1; >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ goto END; >+ } else >+ printf("Created symlink %s -> %s\n", remote_tmp, link); >+ >+ xfree(remote_tmp); >+ remote_tmp = NULL; >+ >+ break; >+ case FTS_DEFAULT: >+ debug3("FTS_DEFAULT: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path); >+ error("skipping non-regular file %s", local_fsent->fts_accpath); >+ break; >+ case FTS_DC: /* Directory visited in a cycle, already exists on remote machine from FTS_D, non-error */ >+ case FTS_DP: /* Directory visited in post-order, non-error */ >+ /* Do-nothing cases. */ >+ break; >+ default: >+ /* Unknown/unaccounted for FTS_* case. Cause a fatal error. */ >+ error("skipping non-regular file %s", local_fsent->fts_accpath); >+ debug3("do_recursive_upload: fts_read returned unknown case! See fts(3) for more information."); >+ debug3("type: %d, ", local_fsent->fts_info); >+ debug3("local path: %s, ", local_fsent->fts_accpath); >+ debug3("remote path: %s\n", local_fsent->fts_path); >+ break; >+ } >+ >+ } >+ >+ /* Break out of the while loop. */ >+ END: >+ >+ /* Finished processing, close the tree. */ >+ if ( -1 == (rc = fts_close(local_tree)) ) { >+ fatal("do_recursive_upload: fts_close() returned error: %s", strerror(errno)); >+ } >+ >+ return this_rc; >+} >+ >+static int >+process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag, >+ int recursive_flag) > { > char *abs_src = NULL; > char *abs_dst = NULL; >@@ -499,8 +832,31 @@ > return(err); > } > >+/* >+ * The inputs into the upload is file-glob fg. fg matches a set of >+ * local files {f1..fn}. For src-fsent in {f1..fn}: >+ * >+ * if (src-fsent is a file) { >+ * * Recursive upload is irrelevant. Use standard upload rules for >+ * this file. >+ * } else if (src-fsent is a directory) { >+ * if (dst exists) { >+ * if (dst is a directory) { >+ * Put (local) src-fsent as (remote) dst/src-fsent >+ * } else * dst is not directory * { >+ * Error out, no way to add into dst/src-fsent (dst is a file!) >+ * } >+ * } else * dst doesn't exist * { >+ * create a directory dst >+ * let all paths src-fsent/{f1..fn} become dst/{f1..fn} >+ * } >+ * } else * src-fsent is an un-uploadable filetype * { >+ * } >+ */ >+ > static int >-process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) >+process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag, >+ int recursive_flag) > { > char *tmp_dst = NULL; > char *abs_dst = NULL; >@@ -531,37 +887,85 @@ > } > > for (i = 0; g.gl_pathv[i]; i++) { >- if (!is_reg(g.gl_pathv[i])) { >- error("skipping non-regular file %s", >- g.gl_pathv[i]); >- continue; >- } >- if (infer_path(g.gl_pathv[i], &tmp)) { >- err = -1; >- goto out; >- } >+ if (recursive_flag) { >+ if ( !is_reg(g.gl_pathv[i]) && !is_dir(g.gl_pathv[i]) && !is_symlink(g.gl_pathv[i])) { >+ error("skipping %s", g.gl_pathv[i]); >+ continue; >+ } > >- if (g.gl_matchc == 1 && tmp_dst) { >- /* If directory specified, append filename */ >- if (remote_is_dir(conn, tmp_dst)) { >- if (infer_path(g.gl_pathv[0], &tmp)) { >+ if (tmp_dst) { >+ if (remote_is_dir(conn, tmp_dst)) { >+ /* If directory specified, append filename */ >+ if (infer_path(g.gl_pathv[i], &tmp)) { >+ err = 1; >+ goto out; >+ } >+ abs_dst = path_append(tmp_dst, tmp); >+ xfree(tmp); >+ tmp = NULL; >+ } else { >+ /* >+ * Possible cases: >+ * 1. Upload the file/dir to remote, overwriting remote file: dup specified name >+ * 2. Remote tmp_dst doesn't exist: dup specified name >+ * >+ * Impossible cases: >+ * 1. tmp_dst specified, more than one match, and !remote_is_dir() checked for earlier. >+ */ >+ abs_dst = xstrdup(tmp_dst); >+ abs_dst = make_absolute(tmp_dst, pwd); >+ } >+ } else { >+ if (infer_path(g.gl_pathv[i], &tmp)) { > err = 1; > goto out; > } >+ abs_dst = make_absolute(tmp, pwd); >+ xfree(tmp); >+ tmp = NULL; >+ } >+ >+ printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); >+ if (do_recursive_upload(conn, g.gl_pathv[i], abs_dst, pflag, pwd) == -1) >+ err = -1; >+ } else { >+ if (!is_reg(g.gl_pathv[i])) { >+ error("skipping non-regular file %s", >+ g.gl_pathv[i]); >+ continue; >+ } >+ if (infer_path(g.gl_pathv[i], &tmp)) { >+ err = -1; >+ goto out; >+ } >+ >+ if (g.gl_matchc == 1 && tmp_dst) { >+ /* If directory specified, append filename */ >+ if (remote_is_dir(conn, tmp_dst)) { >+ if (infer_path(g.gl_pathv[0], &tmp)) { >+ err = 1; >+ goto out; >+ } >+ abs_dst = path_append(tmp_dst, tmp); >+ xfree(tmp); >+ tmp = NULL; >+ } else >+ abs_dst = xstrdup(tmp_dst); >+ >+ } else if (tmp_dst) { > abs_dst = path_append(tmp_dst, tmp); > xfree(tmp); >+ tmp = NULL; > } else >- abs_dst = xstrdup(tmp_dst); >+ abs_dst = make_absolute(tmp, pwd); > >- } else if (tmp_dst) { >- abs_dst = path_append(tmp_dst, tmp); >- xfree(tmp); >- } else >- abs_dst = make_absolute(tmp, pwd); >+ printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); >+ if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1) >+ err = -1; >+ } > >- printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst); >- if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1) >- err = -1; >+ xfree(abs_dst); >+ abs_dst = NULL; > } > > out: >@@ -746,7 +1150,7 @@ > } > > 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 *recursive_flag, > unsigned long *n_arg, char **path1, char **path2) > { > const char *cmd, *cp = *cpp; >@@ -794,12 +1198,12 @@ > } > > /* Get arguments and parse flags */ >- *lflag = *pflag = *n_arg = 0; >+ *lflag = *pflag = *recursive_flag = *n_arg = 0; > *path1 = *path2 = NULL; > switch (cmdnum) { > case I_GET: > case I_PUT: >- if (parse_getput_flags(&cp, pflag)) >+ if (parse_getput_flags(&cp, pflag, recursive_flag)) > return(-1); > /* Get first pathname (mandatory) */ > if (get_pathname(&cp, path1)) >@@ -905,7 +1309,7 @@ > int err_abort) > { > char *path1, *path2, *tmp; >- int pflag, lflag, iflag, cmdnum, i; >+ int pflag, lflag, iflag, recursive_flag, cmdnum, i; > unsigned long n_arg; > Attrib a, *aa; > char path_buf[MAXPATHLEN]; >@@ -913,7 +1317,7 @@ > glob_t g; > > path1 = path2 = NULL; >- cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, >+ cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &recursive_flag, &n_arg, > &path1, &path2); > > if (iflag != 0) >@@ -931,10 +1335,10 @@ > err = -1; > break; > case I_GET: >- err = process_get(conn, path1, path2, *pwd, pflag); >+ err = process_get(conn, path1, path2, *pwd, pflag, recursive_flag); > break; > case I_PUT: >- err = process_put(conn, path1, path2, *pwd, pflag); >+ err = process_put(conn, path1, path2, *pwd, pflag, recursive_flag); > break; > case I_RENAME: > path1 = make_absolute(path1, *pwd); >diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-server.c openssh/openssh_sftp_mod-src/sftp-server.c >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-server.c 2003-11-17 04:18:23.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/sftp-server.c 2004-02-03 22:43:01.000000000 -0600 >@@ -86,6 +86,9 @@ > case EINVAL: > ret = SSH2_FX_BAD_MESSAGE; > break; >+ case EEXIST: >+ ret = SSH2_FX_FILE_ALREADY_EXISTS; >+ break; > default: > ret = SSH2_FX_FAILURE; > break; >diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.0 openssh/openssh_sftp_mod-src/sftp.0 >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.0 2004-01-27 04:22:19.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/sftp.0 2004-02-03 22:43:02.000000000 -0600 >@@ -181,12 +181,15 @@ > > progress Toggle display of progress meter. > >+ recurse Toggle recursive operations. >+ > put [flags] local-path [remote-path] > Upload local-path and store it on the remote machine. If the > remote path name is not specified, it is given the same name > it has on the local machine. If the -P flag is specified, > then the file's full permission and access time are copied >- too. >+ too. If the -r flag is specified, then the upload is per- >+ formed recursively. > > pwd Display remote working directory. > >diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.1 openssh/openssh_sftp_mod-src/sftp.1 >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.1 2004-01-20 18:00:05.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/sftp.1 2004-02-03 22:43:01.000000000 -0600 >@@ -307,6 +307,8 @@ > .Ar path . > .It Ic progress > Toggle display of progress meter. >+.It Ic recurse >+Toggle recursive operations. > .It Xo Ic put > .Op Ar flags > .Ar local-path >@@ -321,6 +323,9 @@ > .Fl P > flag is specified, then the file's full permission and access time are > copied too. >+If the >+.Fl r >+flag is specified, then the upload is performed recursively. > .It Ic pwd > Display remote working directory. > .It Ic quit >diff -Nur /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.h openssh/openssh_sftp_mod-src/sftp.h >--- /home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.h 2002-02-12 21:10:33.000000000 -0600 >+++ openssh/openssh_sftp_mod-src/sftp.h 2004-02-03 22:43:01.000000000 -0600 >@@ -89,4 +89,5 @@ > #define SSH2_FX_NO_CONNECTION 6 > #define SSH2_FX_CONNECTION_LOST 7 > #define SSH2_FX_OP_UNSUPPORTED 8 >-#define SSH2_FX_MAX 8 >+#define SSH2_FX_FILE_ALREADY_EXISTS 9 >+#define SSH2_FX_MAX 9
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 520
: 749