2 Convenient functions for openchange tools
6 Copyright (C) Julien Kerihuel 2007
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.
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.
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/>.
22 #include "libmapi/libmapi.h"
23 #include "openchange-tools.h"
25 static void popt_openchange_version_callback(poptContext con,
26 enum poptCallbackReason reason,
27 const struct poptOption *opt,
33 printf("Version %s\n", OPENCHANGE_VERSION_STRING);
38 struct poptOption popt_openchange_version[] = {
39 { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_openchange_version_callback, '\0', NULL, NULL },
40 { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version ", NULL },
46 * Retrieve the property value for a given SRow and property tag.
48 * If the property type is a string: fetch PT_UNICODE then PT_STRING8
49 * in case the desired property is not available in first choice.
51 * Fetch property normally for any others properties
53 _PUBLIC_ void *octool_get_propval(struct SRow *aRow, uint32_t proptag)
57 if (((proptag & 0xFFFF) == PT_STRING8) ||
58 ((proptag & 0xFFFF) == PT_UNICODE)) {
59 proptag = (proptag & 0xFFFF0000) | PT_UNICODE;
60 str = (const char *) find_SPropValue_data(aRow, proptag);
61 if (str) return (void *)str;
63 proptag = (proptag & 0xFFFF0000) | PT_STRING8;
64 str = (const char *) find_SPropValue_data(aRow, proptag);
68 return (void *)find_SPropValue_data(aRow, proptag);
73 * Read a stream and store it in a DATA_BLOB
75 _PUBLIC_ enum MAPISTATUS octool_get_stream(TALLOC_CTX *mem_ctx,
76 mapi_object_t *obj_stream,
79 enum MAPISTATUS retval;
84 body->data = talloc_zero(mem_ctx, uint8_t);
87 retval = ReadStream(obj_stream, buf, 0x1000, &read_size);
88 MAPI_RETVAL_IF(retval, GetLastError(), body->data);
90 body->data = talloc_realloc(mem_ctx, body->data, uint8_t,
91 body->length + read_size);
92 memcpy(&(body->data[body->length]), buf, read_size);
93 body->length += read_size;
98 return MAPI_E_SUCCESS;
103 * Fetch the body given PR_MSG_EDITOR_FORMAT property value
105 _PUBLIC_ enum MAPISTATUS octool_get_body(TALLOC_CTX *mem_ctx,
106 mapi_object_t *obj_message,
110 enum MAPISTATUS retval;
111 const struct SBinary_short *bin;
112 mapi_object_t obj_stream;
117 MAPI_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
119 /* initialize body DATA_BLOB */
123 retval = GetBestBody(obj_message, &format);
124 MAPI_RETVAL_IF(retval, retval, NULL);
128 data = octool_get_propval(aRow, PR_BODY_UNICODE);
130 body->data = talloc_memdup(mem_ctx, data, strlen(data));
131 body->length = strlen(data);
133 mapi_object_init(&obj_stream);
134 retval = OpenStream(obj_message, PR_BODY_UNICODE, 0, &obj_stream);
135 MAPI_RETVAL_IF(retval, GetLastError(), NULL);
137 retval = octool_get_stream(mem_ctx, &obj_stream, body);
138 MAPI_RETVAL_IF(retval, GetLastError(), NULL);
140 mapi_object_release(&obj_stream);
144 bin = (const struct SBinary_short *) octool_get_propval(aRow, PR_HTML);
146 body->data = talloc_memdup(mem_ctx, bin->lpb, bin->cb);
147 body->length = bin->cb;
149 mapi_object_init(&obj_stream);
150 retval = OpenStream(obj_message, PR_HTML, 0, &obj_stream);
151 MAPI_RETVAL_IF(retval, GetLastError(), NULL);
153 retval = octool_get_stream(mem_ctx, &obj_stream, body);
154 MAPI_RETVAL_IF(retval, GetLastError(), NULL);
156 mapi_object_release(&obj_stream);
160 mapi_object_init(&obj_stream);
162 retval = OpenStream(obj_message, PR_RTF_COMPRESSED, 0, &obj_stream);
163 MAPI_RETVAL_IF(retval, GetLastError(), NULL);
165 retval = WrapCompressedRTFStream(&obj_stream, body);
166 MAPI_RETVAL_IF(retval, GetLastError(), NULL);
168 mapi_object_release(&obj_stream);
171 DEBUG(0, ("Undefined Body\n"));
175 return MAPI_E_SUCCESS;
180 * Optimized dump message routine (use GetProps rather than GetPropsAll)
182 _PUBLIC_ enum MAPISTATUS octool_message(TALLOC_CTX *mem_ctx,
183 mapi_object_t *obj_message)
185 enum MAPISTATUS retval;
186 struct SPropTagArray *SPropTagArray;
187 struct SPropValue *lpProps;
191 /* common email fields */
193 const char *from, *to, *cc, *bcc;
196 const uint8_t *has_attach;
198 const char *codepage;
200 /* Build the array of properties we want to fetch */
201 SPropTagArray = set_SPropTagArray(mem_ctx, 0x13,
202 PR_INTERNET_MESSAGE_ID,
203 PR_INTERNET_MESSAGE_ID_UNICODE,
204 PR_CONVERSATION_TOPIC,
205 PR_CONVERSATION_TOPIC_UNICODE,
206 PR_MSG_EDITOR_FORMAT,
211 PR_SENT_REPRESENTING_NAME,
212 PR_SENT_REPRESENTING_NAME_UNICODE,
214 PR_DISPLAY_TO_UNICODE,
216 PR_DISPLAY_CC_UNICODE,
218 PR_DISPLAY_BCC_UNICODE,
220 PR_MESSAGE_CODEPAGE);
221 lpProps = talloc_zero(mem_ctx, struct SPropValue);
222 retval = GetProps(obj_message, SPropTagArray, &lpProps, &count);
223 MAPIFreeBuffer(SPropTagArray);
224 MAPI_RETVAL_IF(retval, retval, NULL);
226 /* Build a SRow structure */
227 aRow.ulAdrEntryPad = 0;
228 aRow.cValues = count;
229 aRow.lpProps = lpProps;
231 msgid = (const char *) octool_get_propval(&aRow, PR_INTERNET_MESSAGE_ID);
232 subject = (const char *) octool_get_propval(&aRow, PR_CONVERSATION_TOPIC);
234 retval = octool_get_body(mem_ctx, obj_message, &aRow, &body);
236 if (retval != MAPI_E_SUCCESS) {
237 printf("Invalid Message: %s\n", msgid ? msgid : "");
238 MAPI_RETVAL_IF(retval, GetLastError(), NULL);
241 from = (const char *) octool_get_propval(&aRow, PR_SENT_REPRESENTING_NAME);
242 to = (const char *) octool_get_propval(&aRow, PR_DISPLAY_TO_UNICODE);
243 cc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_CC_UNICODE);
244 bcc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_BCC_UNICODE);
246 has_attach = (const uint8_t *) octool_get_propval(&aRow, PR_HASATTACH);
247 cp = (const uint32_t *) octool_get_propval(&aRow, PR_MESSAGE_CODEPAGE);
248 switch (cp ? *cp : 0) {
250 codepage = "CP_USASCII";
253 codepage = "CP_UNICODE";
256 codepage = "CP_JAUTODETECT";
259 codepage = "CP_KAUTODETECT";
261 case CP_ISO2022JPESC:
262 codepage = "CP_ISO2022JPESC";
264 case CP_ISO2022JPSIO:
265 codepage = "CP_ISO2022JPSIO";
272 printf("+-------------------------------------+\n");
273 printf("message id: %s\n", msgid ? msgid : "");
274 printf("subject: %s\n", subject ? subject : "");
275 printf("From: %s\n", from ? from : "");
276 printf("To: %s\n", to ? to : "");
277 printf("Cc: %s\n", cc ? cc : "");
278 printf("Bcc: %s\n", bcc ? bcc : "");
280 printf("Attachment: %s\n", *has_attach ? "True" : "False");
282 printf("Codepage: %s\n", codepage);
286 len = write(1, body.data, body.length);
287 len = write(1, "\n", 1);
289 talloc_free(body.data);
291 return MAPI_E_SUCCESS;
296 * OpenChange MAPI programs initialization routine
298 _PUBLIC_ struct mapi_session *octool_init_mapi(struct mapi_context *mapi_ctx,
299 const char *opt_profname,
300 const char *opt_password,
303 enum MAPISTATUS retval;
304 char *profname = NULL;
305 struct mapi_session *session = NULL;
306 TALLOC_CTX *mem_ctx = NULL;
308 mem_ctx = talloc_named(NULL, 0, "octool_init_mapi");
310 profname = talloc_strdup(mem_ctx, (char *)opt_profname);
312 retval = GetDefaultProfile(mapi_ctx, &profname);
313 if (retval != MAPI_E_SUCCESS) {
314 mapi_errstr("GetDefaultProfile", GetLastError());
315 talloc_free(mem_ctx);
321 retval = MapiLogonEx(mapi_ctx, &session, profname, opt_password);
323 retval = MapiLogonProvider(mapi_ctx, &session, profname, opt_password, provider);
325 MAPIFreeBuffer((char *)profname);
327 if (retval != MAPI_E_SUCCESS) {
328 mapi_errstr("MapiLogonEx", GetLastError());
329 talloc_free(mem_ctx);
333 talloc_free(mem_ctx);