sftp.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. /*
  2. * sftp.h: definitions for SFTP and the sftp.c routines.
  3. */
  4. #include "defs.h"
  5. #define SSH_FXP_INIT 1 /* 0x1 */
  6. #define SSH_FXP_VERSION 2 /* 0x2 */
  7. #define SSH_FXP_OPEN 3 /* 0x3 */
  8. #define SSH_FXP_CLOSE 4 /* 0x4 */
  9. #define SSH_FXP_READ 5 /* 0x5 */
  10. #define SSH_FXP_WRITE 6 /* 0x6 */
  11. #define SSH_FXP_LSTAT 7 /* 0x7 */
  12. #define SSH_FXP_FSTAT 8 /* 0x8 */
  13. #define SSH_FXP_SETSTAT 9 /* 0x9 */
  14. #define SSH_FXP_FSETSTAT 10 /* 0xa */
  15. #define SSH_FXP_OPENDIR 11 /* 0xb */
  16. #define SSH_FXP_READDIR 12 /* 0xc */
  17. #define SSH_FXP_REMOVE 13 /* 0xd */
  18. #define SSH_FXP_MKDIR 14 /* 0xe */
  19. #define SSH_FXP_RMDIR 15 /* 0xf */
  20. #define SSH_FXP_REALPATH 16 /* 0x10 */
  21. #define SSH_FXP_STAT 17 /* 0x11 */
  22. #define SSH_FXP_RENAME 18 /* 0x12 */
  23. #define SSH_FXP_STATUS 101 /* 0x65 */
  24. #define SSH_FXP_HANDLE 102 /* 0x66 */
  25. #define SSH_FXP_DATA 103 /* 0x67 */
  26. #define SSH_FXP_NAME 104 /* 0x68 */
  27. #define SSH_FXP_ATTRS 105 /* 0x69 */
  28. #define SSH_FXP_EXTENDED 200 /* 0xc8 */
  29. #define SSH_FXP_EXTENDED_REPLY 201 /* 0xc9 */
  30. #define SSH_FX_OK 0
  31. #define SSH_FX_EOF 1
  32. #define SSH_FX_NO_SUCH_FILE 2
  33. #define SSH_FX_PERMISSION_DENIED 3
  34. #define SSH_FX_FAILURE 4
  35. #define SSH_FX_BAD_MESSAGE 5
  36. #define SSH_FX_NO_CONNECTION 6
  37. #define SSH_FX_CONNECTION_LOST 7
  38. #define SSH_FX_OP_UNSUPPORTED 8
  39. #define SSH_FILEXFER_ATTR_SIZE 0x00000001
  40. #define SSH_FILEXFER_ATTR_UIDGID 0x00000002
  41. #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
  42. #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
  43. #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
  44. #define SSH_FXF_READ 0x00000001
  45. #define SSH_FXF_WRITE 0x00000002
  46. #define SSH_FXF_APPEND 0x00000004
  47. #define SSH_FXF_CREAT 0x00000008
  48. #define SSH_FXF_TRUNC 0x00000010
  49. #define SSH_FXF_EXCL 0x00000020
  50. #define SFTP_PROTO_VERSION 3
  51. #define PERMS_DIRECTORY 040000
  52. /*
  53. * External references. The sftp client module sftp.c expects to be
  54. * able to get at these functions.
  55. *
  56. * sftp_recvdata must never return less than len. It either blocks
  57. * until len is available and then returns true, or it returns false
  58. * for failure.
  59. *
  60. * sftp_senddata returns true on success, false on failure.
  61. *
  62. * sftp_sendbuffer returns the size of the backlog of data in the
  63. * transmit queue.
  64. */
  65. bool sftp_senddata(const char *data, size_t len);
  66. size_t sftp_sendbuffer(void);
  67. bool sftp_recvdata(char *data, size_t len);
  68. /*
  69. * Free sftp_requests
  70. */
  71. void sftp_cleanup_request(void);
  72. struct fxp_attrs {
  73. unsigned long flags;
  74. uint64_t size;
  75. unsigned long uid;
  76. unsigned long gid;
  77. unsigned long permissions;
  78. unsigned long atime;
  79. unsigned long mtime;
  80. };
  81. extern const struct fxp_attrs no_attrs;
  82. /*
  83. * Copy between the possibly-unused permissions field in an fxp_attrs
  84. * and a possibly-negative integer containing the same permissions.
  85. */
  86. #define PUT_PERMISSIONS(attrs, perms) \
  87. ((perms) >= 0 ? \
  88. ((attrs).flags |= SSH_FILEXFER_ATTR_PERMISSIONS, \
  89. (attrs).permissions = (perms)) : \
  90. ((attrs).flags &= ~SSH_FILEXFER_ATTR_PERMISSIONS))
  91. #define GET_PERMISSIONS(attrs, defaultperms) \
  92. ((attrs).flags & SSH_FILEXFER_ATTR_PERMISSIONS ? \
  93. (attrs).permissions : defaultperms)
  94. struct fxp_handle {
  95. char *hstring;
  96. int hlen;
  97. };
  98. struct fxp_name {
  99. char *filename, *longname;
  100. struct fxp_attrs attrs;
  101. };
  102. struct fxp_names {
  103. int nnames;
  104. struct fxp_name *names;
  105. };
  106. struct sftp_request;
  107. /*
  108. * Packet-manipulation functions.
  109. */
  110. struct sftp_packet {
  111. char *data;
  112. size_t length, maxlen, savedpos;
  113. int type;
  114. BinarySink_IMPLEMENTATION;
  115. BinarySource_IMPLEMENTATION;
  116. };
  117. /* When sending a packet, create it with sftp_pkt_init, then add
  118. * things to it by treating it as a BinarySink. When it's done, call
  119. * sftp_send_prepare, and then pkt->data and pkt->length describe its
  120. * wire format. */
  121. struct sftp_packet *sftp_pkt_init(int pkt_type);
  122. void sftp_send_prepare(struct sftp_packet *pkt);
  123. /* When receiving a packet, create it with sftp_recv_prepare once you
  124. * decode its length from the first 4 bytes of wire data. Then write
  125. * that many bytes into pkt->data, and call sftp_recv_finish to set up
  126. * the type code and BinarySource. */
  127. struct sftp_packet *sftp_recv_prepare(unsigned length);
  128. bool sftp_recv_finish(struct sftp_packet *pkt);
  129. /* Either kind of packet can be freed afterwards with sftp_pkt_free. */
  130. void sftp_pkt_free(struct sftp_packet *pkt);
  131. void BinarySink_put_fxp_attrs(BinarySink *bs, struct fxp_attrs attrs);
  132. bool BinarySource_get_fxp_attrs(BinarySource *src, struct fxp_attrs *attrs);
  133. #define put_fxp_attrs(bs, attrs) \
  134. BinarySink_put_fxp_attrs(BinarySink_UPCAST(bs), attrs)
  135. #define get_fxp_attrs(bs, attrs) \
  136. BinarySource_get_fxp_attrs(BinarySource_UPCAST(bs), attrs)
  137. /*
  138. * Error handling.
  139. */
  140. const char *fxp_error(void);
  141. int fxp_error_type(void);
  142. /*
  143. * Perform exchange of init/version packets. Return false on failure.
  144. */
  145. bool fxp_init(void);
  146. /*
  147. * Canonify a pathname. Concatenate the two given path elements
  148. * with a separating slash, unless the second is NULL.
  149. */
  150. struct sftp_request *fxp_realpath_send(const char *path);
  151. char *fxp_realpath_recv(struct sftp_packet *pktin, struct sftp_request *req);
  152. /*
  153. * Open a file. 'attrs' contains attributes to be applied to the file
  154. * if it's being created.
  155. */
  156. struct sftp_request *fxp_open_send(const char *path, int type,
  157. const struct fxp_attrs *attrs);
  158. struct fxp_handle *fxp_open_recv(struct sftp_packet *pktin,
  159. struct sftp_request *req);
  160. /*
  161. * Open a directory.
  162. */
  163. struct sftp_request *fxp_opendir_send(const char *path);
  164. struct fxp_handle *fxp_opendir_recv(struct sftp_packet *pktin,
  165. struct sftp_request *req);
  166. /*
  167. * Close a file/dir. Returns true on success, false on error.
  168. */
  169. struct sftp_request *fxp_close_send(struct fxp_handle *handle);
  170. bool fxp_close_recv(struct sftp_packet *pktin, struct sftp_request *req);
  171. /*
  172. * Make a directory.
  173. */
  174. struct sftp_request *fxp_mkdir_send(const char *path,
  175. const struct fxp_attrs *attrs);
  176. bool fxp_mkdir_recv(struct sftp_packet *pktin, struct sftp_request *req);
  177. /*
  178. * Remove a directory.
  179. */
  180. struct sftp_request *fxp_rmdir_send(const char *path);
  181. bool fxp_rmdir_recv(struct sftp_packet *pktin, struct sftp_request *req);
  182. /*
  183. * Remove a file.
  184. */
  185. struct sftp_request *fxp_remove_send(const char *fname);
  186. bool fxp_remove_recv(struct sftp_packet *pktin, struct sftp_request *req);
  187. /*
  188. * Rename a file.
  189. */
  190. struct sftp_request *fxp_rename_send(const char *srcfname,
  191. const char *dstfname);
  192. bool fxp_rename_recv(struct sftp_packet *pktin, struct sftp_request *req);
  193. /*
  194. * Return file attributes.
  195. */
  196. struct sftp_request *fxp_stat_send(const char *fname);
  197. bool fxp_stat_recv(struct sftp_packet *pktin, struct sftp_request *req,
  198. struct fxp_attrs *attrs);
  199. struct sftp_request *fxp_fstat_send(struct fxp_handle *handle);
  200. bool fxp_fstat_recv(struct sftp_packet *pktin, struct sftp_request *req,
  201. struct fxp_attrs *attrs);
  202. /*
  203. * Set file attributes.
  204. */
  205. struct sftp_request *fxp_setstat_send(const char *fname,
  206. struct fxp_attrs attrs);
  207. bool fxp_setstat_recv(struct sftp_packet *pktin, struct sftp_request *req);
  208. struct sftp_request *fxp_fsetstat_send(struct fxp_handle *handle,
  209. struct fxp_attrs attrs);
  210. bool fxp_fsetstat_recv(struct sftp_packet *pktin, struct sftp_request *req);
  211. /*
  212. * Read from a file.
  213. */
  214. struct sftp_request *fxp_read_send(struct fxp_handle *handle,
  215. uint64_t offset, int len);
  216. int fxp_read_recv(struct sftp_packet *pktin, struct sftp_request *req,
  217. char *buffer, int len);
  218. /*
  219. * Write to a file.
  220. */
  221. struct sftp_request *fxp_write_send(struct fxp_handle *handle,
  222. void *buffer, uint64_t offset, int len);
  223. bool fxp_write_recv(struct sftp_packet *pktin, struct sftp_request *req);
  224. /*
  225. * Read from a directory.
  226. */
  227. struct sftp_request *fxp_readdir_send(struct fxp_handle *handle);
  228. struct fxp_names *fxp_readdir_recv(struct sftp_packet *pktin,
  229. struct sftp_request *req);
  230. /*
  231. * Free up an fxp_names structure.
  232. */
  233. void fxp_free_names(struct fxp_names *names);
  234. /*
  235. * Duplicate and free fxp_name structures.
  236. */
  237. struct fxp_name *fxp_dup_name(struct fxp_name *name);
  238. void fxp_free_name(struct fxp_name *name);
  239. /*
  240. * Store user data in an sftp_request structure.
  241. */
  242. void *fxp_get_userdata(struct sftp_request *req);
  243. void fxp_set_userdata(struct sftp_request *req, void *data);
  244. /*
  245. * These functions might well be temporary placeholders to be
  246. * replaced with more useful similar functions later. They form the
  247. * main dispatch loop for processing incoming SFTP responses.
  248. */
  249. void sftp_register(struct sftp_request *req);
  250. struct sftp_request *sftp_find_request(struct sftp_packet *pktin);
  251. struct sftp_packet *sftp_recv(void);
  252. /*
  253. * A wrapper to go round fxp_read_* and fxp_write_*, which manages
  254. * the queueing of multiple read/write requests.
  255. */
  256. struct fxp_xfer;
  257. struct fxp_xfer *xfer_download_init(struct fxp_handle *fh, uint64_t offset);
  258. void xfer_download_queue(struct fxp_xfer *xfer);
  259. int xfer_download_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin);
  260. bool xfer_download_data(struct fxp_xfer *xfer, void **buf, int *len);
  261. struct fxp_xfer *xfer_upload_init(struct fxp_handle *fh, uint64_t offset);
  262. bool xfer_upload_ready(struct fxp_xfer *xfer);
  263. void xfer_upload_data(struct fxp_xfer *xfer, char *buffer, int len);
  264. int xfer_upload_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin);
  265. bool xfer_done(struct fxp_xfer *xfer);
  266. void xfer_set_error(struct fxp_xfer *xfer);
  267. void xfer_cleanup(struct fxp_xfer *xfer);
  268. /*
  269. * Vtable for the platform-specific filesystem implementation that
  270. * answers requests in an SFTP server.
  271. */
  272. typedef struct SftpReplyBuilder SftpReplyBuilder;
  273. struct SftpServer {
  274. const SftpServerVtable *vt;
  275. };
  276. struct SftpServerVtable {
  277. SftpServer *(*new)(const SftpServerVtable *vt);
  278. void (*free)(SftpServer *srv);
  279. /*
  280. * Handle actual filesystem requests.
  281. *
  282. * Each of these functions replies by calling an appropriate
  283. * sftp_reply_foo() function on the given reply packet.
  284. */
  285. /* Should call fxp_reply_error or fxp_reply_simple_name */
  286. void (*realpath)(SftpServer *srv, SftpReplyBuilder *reply,
  287. ptrlen path);
  288. /* Should call fxp_reply_error or fxp_reply_handle */
  289. void (*open)(SftpServer *srv, SftpReplyBuilder *reply,
  290. ptrlen path, unsigned flags, struct fxp_attrs attrs);
  291. /* Should call fxp_reply_error or fxp_reply_handle */
  292. void (*opendir)(SftpServer *srv, SftpReplyBuilder *reply,
  293. ptrlen path);
  294. /* Should call fxp_reply_error or fxp_reply_ok */
  295. void (*close)(SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle);
  296. /* Should call fxp_reply_error or fxp_reply_ok */
  297. void (*mkdir)(SftpServer *srv, SftpReplyBuilder *reply,
  298. ptrlen path, struct fxp_attrs attrs);
  299. /* Should call fxp_reply_error or fxp_reply_ok */
  300. void (*rmdir)(SftpServer *srv, SftpReplyBuilder *reply, ptrlen path);
  301. /* Should call fxp_reply_error or fxp_reply_ok */
  302. void (*remove)(SftpServer *srv, SftpReplyBuilder *reply, ptrlen path);
  303. /* Should call fxp_reply_error or fxp_reply_ok */
  304. void (*rename)(SftpServer *srv, SftpReplyBuilder *reply,
  305. ptrlen srcpath, ptrlen dstpath);
  306. /* Should call fxp_reply_error or fxp_reply_attrs */
  307. void (*stat)(SftpServer *srv, SftpReplyBuilder *reply, ptrlen path,
  308. bool follow_symlinks);
  309. /* Should call fxp_reply_error or fxp_reply_attrs */
  310. void (*fstat)(SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle);
  311. /* Should call fxp_reply_error or fxp_reply_ok */
  312. void (*setstat)(SftpServer *srv, SftpReplyBuilder *reply,
  313. ptrlen path, struct fxp_attrs attrs);
  314. /* Should call fxp_reply_error or fxp_reply_ok */
  315. void (*fsetstat)(SftpServer *srv, SftpReplyBuilder *reply,
  316. ptrlen handle, struct fxp_attrs attrs);
  317. /* Should call fxp_reply_error or fxp_reply_data */
  318. void (*read)(SftpServer *srv, SftpReplyBuilder *reply,
  319. ptrlen handle, uint64_t offset, unsigned length);
  320. /* Should call fxp_reply_error or fxp_reply_ok */
  321. void (*write)(SftpServer *srv, SftpReplyBuilder *reply,
  322. ptrlen handle, uint64_t offset, ptrlen data);
  323. /* Should call fxp_reply_error, or fxp_reply_name_count once and
  324. * then fxp_reply_full_name that many times */
  325. void (*readdir)(SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle,
  326. int max_entries, bool omit_longname);
  327. };
  328. static inline SftpServer *sftpsrv_new(const SftpServerVtable *vt)
  329. { return vt->new(vt); }
  330. static inline void sftpsrv_free(SftpServer *srv)
  331. { srv->vt->free(srv); }
  332. static inline void sftpsrv_realpath(SftpServer *srv, SftpReplyBuilder *reply,
  333. ptrlen path)
  334. { srv->vt->realpath(srv, reply, path); }
  335. static inline void sftpsrv_open(
  336. SftpServer *srv, SftpReplyBuilder *reply,
  337. ptrlen path, unsigned flags, struct fxp_attrs attrs)
  338. { srv->vt->open(srv, reply, path, flags, attrs); }
  339. static inline void sftpsrv_opendir(
  340. SftpServer *srv, SftpReplyBuilder *reply, ptrlen path)
  341. { srv->vt->opendir(srv, reply, path); }
  342. static inline void sftpsrv_close(
  343. SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle)
  344. { srv->vt->close(srv, reply, handle); }
  345. static inline void sftpsrv_mkdir(SftpServer *srv, SftpReplyBuilder *reply,
  346. ptrlen path, struct fxp_attrs attrs)
  347. { srv->vt->mkdir(srv, reply, path, attrs); }
  348. static inline void sftpsrv_rmdir(
  349. SftpServer *srv, SftpReplyBuilder *reply, ptrlen path)
  350. { srv->vt->rmdir(srv, reply, path); }
  351. static inline void sftpsrv_remove(
  352. SftpServer *srv, SftpReplyBuilder *reply, ptrlen path)
  353. { srv->vt->remove(srv, reply, path); }
  354. static inline void sftpsrv_rename(SftpServer *srv, SftpReplyBuilder *reply,
  355. ptrlen srcpath, ptrlen dstpath)
  356. { srv->vt->rename(srv, reply, srcpath, dstpath); }
  357. static inline void sftpsrv_stat(
  358. SftpServer *srv, SftpReplyBuilder *reply, ptrlen path, bool follow)
  359. { srv->vt->stat(srv, reply, path, follow); }
  360. static inline void sftpsrv_fstat(
  361. SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle)
  362. { srv->vt->fstat(srv, reply, handle); }
  363. static inline void sftpsrv_setstat(SftpServer *srv, SftpReplyBuilder *reply,
  364. ptrlen path, struct fxp_attrs attrs)
  365. { srv->vt->setstat(srv, reply, path, attrs); }
  366. static inline void sftpsrv_fsetstat(SftpServer *srv, SftpReplyBuilder *reply,
  367. ptrlen handle, struct fxp_attrs attrs)
  368. { srv->vt->fsetstat(srv, reply, handle, attrs); }
  369. static inline void sftpsrv_read(
  370. SftpServer *srv, SftpReplyBuilder *reply,
  371. ptrlen handle, uint64_t offset, unsigned length)
  372. { srv->vt->read(srv, reply, handle, offset, length); }
  373. static inline void sftpsrv_write(SftpServer *srv, SftpReplyBuilder *reply,
  374. ptrlen handle, uint64_t offset, ptrlen data)
  375. { srv->vt->write(srv, reply, handle, offset, data); }
  376. static inline void sftpsrv_readdir(
  377. SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle,
  378. int max_entries, bool omit_longname)
  379. { srv->vt->readdir(srv, reply, handle, max_entries, omit_longname); }
  380. typedef struct SftpReplyBuilderVtable SftpReplyBuilderVtable;
  381. struct SftpReplyBuilder {
  382. const SftpReplyBuilderVtable *vt;
  383. };
  384. struct SftpReplyBuilderVtable {
  385. void (*reply_ok)(SftpReplyBuilder *reply);
  386. void (*reply_error)(SftpReplyBuilder *reply, unsigned code,
  387. const char *msg);
  388. void (*reply_simple_name)(SftpReplyBuilder *reply, ptrlen name);
  389. void (*reply_name_count)(SftpReplyBuilder *reply, unsigned count);
  390. void (*reply_full_name)(SftpReplyBuilder *reply, ptrlen name,
  391. ptrlen longname, struct fxp_attrs attrs);
  392. void (*reply_handle)(SftpReplyBuilder *reply, ptrlen handle);
  393. void (*reply_data)(SftpReplyBuilder *reply, ptrlen data);
  394. void (*reply_attrs)(SftpReplyBuilder *reply, struct fxp_attrs attrs);
  395. };
  396. static inline void fxp_reply_ok(SftpReplyBuilder *reply)
  397. { reply->vt->reply_ok(reply); }
  398. static inline void fxp_reply_error(SftpReplyBuilder *reply, unsigned code,
  399. const char *msg)
  400. { reply->vt->reply_error(reply, code, msg); }
  401. static inline void fxp_reply_simple_name(SftpReplyBuilder *reply, ptrlen name)
  402. { reply->vt->reply_simple_name(reply, name); }
  403. static inline void fxp_reply_name_count(
  404. SftpReplyBuilder *reply, unsigned count)
  405. { reply->vt->reply_name_count(reply, count); }
  406. static inline void fxp_reply_full_name(SftpReplyBuilder *reply, ptrlen name,
  407. ptrlen longname, struct fxp_attrs attrs)
  408. { reply->vt->reply_full_name(reply, name, longname, attrs); }
  409. static inline void fxp_reply_handle(SftpReplyBuilder *reply, ptrlen handle)
  410. { reply->vt->reply_handle(reply, handle); }
  411. static inline void fxp_reply_data(SftpReplyBuilder *reply, ptrlen data)
  412. { reply->vt->reply_data(reply, data); }
  413. static inline void fxp_reply_attrs(
  414. SftpReplyBuilder *reply, struct fxp_attrs attrs)
  415. { reply->vt->reply_attrs(reply, attrs); }
  416. /*
  417. * The usual implementation of an SftpReplyBuilder, containing a
  418. * 'struct sftp_packet' which is assumed to be already initialised
  419. * before one of the above request methods is called.
  420. */
  421. extern const struct SftpReplyBuilderVtable DefaultSftpReplyBuilder_vt;
  422. typedef struct DefaultSftpReplyBuilder DefaultSftpReplyBuilder;
  423. struct DefaultSftpReplyBuilder {
  424. SftpReplyBuilder rb;
  425. struct sftp_packet *pkt;
  426. };
  427. /*
  428. * The top-level function that handles an SFTP request, given an
  429. * implementation of the above SftpServer abstraction to do the actual
  430. * filesystem work. It handles all the marshalling and unmarshalling
  431. * of packets, and the copying of request ids into the responses.
  432. */
  433. struct sftp_packet *sftp_handle_request(
  434. SftpServer *srv, struct sftp_packet *request);
  435. /* ----------------------------------------------------------------------
  436. * Not exactly SFTP-related, but here's a system that implements an
  437. * old-fashioned SCP server module, given an SftpServer vtable to use
  438. * as its underlying filesystem access.
  439. */
  440. typedef struct ScpServer ScpServer;
  441. typedef struct ScpServerVtable ScpServerVtable;
  442. struct ScpServer {
  443. const struct ScpServerVtable *vt;
  444. };
  445. struct ScpServerVtable {
  446. void (*free)(ScpServer *s);
  447. size_t (*send)(ScpServer *s, const void *data, size_t length);
  448. void (*throttle)(ScpServer *s, bool throttled);
  449. void (*eof)(ScpServer *s);
  450. };
  451. static inline void scp_free(ScpServer *s)
  452. { s->vt->free(s); }
  453. static inline size_t scp_send(ScpServer *s, const void *data, size_t length)
  454. { return s->vt->send(s, data, length); }
  455. static inline void scp_throttle(ScpServer *s, bool throttled)
  456. { s->vt->throttle(s, throttled); }
  457. static inline void scp_eof(ScpServer *s)
  458. { s->vt->eof(s); }
  459. /*
  460. * Create an ScpServer by calling this function, giving it the command
  461. * you received from the SSH client to execute. If that command is
  462. * recognised as an scp command, it will construct an ScpServer object
  463. * and return it; otherwise, it will return NULL, and you should
  464. * execute the command in whatever way you normally would.
  465. *
  466. * The ScpServer will generate output for the client by writing it to
  467. * the provided SshChannel using sshfwd_write; you pass it input using
  468. * the send method in its own vtable.
  469. */
  470. ScpServer *scp_recognise_exec(
  471. SshChannel *sc, const SftpServerVtable *sftpserver_vt, ptrlen command);