I wrote a patch to fix this problem. I has not been toroughly tested and it may not apply anymore but it may help some people.
It has been marked as WONTFIX in the OpenSSH Bugzilla. http://bugzilla.mindrot.org/show_bug.cgi?id=1059 http://openssh.org/faq.html#2.10 Of course nobody is supposed to use scp anymore :)
# Adds an -s option to scp(1) to ignore symlinks. # Applies to scp.c 1.124 (that's -current from 17 June 2005) # Patch submitted as part of bugreport #1059 (attachment #933) on 1 July 2005, # rejected on 12 July 2006. # http://bugzilla.mindrot.org/show_bug.cgi?id=1059 diff -ur ssh.old/scp.1 ssh/scp.1 --- ssh.old/scp.1 2005-06-30 18:40:29.116463608 +0200 +++ ssh/scp.1 2005-06-30 18:41:12.493869240 +0200 @@ -20,7 +20,7 @@ .Sh SYNOPSIS .Nm scp .Bk -words -.Op Fl 1246BCpqrv +.Op Fl 1246BCpqrsv .Op Fl c Ar cipher .Op Fl F Ar ssh_config .Op Fl i Ar identity_file @@ -180,6 +180,8 @@ Disables the progress meter. .It Fl r Recursively copy entire directories. +.It Fl s +Ignore symbolic links. .It Fl S Ar program Name of .Ar program @@ -218,3 +220,4 @@ .Sh AUTHORS .An Timo Rinne Aq [EMAIL PROTECTED] .An Tatu Ylonen Aq [EMAIL PROTECTED] +.An Adrien Kunysz (for the -s option) Aq [EMAIL PROTECTED] diff -ur ssh.old/scp.c ssh/scp.c --- ssh.old/scp.c 2005-06-30 18:40:29.117463456 +0200 +++ ssh/scp.c 2005-06-30 18:41:12.532863312 +0200 @@ -200,10 +200,10 @@ struct passwd *pwd; uid_t userid; int errs, remin, remout; -int pflag, iamremote, iamrecursive, targetshouldbedirectory; +int pflag, iamremote, iamrecursive, targetshouldbedirectory, ignorelinks; #define CMDNEEDS 64 -char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ +char cmd[CMDNEEDS]; /* must hold "scp -v -r -p -s -d\0" */ int response(void); void rsource(char *, struct stat *); @@ -229,7 +229,7 @@ addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfl:prstvBCc:i:P:q1246S:o:F:")) != -1) switch (ch) { /* User-visible flags. */ case '1': @@ -263,6 +263,9 @@ case 'r': iamrecursive = 1; break; + case 's': + ignorelinks = 1; + break; case 'S': ssh_program = xstrdup(optarg); break; @@ -321,9 +324,10 @@ remin = remout = -1; do_cmd_pid = -1; /* Command to be executed on remote system using "ssh". */ - (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", + (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s%s", verbose_mode ? " -v" : "", - iamrecursive ? " -r" : "", pflag ? " -p" : "", + iamrecursive ? " -r" : "", ignorelinks ? " -s" : "", + pflag ? " -p" : "", targetshouldbedirectory ? " -d" : ""); (void) signal(SIGPIPE, lostconn); @@ -455,8 +459,9 @@ len = strlen(_PATH_CP) + strlen(argv[i]) + strlen(argv[argc - 1]) + 20; bp = xmalloc(len); - (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, - iamrecursive ? " -r" : "", pflag ? " -p" : "", + (void)snprintf(bp, len, "exec %s%s%s%s %s %s", _PATH_CP, + iamrecursive ? " -r" : "", ignorelinks ? " -s" : "", + pflag ? " -p" : "", argv[i], argv[argc - 1]); if (verbose_mode) fprintf(stderr, "Executing: %s\n", bp); @@ -516,6 +521,12 @@ name); goto next; } + if (ignorelinks) { + if (lstat(name, &stb) < 0) + goto syserr; + if (S_ISLNK(stb.st_mode)) + goto next; + } if ((fd = open(name, O_RDONLY, 0)) < 0) goto syserr; if (fstat(fd, &stb) < 0) { @@ -1019,7 +1030,7 @@ usage(void) { (void) fprintf(stderr, - "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" + "usage: scp [-1246BCpqrsv] [-c cipher] [-F ssh_config] [-i identity_file]\n" " [-l limit] [-o ssh_option] [-P port] [-S program]\n" " [EMAIL PROTECTED]:]file1 [...] [EMAIL PROTECTED]:]file2\n"); exit(1);