2 Unix SMB/CIFS implementation.
4 Copyright (C) Volker Lendecke 2005
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 a composite API for loading a whole file into memory
25 #include "libcli/raw/libcliraw.h"
26 #include "libcli/composite/composite.h"
27 #include "librpc/gen_ndr/ndr_security.h"
29 enum fetchfile_stage
{FETCHFILE_CONNECT
,
32 struct fetchfile_state
{
33 enum fetchfile_stage stage
;
34 struct smb_composite_fetchfile
*io
;
35 struct composite_context
*req
;
36 struct smb_composite_connect
*connect
;
37 struct smb_composite_loadfile
*loadfile
;
40 static void fetchfile_composite_handler(struct composite_context
*req
);
42 static NTSTATUS
fetchfile_connect(struct composite_context
*c
,
43 struct smb_composite_fetchfile
*io
)
46 struct fetchfile_state
*state
;
47 state
= talloc_get_type(c
->private, struct fetchfile_state
);
49 status
= smb_composite_connect_recv(state
->req
, c
);
50 NT_STATUS_NOT_OK_RETURN(status
);
52 state
->loadfile
= talloc(state
, struct smb_composite_loadfile
);
53 NT_STATUS_NOT_OK_RETURN(status
);
55 state
->loadfile
->in
.fname
= io
->in
.filename
;
57 state
->req
= smb_composite_loadfile_send(state
->connect
->out
.tree
,
59 NT_STATUS_HAVE_NO_MEMORY(state
->req
);
61 state
->req
->async
.private = c
;
62 state
->req
->async
.fn
= fetchfile_composite_handler
;
64 state
->stage
= FETCHFILE_READ
;
65 c
->event_ctx
= talloc_reference(c
, state
->req
->event_ctx
);
70 static NTSTATUS
fetchfile_read(struct composite_context
*c
,
71 struct smb_composite_fetchfile
*io
)
74 struct fetchfile_state
*state
;
75 state
= talloc_get_type(c
->private, struct fetchfile_state
);
77 status
= smb_composite_loadfile_recv(state
->req
, NULL
);
78 NT_STATUS_NOT_OK_RETURN(status
);
80 io
->out
.data
= state
->loadfile
->out
.data
;
81 io
->out
.size
= state
->loadfile
->out
.size
;
83 c
->state
= SMBCLI_REQUEST_DONE
;
90 static void fetchfile_state_handler(struct composite_context
*c
)
92 struct fetchfile_state
*state
;
95 state
= talloc_get_type(c
->private, struct fetchfile_state
);
97 /* when this handler is called, the stage indicates what
98 call has just finished */
99 switch (state
->stage
) {
100 case FETCHFILE_CONNECT
:
101 status
= fetchfile_connect(c
, state
->io
);
104 status
= fetchfile_read(c
, state
->io
);
108 if (!NT_STATUS_IS_OK(status
)) {
110 c
->state
= SMBCLI_REQUEST_ERROR
;
117 static void fetchfile_composite_handler(struct composite_context
*req
)
119 struct composite_context
*c
= talloc_get_type(req
->async
.private,
120 struct composite_context
);
121 return fetchfile_state_handler(c
);
124 struct composite_context
*smb_composite_fetchfile_send(struct smb_composite_fetchfile
*io
,
125 struct event_context
*event_ctx
)
127 struct composite_context
*c
;
128 struct fetchfile_state
*state
;
130 c
= talloc_zero(NULL
, struct composite_context
);
131 if (c
== NULL
) goto failed
;
133 state
= talloc(c
, struct fetchfile_state
);
134 if (state
== NULL
) goto failed
;
136 state
->connect
= talloc(state
, struct smb_composite_connect
);
137 if (state
->connect
== NULL
) goto failed
;
141 state
->connect
->in
.dest_host
= io
->in
.dest_host
;
142 state
->connect
->in
.port
= io
->in
.port
;
143 state
->connect
->in
.called_name
= io
->in
.called_name
;
144 state
->connect
->in
.calling_name
= io
->in
.calling_name
;
145 state
->connect
->in
.service
= io
->in
.service
;
146 state
->connect
->in
.service_type
= io
->in
.service_type
;
147 state
->connect
->in
.user
= io
->in
.user
;
148 state
->connect
->in
.domain
= io
->in
.domain
;
149 state
->connect
->in
.password
= io
->in
.password
;
151 state
->req
= smb_composite_connect_send(state
->connect
, event_ctx
);
152 if (state
->req
== NULL
) goto failed
;
154 state
->req
->async
.private = c
;
155 state
->req
->async
.fn
= fetchfile_composite_handler
;
157 c
->state
= SMBCLI_REQUEST_SEND
;
158 state
->stage
= FETCHFILE_CONNECT
;
159 c
->event_ctx
= talloc_reference(c
, state
->req
->event_ctx
);
168 NTSTATUS
smb_composite_fetchfile_recv(struct composite_context
*c
,
173 status
= composite_wait(c
);
175 if (NT_STATUS_IS_OK(status
)) {
176 struct fetchfile_state
*state
= talloc_get_type(c
->private, struct fetchfile_state
);
177 talloc_steal(mem_ctx
, state
->io
->out
.data
);
184 NTSTATUS
smb_composite_fetchfile(struct smb_composite_fetchfile
*io
,
187 struct composite_context
*c
= smb_composite_fetchfile_send(io
, NULL
);
188 return smb_composite_fetchfile_recv(c
, mem_ctx
);