diff options
author | Stefan Metzmacher <metze@samba.org> | 2005-09-26 11:47:55 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:38:57 -0500 |
commit | ab4d635b92b116b02b88843b4ec4f5b7517bab1a (patch) | |
tree | 63c3ee12153b629071d2ba0209a0a31b134c449e /source4/libcli/composite/savefile.c | |
parent | 0d46be147a1e755bdd6f21a5ddc83b5c39585529 (diff) | |
download | samba-ab4d635b92b116b02b88843b4ec4f5b7517bab1a.tar.gz samba-ab4d635b92b116b02b88843b4ec4f5b7517bab1a.tar.bz2 samba-ab4d635b92b116b02b88843b4ec4f5b7517bab1a.zip |
r10504: - seperate implementation specific stuff, from the generic composite
stuff.
- don't use SMBCLI_REQUEST_* state's in the genreic composite stuff
- move monitor_fn to libnet.
NOTE: I have maybe found some bugs, in code that is dirrectly in DONE or ERROR
state in the _send() function. I haven't fixed this bugs in this
commit! We may need some composite_trigger_*() functions or so.
And maybe some other generic helper functions...
metze
(This used to be commit 4527815a0a9b96e460f301cb1f0c0b3964c166fc)
Diffstat (limited to 'source4/libcli/composite/savefile.c')
-rw-r--r-- | source4/libcli/composite/savefile.c | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c deleted file mode 100644 index 0b08963966..0000000000 --- a/source4/libcli/composite/savefile.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* - a composite API for saving a whole file from memory -*/ - -#include "includes.h" -#include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" -#include "librpc/gen_ndr/ndr_security.h" - -/* the stages of this call */ -enum savefile_stage {SAVEFILE_OPEN, SAVEFILE_WRITE, SAVEFILE_CLOSE}; - -static void savefile_handler(struct smbcli_request *req); - -struct savefile_state { - enum savefile_stage stage; - off_t total_written; - struct smb_composite_savefile *io; - union smb_open *io_open; - union smb_write *io_write; - struct smbcli_request *req; -}; - - -/* - setup for the close -*/ -static NTSTATUS setup_close(struct composite_context *c, - struct smbcli_tree *tree, uint16_t fnum) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - union smb_close *io_close; - - /* nothing to write, setup the close */ - io_close = talloc(c, union smb_close); - NT_STATUS_HAVE_NO_MEMORY(io_close); - - io_close->close.level = RAW_CLOSE_CLOSE; - io_close->close.in.fnum = fnum; - io_close->close.in.write_time = 0; - - state->req = smb_raw_close_send(tree, io_close); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the close is done */ - state->stage = SAVEFILE_CLOSE; - state->req->async.fn = savefile_handler; - state->req->async.private = c; - - return NT_STATUS_OK; -} - -/* - called when the open is done - pull the results and setup for the - first writex, or close if the file is zero size -*/ -static NTSTATUS savefile_open(struct composite_context *c, - struct smb_composite_savefile *io) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - union smb_write *io_write; - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - - status = smb_raw_open_recv(state->req, c, state->io_open); - NT_STATUS_NOT_OK_RETURN(status); - - if (io->in.size == 0) { - return setup_close(c, tree, state->io_open->ntcreatex.out.fnum); - } - - /* setup for the first write */ - io_write = talloc(c, union smb_write); - NT_STATUS_HAVE_NO_MEMORY(io_write); - - io_write->writex.level = RAW_WRITE_WRITEX; - io_write->writex.in.fnum = state->io_open->ntcreatex.out.fnum; - io_write->writex.in.offset = 0; - io_write->writex.in.wmode = 0; - io_write->writex.in.remaining = 0; - io_write->writex.in.count = MIN(max_xmit - 100, io->in.size); - io_write->writex.in.data = io->in.data; - state->io_write = io_write; - - state->req = smb_raw_write_send(tree, io_write); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the first write is done */ - state->stage = SAVEFILE_WRITE; - state->req->async.fn = savefile_handler; - state->req->async.private = c; - talloc_free(state->io_open); - - return NT_STATUS_OK; -} - - -/* - called when a write is done - pull the results and setup for the - next write, or close if the file is all done -*/ -static NTSTATUS savefile_write(struct composite_context *c, - struct smb_composite_savefile *io) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - struct smbcli_tree *tree = state->req->tree; - NTSTATUS status; - uint32_t max_xmit = tree->session->transport->negotiate.max_xmit; - - status = smb_raw_write_recv(state->req, state->io_write); - NT_STATUS_NOT_OK_RETURN(status); - - state->total_written += state->io_write->writex.out.nwritten; - - /* we might be done */ - if (state->io_write->writex.out.nwritten != state->io_write->writex.in.count || - state->total_written == io->in.size) { - return setup_close(c, tree, state->io_write->writex.in.fnum); - } - - /* setup for the next write */ - state->io_write->writex.in.offset = state->total_written; - state->io_write->writex.in.count = MIN(max_xmit - 100, - io->in.size - state->total_written); - state->io_write->writex.in.data = io->in.data + state->total_written; - - state->req = smb_raw_write_send(tree, state->io_write); - NT_STATUS_HAVE_NO_MEMORY(state->req); - - /* call the handler again when the write is done */ - state->req->async.fn = savefile_handler; - state->req->async.private = c; - - return NT_STATUS_OK; -} - -/* - called when the close is done, check the status and cleanup -*/ -static NTSTATUS savefile_close(struct composite_context *c, - struct smb_composite_savefile *io) -{ - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - NTSTATUS status; - - status = smbcli_request_simple_recv(state->req); - NT_STATUS_NOT_OK_RETURN(status); - - if (state->total_written != io->in.size) { - return NT_STATUS_DISK_FULL; - } - - c->state = SMBCLI_REQUEST_DONE; - - return NT_STATUS_OK; -} - - -/* - handler for completion of a sub-request in savefile -*/ -static void savefile_handler(struct smbcli_request *req) -{ - struct composite_context *c = req->async.private; - struct savefile_state *state = talloc_get_type(c->private, struct savefile_state); - - /* when this handler is called, the stage indicates what - call has just finished */ - switch (state->stage) { - case SAVEFILE_OPEN: - c->status = savefile_open(c, state->io); - break; - - case SAVEFILE_WRITE: - c->status = savefile_write(c, state->io); - break; - - case SAVEFILE_CLOSE: - c->status = savefile_close(c, state->io); - break; - } - - if (!NT_STATUS_IS_OK(c->status)) { - c->state = SMBCLI_REQUEST_ERROR; - } - - if (c->state >= SMBCLI_REQUEST_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/* - composite savefile call - does an openx followed by a number of writex calls, - followed by a close -*/ -struct composite_context *smb_composite_savefile_send(struct smbcli_tree *tree, - struct smb_composite_savefile *io) -{ - struct composite_context *c; - struct savefile_state *state; - union smb_open *io_open; - - c = talloc_zero(tree, struct composite_context); - if (c == NULL) goto failed; - - c->state = SMBCLI_REQUEST_SEND; - c->event_ctx = tree->session->transport->socket->event.ctx; - - state = talloc(c, struct savefile_state); - if (state == NULL) goto failed; - - state->stage = SAVEFILE_OPEN; - state->total_written = 0; - state->io = io; - - /* setup for the open */ - io_open = talloc_zero(c, union smb_open); - if (io_open == NULL) goto failed; - - io_open->ntcreatex.level = RAW_OPEN_NTCREATEX; - io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; - io_open->ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; - io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; - io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; - io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; - io_open->ntcreatex.in.fname = io->in.fname; - state->io_open = io_open; - - /* send the open on its way */ - state->req = smb_raw_open_send(tree, io_open); - if (state->req == NULL) goto failed; - - /* setup the callback handler */ - state->req->async.fn = savefile_handler; - state->req->async.private = c; - c->private = state; - - return c; - -failed: - talloc_free(c); - return NULL; -} - - -/* - composite savefile call - recv side -*/ -NTSTATUS smb_composite_savefile_recv(struct composite_context *c) -{ - NTSTATUS status; - status = composite_wait(c); - talloc_free(c); - return status; -} - - -/* - composite savefile call - sync interface -*/ -NTSTATUS smb_composite_savefile(struct smbcli_tree *tree, - struct smb_composite_savefile *io) -{ - struct composite_context *c = smb_composite_savefile_send(tree, io); - return smb_composite_savefile_recv(c); -} |