server: intialize aux_header buffer to null if the data is missing.
[tridge/openchange.git] / branches / plugfest / pyopenchange / pyocpf.c
1 /*
2    OpenChange OCPF (OpenChange Property File) implementation.
3
4    Python interface to ocpf
5
6    Copyright (C) Julien Kerihuel 2010.
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 <Python.h>
23 #include "pyopenchange/pyocpf.h"
24 #include "pyopenchange/pymapi.h"
25 #include "libocpf/ocpf.h"
26
27 static PyTypeObject *SPropValue_Type;
28
29 void initocpf(void);
30
31 PyAPI_DATA(PyTypeObject) PyOcpf;
32
33 static PyObject *py_new_context(PyTypeObject *type, PyObject *args, PyObject *kwargs)
34 {
35         TALLOC_CTX      *mem_ctx;
36         PyOcpfObject    *ocpf_object;
37         char            *kwnames[] = { "filename", "flags", NULL };
38         int             ret;
39         const char      *filename;
40         uint32_t        context_id;
41         uint8_t         flags;
42
43         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sH", kwnames,
44                                          &filename, &flags)) {
45                 return NULL;
46         }
47
48         mem_ctx = talloc_new(NULL);
49         if (mem_ctx == NULL) {
50                 PyErr_NoMemory();
51                 return NULL;
52         }
53
54         printf("filename = %s, flags = 0x%x\n", filename, flags);
55         ret = ocpf_new_context(filename, &context_id, flags);
56         if (ret == OCPF_ERROR) {
57                 return NULL;
58         }
59
60         printf("context_id = %d\n", context_id);
61         ocpf_object = PyObject_New(PyOcpfObject, &PyOcpf);
62         ocpf_object->context_id = context_id;
63         ocpf_object->mem_ctx = mem_ctx;
64
65         return (PyObject *) ocpf_object;
66 }
67
68 static PyObject *py_ocpf_parse(PyOcpfObject *self)
69 {
70         int     ret;
71
72         ret = ocpf_parse(self->context_id);
73         return PyInt_FromLong(ret);
74 }
75
76 static PyObject *py_ocpf_set_SPropValue_array(PyOcpfObject *self)
77 {
78         int     ret;
79
80         ret = ocpf_server_set_SPropValue(self->mem_ctx, self->context_id);
81         return PyInt_FromLong(ret);
82 }
83
84 static PyObject *py_ocpf_get_SPropValue(PyOcpfObject *self)
85 {
86         uint32_t                cValues = 0;
87         PyObject                *mod_mapi;
88         PySPropValueObject      *pySPropValue;
89         struct SPropValue       *SPropValue;
90
91         mod_mapi = PyImport_ImportModule("openchange.mapi");
92         if (mod_mapi == NULL) {
93                 printf("Can't load module\n");
94                 return NULL;
95         }
96         SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue");
97         if (SPropValue_Type == NULL)
98                 return NULL;
99
100         SPropValue = ocpf_get_SPropValue(self->context_id, &cValues);
101
102         pySPropValue = (PySPropValueObject *)SPropValue_Type->tp_new(NULL, NULL, NULL);
103         talloc_free(pySPropValue->SPropValue);
104         pySPropValue->SPropValue = SPropValue;
105         talloc_steal(pySPropValue->mem_ctx, pySPropValue->SPropValue);
106         pySPropValue->cValues = cValues;
107
108         return (PyObject *) pySPropValue;
109 }
110
111
112 static PyObject *py_ocpf_add_SPropValue(PyOcpfObject *self, PyObject *args)
113 {
114         PyObject                *mod_mapi;
115         PyObject                *pySPropValue;
116         PySPropValueObject      *SPropValue;
117         int                     ret;
118         int                     i;
119
120         mod_mapi = PyImport_ImportModule("openchange.mapi");
121         if (mod_mapi == NULL) {
122                 printf("Can't load module\n");
123                 return NULL;
124         }
125
126         SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue");
127         if (SPropValue_Type == NULL) {
128                 return NULL;
129         }
130
131         if (!PyArg_ParseTuple(args, "O", &pySPropValue)) {
132                 return NULL;
133         }
134
135         if (!PyObject_TypeCheck(pySPropValue, SPropValue_Type)) {
136                 PyErr_SetString(PyExc_TypeError, "Function requires SPropValue obnject");
137                 return NULL;
138         }
139
140         SPropValue = (PySPropValueObject *) pySPropValue;
141
142         for (i = 0; i < SPropValue->cValues; i++) {
143                 ret = ocpf_server_add_SPropValue(self->context_id, &SPropValue->SPropValue[i]);
144                 if (ret) {
145                         return PyInt_FromLong(ret);
146                 }
147         }
148
149         return PyInt_FromLong(ret);
150 }
151
152
153 static PyObject *py_ocpf_dump(PyOcpfObject *self)
154 {
155         ocpf_dump(self->context_id);
156         Py_RETURN_NONE;
157 }
158
159 static PyObject *py_ocpf_write_init(PyOcpfObject *self, PyObject *args)
160 {
161         int             ret;
162         uint64_t        folder_id;
163
164         if (!PyArg_ParseTuple(args, "K", &folder_id)) {
165                 return NULL;
166         }
167
168         ret = ocpf_write_init(self->context_id, folder_id);
169         return PyInt_FromLong(ret);
170 }
171
172 static PyObject *py_ocpf_write(PyOcpfObject *self, PyObject *args)
173 {
174         int                             ret;
175         PyObject                        *pySPropValue;
176         PySPropValueObject              *SPropValue;
177         struct mapi_SPropValue_array    mapi_lpProps;
178         PyObject                        *mod_mapi;
179         int                             i;
180
181         mod_mapi = PyImport_ImportModule("openchange.mapi");
182         if (mod_mapi == NULL) {
183                 printf("Can't load module\n");
184                 return NULL;
185         }
186         SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue");
187         if (SPropValue_Type == NULL)
188                 return NULL;
189
190
191         if (!PyArg_ParseTuple(args, "O", &pySPropValue)) {
192                 return NULL;
193         }
194
195         if (!PyObject_TypeCheck(pySPropValue, SPropValue_Type)) {
196                 PyErr_SetString(PyExc_TypeError, "Function require SPropValue object");
197                 return NULL;
198         }
199         SPropValue = (PySPropValueObject *) pySPropValue;
200
201         mapi_lpProps.cValues = SPropValue->cValues;
202         mapi_lpProps.lpProps = talloc_array(SPropValue->mem_ctx, struct mapi_SPropValue, SPropValue->cValues);
203         for (i = 0; i < SPropValue->cValues; i++) {
204           cast_mapi_SPropValue((TALLOC_CTX *)mapi_lpProps.lpProps,
205                                &(mapi_lpProps.lpProps[i]), &(SPropValue->SPropValue[i]));
206         }
207
208         ret = ocpf_write_auto(self->context_id, NULL, &mapi_lpProps);
209         talloc_free(mapi_lpProps.lpProps);
210         return PyInt_FromLong(ret);
211 }
212
213 static PyObject *py_ocpf_write_commit(PyOcpfObject *self)
214 {
215         int             ret;
216
217         ret = ocpf_write_commit(self->context_id);
218         return PyInt_FromLong(ret);
219 }
220
221 static PyObject *py_ocpf_set_type(PyOcpfObject *self, PyObject *args)
222 {
223         const char      *type;
224
225         if (!PyArg_ParseTuple(args, "s", &type)) {
226                 return NULL;
227         }
228
229         return PyInt_FromLong(ocpf_server_set_type(self->context_id, type));
230 }
231
232 static PyMethodDef py_ocpf_global_methods[] = {
233         { NULL }
234 };
235
236 static PyMethodDef ocpf_methods[] = {
237         { "parse", (PyCFunction) py_ocpf_parse, METH_NOARGS },
238         { "dump", (PyCFunction) py_ocpf_dump, METH_NOARGS },
239         { "write_init", (PyCFunction) py_ocpf_write_init, METH_VARARGS },
240         { "write", (PyCFunction) py_ocpf_write, METH_VARARGS },
241         { "write_commit", (PyCFunction) py_ocpf_write_commit, METH_NOARGS },
242         { "set_SPropValue_array", (PyCFunction) py_ocpf_set_SPropValue_array, METH_NOARGS },
243         { "get_SPropValue", (PyCFunction) py_ocpf_get_SPropValue, METH_NOARGS },
244         { "add_SPropValue", (PyCFunction) py_ocpf_add_SPropValue, METH_VARARGS },
245         { "set_type", (PyCFunction) py_ocpf_set_type, METH_VARARGS },
246         { NULL },
247 };
248
249 static PyGetSetDef ocpf_getsetters[] = {
250         { NULL }
251 };
252
253 static void py_ocpf_dealloc(PyObject *_self)
254 {
255         PyOcpfObject *self = (PyOcpfObject *)_self;
256
257         talloc_free(self->mem_ctx);
258
259         printf("ocpf_del_context\n");
260         ocpf_del_context(self->context_id);
261         PyObject_Del(_self);
262 }
263
264 PyTypeObject PyOcpf = {
265         PyObject_HEAD_INIT(NULL) 0,
266         .tp_name = "OCPF",
267         .tp_basicsize = sizeof(PyOcpfObject),
268         .tp_methods = ocpf_methods,
269         .tp_getset = ocpf_getsetters,
270         .tp_doc = "OCPF context",
271         .tp_new = py_new_context,
272         .tp_dealloc = (destructor)py_ocpf_dealloc,
273         .tp_flags = Py_TPFLAGS_DEFAULT,
274 };
275
276 void initocpf(void)
277 {
278         PyObject        *m;
279
280         if (PyType_Ready(&PyOcpf) < 0) {
281                 return;
282         }
283
284         m = Py_InitModule3("ocpf", py_ocpf_global_methods, 
285                            "An interface to OCPF, an OpenChange file format used to represent MAPI messages");
286         if (m == NULL) {
287                 return;
288         }
289
290         PyModule_AddObject(m, "OCPF_FLAGS_RDWR", PyInt_FromLong(OCPF_FLAGS_RDWR));
291         PyModule_AddObject(m, "OCPF_FLAGS_READ", PyInt_FromLong(OCPF_FLAGS_READ));
292         PyModule_AddObject(m, "OCPF_FLAGS_WRITE", PyInt_FromLong(OCPF_FLAGS_WRITE));
293         PyModule_AddObject(m, "OCPF_FLAGS_CREATE", PyInt_FromLong(OCPF_FLAGS_CREATE));
294
295         Py_INCREF(&PyOcpf);
296
297         PyModule_AddObject(m, "Ocpf", (PyObject *)&PyOcpf);
298
299         /* Initialize OCPF subsystem */
300         ocpf_init();
301 }