/* Name of current file being transferred. */
char *curfile;
+/* This is set to non-zero if IPv4 is desired. */
+int IPv4 = 0;
+
+/* This is set to non-zero if IPv6 is desired. */
+int IPv6 = 0;
+
/* This is set to non-zero to enable verbose mode. */
int verbose_mode = 0;
args[i++] = SSH_PROGRAM;
args[i++] = "-x";
args[i++] = "-oFallBackToRsh no";
+ if (IPv4)
+ args[i++] = "-4";
+ if (IPv6)
+ args[i++] = "-6";
+ args[i++] = "-oFallBackToRsh no";
if (verbose_mode)
args[i++] = "-v";
if (compress_flag)
extern int optind;
fflag = tflag = 0;
- while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q")) != EOF)
+ while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46")) != EOF)
switch (ch) {
/* User-visible flags. */
+ case '4':
+ IPv4 = 1;
+ break;
+ case '6':
+ IPv6 = 1;
+ break;
case 'p':
pflag = 1;
break;
exit(errs != 0);
}
+char *
+cleanhostname(host)
+ char *host;
+{
+ if (*host == '[' && host[strlen(host) - 1] == ']') {
+ host[strlen(host) - 1] = '\0';
+ return (host + 1);
+ } else
+ return host;
+}
+
void
toremote(targ, argc, argv)
char *targ, *argv[];
bp = xmalloc(len);
if (host) {
*host++ = 0;
+ host = cleanhostname(host);
suser = argv[i];
if (*suser == '\0')
suser = pwd->pw_name;
suser, host, cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
- } else
+ } else {
+ host = cleanhostname(argv[i]);
(void) sprintf(bp,
"exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'",
SSH_PROGRAM, verbose_mode ? " -v" : "",
- argv[i], cmd, src,
+ host, cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
+ }
if (verbose_mode)
fprintf(stderr, "Executing: %s\n", bp);
(void) system(bp);
len = strlen(targ) + CMDNEEDS + 20;
bp = xmalloc(len);
(void) sprintf(bp, "%s -t %s", cmd, targ);
- host = thost;
+ host = cleanhostname(thost);
if (do_cmd(host, tuser,
bp, &remin, &remout) < 0)
exit(1);
else if (!okname(suser))
continue;
}
+ host = cleanhostname(host);
len = strlen(src) + CMDNEEDS + 20;
bp = xmalloc(len);
(void) sprintf(bp, "%s -f %s", cmd, src);
if (haderr)
(void) write(remout, bp->buf, amt);
else {
- result = write(remout, bp->buf, amt);
+ result = atomicio(write, remout, bp->buf, amt);
if (result != amt)
haderr = result >= 0 ? EIO : errno;
statbytes += result;
usage()
{
(void) fprintf(stderr,
- "usage: scp [-pqrvC] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n");
+ "usage: scp [-pqrvC46] [-P port] [-c cipher] [-i identity] f1 f2; or:\n scp [options] f1 ... fn directory\n");
exit(1);
}
{
static FILE *fp;
va_list ap;
- va_start(ap, fmt);
++errs;
if (fp == NULL && !(fp = fdopen(remout, "w")))
return;
(void) fprintf(fp, "%c", 0x01);
(void) fprintf(fp, "scp: ");
+ va_start(ap, fmt);
(void) vfprintf(fp, fmt, ap);
+ va_end(ap);
(void) fprintf(fp, "\n");
(void) fflush(fp);
if (!iamremote) {
+ va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
+ va_end(ap);
fprintf(stderr, "\n");
}
- va_end(ap);
}
/* Stuff below is from BSD rcp util.c. */
colon(cp)
char *cp;
{
+ int flag = 0;
+
if (*cp == ':') /* Leading colon is part of file name. */
return (0);
+ if (*cp == '[')
+ flag = 1;
for (; *cp; ++cp) {
- if (*cp == ':')
+ if (*cp == '@' && *(cp+1) == '[')
+ flag = 1;
+ if (*cp == ']' && *(cp+1) == ':' && flag)
+ return (cp+1);
+ if (*cp == ':' && !flag)
return (cp);
if (*cp == '/')
return (0);
} while (*++cp);
return (1);
-bad: fprintf(stderr, "%s: invalid user name", cp0);
+bad: fprintf(stderr, "%s: invalid user name\n", cp0);
return (0);
}
exit(1);
}
-/*
- * ensure all of data on socket comes through. f==read || f==write
- */
-int
-atomicio(f, fd, s, n)
- int (*f) ();
- char *s;
-{
- int res, pos = 0;
-
- while (n > pos) {
- res = (f) (fd, s + pos, n - pos);
- switch (res) {
- case -1:
- if (errno == EINTR || errno == EAGAIN)
- continue;
- case 0:
- return (res);
- default:
- pos += res;
- }
- }
- return (pos);
-}
void
alarmtimer(int wait)
}
void
-updateprogressmeter(void)
+updateprogressmeter(int sig)
{
int save_errno = errno;
i++;
abbrevsize >>= 10;
}
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5qd %c%c ",
- (quad_t) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' :
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5d %c%c ",
+ (int) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' :
'B');
timersub(&now, &lastupdate, &wait);
atomicio(write, fileno(stdout), buf, strlen(buf));
if (flag == -1) {
- signal(SIGALRM, (void *) updateprogressmeter);
+ struct sigaction sa;
+ sa.sa_handler = updateprogressmeter;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGALRM, &sa, NULL);
alarmtimer(1);
} else if (flag == 1) {
alarmtimer(0);