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 3 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, see <http://www.gnu.org/licenses/>.
20 a composite API for loading a whole file into memory
24 #include "libcli/composite/composite.h"
25 #include "libcli/smb_composite/smb_composite.h"
26 #include "libcli/resolve/resolve.h"
28 enum fetchfile_stage
{FETCHFILE_CONNECT
,
31 struct fetchfile_state
{
32 enum fetchfile_stage stage
;
33 struct smb_composite_fetchfile
*io
;
34 struct composite_context
*creq
;
35 struct smb_composite_connect
*connect
;
36 struct smb_composite_loadfile
*loadfile
;
39 static void fetchfile_composite_handler(struct composite_context
*req
);
41 static NTSTATUS
fetchfile_connect(struct composite_context
*c
,
42 struct smb_composite_fetchfile
*io
)
45 struct fetchfile_state
*state
;
46 state
= talloc_get_type(c
->private_data
, struct fetchfile_state
);
48 status
= smb_composite_connect_recv(state
->creq
, c
);
49 NT_STATUS_NOT_OK_RETURN(status
);
51 state
->loadfile
= talloc(state
, struct smb_composite_loadfile
);
52 NT_STATUS_HAVE_NO_MEMORY(state
->loadfile
);
54 state
->loadfile
->in
.fname
= io
->in
.filename
;
56 state
->creq
= smb_composite_loadfile_send(state
->connect
->out
.tree
,
58 NT_STATUS_HAVE_NO_MEMORY(state
->creq
);
60 state
->creq
->async
.private_data
= c
;
61 state
->creq
->async
.fn
= fetchfile_composite_handler
;
63 state
->stage
= FETCHFILE_READ
;
68 static NTSTATUS
fetchfile_read(struct composite_context
*c
,
69 struct smb_composite_fetchfile
*io
)
72 struct fetchfile_state
*state
;
73 state
= talloc_get_type(c
->private_data
, struct fetchfile_state
);
75 status
= smb_composite_loadfile_recv(state
->creq
, NULL
);
76 NT_STATUS_NOT_OK_RETURN(status
);
78 io
->out
.data
= state
->loadfile
->out
.data
;
79 io
->out
.size
= state
->loadfile
->out
.size
;
81 c
->state
= COMPOSITE_STATE_DONE
;
88 static void fetchfile_state_handler(struct composite_context
*c
)
90 struct fetchfile_state
*state
;
91 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
93 state
= talloc_get_type(c
->private_data
, struct fetchfile_state
);
95 /* when this handler is called, the stage indicates what
96 call has just finished */
97 switch (state
->stage
) {
98 case FETCHFILE_CONNECT
:
99 status
= fetchfile_connect(c
, state
->io
);
102 status
= fetchfile_read(c
, state
->io
);
106 if (!NT_STATUS_IS_OK(status
)) {
108 c
->state
= COMPOSITE_STATE_ERROR
;
115 static void fetchfile_composite_handler(struct composite_context
*creq
)
117 struct composite_context
*c
= talloc_get_type(creq
->async
.private_data
,
118 struct composite_context
);
119 fetchfile_state_handler(c
);
122 struct composite_context
*smb_composite_fetchfile_send(struct smb_composite_fetchfile
*io
,
123 struct tevent_context
*event_ctx
)
125 struct composite_context
*c
;
126 struct fetchfile_state
*state
;
128 c
= talloc_zero(NULL
, struct composite_context
);
129 if (c
== NULL
) goto failed
;
131 state
= talloc(c
, struct fetchfile_state
);
132 if (state
== NULL
) goto failed
;
134 state
->connect
= talloc(state
, struct smb_composite_connect
);
135 if (state
->connect
== NULL
) goto failed
;
139 state
->connect
->in
.dest_host
= io
->in
.dest_host
;
140 state
->connect
->in
.dest_ports
= io
->in
.ports
;
141 state
->connect
->in
.socket_options
= io
->in
.socket_options
;
142 state
->connect
->in
.called_name
= io
->in
.called_name
;
143 state
->connect
->in
.service
= io
->in
.service
;
144 state
->connect
->in
.service_type
= io
->in
.service_type
;
145 state
->connect
->in
.credentials
= io
->in
.credentials
;
146 state
->connect
->in
.fallback_to_anonymous
= false;
147 state
->connect
->in
.workgroup
= io
->in
.workgroup
;
148 state
->connect
->in
.gensec_settings
= io
->in
.gensec_settings
;
150 state
->connect
->in
.options
= io
->in
.options
;
151 state
->connect
->in
.session_options
= io
->in
.session_options
;
153 state
->creq
= smb_composite_connect_send(state
->connect
, state
,
154 io
->in
.resolve_ctx
, event_ctx
);
155 if (state
->creq
== NULL
) goto failed
;
157 state
->creq
->async
.private_data
= c
;
158 state
->creq
->async
.fn
= fetchfile_composite_handler
;
160 c
->state
= COMPOSITE_STATE_IN_PROGRESS
;
161 state
->stage
= FETCHFILE_CONNECT
;
162 c
->private_data
= state
;
170 NTSTATUS
smb_composite_fetchfile_recv(struct composite_context
*c
,
175 status
= composite_wait(c
);
177 if (NT_STATUS_IS_OK(status
)) {
178 struct fetchfile_state
*state
= talloc_get_type(c
->private_data
, struct fetchfile_state
);
179 talloc_steal(mem_ctx
, state
->io
->out
.data
);
186 NTSTATUS
smb_composite_fetchfile(struct smb_composite_fetchfile
*io
,
189 struct composite_context
*c
= smb_composite_fetchfile_send(io
, NULL
);
190 return smb_composite_fetchfile_recv(c
, mem_ctx
);