View | Details | Raw Unified | Return to bug 520
Collapse All | Expand All

(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/configure.ac (-2 / +3 lines)
Lines 469-475 Link Here
469
469
470
# Checks for header files.
470
# Checks for header files.
471
AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \
471
AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \
472
	getopt.h glob.h ia.h lastlog.h limits.h login.h \
472
	fts.h getopt.h glob.h ia.h lastlog.h limits.h login.h \
473
	login_cap.h maillock.h netdb.h netgroup.h \
473
	login_cap.h maillock.h netdb.h netgroup.h \
474
	netinet/in_systm.h pam/pam_appl.h paths.h pty.h readpassphrase.h \
474
	netinet/in_systm.h pam/pam_appl.h paths.h pty.h readpassphrase.h \
475
	rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \
475
	rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \
Lines 754-760 Link Here
754
dnl    Checks for library functions. Please keep in alphabetical order
754
dnl    Checks for library functions. Please keep in alphabetical order
755
AC_CHECK_FUNCS(\
755
AC_CHECK_FUNCS(\
756
	arc4random __b64_ntop b64_ntop __b64_pton b64_pton \
756
	arc4random __b64_ntop b64_ntop __b64_pton b64_pton \
757
	bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \
757
	bcopy bindresvport_sa calloc clock fchmod fchown freeaddrinfo \
758
	fts_close fts_open fts_read futimes \
758
	getaddrinfo getcwd getgrouplist getnameinfo getopt \
759
	getaddrinfo getcwd getgrouplist getnameinfo getopt \
759
	getpeereid _getpty getrlimit getttyent glob inet_aton \
760
	getpeereid _getpty getrlimit getttyent glob inet_aton \
760
	inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \
761
	inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \
(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/includes.h (+1 lines)
Lines 33-38 Link Here
33
#include <grp.h>
33
#include <grp.h>
34
#include <time.h>
34
#include <time.h>
35
#include <dirent.h>
35
#include <dirent.h>
36
#include <fts.h>
36
37
37
#ifdef HAVE_LIMITS_H
38
#ifdef HAVE_LIMITS_H
38
# include <limits.h> /* For PATH_MAX */
39
# include <limits.h> /* For PATH_MAX */
(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-common.c (+2 lines)
Lines 164-169 Link Here
164
		return("Connection lost");
164
		return("Connection lost");
165
	case SSH2_FX_OP_UNSUPPORTED:
165
	case SSH2_FX_OP_UNSUPPORTED:
166
		return("Operation unsupported");
166
		return("Operation unsupported");
167
	case SSH2_FX_FILE_ALREADY_EXISTS:
168
		return("Already exists");
167
	default:
169
	default:
168
		return("Unknown status");
170
		return("Unknown status");
169
	}
171
	}
(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-int.c (-32 / +436 lines)
Lines 282-288 Link Here
282
}
282
}
283
283
284
static int
284
static int
285
parse_getput_flags(const char **cpp, int *pflag)
285
parse_getput_flags(const char **cpp, int *pflag, int *recursive_flag)
286
{
286
{
287
	const char *cp = *cpp;
287
	const char *cp = *cpp;
288
288
Lines 293-298 Link Here
293
		case 'P':
293
		case 'P':
294
			*pflag = 1;
294
			*pflag = 1;
295
			break;
295
			break;
296
		case 'r':
297
		case 'R':
298
			*recursive_flag = 1;
299
			break;
296
		default:
300
		default:
297
			error("Invalid flag -%c", cp[1]);
301
			error("Invalid flag -%c", cp[1]);
298
			return(-1);
302
			return(-1);
Lines 420-425 Link Here
420
}
424
}
421
425
422
static int
426
static int
427
is_symlink(char *path)
428
{
429
	struct stat sb;
430
431
	if (stat(path, &sb) == -1)
432
		fatal("stat %s: %s", path, strerror(errno));
433
434
	return(S_ISLNK(sb.st_mode));
435
}
436
437
static int
438
remote_file_exists(struct sftp_conn *conn, char *path)
439
{
440
	Attrib *a;
441
442
	/* XXX: report errors? */
443
	if ((a = do_stat(conn, path, 1)) == NULL)
444
		return(0);
445
	if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
446
		return(0);
447
	return(1);
448
}
449
450
static int
423
remote_is_dir(struct sftp_conn *conn, char *path)
451
remote_is_dir(struct sftp_conn *conn, char *path)
424
{
452
{
425
	Attrib *a;
453
	Attrib *a;
Lines 433-439 Link Here
433
}
461
}
434
462
435
static int
463
static int
436
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
464
remote_is_reg(struct sftp_conn *conn, char *path)
465
{
466
	Attrib *a;
467
468
	/* XXX: report errors? */
469
	if ((a = do_stat(conn, path, 1)) == NULL)
470
		return(0);
471
	if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
472
		return(0);
473
	return(a->perm & S_IFREG);
474
}
475
476
static int
477
remote_is_symlink(struct sftp_conn *conn, char *path)
478
{
479
	Attrib *a;
480
481
	/* XXX: report errors? */
482
	if ((a = do_stat(conn, path, 1)) == NULL)
483
		return(0);
484
	if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
485
		return(0);
486
	return(a->perm & S_IFLNK);
487
}
488
489
char *
490
str_replace(char *string, char *target, char *replacement)
491
{
492
	char *strloc_p;
493
	char *new_buffer;
494
	int len;
495
496
	new_buffer = NULL;
497
	new_buffer = xrealloc(new_buffer, 1);
498
	new_buffer[0] = NULL;
499
500
	/* Search for the target string */
501
502
	if ( NULL != (strloc_p = strstr(string, target)) ) {
503
		/* Test for wherein the string we found the target. */
504
505
		if (strloc_p != string) {
506
			/* In the middle of the string */
507
			len = 0;
508
			len += strlen(new_buffer);
509
			len += strloc_p - string;
510
			len += 1; /* for NULL byte */
511
			new_buffer = xrealloc(new_buffer, len);
512
			new_buffer = strncpy(new_buffer, string, len);
513
		}
514
515
		/* Put the replacement in place. */
516
517
		len = 0;
518
		len += strlen(new_buffer);
519
		len += ( replacement == NULL ) ? 0 : strlen(replacement);
520
		len += 1; /* for NULL byte added by strcat */
521
		new_buffer = xrealloc(new_buffer, len);
522
		new_buffer = strcat(new_buffer, replacement);
523
524
		/* Advance the pointer past the target string. */
525
526
		len = 0;
527
		len += ( target == NULL ) ? 0 : strlen(target);
528
		strloc_p += len;
529
530
		/* Add the rest of the old string to the new string. */
531
532
		len = 0;
533
		len += strlen(new_buffer);
534
		len += ( strloc_p == NULL ) ? 0 : strlen(strloc_p);
535
		len += 1; /* for NULL byte added by strcat */
536
		new_buffer = xrealloc(new_buffer, len);
537
		new_buffer = strcat(new_buffer, strloc_p);
538
	}
539
540
	return(new_buffer);
541
}
542
543
static int
544
do_recursive_upload(struct sftp_conn *conn, char *local_path,
545
		    char *remote_path, int pflag, char *pwd)
546
{
547
	int this_rc = 1;		/* our return value */
548
	int rc, len;			/* internal return values, stores length values */
549
550
	Attrib a;
551
552
	char link[MAXPATHLEN];		/* stores contents of symbolic links */
553
	char *remote_tmp;
554
	char *tmp_path;
555
	char **local_paths;		/* for fts_open string array */
556
557
	FTS *local_tree;		/* for fts_open/fts_read */
558
	FTSENT *local_fsent;		/* for fts_read */
559
560
	/* Create the string array needed for fts_open. */
561
562
	local_paths = calloc(2, sizeof(char *));
563
	local_paths[0] = local_path;
564
	local_paths[1] = NULL;
565
566
	if ( NULL == (local_tree = fts_open(local_paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) ) {
567
		fatal("do_recursive_upload: fts_open() returned null: %s", strerror(errno));
568
	}
569
570
	xfree(local_paths);
571
	local_paths = NULL;
572
573
	/* Loop over all the fs entries in the tree. */
574
575
	while ( NULL != (local_fsent = fts_read(local_tree)) ) {
576
		switch (local_fsent->fts_info) {
577
		case FTS_ERR:
578
		case FTS_DNR:
579
		case FTS_NS:
580
			/* Fatal error generated from fts_read. */
581
			fatal("fts_read error: %s: %s", local_fsent->fts_path, strerror(local_fsent->fts_errno));
582
		case FTS_DOT:
583
			/* We should *not* see dot directories since we're not using FTS_SEEDOT. */
584
			fatal("do_recursive_upload: fts_read returned dot directory but FTS_SEEDOT wasn't used! See fts(3) for more information.");
585
		case FTS_D:
586
			debug3("FTS_D: Will make the directory %s\n", local_fsent->fts_path);
587
588
			/* Create the directory on the remote machine. */
589
			attrib_clear(&a);
590
			a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
591
			a.perm = 0777;
592
593
			if ( NULL != remote_path ) {
594
				remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path);
595
			} else {
596
				remote_tmp = xstrdup(local_fsent->fts_path);
597
				remote_tmp = make_absolute(remote_tmp, pwd);
598
			}
599
600
			/* If the directory we plan to use is already in place, move on. */
601
602
			if ( remote_is_dir(conn, remote_tmp) ) {
603
				printf("%s already exists as directory\n", remote_tmp);
604
				xfree(remote_tmp);
605
				remote_tmp = NULL;
606
				break;
607
			} else if ( remote_file_exists(conn, remote_tmp) ) {
608
				printf("%s already exists as non-directory... removing\n", remote_tmp);
609
610
				if ( -1 == do_rm(conn, remote_tmp) )
611
				{
612
					error("Couldn't remove \"%s\"", remote_tmp);
613
					this_rc = -1;
614
					xfree(remote_tmp);
615
					remote_tmp = NULL;
616
					goto END;
617
				}
618
			}
619
620
			if ( -1 == do_mkdir(conn, remote_tmp, &a) ) {
621
				error("Couldn't create remote directory \"%s\"", remote_tmp);
622
				this_rc = -1;
623
				xfree(remote_tmp);
624
				remote_tmp = NULL;
625
				goto END;
626
			} else
627
				printf("Created directory %s\n", remote_tmp);
628
629
			xfree(remote_tmp);
630
			remote_tmp = NULL;
631
632
			break;
633
		case FTS_F:
634
			debug3("FTS_F: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path);
635
636
			/* Upload the file. */
637
638
			if ( NULL != remote_path ) {
639
				remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path);
640
			} else {
641
				remote_tmp = xstrdup(local_fsent->fts_path);
642
				remote_tmp = make_absolute(remote_tmp, pwd);
643
			}
644
645
			/* If the file we plan to upload is already in place, remove it. */
646
647
			if ( remote_is_dir(conn, remote_tmp) ) {
648
				printf("%s already exists as directory\n", remote_tmp);
649
				xfree(remote_tmp);
650
				remote_tmp = NULL;
651
				break;
652
			} else if ( remote_file_exists(conn, remote_tmp) ) {
653
				printf("%s already exists as non-directory... removing\n", remote_tmp);
654
655
				if ( -1 == do_rm(conn, remote_tmp) )
656
				{
657
					error("Couldn't remove \"%s\"", remote_tmp);
658
					this_rc = -1;
659
					xfree(remote_tmp);
660
					remote_tmp = NULL;
661
					goto END;
662
				}
663
			}
664
665
			if ( -1 == do_upload(conn, local_fsent->fts_accpath, remote_tmp, pflag) ) {
666
				error("Couldn't upload \"%s\"", remote_tmp);
667
				this_rc = -1;
668
				xfree(remote_tmp);
669
				remote_tmp = NULL;
670
				goto END;
671
			}
672
673
			xfree(remote_tmp);
674
			remote_tmp = NULL;
675
676
			break;
677
		case FTS_SL:
678
		case FTS_SLNONE:
679
			debug3("FTS_SL: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path);
680
681
			/* Read the fts_statp information and create a link on the remote machine. */
682
683
			if ( -1 == (len = readlink(local_fsent->fts_accpath, link, sizeof(link) - 1)) ) {
684
				error("Couldn't readlink \"%s\"", local_fsent->fts_accpath);
685
				this_rc = -1;
686
				goto END;
687
			}
688
689
			link[len] = '\0';
690
691
			if ( NULL != remote_path ) {
692
				remote_tmp = str_replace(local_fsent->fts_path, local_path, remote_path);
693
			} else {
694
				remote_tmp = xstrdup(local_fsent->fts_path);
695
				remote_tmp = make_absolute(remote_tmp, pwd);
696
			}
697
698
			/* If the symlink we plan to make is already in place, remove it. */
699
700
			if ( remote_is_dir(conn, remote_tmp) ) {
701
				printf("%s already exists as directory\n", remote_tmp);
702
				xfree(remote_tmp);
703
				remote_tmp = NULL;
704
705
				if ( -1 == fts_set(local_tree, local_fsent, FTS_SKIP) ) {
706
					fatal("fts_set error: %s: %s", local_fsent->fts_path, strerror(errno));
707
				}
708
709
				break;
710
			} else if ( remote_file_exists(conn, remote_tmp) ) {
711
				printf("%s already exists as non-directory... removing\n", remote_tmp);
712
713
				if ( -1 == do_rm(conn, remote_tmp) )
714
				{
715
					error("Couldn't remove \"%s\"", remote_tmp);
716
					this_rc = -1;
717
					xfree(remote_tmp);
718
					remote_tmp = NULL;
719
					goto END;
720
				}
721
			}
722
723
			if ( -1 == do_symlink(conn, link, remote_tmp) ) {
724
				error("Couldn't symlink \"%s\"", remote_tmp);
725
				this_rc = -1;
726
				xfree(remote_tmp);
727
				remote_tmp = NULL;
728
				goto END;
729
			} else
730
				printf("Created symlink %s -> %s\n", remote_tmp, link);
731
732
			xfree(remote_tmp);
733
			remote_tmp = NULL;
734
735
			break;
736
		case FTS_DEFAULT:
737
			debug3("FTS_DEFAULT: %s -> %s\n", local_fsent->fts_accpath, local_fsent->fts_path);
738
			error("skipping non-regular file %s", local_fsent->fts_accpath);
739
			break;
740
		case FTS_DC: /* Directory visited in a cycle, already exists on remote machine from FTS_D, non-error */
741
		case FTS_DP: /* Directory visited in post-order, non-error */
742
			/* Do-nothing cases. */
743
			break;
744
		default:
745
			/* Unknown/unaccounted for FTS_* case.  Cause a fatal error. */
746
			error("skipping non-regular file %s", local_fsent->fts_accpath);
747
			debug3("do_recursive_upload: fts_read returned unknown case! See fts(3) for more information.");
748
			debug3("type: %d, ", local_fsent->fts_info);
749
			debug3("local path: %s, ", local_fsent->fts_accpath);
750
			debug3("remote path: %s\n", local_fsent->fts_path);
751
			break;
752
		}
753
754
	}
755
756
	/* Break out of the while loop. */
757
	END:
758
759
	/* Finished processing, close the tree. */
760
	if ( -1 == (rc = fts_close(local_tree)) ) {
761
		fatal("do_recursive_upload: fts_close() returned error: %s", strerror(errno));
762
	}
763
764
	return this_rc;
765
}
766
767
static int
768
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag,
769
	    int recursive_flag)
437
{
770
{
438
	char *abs_src = NULL;
771
	char *abs_src = NULL;
439
	char *abs_dst = NULL;
772
	char *abs_dst = NULL;
Lines 499-506 Link Here
499
	return(err);
832
	return(err);
500
}
833
}
501
834
835
/*
836
 * The inputs into the upload is file-glob fg.  fg matches a set of 
837
 * local files {f1..fn}.  For src-fsent in {f1..fn}:
838
 *  
839
 *   if (src-fsent is a file) {
840
 *     * Recursive upload is irrelevant.  Use standard upload rules for 
841
 *       this file.
842
 *   } else if (src-fsent is a directory) {
843
 *     if (dst exists) {
844
 *       if (dst is a directory) {
845
 *         Put (local) src-fsent as (remote) dst/src-fsent
846
 *       } else * dst is not directory * {
847
 *         Error out, no way to add into dst/src-fsent (dst is a file!)
848
 *       }
849
 *     } else * dst doesn't exist * {
850
 *       create a directory dst
851
 *       let all paths src-fsent/{f1..fn} become dst/{f1..fn}
852
 *     }
853
 *   } else * src-fsent is an un-uploadable filetype * {
854
 *   }
855
 */
856
502
static int
857
static int
503
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
858
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag,
859
	    int recursive_flag)
504
{
860
{
505
	char *tmp_dst = NULL;
861
	char *tmp_dst = NULL;
506
	char *abs_dst = NULL;
862
	char *abs_dst = NULL;
Lines 531-567 Link Here
531
	}
887
	}
532
888
533
	for (i = 0; g.gl_pathv[i]; i++) {
889
	for (i = 0; g.gl_pathv[i]; i++) {
534
		if (!is_reg(g.gl_pathv[i])) {
890
		if (recursive_flag) {
535
			error("skipping non-regular file %s",
891
			if ( !is_reg(g.gl_pathv[i]) && !is_dir(g.gl_pathv[i]) && !is_symlink(g.gl_pathv[i])) {
536
			    g.gl_pathv[i]);
892
				error("skipping %s", g.gl_pathv[i]);
537
			continue;
893
				continue;
538
		}
894
			}
539
		if (infer_path(g.gl_pathv[i], &tmp)) {
540
			err = -1;
541
			goto out;
542
		}
543
895
544
		if (g.gl_matchc == 1 && tmp_dst) {
896
			if (tmp_dst) {
545
			/* If directory specified, append filename */
897
				if (remote_is_dir(conn, tmp_dst)) {
546
			if (remote_is_dir(conn, tmp_dst)) {
898
					/* If directory specified, append filename */
547
				if (infer_path(g.gl_pathv[0], &tmp)) {
899
					if (infer_path(g.gl_pathv[i], &tmp)) {
900
						err = 1;
901
						goto out;
902
					}
903
					abs_dst = path_append(tmp_dst, tmp);
904
					xfree(tmp);
905
					tmp = NULL;
906
				} else {
907
					/*
908
					 * Possible cases:
909
					 *  1. Upload the file/dir to remote, overwriting remote file: dup specified name
910
					 *  2. Remote tmp_dst doesn't exist: dup specified name
911
					 *
912
					 * Impossible cases:
913
					 *  1. tmp_dst specified, more than one match, and !remote_is_dir() checked for earlier.
914
					 */
915
					abs_dst = xstrdup(tmp_dst);
916
					abs_dst = make_absolute(tmp_dst, pwd);
917
				}
918
			} else {
919
				if (infer_path(g.gl_pathv[i], &tmp)) {
548
					err = 1;
920
					err = 1;
549
					goto out;
921
					goto out;
550
				}
922
				}
923
				abs_dst = make_absolute(tmp, pwd);
924
				xfree(tmp);
925
				tmp = NULL;
926
			}
927
928
			printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
929
			if (do_recursive_upload(conn, g.gl_pathv[i], abs_dst, pflag, pwd) == -1)
930
				err = -1;
931
		} else {
932
			if (!is_reg(g.gl_pathv[i])) {
933
				error("skipping non-regular file %s",
934
				    g.gl_pathv[i]);
935
				continue;
936
			}
937
			if (infer_path(g.gl_pathv[i], &tmp)) {
938
				err = -1;
939
				goto out;
940
			}
941
942
			if (g.gl_matchc == 1 && tmp_dst) {
943
				/* If directory specified, append filename */
944
				if (remote_is_dir(conn, tmp_dst)) {
945
					if (infer_path(g.gl_pathv[0], &tmp)) {
946
						err = 1;
947
						goto out;
948
					}
949
					abs_dst = path_append(tmp_dst, tmp);
950
					xfree(tmp);
951
					tmp = NULL;
952
				} else
953
					abs_dst = xstrdup(tmp_dst);
954
955
			} else if (tmp_dst) {
551
				abs_dst = path_append(tmp_dst, tmp);
956
				abs_dst = path_append(tmp_dst, tmp);
552
				xfree(tmp);
957
				xfree(tmp);
958
				tmp = NULL;
553
			} else
959
			} else
554
				abs_dst = xstrdup(tmp_dst);
960
				abs_dst = make_absolute(tmp, pwd);
555
961
556
		} else if (tmp_dst) {
962
			printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
557
			abs_dst = path_append(tmp_dst, tmp);
963
			if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
558
			xfree(tmp);
964
				err = -1;
559
		} else
965
		}
560
			abs_dst = make_absolute(tmp, pwd);
561
966
562
		printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
967
		xfree(abs_dst);
563
		if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
968
		abs_dst = NULL;
564
			err = -1;
565
	}
969
	}
566
970
567
out:
971
out:
Lines 746-752 Link Here
746
}
1150
}
747
1151
748
static int
1152
static int
749
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
1153
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *recursive_flag,
750
    unsigned long *n_arg, char **path1, char **path2)
1154
    unsigned long *n_arg, char **path1, char **path2)
751
{
1155
{
752
	const char *cmd, *cp = *cpp;
1156
	const char *cmd, *cp = *cpp;
Lines 794-805 Link Here
794
	}
1198
	}
795
1199
796
	/* Get arguments and parse flags */
1200
	/* Get arguments and parse flags */
797
	*lflag = *pflag = *n_arg = 0;
1201
	*lflag = *pflag = *recursive_flag = *n_arg = 0;
798
	*path1 = *path2 = NULL;
1202
	*path1 = *path2 = NULL;
799
	switch (cmdnum) {
1203
	switch (cmdnum) {
800
	case I_GET:
1204
	case I_GET:
801
	case I_PUT:
1205
	case I_PUT:
802
		if (parse_getput_flags(&cp, pflag))
1206
		if (parse_getput_flags(&cp, pflag, recursive_flag))
803
			return(-1);
1207
			return(-1);
804
		/* Get first pathname (mandatory) */
1208
		/* Get first pathname (mandatory) */
805
		if (get_pathname(&cp, path1))
1209
		if (get_pathname(&cp, path1))
Lines 905-911 Link Here
905
    int err_abort)
1309
    int err_abort)
906
{
1310
{
907
	char *path1, *path2, *tmp;
1311
	char *path1, *path2, *tmp;
908
	int pflag, lflag, iflag, cmdnum, i;
1312
	int pflag, lflag, iflag, recursive_flag, cmdnum, i;
909
	unsigned long n_arg;
1313
	unsigned long n_arg;
910
	Attrib a, *aa;
1314
	Attrib a, *aa;
911
	char path_buf[MAXPATHLEN];
1315
	char path_buf[MAXPATHLEN];
Lines 913-919 Link Here
913
	glob_t g;
1317
	glob_t g;
914
1318
915
	path1 = path2 = NULL;
1319
	path1 = path2 = NULL;
916
	cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,
1320
	cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &recursive_flag, &n_arg,
917
	    &path1, &path2);
1321
	    &path1, &path2);
918
1322
919
	if (iflag != 0)
1323
	if (iflag != 0)
Lines 931-940 Link Here
931
		err = -1;
1335
		err = -1;
932
		break;
1336
		break;
933
	case I_GET:
1337
	case I_GET:
934
		err = process_get(conn, path1, path2, *pwd, pflag);
1338
		err = process_get(conn, path1, path2, *pwd, pflag, recursive_flag);
935
		break;
1339
		break;
936
	case I_PUT:
1340
	case I_PUT:
937
		err = process_put(conn, path1, path2, *pwd, pflag);
1341
		err = process_put(conn, path1, path2, *pwd, pflag, recursive_flag);
938
		break;
1342
		break;
939
	case I_RENAME:
1343
	case I_RENAME:
940
		path1 = make_absolute(path1, *pwd);
1344
		path1 = make_absolute(path1, *pwd);
(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp-server.c (+3 lines)
Lines 86-91 Link Here
86
	case EINVAL:
86
	case EINVAL:
87
		ret = SSH2_FX_BAD_MESSAGE;
87
		ret = SSH2_FX_BAD_MESSAGE;
88
		break;
88
		break;
89
	case EEXIST:
90
		ret = SSH2_FX_FILE_ALREADY_EXISTS;
91
		break;
89
	default:
92
	default:
90
		ret = SSH2_FX_FAILURE;
93
		ret = SSH2_FX_FAILURE;
91
		break;
94
		break;
(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.0 (-1 / +4 lines)
Lines 181-192 Link Here
181
181
182
     progress    Toggle display of progress meter.
182
     progress    Toggle display of progress meter.
183
183
184
     recurse     Toggle recursive operations.
185
184
     put [flags] local-path [remote-path]
186
     put [flags] local-path [remote-path]
185
                 Upload local-path and store it on the remote machine.  If the
187
                 Upload local-path and store it on the remote machine.  If the
186
                 remote path name is not specified, it is given the same name
188
                 remote path name is not specified, it is given the same name
187
                 it has on the local machine.  If the -P flag is specified,
189
                 it has on the local machine.  If the -P flag is specified,
188
                 then the file's full permission and access time are copied
190
                 then the file's full permission and access time are copied
189
                 too.
191
                 too.  If the -r flag is specified, then the upload is per-
192
                 formed recursively.
190
193
191
     pwd         Display remote working directory.
194
     pwd         Display remote working directory.
192
195
(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.1 (+5 lines)
Lines 307-312 Link Here
307
.Ar path .
307
.Ar path .
308
.It Ic progress
308
.It Ic progress
309
Toggle display of progress meter.
309
Toggle display of progress meter.
310
.It Ic recurse
311
Toggle recursive operations.
310
.It Xo Ic put
312
.It Xo Ic put
311
.Op Ar flags
313
.Op Ar flags
312
.Ar local-path
314
.Ar local-path
Lines 321-326 Link Here
321
.Fl P
323
.Fl P
322
flag is specified, then the file's full permission and access time are
324
flag is specified, then the file's full permission and access time are
323
copied too.
325
copied too.
326
If the
327
.Fl r
328
flag is specified, then the upload is performed recursively.
324
.It Ic pwd
329
.It Ic pwd
325
Display remote working directory.
330
Display remote working directory.
326
.It Ic quit
331
.It Ic quit
(-)/home/shepard/sftp-mod/temp/openssh-SNAP-20040127/openssh/sftp.h (-1 / +2 lines)
Lines 89-92 Link Here
89
#define SSH2_FX_NO_CONNECTION		6
89
#define SSH2_FX_NO_CONNECTION		6
90
#define SSH2_FX_CONNECTION_LOST		7
90
#define SSH2_FX_CONNECTION_LOST		7
91
#define SSH2_FX_OP_UNSUPPORTED		8
91
#define SSH2_FX_OP_UNSUPPORTED		8
92
#define SSH2_FX_MAX			8
92
#define SSH2_FX_FILE_ALREADY_EXISTS		9
93
#define SSH2_FX_MAX			9

Return to bug 520