]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - scp.c
Add a configuration option for TCP keepalives (SO_KEEPALIVE), default off.
[PuTTY.git] / scp.c
1 /*
2  * scp.c  -  Scp (Secure Copy) client for PuTTY.
3  * Joris van Rantwijk, Simon Tatham
4  *
5  * This is mainly based on ssh-1.2.26/scp.c by Timo Rinne & Tatu Ylonen.
6  * They, in turn, used stuff from BSD rcp.
7  * 
8  * (SGT, 2001-09-10: Joris van Rantwijk assures me that although
9  * this file as originally submitted was inspired by, and
10  * _structurally_ based on, ssh-1.2.26's scp.c, there wasn't any
11  * actual code duplicated, so the above comment shouldn't give rise
12  * to licensing issues.)
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <limits.h>
19 #include <time.h>
20 #include <assert.h>
21
22 #define PUTTY_DO_GLOBALS
23 #include "putty.h"
24 #include "psftp.h"
25 #include "ssh.h"
26 #include "sftp.h"
27 #include "storage.h"
28
29 static int list = 0;
30 static int verbose = 0;
31 static int recursive = 0;
32 static int preserve = 0;
33 static int targetshouldbedirectory = 0;
34 static int statistics = 1;
35 static int prev_stats_len = 0;
36 static int scp_unsafe_mode = 0;
37 static int errs = 0;
38 static int gui_mode = 0;
39 static int try_scp = 1;
40 static int try_sftp = 1;
41 static int main_cmd_is_sftp = 0;
42 static int fallback_cmd_is_sftp = 0;
43 static int using_sftp = 0;
44
45 static Backend *back;
46 static void *backhandle;
47 static Config cfg;
48
49 static void source(char *src);
50 static void rsource(char *src);
51 static void sink(char *targ, char *src);
52
53 /*
54  * The maximum amount of queued data we accept before we stop and
55  * wait for the server to process some.
56  */
57 #define MAX_SCP_BUFSIZE 16384
58
59 void ldisc_send(void *handle, char *buf, int len, int interactive)
60 {
61     /*
62      * This is only here because of the calls to ldisc_send(NULL,
63      * 0) in ssh.c. Nothing in PSCP actually needs to use the ldisc
64      * as an ldisc. So if we get called with any real data, I want
65      * to know about it.
66      */
67     assert(len == 0);
68 }
69
70 static void tell_char(FILE * stream, char c)
71 {
72     if (!gui_mode)
73         fputc(c, stream);
74     else
75         gui_send_char(stream == stderr, c);
76 }
77
78 static void tell_str(FILE * stream, char *str)
79 {
80     unsigned int i;
81
82     for (i = 0; i < strlen(str); ++i)
83         tell_char(stream, str[i]);
84 }
85
86 static void tell_user(FILE * stream, char *fmt, ...)
87 {
88     char *str, *str2;
89     va_list ap;
90     va_start(ap, fmt);
91     str = dupvprintf(fmt, ap);
92     va_end(ap);
93     str2 = dupcat(str, "\n", NULL);
94     sfree(str);
95     tell_str(stream, str2);
96     sfree(str2);
97 }
98
99 /*
100  *  Print an error message and perform a fatal exit.
101  */
102 void fatalbox(char *fmt, ...)
103 {
104     char *str, *str2;
105     va_list ap;
106     va_start(ap, fmt);
107     str = dupvprintf(fmt, ap);
108     str2 = dupcat("Fatal: ", str, "\n", NULL);
109     sfree(str);
110     va_end(ap);
111     tell_str(stderr, str2);
112     sfree(str2);
113     errs++;
114
115     if (gui_mode)
116         gui_send_errcount(list, errs);
117
118     cleanup_exit(1);
119 }
120 void modalfatalbox(char *fmt, ...)
121 {
122     char *str, *str2;
123     va_list ap;
124     va_start(ap, fmt);
125     str = dupvprintf(fmt, ap);
126     str2 = dupcat("Fatal: ", str, "\n", NULL);
127     sfree(str);
128     va_end(ap);
129     tell_str(stderr, str2);
130     sfree(str2);
131     errs++;
132
133     if (gui_mode)
134         gui_send_errcount(list, errs);
135
136     cleanup_exit(1);
137 }
138 void connection_fatal(void *frontend, char *fmt, ...)
139 {
140     char *str, *str2;
141     va_list ap;
142     va_start(ap, fmt);
143     str = dupvprintf(fmt, ap);
144     str2 = dupcat("Fatal: ", str, "\n", NULL);
145     sfree(str);
146     va_end(ap);
147     tell_str(stderr, str2);
148     sfree(str2);
149     errs++;
150
151     if (gui_mode)
152         gui_send_errcount(list, errs);
153
154     cleanup_exit(1);
155 }
156
157 /*
158  * In pscp, all agent requests should be synchronous, so this is a
159  * never-called stub.
160  */
161 void agent_schedule_callback(void (*callback)(void *, void *, int),
162                              void *callback_ctx, void *data, int len)
163 {
164     assert(!"We shouldn't be here");
165 }
166
167 /*
168  * Receive a block of data from the SSH link. Block until all data
169  * is available.
170  *
171  * To do this, we repeatedly call the SSH protocol module, with our
172  * own trap in from_backend() to catch the data that comes back. We
173  * do this until we have enough data.
174  */
175
176 static unsigned char *outptr;          /* where to put the data */
177 static unsigned outlen;                /* how much data required */
178 static unsigned char *pending = NULL;  /* any spare data */
179 static unsigned pendlen = 0, pendsize = 0;      /* length and phys. size of buffer */
180 int from_backend(void *frontend, int is_stderr, const char *data, int datalen)
181 {
182     unsigned char *p = (unsigned char *) data;
183     unsigned len = (unsigned) datalen;
184
185     /*
186      * stderr data is just spouted to local stderr and otherwise
187      * ignored.
188      */
189     if (is_stderr) {
190         if (len > 0)
191             fwrite(data, 1, len, stderr);
192         return 0;
193     }
194
195     /*
196      * If this is before the real session begins, just return.
197      */
198     if (!outptr)
199         return 0;
200
201     if ((outlen > 0) && (len > 0)) {
202         unsigned used = outlen;
203         if (used > len)
204             used = len;
205         memcpy(outptr, p, used);
206         outptr += used;
207         outlen -= used;
208         p += used;
209         len -= used;
210     }
211
212     if (len > 0) {
213         if (pendsize < pendlen + len) {
214             pendsize = pendlen + len + 4096;
215             pending = sresize(pending, pendsize, unsigned char);
216             if (!pending)
217                 fatalbox("Out of memory");
218         }
219         memcpy(pending + pendlen, p, len);
220         pendlen += len;
221     }
222
223     return 0;
224 }
225 static int ssh_scp_recv(unsigned char *buf, int len)
226 {
227     outptr = buf;
228     outlen = len;
229
230     /*
231      * See if the pending-input block contains some of what we
232      * need.
233      */
234     if (pendlen > 0) {
235         unsigned pendused = pendlen;
236         if (pendused > outlen)
237             pendused = outlen;
238         memcpy(outptr, pending, pendused);
239         memmove(pending, pending + pendused, pendlen - pendused);
240         outptr += pendused;
241         outlen -= pendused;
242         pendlen -= pendused;
243         if (pendlen == 0) {
244             pendsize = 0;
245             sfree(pending);
246             pending = NULL;
247         }
248         if (outlen == 0)
249             return len;
250     }
251
252     while (outlen > 0) {
253         if (ssh_sftp_loop_iteration() < 0)
254             return 0;                  /* doom */
255     }
256
257     return len;
258 }
259
260 /*
261  * Loop through the ssh connection and authentication process.
262  */
263 static void ssh_scp_init(void)
264 {
265     while (!back->sendok(backhandle)) {
266         if (ssh_sftp_loop_iteration() < 0)
267             return;                    /* doom */
268     }
269
270     /* Work out which backend we ended up using. */
271     if (!ssh_fallback_cmd(backhandle))
272         using_sftp = main_cmd_is_sftp;
273     else
274         using_sftp = fallback_cmd_is_sftp;
275
276     if (verbose) {
277         if (using_sftp)
278             tell_user(stderr, "Using SFTP");
279         else
280             tell_user(stderr, "Using SCP1");
281     }
282 }
283
284 /*
285  *  Print an error message and exit after closing the SSH link.
286  */
287 static void bump(char *fmt, ...)
288 {
289     char *str, *str2;
290     va_list ap;
291     va_start(ap, fmt);
292     str = dupvprintf(fmt, ap);
293     va_end(ap);
294     str2 = dupcat(str, "\n", NULL);
295     sfree(str);
296     tell_str(stderr, str2);
297     sfree(str2);
298     errs++;
299
300     if (back != NULL && back->socket(backhandle) != NULL) {
301         char ch;
302         back->special(backhandle, TS_EOF);
303         ssh_scp_recv((unsigned char *) &ch, 1);
304     }
305
306     if (gui_mode)
307         gui_send_errcount(list, errs);
308
309     cleanup_exit(1);
310 }
311
312 /*
313  *  Open an SSH connection to user@host and execute cmd.
314  */
315 static void do_cmd(char *host, char *user, char *cmd)
316 {
317     const char *err;
318     char *realhost;
319     void *logctx;
320
321     if (host == NULL || host[0] == '\0')
322         bump("Empty host name");
323
324     /* Try to load settings for this host */
325     do_defaults(host, &cfg);
326     if (cfg.host[0] == '\0') {
327         /* No settings for this host; use defaults */
328         do_defaults(NULL, &cfg);
329         strncpy(cfg.host, host, sizeof(cfg.host) - 1);
330         cfg.host[sizeof(cfg.host) - 1] = '\0';
331     }
332
333     /*
334      * Force use of SSH. (If they got the protocol wrong we assume the
335      * port is useless too.)
336      */
337     if (cfg.protocol != PROT_SSH) {
338         cfg.protocol = PROT_SSH;
339         cfg.port = 22;
340     }
341
342     /*
343      * Enact command-line overrides.
344      */
345     cmdline_run_saved(&cfg);
346
347     /*
348      * Trim leading whitespace off the hostname if it's there.
349      */
350     {
351         int space = strspn(cfg.host, " \t");
352         memmove(cfg.host, cfg.host+space, 1+strlen(cfg.host)-space);
353     }
354
355     /* See if host is of the form user@host */
356     if (cfg.host[0] != '\0') {
357         char *atsign = strchr(cfg.host, '@');
358         /* Make sure we're not overflowing the user field */
359         if (atsign) {
360             if (atsign - cfg.host < sizeof cfg.username) {
361                 strncpy(cfg.username, cfg.host, atsign - cfg.host);
362                 cfg.username[atsign - cfg.host] = '\0';
363             }
364             memmove(cfg.host, atsign + 1, 1 + strlen(atsign + 1));
365         }
366     }
367
368     /*
369      * Trim a colon suffix off the hostname if it's there.
370      */
371     cfg.host[strcspn(cfg.host, ":")] = '\0';
372
373     /*
374      * Remove any remaining whitespace from the hostname.
375      */
376     {
377         int p1 = 0, p2 = 0;
378         while (cfg.host[p2] != '\0') {
379             if (cfg.host[p2] != ' ' && cfg.host[p2] != '\t') {
380                 cfg.host[p1] = cfg.host[p2];
381                 p1++;
382             }
383             p2++;
384         }
385         cfg.host[p1] = '\0';
386     }
387
388     /* Set username */
389     if (user != NULL && user[0] != '\0') {
390         strncpy(cfg.username, user, sizeof(cfg.username) - 1);
391         cfg.username[sizeof(cfg.username) - 1] = '\0';
392     } else if (cfg.username[0] == '\0') {
393         user = get_username();
394         if (!user)
395             bump("Empty user name");
396         else {
397             if (verbose)
398                 tell_user(stderr, "Guessing user name: %s", user);
399             strncpy(cfg.username, user, sizeof(cfg.username) - 1);
400             cfg.username[sizeof(cfg.username) - 1] = '\0';
401             sfree(user);
402         }
403     }
404
405     /*
406      * Disable scary things which shouldn't be enabled for simple
407      * things like SCP and SFTP: agent forwarding, port forwarding,
408      * X forwarding.
409      */
410     cfg.x11_forward = 0;
411     cfg.agentfwd = 0;
412     cfg.portfwd[0] = cfg.portfwd[1] = '\0';
413
414     /*
415      * Set up main and possibly fallback command depending on
416      * options specified by user.
417      * Attempt to start the SFTP subsystem as a first choice,
418      * falling back to the provided scp command if that fails.
419      */
420     cfg.remote_cmd_ptr2 = NULL;
421     if (try_sftp) {
422         /* First choice is SFTP subsystem. */
423         main_cmd_is_sftp = 1;
424         strcpy(cfg.remote_cmd, "sftp");
425         cfg.ssh_subsys = TRUE;
426         if (try_scp) {
427             /* Fallback is to use the provided scp command. */
428             fallback_cmd_is_sftp = 0;
429             cfg.remote_cmd_ptr2 = cmd;
430             cfg.ssh_subsys2 = FALSE;
431         } else {
432             /* Since we're not going to try SCP, we may as well try
433              * harder to find an SFTP server, since in the current
434              * implementation we have a spare slot. */
435             fallback_cmd_is_sftp = 1;
436             /* see psftp.c for full explanation of this kludge */
437             cfg.remote_cmd_ptr2 = 
438                 "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n"
439                 "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n"
440                 "exec sftp-server";
441             cfg.ssh_subsys2 = FALSE;
442         }
443     } else {
444         /* Don't try SFTP at all; just try the scp command. */
445         main_cmd_is_sftp = 0;
446         cfg.remote_cmd_ptr = cmd;
447         cfg.ssh_subsys = FALSE;
448     }
449     cfg.nopty = TRUE;
450
451     back = &ssh_backend;
452
453     err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost, 
454                      0, cfg.tcp_keepalives);
455     if (err != NULL)
456         bump("ssh_init: %s", err);
457     logctx = log_init(NULL, &cfg);
458     back->provide_logctx(backhandle, logctx);
459     console_provide_logctx(logctx);
460     ssh_scp_init();
461     if (verbose && realhost != NULL)
462         tell_user(stderr, "Connected to %s\n", realhost);
463     sfree(realhost);
464 }
465
466 /*
467  *  Update statistic information about current file.
468  */
469 static void print_stats(char *name, unsigned long size, unsigned long done,
470                         time_t start, time_t now)
471 {
472     float ratebs;
473     unsigned long eta;
474     char *etastr;
475     int pct;
476     int len;
477     int elap;
478
479     elap = (unsigned long) difftime(now, start);
480
481     if (now > start)
482         ratebs = (float) done / elap;
483     else
484         ratebs = (float) done;
485
486     if (ratebs < 1.0)
487         eta = size - done;
488     else
489         eta = (unsigned long) ((size - done) / ratebs);
490     etastr = dupprintf("%02ld:%02ld:%02ld",
491                        eta / 3600, (eta % 3600) / 60, eta % 60);
492
493     pct = (int) (100 * (done * 1.0 / size));
494
495     if (gui_mode) {
496         gui_update_stats(name, size, pct, elap, done, eta,
497                          (unsigned long) ratebs);
498     } else {
499         len = printf("\r%-25.25s | %10ld kB | %5.1f kB/s | ETA: %8s | %3d%%",
500                      name, done / 1024, ratebs / 1024.0, etastr, pct);
501         if (len < prev_stats_len)
502             printf("%*s", prev_stats_len - len, "");
503         prev_stats_len = len;
504
505         if (done == size)
506             printf("\n");
507
508         fflush(stdout);
509     }
510
511     free(etastr);
512 }
513
514 /*
515  *  Find a colon in str and return a pointer to the colon.
516  *  This is used to separate hostname from filename.
517  */
518 static char *colon(char *str)
519 {
520     /* We ignore a leading colon, since the hostname cannot be
521        empty. We also ignore a colon as second character because
522        of filenames like f:myfile.txt. */
523     if (str[0] == '\0' || str[0] == ':' || str[1] == ':')
524         return (NULL);
525     while (*str != '\0' && *str != ':' && *str != '/' && *str != '\\')
526         str++;
527     if (*str == ':')
528         return (str);
529     else
530         return (NULL);
531 }
532
533 /*
534  * Return a pointer to the portion of str that comes after the last
535  * slash (or backslash or colon, if `local' is TRUE).
536  */
537 static char *stripslashes(char *str, int local)
538 {
539     char *p;
540
541     if (local) {
542         p = strchr(str, ':');
543         if (p) str = p+1;
544     }
545
546     p = strrchr(str, '/');
547     if (p) str = p+1;
548
549     if (local) {
550         p = strrchr(str, '\\');
551         if (p) str = p+1;
552     }
553
554     return str;
555 }
556
557 /*
558  * Determine whether a string is entirely composed of dots.
559  */
560 static int is_dots(char *str)
561 {
562     return str[strspn(str, ".")] == '\0';
563 }
564
565 /*
566  *  Wait for a response from the other side.
567  *  Return 0 if ok, -1 if error.
568  */
569 static int response(void)
570 {
571     char ch, resp, rbuf[2048];
572     int p;
573
574     if (ssh_scp_recv((unsigned char *) &resp, 1) <= 0)
575         bump("Lost connection");
576
577     p = 0;
578     switch (resp) {
579       case 0:                          /* ok */
580         return (0);
581       default:
582         rbuf[p++] = resp;
583         /* fallthrough */
584       case 1:                          /* error */
585       case 2:                          /* fatal error */
586         do {
587             if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
588                 bump("Protocol error: Lost connection");
589             rbuf[p++] = ch;
590         } while (p < sizeof(rbuf) && ch != '\n');
591         rbuf[p - 1] = '\0';
592         if (resp == 1)
593             tell_user(stderr, "%s\n", rbuf);
594         else
595             bump("%s", rbuf);
596         errs++;
597         return (-1);
598     }
599 }
600
601 int sftp_recvdata(char *buf, int len)
602 {
603     return ssh_scp_recv((unsigned char *) buf, len);
604 }
605 int sftp_senddata(char *buf, int len)
606 {
607     back->send(backhandle, buf, len);
608     return 1;
609 }
610
611 /* ----------------------------------------------------------------------
612  * sftp-based replacement for the hacky `pscp -ls'.
613  */
614 static int sftp_ls_compare(const void *av, const void *bv)
615 {
616     const struct fxp_name *a = (const struct fxp_name *) av;
617     const struct fxp_name *b = (const struct fxp_name *) bv;
618     return strcmp(a->filename, b->filename);
619 }
620 void scp_sftp_listdir(char *dirname)
621 {
622     struct fxp_handle *dirh;
623     struct fxp_names *names;
624     struct fxp_name *ournames;
625     struct sftp_packet *pktin;
626     struct sftp_request *req, *rreq;
627     int nnames, namesize;
628     int i;
629
630     if (!fxp_init()) {
631         tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
632         errs++;
633         return;
634     }
635
636     printf("Listing directory %s\n", dirname);
637
638     sftp_register(req = fxp_opendir_send(dirname));
639     rreq = sftp_find_request(pktin = sftp_recv());
640     assert(rreq == req);
641     dirh = fxp_opendir_recv(pktin, rreq);
642
643     if (dirh == NULL) {
644         printf("Unable to open %s: %s\n", dirname, fxp_error());
645     } else {
646         nnames = namesize = 0;
647         ournames = NULL;
648
649         while (1) {
650
651             sftp_register(req = fxp_readdir_send(dirh));
652             rreq = sftp_find_request(pktin = sftp_recv());
653             assert(rreq == req);
654             names = fxp_readdir_recv(pktin, rreq);
655
656             if (names == NULL) {
657                 if (fxp_error_type() == SSH_FX_EOF)
658                     break;
659                 printf("Reading directory %s: %s\n", dirname, fxp_error());
660                 break;
661             }
662             if (names->nnames == 0) {
663                 fxp_free_names(names);
664                 break;
665             }
666
667             if (nnames + names->nnames >= namesize) {
668                 namesize += names->nnames + 128;
669                 ournames = sresize(ournames, namesize, struct fxp_name);
670             }
671
672             for (i = 0; i < names->nnames; i++)
673                 ournames[nnames++] = names->names[i];
674
675             names->nnames = 0;         /* prevent free_names */
676             fxp_free_names(names);
677         }
678         sftp_register(req = fxp_close_send(dirh));
679         rreq = sftp_find_request(pktin = sftp_recv());
680         assert(rreq == req);
681         fxp_close_recv(pktin, rreq);
682
683         /*
684          * Now we have our filenames. Sort them by actual file
685          * name, and then output the longname parts.
686          */
687         qsort(ournames, nnames, sizeof(*ournames), sftp_ls_compare);
688
689         /*
690          * And print them.
691          */
692         for (i = 0; i < nnames; i++)
693             printf("%s\n", ournames[i].longname);
694     }
695 }
696
697 /* ----------------------------------------------------------------------
698  * Helper routines that contain the actual SCP protocol elements,
699  * implemented both as SCP1 and SFTP.
700  */
701
702 static struct scp_sftp_dirstack {
703     struct scp_sftp_dirstack *next;
704     struct fxp_name *names;
705     int namepos, namelen;
706     char *dirpath;
707     char *wildcard;
708     int matched_something;             /* wildcard match set was non-empty */
709 } *scp_sftp_dirstack_head;
710 static char *scp_sftp_remotepath, *scp_sftp_currentname;
711 static char *scp_sftp_wildcard;
712 static int scp_sftp_targetisdir, scp_sftp_donethistarget;
713 static int scp_sftp_preserve, scp_sftp_recursive;
714 static unsigned long scp_sftp_mtime, scp_sftp_atime;
715 static int scp_has_times;
716 static struct fxp_handle *scp_sftp_filehandle;
717 static struct fxp_xfer *scp_sftp_xfer;
718 static uint64 scp_sftp_fileoffset;
719
720 void scp_source_setup(char *target, int shouldbedir)
721 {
722     if (using_sftp) {
723         /*
724          * Find out whether the target filespec is in fact a
725          * directory.
726          */
727         struct sftp_packet *pktin;
728         struct sftp_request *req, *rreq;
729         struct fxp_attrs attrs;
730         int ret;
731
732         if (!fxp_init()) {
733             tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
734             errs++;
735             return;
736         }
737
738         sftp_register(req = fxp_stat_send(target));
739         rreq = sftp_find_request(pktin = sftp_recv());
740         assert(rreq == req);
741         ret = fxp_stat_recv(pktin, rreq, &attrs);
742
743         if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS))
744             scp_sftp_targetisdir = 0;
745         else
746             scp_sftp_targetisdir = (attrs.permissions & 0040000) != 0;
747
748         if (shouldbedir && !scp_sftp_targetisdir) {
749             bump("pscp: remote filespec %s: not a directory\n", target);
750         }
751
752         scp_sftp_remotepath = dupstr(target);
753
754         scp_has_times = 0;
755     } else {
756         (void) response();
757     }
758 }
759
760 int scp_send_errmsg(char *str)
761 {
762     if (using_sftp) {
763         /* do nothing; we never need to send our errors to the server */
764     } else {
765         back->send(backhandle, "\001", 1);/* scp protocol error prefix */
766         back->send(backhandle, str, strlen(str));
767     }
768     return 0;                          /* can't fail */
769 }
770
771 int scp_send_filetimes(unsigned long mtime, unsigned long atime)
772 {
773     if (using_sftp) {
774         scp_sftp_mtime = mtime;
775         scp_sftp_atime = atime;
776         scp_has_times = 1;
777         return 0;
778     } else {
779         char buf[80];
780         sprintf(buf, "T%lu 0 %lu 0\n", mtime, atime);
781         back->send(backhandle, buf, strlen(buf));
782         return response();
783     }
784 }
785
786 int scp_send_filename(char *name, unsigned long size, int modes)
787 {
788     if (using_sftp) {
789         char *fullname;
790         struct sftp_packet *pktin;
791         struct sftp_request *req, *rreq;
792
793         if (scp_sftp_targetisdir) {
794             fullname = dupcat(scp_sftp_remotepath, "/", name, NULL);
795         } else {
796             fullname = dupstr(scp_sftp_remotepath);
797         }
798
799         sftp_register(req = fxp_open_send(fullname, SSH_FXF_WRITE |
800                                           SSH_FXF_CREAT | SSH_FXF_TRUNC));
801         rreq = sftp_find_request(pktin = sftp_recv());
802         assert(rreq == req);
803         scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
804
805         if (!scp_sftp_filehandle) {
806             tell_user(stderr, "pscp: unable to open %s: %s",
807                       fullname, fxp_error());
808             errs++;
809             return 1;
810         }
811         scp_sftp_fileoffset = uint64_make(0, 0);
812         scp_sftp_xfer = xfer_upload_init(scp_sftp_filehandle,
813                                          scp_sftp_fileoffset);
814         sfree(fullname);
815         return 0;
816     } else {
817         char buf[40];
818         sprintf(buf, "C%04o %lu ", modes, size);
819         back->send(backhandle, buf, strlen(buf));
820         back->send(backhandle, name, strlen(name));
821         back->send(backhandle, "\n", 1);
822         return response();
823     }
824 }
825
826 int scp_send_filedata(char *data, int len)
827 {
828     if (using_sftp) {
829         int ret;
830         struct sftp_packet *pktin;
831
832         if (!scp_sftp_filehandle) {
833             return 1;
834         }
835
836         while (!xfer_upload_ready(scp_sftp_xfer)) {
837             pktin = sftp_recv();
838             ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
839             if (!ret) {
840                 tell_user(stderr, "error while writing: %s\n", fxp_error());
841                 errs++;
842                 return 1;
843             }
844         }
845
846         xfer_upload_data(scp_sftp_xfer, data, len);
847
848         scp_sftp_fileoffset = uint64_add32(scp_sftp_fileoffset, len);
849         return 0;
850     } else {
851         int bufsize = back->send(backhandle, data, len);
852
853         /*
854          * If the network transfer is backing up - that is, the
855          * remote site is not accepting data as fast as we can
856          * produce it - then we must loop on network events until
857          * we have space in the buffer again.
858          */
859         while (bufsize > MAX_SCP_BUFSIZE) {
860             if (ssh_sftp_loop_iteration() < 0)
861                 return 1;
862             bufsize = back->sendbuffer(backhandle);
863         }
864
865         return 0;
866     }
867 }
868
869 int scp_send_finish(void)
870 {
871     if (using_sftp) {
872         struct fxp_attrs attrs;
873         struct sftp_packet *pktin;
874         struct sftp_request *req, *rreq;
875         int ret;
876
877         while (!xfer_done(scp_sftp_xfer)) {
878             pktin = sftp_recv();
879             xfer_upload_gotpkt(scp_sftp_xfer, pktin);
880         }
881         xfer_cleanup(scp_sftp_xfer);
882
883         if (!scp_sftp_filehandle) {
884             return 1;
885         }
886         if (scp_has_times) {
887             attrs.flags = SSH_FILEXFER_ATTR_ACMODTIME;
888             attrs.atime = scp_sftp_atime;
889             attrs.mtime = scp_sftp_mtime;
890             sftp_register(req = fxp_fsetstat_send(scp_sftp_filehandle, attrs));
891             rreq = sftp_find_request(pktin = sftp_recv());
892             assert(rreq == req);
893             ret = fxp_fsetstat_recv(pktin, rreq);
894             if (!ret) {
895                 tell_user(stderr, "unable to set file times: %s\n", fxp_error());
896                 errs++;
897             }
898         }
899         sftp_register(req = fxp_close_send(scp_sftp_filehandle));
900         rreq = sftp_find_request(pktin = sftp_recv());
901         assert(rreq == req);
902         fxp_close_recv(pktin, rreq);
903         scp_has_times = 0;
904         return 0;
905     } else {
906         back->send(backhandle, "", 1);
907         return response();
908     }
909 }
910
911 char *scp_save_remotepath(void)
912 {
913     if (using_sftp)
914         return scp_sftp_remotepath;
915     else
916         return NULL;
917 }
918
919 void scp_restore_remotepath(char *data)
920 {
921     if (using_sftp)
922         scp_sftp_remotepath = data;
923 }
924
925 int scp_send_dirname(char *name, int modes)
926 {
927     if (using_sftp) {
928         char *fullname;
929         char const *err;
930         struct fxp_attrs attrs;
931         struct sftp_packet *pktin;
932         struct sftp_request *req, *rreq;
933         int ret;
934
935         if (scp_sftp_targetisdir) {
936             fullname = dupcat(scp_sftp_remotepath, "/", name, NULL);
937         } else {
938             fullname = dupstr(scp_sftp_remotepath);
939         }
940
941         /*
942          * We don't worry about whether we managed to create the
943          * directory, because if it exists already it's OK just to
944          * use it. Instead, we will stat it afterwards, and if it
945          * exists and is a directory we will assume we were either
946          * successful or it didn't matter.
947          */
948         sftp_register(req = fxp_mkdir_send(fullname));
949         rreq = sftp_find_request(pktin = sftp_recv());
950         assert(rreq == req);
951         ret = fxp_mkdir_recv(pktin, rreq);
952
953         if (!ret)
954             err = fxp_error();
955         else
956             err = "server reported no error";
957
958         sftp_register(req = fxp_stat_send(fullname));
959         rreq = sftp_find_request(pktin = sftp_recv());
960         assert(rreq == req);
961         ret = fxp_stat_recv(pktin, rreq, &attrs);
962
963         if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
964             !(attrs.permissions & 0040000)) {
965             tell_user(stderr, "unable to create directory %s: %s",
966                       fullname, err);
967             errs++;
968             return 1;
969         }
970
971         scp_sftp_remotepath = fullname;
972
973         return 0;
974     } else {
975         char buf[40];
976         sprintf(buf, "D%04o 0 ", modes);
977         back->send(backhandle, buf, strlen(buf));
978         back->send(backhandle, name, strlen(name));
979         back->send(backhandle, "\n", 1);
980         return response();
981     }
982 }
983
984 int scp_send_enddir(void)
985 {
986     if (using_sftp) {
987         sfree(scp_sftp_remotepath);
988         return 0;
989     } else {
990         back->send(backhandle, "E\n", 2);
991         return response();
992     }
993 }
994
995 /*
996  * Yes, I know; I have an scp_sink_setup _and_ an scp_sink_init.
997  * That's bad. The difference is that scp_sink_setup is called once
998  * right at the start, whereas scp_sink_init is called to
999  * initialise every level of recursion in the protocol.
1000  */
1001 int scp_sink_setup(char *source, int preserve, int recursive)
1002 {
1003     if (using_sftp) {
1004         char *newsource;
1005
1006         if (!fxp_init()) {
1007             tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
1008             errs++;
1009             return 1;
1010         }
1011         /*
1012          * It's possible that the source string we've been given
1013          * contains a wildcard. If so, we must split the directory
1014          * away from the wildcard itself (throwing an error if any
1015          * wildcardness comes before the final slash) and arrange
1016          * things so that a dirstack entry will be set up.
1017          */
1018         newsource = snewn(1+strlen(source), char);
1019         if (!wc_unescape(newsource, source)) {
1020             /* Yes, here we go; it's a wildcard. Bah. */
1021             char *dupsource, *lastpart, *dirpart, *wildcard;
1022             dupsource = dupstr(source);
1023             lastpart = stripslashes(dupsource, 0);
1024             wildcard = dupstr(lastpart);
1025             *lastpart = '\0';
1026             if (*dupsource && dupsource[1]) {
1027                 /*
1028                  * The remains of dupsource are at least two
1029                  * characters long, meaning the pathname wasn't
1030                  * empty or just `/'. Hence, we remove the trailing
1031                  * slash.
1032                  */
1033                 lastpart[-1] = '\0';
1034             } else if (!*dupsource) {
1035                 /*
1036                  * The remains of dupsource are _empty_ - the whole
1037                  * pathname was a wildcard. Hence we need to
1038                  * replace it with ".".
1039                  */
1040                 sfree(dupsource);
1041                 dupsource = dupstr(".");
1042             }
1043
1044             /*
1045              * Now we have separated our string into dupsource (the
1046              * directory part) and wildcard. Both of these will
1047              * need freeing at some point. Next step is to remove
1048              * wildcard escapes from the directory part, throwing
1049              * an error if it contains a real wildcard.
1050              */
1051             dirpart = snewn(1+strlen(dupsource), char);
1052             if (!wc_unescape(dirpart, dupsource)) {
1053                 tell_user(stderr, "%s: multiple-level wildcards unsupported",
1054                           source);
1055                 errs++;
1056                 sfree(dirpart);
1057                 sfree(wildcard);
1058                 sfree(dupsource);
1059                 return 1;
1060             }
1061
1062             /*
1063              * Now we have dirpart (unescaped, ie a valid remote
1064              * path), and wildcard (a wildcard). This will be
1065              * sufficient to arrange a dirstack entry.
1066              */
1067             scp_sftp_remotepath = dirpart;
1068             scp_sftp_wildcard = wildcard;
1069             sfree(dupsource);
1070         } else {
1071             scp_sftp_remotepath = newsource;
1072             scp_sftp_wildcard = NULL;
1073         }
1074         scp_sftp_preserve = preserve;
1075         scp_sftp_recursive = recursive;
1076         scp_sftp_donethistarget = 0;
1077         scp_sftp_dirstack_head = NULL;
1078     }
1079     return 0;
1080 }
1081
1082 int scp_sink_init(void)
1083 {
1084     if (!using_sftp) {
1085         back->send(backhandle, "", 1);
1086     }
1087     return 0;
1088 }
1089
1090 #define SCP_SINK_FILE   1
1091 #define SCP_SINK_DIR    2
1092 #define SCP_SINK_ENDDIR 3
1093 #define SCP_SINK_RETRY  4              /* not an action; just try again */
1094 struct scp_sink_action {
1095     int action;                        /* FILE, DIR, ENDDIR */
1096     char *buf;                         /* will need freeing after use */
1097     char *name;                        /* filename or dirname (not ENDDIR) */
1098     int mode;                          /* access mode (not ENDDIR) */
1099     unsigned long size;                /* file size (not ENDDIR) */
1100     int settime;                       /* 1 if atime and mtime are filled */
1101     unsigned long atime, mtime;        /* access times for the file */
1102 };
1103
1104 int scp_get_sink_action(struct scp_sink_action *act)
1105 {
1106     if (using_sftp) {
1107         char *fname;
1108         int must_free_fname;
1109         struct fxp_attrs attrs;
1110         struct sftp_packet *pktin;
1111         struct sftp_request *req, *rreq;
1112         int ret;
1113
1114         if (!scp_sftp_dirstack_head) {
1115             if (!scp_sftp_donethistarget) {
1116                 /*
1117                  * Simple case: we are only dealing with one file.
1118                  */
1119                 fname = scp_sftp_remotepath;
1120                 must_free_fname = 0;
1121                 scp_sftp_donethistarget = 1;
1122             } else {
1123                 /*
1124                  * Even simpler case: one file _which we've done_.
1125                  * Return 1 (finished).
1126                  */
1127                 return 1;
1128             }
1129         } else {
1130             /*
1131              * We're now in the middle of stepping through a list
1132              * of names returned from fxp_readdir(); so let's carry
1133              * on.
1134              */
1135             struct scp_sftp_dirstack *head = scp_sftp_dirstack_head;
1136             while (head->namepos < head->namelen &&
1137                    (is_dots(head->names[head->namepos].filename) ||
1138                     (head->wildcard &&
1139                      !wc_match(head->wildcard,
1140                                head->names[head->namepos].filename))))
1141                 head->namepos++;       /* skip . and .. */
1142             if (head->namepos < head->namelen) {
1143                 head->matched_something = 1;
1144                 fname = dupcat(head->dirpath, "/",
1145                                head->names[head->namepos++].filename,
1146                                NULL);
1147                 must_free_fname = 1;
1148             } else {
1149                 /*
1150                  * We've come to the end of the list; pop it off
1151                  * the stack and return an ENDDIR action (or RETRY
1152                  * if this was a wildcard match).
1153                  */
1154                 if (head->wildcard) {
1155                     act->action = SCP_SINK_RETRY;
1156                     if (!head->matched_something) {
1157                         tell_user(stderr, "pscp: wildcard '%s' matched "
1158                                   "no files", head->wildcard);
1159                         errs++;
1160                     }
1161                     sfree(head->wildcard);
1162
1163                 } else {
1164                     act->action = SCP_SINK_ENDDIR;
1165                 }
1166
1167                 sfree(head->dirpath);
1168                 sfree(head->names);
1169                 scp_sftp_dirstack_head = head->next;
1170                 sfree(head);
1171
1172                 return 0;
1173             }
1174         }
1175
1176         /*
1177          * Now we have a filename. Stat it, and see if it's a file
1178          * or a directory.
1179          */
1180         sftp_register(req = fxp_stat_send(fname));
1181         rreq = sftp_find_request(pktin = sftp_recv());
1182         assert(rreq == req);
1183         ret = fxp_stat_recv(pktin, rreq, &attrs);
1184
1185         if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
1186             tell_user(stderr, "unable to identify %s: %s", fname,
1187                       ret ? "file type not supplied" : fxp_error());
1188             errs++;
1189             return 1;
1190         }
1191
1192         if (attrs.permissions & 0040000) {
1193             struct scp_sftp_dirstack *newitem;
1194             struct fxp_handle *dirhandle;
1195             int nnames, namesize;
1196             struct fxp_name *ournames;
1197             struct fxp_names *names;
1198
1199             /*
1200              * It's a directory. If we're not in recursive mode,
1201              * this merits a complaint (which is fatal if the name
1202              * was specified directly, but not if it was matched by
1203              * a wildcard).
1204              * 
1205              * We skip this complaint completely if
1206              * scp_sftp_wildcard is set, because that's an
1207              * indication that we're not actually supposed to
1208              * _recursively_ transfer the dir, just scan it for
1209              * things matching the wildcard.
1210              */
1211             if (!scp_sftp_recursive && !scp_sftp_wildcard) {
1212                 tell_user(stderr, "pscp: %s: is a directory", fname);
1213                 errs++;
1214                 if (must_free_fname) sfree(fname);
1215                 if (scp_sftp_dirstack_head) {
1216                     act->action = SCP_SINK_RETRY;
1217                     return 0;
1218                 } else {
1219                     return 1;
1220                 }
1221             }
1222
1223             /*
1224              * Otherwise, the fun begins. We must fxp_opendir() the
1225              * directory, slurp the filenames into memory, return
1226              * SCP_SINK_DIR (unless this is a wildcard match), and
1227              * set targetisdir. The next time we're called, we will
1228              * run through the list of filenames one by one,
1229              * matching them against a wildcard if present.
1230              * 
1231              * If targetisdir is _already_ set (meaning we're
1232              * already in the middle of going through another such
1233              * list), we must push the other (target,namelist) pair
1234              * on a stack.
1235              */
1236             sftp_register(req = fxp_opendir_send(fname));
1237             rreq = sftp_find_request(pktin = sftp_recv());
1238             assert(rreq == req);
1239             dirhandle = fxp_opendir_recv(pktin, rreq);
1240
1241             if (!dirhandle) {
1242                 tell_user(stderr, "scp: unable to open directory %s: %s",
1243                           fname, fxp_error());
1244                 if (must_free_fname) sfree(fname);
1245                 errs++;
1246                 return 1;
1247             }
1248             nnames = namesize = 0;
1249             ournames = NULL;
1250             while (1) {
1251                 int i;
1252
1253                 sftp_register(req = fxp_readdir_send(dirhandle));
1254                 rreq = sftp_find_request(pktin = sftp_recv());
1255                 assert(rreq == req);
1256                 names = fxp_readdir_recv(pktin, rreq);
1257
1258                 if (names == NULL) {
1259                     if (fxp_error_type() == SSH_FX_EOF)
1260                         break;
1261                     tell_user(stderr, "scp: reading directory %s: %s\n",
1262                               fname, fxp_error());
1263                     if (must_free_fname) sfree(fname);
1264                     sfree(ournames);
1265                     errs++;
1266                     return 1;
1267                 }
1268                 if (names->nnames == 0) {
1269                     fxp_free_names(names);
1270                     break;
1271                 }
1272                 if (nnames + names->nnames >= namesize) {
1273                     namesize += names->nnames + 128;
1274                     ournames = sresize(ournames, namesize, struct fxp_name);
1275                 }
1276                 for (i = 0; i < names->nnames; i++)
1277                     ournames[nnames++] = names->names[i];
1278                 names->nnames = 0;             /* prevent free_names */
1279                 fxp_free_names(names);
1280             }
1281             sftp_register(req = fxp_close_send(dirhandle));
1282             rreq = sftp_find_request(pktin = sftp_recv());
1283             assert(rreq == req);
1284             fxp_close_recv(pktin, rreq);
1285
1286             newitem = snew(struct scp_sftp_dirstack);
1287             newitem->next = scp_sftp_dirstack_head;
1288             newitem->names = ournames;
1289             newitem->namepos = 0;
1290             newitem->namelen = nnames;
1291             if (must_free_fname)
1292                 newitem->dirpath = fname;
1293             else
1294                 newitem->dirpath = dupstr(fname);
1295             if (scp_sftp_wildcard) {
1296                 newitem->wildcard = scp_sftp_wildcard;
1297                 newitem->matched_something = 0;
1298                 scp_sftp_wildcard = NULL;
1299             } else {
1300                 newitem->wildcard = NULL;
1301             }
1302             scp_sftp_dirstack_head = newitem;
1303
1304             if (newitem->wildcard) {
1305                 act->action = SCP_SINK_RETRY;
1306             } else {
1307                 act->action = SCP_SINK_DIR;
1308                 act->buf = dupstr(stripslashes(fname, 0));
1309                 act->name = act->buf;
1310                 act->size = 0;         /* duhh, it's a directory */
1311                 act->mode = 07777 & attrs.permissions;
1312                 if (scp_sftp_preserve &&
1313                     (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
1314                     act->atime = attrs.atime;
1315                     act->mtime = attrs.mtime;
1316                     act->settime = 1;
1317                 } else
1318                     act->settime = 0;
1319             }
1320             return 0;
1321
1322         } else {
1323             /*
1324              * It's a file. Return SCP_SINK_FILE.
1325              */
1326             act->action = SCP_SINK_FILE;
1327             act->buf = dupstr(stripslashes(fname, 0));
1328             act->name = act->buf;
1329             if (attrs.flags & SSH_FILEXFER_ATTR_SIZE) {
1330                 if (uint64_compare(attrs.size,
1331                                    uint64_make(0, ULONG_MAX)) > 0) {
1332                     act->size = ULONG_MAX;   /* *boggle* */
1333                 } else
1334                     act->size = attrs.size.lo;
1335             } else
1336                 act->size = ULONG_MAX;   /* no idea */
1337             act->mode = 07777 & attrs.permissions;
1338             if (scp_sftp_preserve &&
1339                 (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
1340                 act->atime = attrs.atime;
1341                 act->mtime = attrs.mtime;
1342                 act->settime = 1;
1343             } else
1344                 act->settime = 0;
1345             if (must_free_fname)
1346                 scp_sftp_currentname = fname;
1347             else
1348                 scp_sftp_currentname = dupstr(fname);
1349             return 0;
1350         }
1351
1352     } else {
1353         int done = 0;
1354         int i, bufsize;
1355         int action;
1356         char ch;
1357
1358         act->settime = 0;
1359         act->buf = NULL;
1360         bufsize = 0;
1361
1362         while (!done) {
1363             if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
1364                 return 1;
1365             if (ch == '\n')
1366                 bump("Protocol error: Unexpected newline");
1367             i = 0;
1368             action = ch;
1369             do {
1370                 if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
1371                     bump("Lost connection");
1372                 if (i >= bufsize) {
1373                     bufsize = i + 128;
1374                     act->buf = sresize(act->buf, bufsize, char);
1375                 }
1376                 act->buf[i++] = ch;
1377             } while (ch != '\n');
1378             act->buf[i - 1] = '\0';
1379             switch (action) {
1380               case '\01':                      /* error */
1381                 tell_user(stderr, "%s\n", act->buf);
1382                 errs++;
1383                 continue;                      /* go round again */
1384               case '\02':                      /* fatal error */
1385                 bump("%s", act->buf);
1386               case 'E':
1387                 back->send(backhandle, "", 1);
1388                 act->action = SCP_SINK_ENDDIR;
1389                 return 0;
1390               case 'T':
1391                 if (sscanf(act->buf, "%ld %*d %ld %*d",
1392                            &act->mtime, &act->atime) == 2) {
1393                     act->settime = 1;
1394                     back->send(backhandle, "", 1);
1395                     continue;          /* go round again */
1396                 }
1397                 bump("Protocol error: Illegal time format");
1398               case 'C':
1399               case 'D':
1400                 act->action = (action == 'C' ? SCP_SINK_FILE : SCP_SINK_DIR);
1401                 break;
1402               default:
1403                 bump("Protocol error: Expected control record");
1404             }
1405             /*
1406              * We will go round this loop only once, unless we hit
1407              * `continue' above.
1408              */
1409             done = 1;
1410         }
1411
1412         /*
1413          * If we get here, we must have seen SCP_SINK_FILE or
1414          * SCP_SINK_DIR.
1415          */
1416         if (sscanf(act->buf, "%o %lu %n", &act->mode, &act->size, &i) != 2)
1417             bump("Protocol error: Illegal file descriptor format");
1418         act->name = act->buf + i;
1419         return 0;
1420     }
1421 }
1422
1423 int scp_accept_filexfer(void)
1424 {
1425     if (using_sftp) {
1426         struct sftp_packet *pktin;
1427         struct sftp_request *req, *rreq;
1428
1429         sftp_register(req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ));
1430         rreq = sftp_find_request(pktin = sftp_recv());
1431         assert(rreq == req);
1432         scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
1433
1434         if (!scp_sftp_filehandle) {
1435             tell_user(stderr, "pscp: unable to open %s: %s",
1436                       scp_sftp_currentname, fxp_error());
1437             errs++;
1438             return 1;
1439         }
1440         scp_sftp_fileoffset = uint64_make(0, 0);
1441         scp_sftp_xfer = xfer_download_init(scp_sftp_filehandle,
1442                                            scp_sftp_fileoffset);
1443         sfree(scp_sftp_currentname);
1444         return 0;
1445     } else {
1446         back->send(backhandle, "", 1);
1447         return 0;                      /* can't fail */
1448     }
1449 }
1450
1451 int scp_recv_filedata(char *data, int len)
1452 {
1453     if (using_sftp) {
1454         struct sftp_packet *pktin;
1455         int ret, actuallen;
1456         void *vbuf;
1457
1458         xfer_download_queue(scp_sftp_xfer);
1459         pktin = sftp_recv();
1460         ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
1461
1462         if (ret < 0) {
1463             tell_user(stderr, "pscp: error while reading: %s", fxp_error());
1464             errs++;
1465             return -1;
1466         }
1467
1468         if (xfer_download_data(scp_sftp_xfer, &vbuf, &actuallen)) {
1469             /*
1470              * This assertion relies on the fact that the natural
1471              * block size used in the xfer manager is at most that
1472              * used in this module. I don't like crossing layers in
1473              * this way, but it'll do for now.
1474              */
1475             assert(actuallen <= len);
1476             memcpy(data, vbuf, actuallen);
1477             sfree(vbuf);
1478         } else
1479             actuallen = 0;
1480
1481         scp_sftp_fileoffset = uint64_add32(scp_sftp_fileoffset, actuallen);
1482
1483         return actuallen;
1484     } else {
1485         return ssh_scp_recv((unsigned char *) data, len);
1486     }
1487 }
1488
1489 int scp_finish_filerecv(void)
1490 {
1491     if (using_sftp) {
1492         struct sftp_packet *pktin;
1493         struct sftp_request *req, *rreq;
1494
1495         /*
1496          * Ensure that xfer_done() will work correctly, so we can
1497          * clean up any outstanding requests from the file
1498          * transfer.
1499          */
1500         xfer_set_error(scp_sftp_xfer);
1501         while (!xfer_done(scp_sftp_xfer)) {
1502             void *vbuf;
1503             int len;
1504
1505             pktin = sftp_recv();
1506             xfer_download_gotpkt(scp_sftp_xfer, pktin);
1507             if (xfer_download_data(scp_sftp_xfer, &vbuf, &len))
1508                 sfree(vbuf);
1509         }
1510         xfer_cleanup(scp_sftp_xfer);
1511
1512         sftp_register(req = fxp_close_send(scp_sftp_filehandle));
1513         rreq = sftp_find_request(pktin = sftp_recv());
1514         assert(rreq == req);
1515         fxp_close_recv(pktin, rreq);
1516         return 0;
1517     } else {
1518         back->send(backhandle, "", 1);
1519         return response();
1520     }
1521 }
1522
1523 /* ----------------------------------------------------------------------
1524  *  Send an error message to the other side and to the screen.
1525  *  Increment error counter.
1526  */
1527 static void run_err(const char *fmt, ...)
1528 {
1529     char *str, *str2;
1530     va_list ap;
1531     va_start(ap, fmt);
1532     errs++;
1533     str = dupvprintf(fmt, ap);
1534     str2 = dupcat("scp: ", str, "\n", NULL);
1535     sfree(str);
1536     scp_send_errmsg(str2);
1537     tell_user(stderr, "%s", str2);
1538     va_end(ap);
1539     sfree(str2);
1540 }
1541
1542 /*
1543  *  Execute the source part of the SCP protocol.
1544  */
1545 static void source(char *src)
1546 {
1547     unsigned long size;
1548     unsigned long mtime, atime;
1549     char *last;
1550     RFile *f;
1551     int attr;
1552     unsigned long i;
1553     unsigned long stat_bytes;
1554     time_t stat_starttime, stat_lasttime;
1555
1556     attr = file_type(src);
1557     if (attr == FILE_TYPE_NONEXISTENT ||
1558         attr == FILE_TYPE_WEIRD) {
1559         run_err("%s: %s file or directory", src,
1560                 (attr == FILE_TYPE_WEIRD ? "Not a" : "No such"));
1561         return;
1562     }
1563
1564     if (attr == FILE_TYPE_DIRECTORY) {
1565         if (recursive) {
1566             /*
1567              * Avoid . and .. directories.
1568              */
1569             char *p;
1570             p = strrchr(src, '/');
1571             if (!p)
1572                 p = strrchr(src, '\\');
1573             if (!p)
1574                 p = src;
1575             else
1576                 p++;
1577             if (!strcmp(p, ".") || !strcmp(p, ".."))
1578                 /* skip . and .. */ ;
1579             else
1580                 rsource(src);
1581         } else {
1582             run_err("%s: not a regular file", src);
1583         }
1584         return;
1585     }
1586
1587     if ((last = strrchr(src, '/')) == NULL)
1588         last = src;
1589     else
1590         last++;
1591     if (strrchr(last, '\\') != NULL)
1592         last = strrchr(last, '\\') + 1;
1593     if (last == src && strchr(src, ':') != NULL)
1594         last = strchr(src, ':') + 1;
1595
1596     f = open_existing_file(src, &size, &mtime, &atime);
1597     if (f == NULL) {
1598         run_err("%s: Cannot open file", src);
1599         return;
1600     }
1601     if (preserve) {
1602         if (scp_send_filetimes(mtime, atime))
1603             return;
1604     }
1605
1606     if (verbose)
1607         tell_user(stderr, "Sending file %s, size=%lu", last, size);
1608     if (scp_send_filename(last, size, 0644))
1609         return;
1610
1611     stat_bytes = 0;
1612     stat_starttime = time(NULL);
1613     stat_lasttime = 0;
1614
1615     for (i = 0; i < size; i += 4096) {
1616         char transbuf[4096];
1617         int j, k = 4096;
1618
1619         if (i + k > size)
1620             k = size - i;
1621         if ((j = read_from_file(f, transbuf, k)) != k) {
1622             if (statistics)
1623                 printf("\n");
1624             bump("%s: Read error", src);
1625         }
1626         if (scp_send_filedata(transbuf, k))
1627             bump("%s: Network error occurred", src);
1628
1629         if (statistics) {
1630             stat_bytes += k;
1631             if (time(NULL) != stat_lasttime || i + k == size) {
1632                 stat_lasttime = time(NULL);
1633                 print_stats(last, size, stat_bytes,
1634                             stat_starttime, stat_lasttime);
1635             }
1636         }
1637
1638     }
1639     close_rfile(f);
1640
1641     (void) scp_send_finish();
1642 }
1643
1644 /*
1645  *  Recursively send the contents of a directory.
1646  */
1647 static void rsource(char *src)
1648 {
1649     char *last;
1650     char *save_target;
1651     DirHandle *dir;
1652
1653     if ((last = strrchr(src, '/')) == NULL)
1654         last = src;
1655     else
1656         last++;
1657     if (strrchr(last, '\\') != NULL)
1658         last = strrchr(last, '\\') + 1;
1659     if (last == src && strchr(src, ':') != NULL)
1660         last = strchr(src, ':') + 1;
1661
1662     /* maybe send filetime */
1663
1664     save_target = scp_save_remotepath();
1665
1666     if (verbose)
1667         tell_user(stderr, "Entering directory: %s", last);
1668     if (scp_send_dirname(last, 0755))
1669         return;
1670
1671     dir = open_directory(src);
1672     if (dir != NULL) {
1673         char *filename;
1674         while ((filename = read_filename(dir)) != NULL) {
1675             char *foundfile = dupcat(src, "/", filename, NULL);
1676             source(foundfile);
1677             sfree(foundfile);
1678             sfree(filename);
1679         }
1680     }
1681     close_directory(dir);
1682
1683     (void) scp_send_enddir();
1684
1685     scp_restore_remotepath(save_target);
1686 }
1687
1688 /*
1689  * Execute the sink part of the SCP protocol.
1690  */
1691 static void sink(char *targ, char *src)
1692 {
1693     char *destfname;
1694     int targisdir = 0;
1695     int exists;
1696     int attr;
1697     WFile *f;
1698     unsigned long received;
1699     int wrerror = 0;
1700     unsigned long stat_bytes;
1701     time_t stat_starttime, stat_lasttime;
1702     char *stat_name;
1703
1704     attr = file_type(targ);
1705     if (attr == FILE_TYPE_DIRECTORY)
1706         targisdir = 1;
1707
1708     if (targetshouldbedirectory && !targisdir)
1709         bump("%s: Not a directory", targ);
1710
1711     scp_sink_init();
1712     while (1) {
1713         struct scp_sink_action act;
1714         if (scp_get_sink_action(&act))
1715             return;
1716
1717         if (act.action == SCP_SINK_ENDDIR)
1718             return;
1719
1720         if (act.action == SCP_SINK_RETRY)
1721             continue;
1722
1723         if (targisdir) {
1724             /*
1725              * Prevent the remote side from maliciously writing to
1726              * files outside the target area by sending a filename
1727              * containing `../'. In fact, it shouldn't be sending
1728              * filenames with any slashes or colons in at all; so
1729              * we'll find the last slash, backslash or colon in the
1730              * filename and use only the part after that. (And
1731              * warn!)
1732              * 
1733              * In addition, we also ensure here that if we're
1734              * copying a single file and the target is a directory
1735              * (common usage: `pscp host:filename .') the remote
1736              * can't send us a _different_ file name. We can
1737              * distinguish this case because `src' will be non-NULL
1738              * and the last component of that will fail to match
1739              * (the last component of) the name sent.
1740              * 
1741              * Well, not always; if `src' is a wildcard, we do
1742              * expect to get back filenames that don't correspond
1743              * exactly to it. Ideally in this case, we would like
1744              * to ensure that the returned filename actually
1745              * matches the wildcard pattern - but one of SCP's
1746              * protocol infelicities is that wildcard matching is
1747              * done at the server end _by the server's rules_ and
1748              * so in general this is infeasible. Hence, we only
1749              * accept filenames that don't correspond to `src' if
1750              * unsafe mode is enabled or we are using SFTP (which
1751              * resolves remote wildcards on the client side and can
1752              * be trusted).
1753              */
1754             char *striptarget, *stripsrc;
1755
1756             striptarget = stripslashes(act.name, 1);
1757             if (striptarget != act.name) {
1758                 tell_user(stderr, "warning: remote host sent a compound"
1759                           " pathname '%s'", act.name);
1760                 tell_user(stderr, "         renaming local file to '%s'",
1761                           striptarget);
1762             }
1763
1764             /*
1765              * Also check to see if the target filename is '.' or
1766              * '..', or indeed '...' and so on because Windows
1767              * appears to interpret those like '..'.
1768              */
1769             if (is_dots(striptarget)) {
1770                 bump("security violation: remote host attempted to write to"
1771                      " a '.' or '..' path!");
1772             }
1773
1774             if (src) {
1775                 stripsrc = stripslashes(src, 1);
1776                 if (strcmp(striptarget, stripsrc) &&
1777                     !using_sftp && !scp_unsafe_mode) {
1778                     tell_user(stderr, "warning: remote host tried to write "
1779                               "to a file called '%s'", striptarget);
1780                     tell_user(stderr, "         when we requested a file "
1781                               "called '%s'.", stripsrc);
1782                     tell_user(stderr, "         If this is a wildcard, "
1783                               "consider upgrading to SSH 2 or using");
1784                     tell_user(stderr, "         the '-unsafe' option. Renaming"
1785                               " of this file has been disallowed.");
1786                     /* Override the name the server provided with our own. */
1787                     striptarget = stripsrc;
1788                 }
1789             }
1790
1791             if (targ[0] != '\0')
1792                 destfname = dir_file_cat(targ, striptarget);
1793             else
1794                 destfname = dupstr(striptarget);
1795         } else {
1796             /*
1797              * In this branch of the if, the target area is a
1798              * single file with an explicitly specified name in any
1799              * case, so there's no danger.
1800              */
1801             destfname = dupstr(targ);
1802         }
1803         attr = file_type(destfname);
1804         exists = (attr != FILE_TYPE_NONEXISTENT);
1805
1806         if (act.action == SCP_SINK_DIR) {
1807             if (exists && attr != FILE_TYPE_DIRECTORY) {
1808                 run_err("%s: Not a directory", destfname);
1809                 continue;
1810             }
1811             if (!exists) {
1812                 if (!create_directory(destfname)) {
1813                     run_err("%s: Cannot create directory", destfname);
1814                     continue;
1815                 }
1816             }
1817             sink(destfname, NULL);
1818             /* can we set the timestamp for directories ? */
1819             continue;
1820         }
1821
1822         f = open_new_file(destfname);
1823         if (f == NULL) {
1824             run_err("%s: Cannot create file", destfname);
1825             continue;
1826         }
1827
1828         if (scp_accept_filexfer())
1829             return;
1830
1831         stat_bytes = 0;
1832         stat_starttime = time(NULL);
1833         stat_lasttime = 0;
1834         stat_name = stripslashes(destfname, 1);
1835
1836         received = 0;
1837         while (received < act.size) {
1838             char transbuf[4096];
1839             unsigned long blksize;
1840             int read;
1841             blksize = 4096;
1842             if (blksize > (act.size - received))
1843                 blksize = act.size - received;
1844             read = scp_recv_filedata(transbuf, (int)blksize);
1845             if (read <= 0)
1846                 bump("Lost connection");
1847             if (wrerror)
1848                 continue;
1849             if (write_to_file(f, transbuf, read) != (int)read) {
1850                 wrerror = 1;
1851                 /* FIXME: in sftp we can actually abort the transfer */
1852                 if (statistics)
1853                     printf("\r%-25.25s | %50s\n",
1854                            stat_name,
1855                            "Write error.. waiting for end of file");
1856                 continue;
1857             }
1858             if (statistics) {
1859                 stat_bytes += read;
1860                 if (time(NULL) > stat_lasttime ||
1861                     received + read == act.size) {
1862                     stat_lasttime = time(NULL);
1863                     print_stats(stat_name, act.size, stat_bytes,
1864                                 stat_starttime, stat_lasttime);
1865                 }
1866             }
1867             received += read;
1868         }
1869         if (act.settime) {
1870             set_file_times(f, act.mtime, act.atime);
1871         }
1872
1873         close_wfile(f);
1874         if (wrerror) {
1875             run_err("%s: Write error", destfname);
1876             continue;
1877         }
1878         (void) scp_finish_filerecv();
1879         sfree(destfname);
1880         sfree(act.buf);
1881     }
1882 }
1883
1884 /*
1885  * We will copy local files to a remote server.
1886  */
1887 static void toremote(int argc, char *argv[])
1888 {
1889     char *src, *targ, *host, *user;
1890     char *cmd;
1891     int i, wc_type;
1892
1893     targ = argv[argc - 1];
1894
1895     /* Separate host from filename */
1896     host = targ;
1897     targ = colon(targ);
1898     if (targ == NULL)
1899         bump("targ == NULL in toremote()");
1900     *targ++ = '\0';
1901     if (*targ == '\0')
1902         targ = ".";
1903     /* Substitute "." for emtpy target */
1904
1905     /* Separate host and username */
1906     user = host;
1907     host = strrchr(host, '@');
1908     if (host == NULL) {
1909         host = user;
1910         user = NULL;
1911     } else {
1912         *host++ = '\0';
1913         if (*user == '\0')
1914             user = NULL;
1915     }
1916
1917     if (argc == 2) {
1918         if (colon(argv[0]) != NULL)
1919             bump("%s: Remote to remote not supported", argv[0]);
1920
1921         wc_type = test_wildcard(argv[0], 1);
1922         if (wc_type == WCTYPE_NONEXISTENT)
1923             bump("%s: No such file or directory\n", argv[0]);
1924         else if (wc_type == WCTYPE_WILDCARD)
1925             targetshouldbedirectory = 1;
1926     }
1927
1928     cmd = dupprintf("scp%s%s%s%s -t %s",
1929                     verbose ? " -v" : "",
1930                     recursive ? " -r" : "",
1931                     preserve ? " -p" : "",
1932                     targetshouldbedirectory ? " -d" : "", targ);
1933     do_cmd(host, user, cmd);
1934     sfree(cmd);
1935
1936     scp_source_setup(targ, targetshouldbedirectory);
1937
1938     for (i = 0; i < argc - 1; i++) {
1939         src = argv[i];
1940         if (colon(src) != NULL) {
1941             tell_user(stderr, "%s: Remote to remote not supported\n", src);
1942             errs++;
1943             continue;
1944         }
1945
1946         wc_type = test_wildcard(src, 1);
1947         if (wc_type == WCTYPE_NONEXISTENT) {
1948             run_err("%s: No such file or directory", src);
1949             continue;
1950         } else if (wc_type == WCTYPE_FILENAME) {
1951             source(src);
1952             continue;
1953         } else {
1954             WildcardMatcher *wc;
1955             char *filename;
1956
1957             wc = begin_wildcard_matching(src);
1958             if (wc == NULL) {
1959                 run_err("%s: No such file or directory", src);
1960                 continue;
1961             }
1962
1963             while ((filename = wildcard_get_filename(wc)) != NULL) {
1964                 source(filename);
1965                 sfree(filename);
1966             }
1967
1968             finish_wildcard_matching(wc);
1969         }
1970     }
1971 }
1972
1973 /*
1974  *  We will copy files from a remote server to the local machine.
1975  */
1976 static void tolocal(int argc, char *argv[])
1977 {
1978     char *src, *targ, *host, *user;
1979     char *cmd;
1980
1981     if (argc != 2)
1982         bump("More than one remote source not supported");
1983
1984     src = argv[0];
1985     targ = argv[1];
1986
1987     /* Separate host from filename */
1988     host = src;
1989     src = colon(src);
1990     if (src == NULL)
1991         bump("Local to local copy not supported");
1992     *src++ = '\0';
1993     if (*src == '\0')
1994         src = ".";
1995     /* Substitute "." for empty filename */
1996
1997     /* Separate username and hostname */
1998     user = host;
1999     host = strrchr(host, '@');
2000     if (host == NULL) {
2001         host = user;
2002         user = NULL;
2003     } else {
2004         *host++ = '\0';
2005         if (*user == '\0')
2006             user = NULL;
2007     }
2008
2009     cmd = dupprintf("scp%s%s%s%s -f %s",
2010                     verbose ? " -v" : "",
2011                     recursive ? " -r" : "",
2012                     preserve ? " -p" : "",
2013                     targetshouldbedirectory ? " -d" : "", src);
2014     do_cmd(host, user, cmd);
2015     sfree(cmd);
2016
2017     if (scp_sink_setup(src, preserve, recursive))
2018         return;
2019
2020     sink(targ, src);
2021 }
2022
2023 /*
2024  *  We will issue a list command to get a remote directory.
2025  */
2026 static void get_dir_list(int argc, char *argv[])
2027 {
2028     char *src, *host, *user;
2029     char *cmd, *p, *q;
2030     char c;
2031
2032     src = argv[0];
2033
2034     /* Separate host from filename */
2035     host = src;
2036     src = colon(src);
2037     if (src == NULL)
2038         bump("Local to local copy not supported");
2039     *src++ = '\0';
2040     if (*src == '\0')
2041         src = ".";
2042     /* Substitute "." for empty filename */
2043
2044     /* Separate username and hostname */
2045     user = host;
2046     host = strrchr(host, '@');
2047     if (host == NULL) {
2048         host = user;
2049         user = NULL;
2050     } else {
2051         *host++ = '\0';
2052         if (*user == '\0')
2053             user = NULL;
2054     }
2055
2056     cmd = snewn(4 * strlen(src) + 100, char);
2057     strcpy(cmd, "ls -la '");
2058     p = cmd + strlen(cmd);
2059     for (q = src; *q; q++) {
2060         if (*q == '\'') {
2061             *p++ = '\'';
2062             *p++ = '\\';
2063             *p++ = '\'';
2064             *p++ = '\'';
2065         } else {
2066             *p++ = *q;
2067         }
2068     }
2069     *p++ = '\'';
2070     *p = '\0';
2071
2072     do_cmd(host, user, cmd);
2073     sfree(cmd);
2074
2075     if (using_sftp) {
2076         scp_sftp_listdir(src);
2077     } else {
2078         while (ssh_scp_recv((unsigned char *) &c, 1) > 0)
2079             tell_char(stdout, c);
2080     }
2081 }
2082
2083 /*
2084  *  Short description of parameters.
2085  */
2086 static void usage(void)
2087 {
2088     printf("PuTTY Secure Copy client\n");
2089     printf("%s\n", ver);
2090     printf("Usage: pscp [options] [user@]host:source target\n");
2091     printf
2092         ("       pscp [options] source [source...] [user@]host:target\n");
2093     printf("       pscp [options] -ls [user@]host:filespec\n");
2094     printf("Options:\n");
2095     printf("  -p        preserve file attributes\n");
2096     printf("  -q        quiet, don't show statistics\n");
2097     printf("  -r        copy directories recursively\n");
2098     printf("  -v        show verbose messages\n");
2099     printf("  -load sessname  Load settings from saved session\n");
2100     printf("  -P port   connect to specified port\n");
2101     printf("  -l user   connect with specified username\n");
2102     printf("  -pw passw login with specified password\n");
2103     printf("  -1 -2     force use of particular SSH protocol version\n");
2104     printf("  -C        enable compression\n");
2105     printf("  -i key    private key file for authentication\n");
2106     printf("  -batch    disable all interactive prompts\n");
2107     printf("  -unsafe   allow server-side wildcards (DANGEROUS)\n");
2108     printf("  -V        print version information\n");
2109     printf("  -sftp     force use of SFTP protocol\n");
2110     printf("  -scp      force use of SCP protocol\n");
2111 #if 0
2112     /*
2113      * -gui is an internal option, used by GUI front ends to get
2114      * pscp to pass progress reports back to them. It's not an
2115      * ordinary user-accessible option, so it shouldn't be part of
2116      * the command-line help. The only people who need to know
2117      * about it are programmers, and they can read the source.
2118      */
2119     printf
2120         ("  -gui hWnd GUI mode with the windows handle for receiving messages\n");
2121 #endif
2122     cleanup_exit(1);
2123 }
2124
2125 void version(void)
2126 {
2127     printf("pscp: %s\n", ver);
2128     cleanup_exit(1);
2129 }
2130
2131 void cmdline_error(char *p, ...)
2132 {
2133     va_list ap;
2134     fprintf(stderr, "pscp: ");
2135     va_start(ap, p);
2136     vfprintf(stderr, p, ap);
2137     va_end(ap);
2138     fprintf(stderr, "\n      try typing just \"pscp\" for help\n");
2139     exit(1);
2140 }
2141
2142 /*
2143  * Main program. (Called `psftp_main' because it gets called from
2144  * *sftp.c; bit silly, I know, but it had to be called _something_.)
2145  */
2146 int psftp_main(int argc, char *argv[])
2147 {
2148     int i;
2149
2150     default_protocol = PROT_TELNET;
2151
2152     flags = FLAG_STDERR
2153 #ifdef FLAG_SYNCAGENT
2154         | FLAG_SYNCAGENT
2155 #endif
2156         ;
2157     cmdline_tooltype = TOOLTYPE_FILETRANSFER;
2158     ssh_get_line = &console_get_line;
2159     sk_init();
2160
2161     for (i = 1; i < argc; i++) {
2162         int ret;
2163         if (argv[i][0] != '-')
2164             break;
2165         ret = cmdline_process_param(argv[i], i+1<argc?argv[i+1]:NULL, 1, &cfg);
2166         if (ret == -2) {
2167             cmdline_error("option \"%s\" requires an argument", argv[i]);
2168         } else if (ret == 2) {
2169             i++;               /* skip next argument */
2170         } else if (ret == 1) {
2171             /* We have our own verbosity in addition to `flags'. */
2172             if (flags & FLAG_VERBOSE)
2173                 verbose = 1;
2174         } else if (strcmp(argv[i], "-r") == 0) {
2175             recursive = 1;
2176         } else if (strcmp(argv[i], "-p") == 0) {
2177             preserve = 1;
2178         } else if (strcmp(argv[i], "-q") == 0) {
2179             statistics = 0;
2180         } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) {
2181             usage();
2182         } else if (strcmp(argv[i], "-V") == 0) {
2183             version();
2184         } else if (strcmp(argv[i], "-gui") == 0 && i + 1 < argc) {
2185             gui_enable(argv[++i]);
2186             gui_mode = 1;
2187             console_batch_mode = TRUE;
2188         } else if (strcmp(argv[i], "-ls") == 0) {
2189             list = 1;
2190         } else if (strcmp(argv[i], "-batch") == 0) {
2191             console_batch_mode = 1;
2192         } else if (strcmp(argv[i], "-unsafe") == 0) {
2193             scp_unsafe_mode = 1;
2194         } else if (strcmp(argv[i], "-sftp") == 0) {
2195             try_scp = 0; try_sftp = 1;
2196         } else if (strcmp(argv[i], "-scp") == 0) {
2197             try_scp = 1; try_sftp = 0;
2198         } else if (strcmp(argv[i], "--") == 0) {
2199             i++;
2200             break;
2201         } else {
2202             cmdline_error("unknown option \"%s\"", argv[i]);
2203         }
2204     }
2205     argc -= i;
2206     argv += i;
2207     back = NULL;
2208
2209     if (list) {
2210         if (argc != 1)
2211             usage();
2212         get_dir_list(argc, argv);
2213
2214     } else {
2215
2216         if (argc < 2)
2217             usage();
2218         if (argc > 2)
2219             targetshouldbedirectory = 1;
2220
2221         if (colon(argv[argc - 1]) != NULL)
2222             toremote(argc, argv);
2223         else
2224             tolocal(argc, argv);
2225     }
2226
2227     if (back != NULL && back->socket(backhandle) != NULL) {
2228         char ch;
2229         back->special(backhandle, TS_EOF);
2230         ssh_scp_recv((unsigned char *) &ch, 1);
2231     }
2232     random_save_seed();
2233
2234     if (gui_mode)
2235         gui_send_errcount(list, errs);
2236
2237     cmdline_cleanup();
2238     console_provide_logctx(NULL);
2239     back->free(backhandle);
2240     backhandle = NULL;
2241     back = NULL;
2242     sk_cleanup();
2243     return (errs == 0 ? 0 : 1);
2244 }
2245
2246 /* end */