pscp.c 60 KB

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