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