From e091fdc5658e65be290ebb3b62a1bdf517781a65 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 5 May 2009 16:28:44 -0700 Subject: Make cli_getattrE async. Jeremy. --- source3/client/client.c | 6 +- source3/include/proto.h | 23 ++++-- source3/lib/time.c | 2 +- source3/libsmb/clifile.c | 156 ++++++++++++++++++++++++++++++++-------- source3/libsmb/libsmb_file.c | 5 +- source3/libsmb/libsmb_stat.c | 4 +- source3/utils/net_rpc_printer.c | 4 +- 7 files changed, 156 insertions(+), 44 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index d3cf08cce81..9c534728409 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1060,8 +1060,8 @@ static int do_get(const char *rname, const char *lname_in, bool reget) if (!cli_qfileinfo(targetcli, fnum, &attr, &size, NULL, NULL, NULL, NULL, NULL) && - !cli_getattrE(targetcli, fnum, - &attr, &size, NULL, NULL, NULL)) { + !NT_STATUS_IS_OK(cli_getattrE(targetcli, fnum, + &attr, &size, NULL, NULL, NULL))) { d_printf("getattrib: %s\n",cli_errstr(targetcli)); return 1; } @@ -1639,7 +1639,7 @@ static int do_put(const char *rname, const char *lname, bool reput) status = cli_open(targetcli, targetname, O_RDWR|O_CREAT, DENY_NONE, &fnum); if (NT_STATUS_IS_OK(status)) { if (!cli_qfileinfo(targetcli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) && - !cli_getattrE(targetcli, fnum, NULL, &start, NULL, NULL, NULL)) { + !NT_STATUS_IS_OK(cli_getattrE(targetcli, fnum, NULL, &start, NULL, NULL, NULL))) { d_printf("getattrib: %s\n",cli_errstr(cli)); return 1; } diff --git a/source3/include/proto.h b/source3/include/proto.h index 936a724ac50..30c11a50eeb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1017,6 +1017,7 @@ void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts); struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst); void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts); void dos_filetime_timespec(struct timespec *tsp); +time_t make_unix_date2(const void *date_ptr, int zone_offset); time_t srv_make_unix_date(const void *date_ptr); time_t srv_make_unix_date2(const void *date_ptr); time_t srv_make_unix_date3(const void *date_ptr); @@ -2441,11 +2442,23 @@ bool cli_posix_lock(struct cli_state *cli, uint16_t fnum, bool wait_lock, enum brl_type lock_type); bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen); -bool cli_getattrE(struct cli_state *cli, int fd, - uint16_t *attr, SMB_OFF_T *size, - time_t *change_time, - time_t *access_time, - time_t *write_time); +struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum); +NTSTATUS cli_getattrE_recv(struct tevent_req *req, + uint16_t *attr, + SMB_OFF_T *size, + time_t *change_time, + time_t *access_time, + time_t *write_time); +NTSTATUS cli_getattrE(struct cli_state *cli, + uint16_t fnum, + uint16_t *attr, + SMB_OFF_T *size, + time_t *change_time, + time_t *access_time, + time_t *write_time); bool cli_getatr(struct cli_state *cli, const char *fname, uint16_t *attr, SMB_OFF_T *size, time_t *write_time); bool cli_setattrE(struct cli_state *cli, int fd, diff --git a/source3/lib/time.c b/source3/lib/time.c index 865456b23b0..3e45a2e6e42 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -605,7 +605,7 @@ static time_t make_unix_date(const void *date_ptr, int zone_offset) Like make_unix_date() but the words are reversed. ********************************************************************/ -static time_t make_unix_date2(const void *date_ptr, int zone_offset) +time_t make_unix_date2(const void *date_ptr, int zone_offset) { uint32_t x,x2; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a4e70c53cde..bc466d13159 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -2090,53 +2090,153 @@ bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, Do a SMBgetattrE call. ****************************************************************************/ -bool cli_getattrE(struct cli_state *cli, int fd, - uint16_t *attr, SMB_OFF_T *size, - time_t *change_time, - time_t *access_time, - time_t *write_time) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); +static void cli_getattrE_done(struct tevent_req *subreq); + +struct cli_getattrE_state { + int zone_offset; + uint16_t attr; + SMB_OFF_T size; + time_t change_time; + time_t access_time; + time_t write_time; +}; - cli_set_message(cli->outbuf,1,0,True); +struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_getattrE_state *state = NULL; + uint8_t additional_flags = 0; + uint16_t vwv[1]; - SCVAL(cli->outbuf,smb_com,SMBgetattrE); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + req = tevent_req_create(mem_ctx, &state, struct cli_getattrE_state); + if (req == NULL) { + return NULL; + } - SSVAL(cli->outbuf,smb_vwv0,fd); + state->zone_offset = cli->serverzone; + SSVAL(vwv+0,0,fnum); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; + subreq = cli_smb_send(state, ev, cli, SMBgetattrE, additional_flags, + 1, vwv, 0, NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, cli_getattrE_done, req); + return req; +} - if (cli_is_error(cli)) { - return False; +static void cli_getattrE_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_getattrE_state *state = tevent_req_data( + req, struct cli_getattrE_state); + uint8_t wct; + uint16_t *vwv = NULL; + NTSTATUS status; + + status = cli_smb_recv(subreq, 11, &wct, &vwv, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + state->size = (SMB_OFF_T)IVAL(vwv+6,0); + state->attr = SVAL(vwv+10,0); + state->change_time = make_unix_date2(vwv+0, state->zone_offset); + state->access_time = make_unix_date2(vwv+2, state->zone_offset); + state->write_time = make_unix_date2(vwv+4, state->zone_offset); + + TALLOC_FREE(subreq); + tevent_req_done(req); +} + +NTSTATUS cli_getattrE_recv(struct tevent_req *req, + uint16_t *attr, + SMB_OFF_T *size, + time_t *change_time, + time_t *access_time, + time_t *write_time) +{ + struct cli_getattrE_state *state = tevent_req_data( + req, struct cli_getattrE_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + if (attr) { + *attr = state->attr; + } if (size) { - *size = IVAL(cli->inbuf, smb_vwv6); + *size = state->size; + } + if (change_time) { + *change_time = state->change_time; + } + if (access_time) { + *access_time = state->access_time; + } + if (write_time) { + *write_time = state->write_time; } + return NT_STATUS_OK; +} - if (attr) { - *attr = SVAL(cli->inbuf,smb_vwv10); +NTSTATUS cli_getattrE(struct cli_state *cli, + uint16_t fnum, + uint16_t *attr, + SMB_OFF_T *size, + time_t *change_time, + time_t *access_time, + time_t *write_time) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; } - if (change_time) { - *change_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0); + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; } - if (access_time) { - *access_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2); + req = cli_getattrE_send(frame, ev, cli, fnum); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; } - if (write_time) { - *write_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4); + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; } - return True; + status = cli_getattrE_recv(req, + attr, + size, + change_time, + access_time, + write_time); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index bf53267054b..a56126587a8 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -779,9 +779,8 @@ SMBC_lseek_ctx(SMBCCTX *context, &size, NULL, NULL, NULL, NULL, NULL)) { SMB_OFF_T b_size = size; - if (!cli_getattrE(targetcli, file->cli_fd, - NULL, &b_size, NULL, NULL, NULL)) - { + if (!NT_STATUS_IS_OK(cli_getattrE(targetcli, file->cli_fd, + NULL, &b_size, NULL, NULL, NULL))) { errno = EINVAL; TALLOC_FREE(frame); return -1; diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index c2806daddb9..af7800ba32b 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -276,8 +276,8 @@ SMBC_fstat_ctx(SMBCCTX *context, time_t change_time, access_time, write_time; - if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, - &change_time, &access_time, &write_time)) { + if (!NT_STATUS_IS_OK(cli_getattrE(targetcli, file->cli_fd, &mode, &size, + &change_time, &access_time, &write_time))) { errno = EINVAL; TALLOC_FREE(frame); diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 39b5e81bd6e..10fd4157b7a 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -198,8 +198,8 @@ NTSTATUS net_copy_fileattr(struct net_context *c, if (copy_attrs || copy_timestamps) { /* get file attributes */ - if (!cli_getattrE(cli_share_src, fnum_src, &attr, NULL, - &f_ctime, &f_atime, &f_mtime)) { + if (!NT_STATUS_IS_OK(cli_getattrE(cli_share_src, fnum_src, &attr, NULL, + &f_ctime, &f_atime, &f_mtime))) { DEBUG(0,("failed to get file-attrs: %s\n", cli_errstr(cli_share_src))); nt_status = cli_nt_error(cli_share_src); -- cgit