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