📄 sftp.c
字号:
pktout = sftp_pkt_init(SSH_FXP_INIT); sftp_pkt_adduint32(pktout, SFTP_PROTO_VERSION); sftp_send(pktout); pktin = sftp_recv(); if (!pktin) { fxp_internal_error("could not connect"); return 0; } if (pktin->type != SSH_FXP_VERSION) { fxp_internal_error("did not receive FXP_VERSION"); sftp_pkt_free(pktin); return 0; } remotever = sftp_pkt_getuint32(pktin); if (remotever > SFTP_PROTO_VERSION) { fxp_internal_error ("remote protocol is more advanced than we support"); sftp_pkt_free(pktin); return 0; } /* * In principle, this packet might also contain extension- * string pairs. We should work through them and look for any * we recognise. In practice we don't currently do so because * we know we don't recognise _any_. */ sftp_pkt_free(pktin); return 1;}/* * Canonify a pathname. */struct sftp_request *fxp_realpath_send(char *path){ struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_REALPATH); sftp_pkt_adduint32(pktout, req->id); sftp_pkt_addstring_start(pktout); sftp_pkt_addstring_str(pktout, path); sftp_send(pktout); return req;}char *fxp_realpath_recv(struct sftp_packet *pktin, struct sftp_request *req){ sfree(req); if (pktin->type == SSH_FXP_NAME) { int count; char *path; int len; count = sftp_pkt_getuint32(pktin); if (count != 1) { fxp_internal_error("REALPATH returned name count != 1\n"); sftp_pkt_free(pktin); return NULL; } sftp_pkt_getstring(pktin, &path, &len); if (!path) { fxp_internal_error("REALPATH returned malformed FXP_NAME\n"); sftp_pkt_free(pktin); return NULL; } path = mkstr(path, len); sftp_pkt_free(pktin); return path; } else { fxp_got_status(pktin); sftp_pkt_free(pktin); return NULL; }}/* * Open a file. */struct sftp_request *fxp_open_send(char *path, int type){ struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_OPEN); sftp_pkt_adduint32(pktout, req->id); sftp_pkt_addstring(pktout, path); sftp_pkt_adduint32(pktout, type); sftp_pkt_adduint32(pktout, 0); /* (FIXME) empty ATTRS structure */ sftp_send(pktout); return req;}struct fxp_handle *fxp_open_recv(struct sftp_packet *pktin, struct sftp_request *req){ sfree(req); if (pktin->type == SSH_FXP_HANDLE) { char *hstring; struct fxp_handle *handle; int len; sftp_pkt_getstring(pktin, &hstring, &len); if (!hstring) { fxp_internal_error("OPEN returned malformed FXP_HANDLE\n"); sftp_pkt_free(pktin); return NULL; } handle = snew(struct fxp_handle); handle->hstring = mkstr(hstring, len); handle->hlen = len; sftp_pkt_free(pktin); return handle; } else { fxp_got_status(pktin); sftp_pkt_free(pktin); return NULL; }}/* * Open a directory. */struct sftp_request *fxp_opendir_send(char *path){ struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_OPENDIR); sftp_pkt_adduint32(pktout, req->id); sftp_pkt_addstring(pktout, path); sftp_send(pktout); return req;}struct fxp_handle *fxp_opendir_recv(struct sftp_packet *pktin, struct sftp_request *req){ sfree(req); if (pktin->type == SSH_FXP_HANDLE) { char *hstring; struct fxp_handle *handle; int len; sftp_pkt_getstring(pktin, &hstring, &len); if (!hstring) { fxp_internal_error("OPENDIR returned malformed FXP_HANDLE\n"); sftp_pkt_free(pktin); return NULL; } handle = snew(struct fxp_handle); handle->hstring = mkstr(hstring, len); handle->hlen = len; sftp_pkt_free(pktin); return handle; } else { fxp_got_status(pktin); sftp_pkt_free(pktin); return NULL; }}/* * Close a file/dir. */struct sftp_request *fxp_close_send(struct fxp_handle *handle){ struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_CLOSE); sftp_pkt_adduint32(pktout, req->id); sftp_pkt_addstring_start(pktout); sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen); sftp_send(pktout); sfree(handle->hstring); sfree(handle); 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;}/* * Read from a file. Returns the number of bytes read, or -1 on an * error, or possibly 0 if EOF. (I'm not entirely sure whether it * will return 0 on EOF, or return -1 and store SSH_FX_EOF in the * error indicator. It might even depend on the SFTP server.) */struct sftp_request *fxp_read_send(struct fxp_handle *handle, uint64 offset, int len){ struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_READ); sftp_pkt_adduint32(pktout, req->id); sftp_pkt_addstring_start(pktout); sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen); sftp_pkt_adduint64(pktout, offset); sftp_pkt_adduint32(pktout, len); sftp_send(pktout); return req;}int fxp_read_recv(struct sftp_packet *pktin, struct sftp_request *req, char *buffer, int len){ sfree(req); if (pktin->type == SSH_FXP_DATA) { char *str; int rlen; sftp_pkt_getstring(pktin, &str, &rlen); if (rlen > len || rlen < 0) { fxp_internal_error("READ returned more bytes than requested"); sftp_pkt_free(pktin); return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -