Replace deprecated talloc_init calls with talloc_named
[jelmer/openchange.git] / torture / mapi_fetchattach.c
1 /*
2    OpenChange MAPI torture suite implementation.
3
4    Fetch attachments from an Exchange server
5
6    Copyright (C) Julien Kerihuel 2007.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <libmapi/libmapi.h>
23 #include <gen_ndr/ndr_exchange.h>
24 #include <param.h>
25 #include <credentials.h>
26 #include <torture/mapi_torture.h>
27 #include <torture.h>
28 #include <torture/torture_proto.h>
29 #include <samba/popt.h>
30
31
32 static enum MAPISTATUS read_attach_stream(TALLOC_CTX *ctx_mem,
33                                           mapi_object_t *obj_attach,
34                                           mapi_object_t *obj_stream,
35                                           uint8_t** buf_data,
36                                           uint32_t* sz_data)
37 {
38   uint16_t              cn_read;
39   uint32_t              off_data;
40   enum MAPISTATUS       status;
41   int                   done;
42   struct SPropTagArray  *proptags;
43   struct SPropValue     *vals;
44   uint32_t              cn_vals;
45
46   /* Reset 
47    */
48   *buf_data = 0;
49   *sz_data = 0;
50   off_data = 0;
51   done = 0;
52
53   /* Get Attachment size
54    */
55   proptags = set_SPropTagArray(ctx_mem, 0x1, PR_ATTACH_SIZE);
56   status = GetProps(obj_attach, proptags, &vals, &cn_vals);
57   mapi_errstr("GetProps", GetLastError());
58   if (status != MAPI_E_SUCCESS) return status;
59
60   /* Alloc buffer
61    */
62   *sz_data = (uint32_t)vals[0].value.b;
63   *buf_data = talloc_size(ctx_mem, *sz_data);
64   if (*buf_data == 0)
65     return -1;
66
67   /* Read attachment
68    */
69   while (done == 0) {
70           status = ReadStream(obj_stream,
71                               (*buf_data) + off_data,
72                               (*sz_data) - off_data,
73                               &cn_read);
74           mapi_errstr("ReadStream", GetLastError());
75           if ((status != MAPI_E_SUCCESS) || (cn_read == 0)) {
76                   done = 1;
77           }
78           else {
79                   off_data += cn_read;
80                   if (off_data >= *sz_data)
81                           done = 1;
82           }
83   }
84
85   *sz_data = off_data;
86
87   return status;
88 }
89
90 bool torture_rpc_mapi_fetchattach(struct torture_context *torture)
91 {
92         enum MAPISTATUS         retval;
93         TALLOC_CTX              *mem_ctx;
94         bool                    ret = true;
95         struct mapi_session     *session;
96         mapi_object_t           obj_store;
97         mapi_object_t           obj_inbox;
98         mapi_object_t           obj_message;
99         mapi_object_t           obj_tb_contents;
100         mapi_object_t           obj_tb_attach;
101         mapi_object_t           obj_attach;
102         mapi_object_t           obj_stream;
103         mapi_id_t               id_inbox;
104         mapi_id_t               id_folder;
105         mapi_id_t               id_message;
106         struct SPropTagArray    *proptags;
107         struct SRowSet          rows_msgs;
108         struct SRowSet          rows_attach;
109         uint32_t                i_msg;
110         uint32_t                i_row_attach;
111         uint32_t                num_attach;
112         uint8_t                 *buf_attach;
113         uint32_t                sz_attach;
114
115         /* init torture */
116         mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchattach");
117
118         /* init mapi */
119         if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
120
121         /* init objects */
122         mapi_object_init(&obj_store);
123         mapi_object_init(&obj_inbox);
124         mapi_object_init(&obj_message);
125         mapi_object_init(&obj_tb_contents);
126         mapi_object_init(&obj_tb_attach);
127         mapi_object_init(&obj_attach);
128         mapi_object_init(&obj_stream);
129
130         /* session::OpenMsgStore() */
131         retval = OpenMsgStore(session, &obj_store);
132         mapi_errstr("OpenMsgStore", GetLastError());
133         if (retval != MAPI_E_SUCCESS) return false;
134
135         /* id_inbox = store->GetReceiveFolder */
136         retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
137         mapi_errstr("GetReceiveFolder", GetLastError());
138         if (retval != MAPI_E_SUCCESS) return false;
139
140         /* inbox = store->OpenFolder() */
141         retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
142         mapi_errstr("OpenFolder", GetLastError());
143         if (retval != MAPI_E_SUCCESS) return false;
144
145         /* table = inbox->GetContentsTable() */
146         retval = GetContentsTable(&obj_inbox, &obj_tb_contents, 0, NULL);
147         mapi_errstr("GetContentsTable", GetLastError());
148         if (retval != MAPI_E_SUCCESS) return false;
149
150         proptags = set_SPropTagArray(mem_ctx, 0x5,
151                                      PR_FID,
152                                      PR_MID,
153                                      PR_INST_ID,
154                                      PR_INSTANCE_NUM,
155                                      PR_SUBJECT);
156         retval = SetColumns(&obj_tb_contents, proptags);
157         mapi_errstr("SetColumns", GetLastError());
158         if (retval != MAPI_E_SUCCESS) return false;
159
160         retval = QueryRows(&obj_tb_contents, 0xa, TBL_ADVANCE, &rows_msgs);
161         mapi_errstr("QueryRows", GetLastError());
162         if (retval != MAPI_E_SUCCESS) return false;
163
164         /* foreach message get attachment table
165            foreach attachment, get PR_NUM
166            foreach PR_NUM, open attachment
167          */
168         
169         for (i_msg = 0; i_msg < rows_msgs.cRows; i_msg++) {
170
171                 /* open message
172                  */
173                 id_folder = rows_msgs.aRow[i_msg].lpProps[0].value.d;
174                 id_message = rows_msgs.aRow[i_msg].lpProps[1].value.d;
175                 retval = OpenMessage(&obj_store, 
176                                      id_folder, 
177                                      id_message, 
178                                      &obj_message, 0);
179                 mapi_errstr("OpenMessage", GetLastError());
180                 if (retval == MAPI_E_SUCCESS) {
181
182                         /* open attachment table */
183                         retval = GetAttachmentTable(&obj_message, &obj_tb_attach);
184                         mapi_errstr("GetAttachmentTable", GetLastError());
185
186                         /* foreach attachment, open by PR_ATTACH_NUM */
187                         if (retval == MAPI_E_SUCCESS) {
188                                 proptags = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM);
189                                 retval = SetColumns(&obj_tb_attach, proptags);
190                                 mapi_errstr("SetColumns", GetLastError());
191                                 if (retval != MAPI_E_SUCCESS) return false;
192
193                                 retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rows_attach);
194                                 mapi_errstr("QueryRows", GetLastError());
195                                 if (retval != MAPI_E_SUCCESS) return false;
196
197                                 /* get a stream on PR_ATTACH_DATA_BIN */
198                                 for (i_row_attach = 0; i_row_attach < rows_attach.cRows; i_row_attach++) {
199                                         num_attach = rows_attach.aRow[i_row_attach].lpProps[0].value.l;
200                                         retval = OpenAttach(&obj_message, num_attach, &obj_attach);
201                                         mapi_errstr("OpenAttach", GetLastError());
202                                         if (retval == MAPI_E_SUCCESS) {
203                                                 retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
204                                                 mapi_errstr("OpenStream", GetLastError());
205
206                                                 /* read stream content */
207                                                 if (retval == MAPI_E_SUCCESS) {
208                                                         read_attach_stream(mem_ctx,
209                                                                            &obj_attach, &obj_stream, &buf_attach,
210                                                                            &sz_attach);
211                                                 }
212                                         }
213                                 }
214                         }
215                 }
216         }
217
218         mapi_object_release(&obj_store);
219         mapi_object_release(&obj_inbox);
220         mapi_object_release(&obj_message);
221         mapi_object_release(&obj_tb_contents);
222         mapi_object_release(&obj_tb_attach);
223         mapi_object_release(&obj_attach);
224         mapi_object_release(&obj_stream);
225
226         MAPIUninitialize();
227
228         talloc_free(mem_ctx);
229         return (ret);
230 }