+
+ return req;
+}
+
+void fxp_close_recv(struct sftp_packet *pktin, struct sftp_request *req)
+{
+ sfree(req);
+ fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+}
+
+struct sftp_request *fxp_mkdir_send(char *path)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_MKDIR);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring(pktout, path);
+ sftp_pkt_adduint32(pktout, 0); /* (FIXME) empty ATTRS structure */
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_mkdir_recv(struct sftp_packet *pktin, struct sftp_request *req)
+{
+ int id;
+ sfree(req);
+ id = fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ if (id != 1) {
+ return 0;
+ }
+ return 1;
+}
+
+struct sftp_request *fxp_rmdir_send(char *path)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_RMDIR);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring(pktout, path);
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_rmdir_recv(struct sftp_packet *pktin, struct sftp_request *req)
+{
+ int id;
+ sfree(req);
+ id = fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ if (id != 1) {
+ return 0;
+ }
+ return 1;
+}
+
+struct sftp_request *fxp_remove_send(char *fname)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_REMOVE);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring(pktout, fname);
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_remove_recv(struct sftp_packet *pktin, struct sftp_request *req)
+{
+ int id;
+ sfree(req);
+ id = fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ if (id != 1) {
+ return 0;
+ }
+ return 1;
+}
+
+struct sftp_request *fxp_rename_send(char *srcfname, char *dstfname)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_RENAME);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring(pktout, srcfname);
+ sftp_pkt_addstring(pktout, dstfname);
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_rename_recv(struct sftp_packet *pktin, struct sftp_request *req)
+{
+ int id;
+ sfree(req);
+ id = fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ if (id != 1) {
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Retrieve the attributes of a file. We have fxp_stat which works
+ * on filenames, and fxp_fstat which works on open file handles.
+ */
+struct sftp_request *fxp_stat_send(char *fname)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_STAT);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring(pktout, fname);
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_stat_recv(struct sftp_packet *pktin, struct sftp_request *req,
+ struct fxp_attrs *attrs)
+{
+ sfree(req);
+ if (pktin->type == SSH_FXP_ATTRS) {
+ *attrs = sftp_pkt_getattrs(pktin);
+ sftp_pkt_free(pktin);
+ return 1;
+ } else {
+ fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ return 0;
+ }
+}
+
+struct sftp_request *fxp_fstat_send(struct fxp_handle *handle)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_FSTAT);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring_start(pktout);
+ sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen);
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_fstat_recv(struct sftp_packet *pktin, struct sftp_request *req,
+ struct fxp_attrs *attrs)
+{
+ sfree(req);
+ if (pktin->type == SSH_FXP_ATTRS) {
+ *attrs = sftp_pkt_getattrs(pktin);
+ sftp_pkt_free(pktin);
+ return 1;
+ } else {
+ fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ return 0;
+ }
+}
+
+/*
+ * Set the attributes of a file.
+ */
+struct sftp_request *fxp_setstat_send(char *fname, struct fxp_attrs attrs)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_SETSTAT);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring(pktout, fname);
+ sftp_pkt_addattrs(pktout, attrs);
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_setstat_recv(struct sftp_packet *pktin, struct sftp_request *req)
+{
+ int id;
+ sfree(req);
+ id = fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ if (id != 1) {
+ return 0;
+ }
+ return 1;
+}
+
+struct sftp_request *fxp_fsetstat_send(struct fxp_handle *handle,
+ struct fxp_attrs attrs)
+{
+ struct sftp_request *req = sftp_alloc_request();
+ struct sftp_packet *pktout;
+
+ pktout = sftp_pkt_init(SSH_FXP_FSETSTAT);
+ sftp_pkt_adduint32(pktout, req->id);
+ sftp_pkt_addstring_start(pktout);
+ sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen);
+ sftp_pkt_addattrs(pktout, attrs);
+ sftp_send(pktout);
+
+ return req;
+}
+
+int fxp_fsetstat_recv(struct sftp_packet *pktin, struct sftp_request *req)
+{
+ int id;
+ sfree(req);
+ id = fxp_got_status(pktin);
+ sftp_pkt_free(pktin);
+ if (id != 1) {
+ return 0;
+ }
+ return 1;