Merge in sogo branch changes r3949-3962
authorJulien Kerihuel <j.kerihuel@openchange.org>
Mon, 14 May 2012 13:11:50 +0000 (13:11 +0000)
committerJulien Kerihuel <j.kerihuel@openchange.org>
Mon, 14 May 2012 13:11:50 +0000 (13:11 +0000)
mapiproxy/libmapiproxy/openchangedb_property.c
mapiproxy/libmapiproxy/openchangedb_table.c
mapiproxy/libmapistore/mapistore_backend.c
mapiproxy/services/ocsmanager/ocsmanager/controllers/as.py
pyopenchange/mapistore/context.c
pyopenchange/mapistore/folder.c
pyopenchange/mapistore/freebusy_properties.c
pyopenchange/mapistore/mgmt.c
pyopenchange/mapistore/pymapistore.c
pyopenchange/mapistore/pymapistore.h
pyopenchange/mapistore/table.c

index 02dd894..c5de022 100644 (file)
@@ -341,7 +341,7 @@ static struct pidtags pidtags[] = {
        { PidTagMessageStatus,                                                "PidTagMessageStatus" },
        { PidTagMessageSubmissionId,                                          "PidTagMessageSubmissionId" },
        { PidTagMessageToMe,                                                  "PidTagMessageToMe" },
-       { PidTagMid,                                                          "PidTagMid" },
+       { PidTagMid,                                                          "PidTagMessageId" },
        { PidTagMiddleName,                                                   "PidTagMiddleName" },
        { PidTagMimeSkeleton,                                                 "PidTagMimeSkeleton" },
        { PidTagMobileTelephoneNumber,                                        "PidTagMobileTelephoneNumber" },
index 2f2e244..6c0d202 100644 (file)
@@ -264,6 +264,8 @@ _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx,
 
        /* If live filtering, make sure the specified row match the restrictions */
        if (live_filtered) {
+               TALLOC_CTX *local_mem_ctx;
+
                switch (table->table_type) {
                case 0x3 /* EMSMDBP_TABLE_FAI_TYPE */:
                case 0x2 /* EMSMDBP_TABLE_MESSAGE_TYPE */:
@@ -281,17 +283,15 @@ _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx,
                        DEBUG(0, ("ldb object must have a '%s' field\n", childIdAttr));
                        abort();
                }
-               ldb_filter = openchangedb_table_build_filter(NULL, table, *row_fmid, table->restrictions);
+
+               local_mem_ctx = talloc_zero(NULL, TALLOC_CTX);
+
+               ldb_filter = openchangedb_table_build_filter(local_mem_ctx, table, *row_fmid, table->restrictions);
                OPENCHANGE_RETVAL_IF(!ldb_filter, MAPI_E_TOO_COMPLEX, NULL);
                DEBUG(0, ("  row ldb_filter = %s\n", ldb_filter));
-               ret = ldb_search(ldb_ctx, NULL, &live_res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL);
-               talloc_free(ldb_filter);
-               OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_INVALID_OBJECT, NULL);
-               if (live_res->count == 0) {
-                       talloc_free(live_res);
-                       return MAPI_E_INVALID_OBJECT;
-               }
-               talloc_free(live_res);
+               ret = ldb_search(ldb_ctx, local_mem_ctx, &live_res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL);
+               OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || live_res->count == 0, MAPI_E_INVALID_OBJECT, local_mem_ctx);
+               talloc_free(local_mem_ctx);
        }
 
        /* hacks for some attributes specific to tables */
index 070bd87..fe3ab97 100644 (file)
@@ -421,8 +421,8 @@ _PUBLIC_ enum mapistore_error mapistore_backend_add_ref_count(struct backend_con
  */
 _PUBLIC_ enum mapistore_error mapistore_backend_delete_context(struct backend_context *bctx)
 {
+       bctx->ref_count -= 1;
        if (bctx->ref_count) {
-               bctx->ref_count -= 1;
                return MAPISTORE_ERR_REF_COUNT;
        }
 
index da168d5..b71070e 100644 (file)
@@ -314,6 +314,31 @@ class ExchangeService(ServiceBase):
 
         return cal_folder
 
+    @staticmethod
+    def _timezone_datetime(year, tz_time):
+        # we round the dates to midnight since events are unlikely to start at
+        # such an early time of day
+        return datetime.datetime(year, tz_time.Month, tz_time.DayOrder)
+
+    @staticmethod
+    def _freebusy_date(timezone, utcdate):
+        bias = timezone.Bias
+        if timezone.DaylightTime is not None:
+            std_datetime = ExchangeService._timezone_datetime(utcdate.year, timezone.StandardTime)
+            dst_datetime = ExchangeService._timezone_datetime(utcdate.year, timezone.DaylightTime)
+            if std_datetime < dst_datetime:
+                if utcdate >= std_datetime and utcdate < dst_datetime:
+                    bias = bias + timezone.StandardTime.Bias
+                else:
+                    bias = bias + timezone.DaylightTime.Bias
+            else:
+                if utcdate >= dst_datetime and utcdate < std_datetime:
+                    bias = bias + timezone.DaylightTime.Bias
+                else:
+                    bias = bias + timezone.StandardTime.Bias
+
+        return utcdate - datetime.timedelta(0, bias * 60)
+
     @staticmethod
     def _freebusy_response(cal_folder, timezone, freebusy_view_options):
         start = freebusy_view_options.TimeWindow.StartTime
@@ -336,12 +361,13 @@ class ExchangeService(ServiceBase):
                     "tentative": "Tentative",
                     "busy": "Busy",
                     "away": "OOF"}
+
         for (fb_attribute, label) in fb_types.iteritems():
             fb_event_list = getattr(freebusy_props, fb_attribute)
             for fb_event in fb_event_list:
                 event = CalendarEvent()
-                event.StartTime = fb_event[0]
-                event.EndTime = fb_event[1]
+                event.StartTime = ExchangeService._freebusy_date(timezone, fb_event[0])
+                event.EndTime = ExchangeService._freebusy_date(timezone, fb_event[1])
                 event.BusyType = label
                 events.append(event)
         fb_response.FreeBusyView.CalendarEventArray = events
index 69bcd26..fa6aca3 100644 (file)
@@ -39,10 +39,12 @@ static PyObject *py_MAPIStoreContext_open(PyMAPIStoreContextObject *self, PyObje
        folder = PyObject_New(PyMAPIStoreFolderObject, &PyMAPIStoreFolder);
        
        folder->context = self;
+       Py_INCREF(folder->context);
+
        folder->folder_object = self->folder_object;
+       (void) talloc_reference(NULL, folder->folder_object);
        folder->fid = self->fid;
        
-       Py_INCREF(self);
        return (PyObject *)folder;
 }
 
@@ -59,6 +61,7 @@ static PyObject *py_MAPIStoreContext_register_subscription(PyMAPIStoreContextObj
        struct mapistore_subscription                   *subscription;
        struct mapistore_object_subscription_parameters subscription_params;
        uint32_t                                        random_int;
+       PyMAPIStoreGlobals                              *globals;
 
        if (!PyArg_ParseTuple(args, "sbh", &mapistoreURI, &WholeStore, &NotificationFlags)) {
                return NULL;
@@ -73,7 +76,9 @@ static PyObject *py_MAPIStoreContext_register_subscription(PyMAPIStoreContextObj
                n.MAPIStoreURI = NULL;
        } else {
                /* Retrieve folderID from mapistoreURI in openchange.ldb */
-               ret = openchangedb_get_fid(self->parent->ocdb_ctx, mapistoreURI, &FolderID);
+
+               globals = get_PyMAPIStoreGlobals();
+               ret = openchangedb_get_fid(globals->ocdb_ctx, mapistoreURI, &FolderID);
                if (ret != MAPISTORE_SUCCESS) {
                        /* Try to retrieve URI from user indexing.tdb */
                        ret = mapistore_indexing_record_get_fmid(self->mstore_ctx, 
@@ -126,6 +131,7 @@ static PyObject *py_MAPIStoreContext_unregister_subscription(PyMAPIStoreContextO
        uint16_t                                NotificationFlags;
        uint64_t                                FolderID;
        uint32_t                                identifier;
+       PyMAPIStoreGlobals *globals;
 
        if (!PyArg_ParseTuple(args, "sbhi", &mapistoreURI, &WholeStore, &NotificationFlags, &identifier)) {
                return NULL;
@@ -140,7 +146,8 @@ static PyObject *py_MAPIStoreContext_unregister_subscription(PyMAPIStoreContextO
                n.MAPIStoreURI = NULL;
        } else {
                /* Retrieve folderID from mapistoreURI in openchange.ldb */
-               ret = openchangedb_get_fid(self->parent->ocdb_ctx, mapistoreURI, &FolderID);
+               globals = get_PyMAPIStoreGlobals();
+               ret = openchangedb_get_fid(globals->ocdb_ctx, mapistoreURI, &FolderID);
                if (ret != MAPISTORE_SUCCESS) {
                        /* Try to retrieve URI from user indexing.tdb */
                }
@@ -209,3 +216,11 @@ PyTypeObject PyMAPIStoreContext = {
        .tp_dealloc = (destructor)py_MAPIStoreContext_dealloc,
        .tp_flags = Py_TPFLAGS_DEFAULT,
 };
+
+void initmapistore_context(PyObject *m)
+{
+       if (PyType_Ready(&PyMAPIStoreContext) < 0) {
+               return;
+       }
+       Py_INCREF(&PyMAPIStoreContext);
+}
index 5df134e..97bc44d 100644 (file)
@@ -27,7 +27,9 @@ static void py_MAPIStoreFolder_dealloc(PyObject *_self)
 {
        PyMAPIStoreFolderObject *self = (PyMAPIStoreFolderObject *)_self;
 
-       Py_DECREF(self->context);
+       talloc_unlink(NULL, self->folder_object);
+
+       Py_XDECREF(self->context);
        PyObject_Del(_self);
 }
 
@@ -53,8 +55,8 @@ static PyObject *py_MAPIStoreFolder_create_folder(PyMAPIStoreFolderObject *self,
                                                     name, &fid);
        if (ret == MAPISTORE_SUCCESS) {
                if (flags != OPEN_IF_EXISTS) {
-                       PyErr_MAPIStore_IS_ERR_RAISE(MAPISTORE_ERR_EXIST);
-                       Py_RETURN_NONE;
+                       PyErr_SetMAPIStoreError(ret);
+                       return NULL;
                }
        }
        
@@ -147,6 +149,7 @@ static PyObject *py_MAPIStoreFolder_fetch_freebusy_properties(PyMAPIStoreFolderO
        struct tm               *start_tm, *end_tm;
        enum mapistore_error    retval;
        struct mapistore_freebusy_properties *fb_props;
+       PyMAPIStoreGlobals *globals;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwnames, &start, &end)) {
                return NULL;
@@ -154,9 +157,10 @@ static PyObject *py_MAPIStoreFolder_fetch_freebusy_properties(PyMAPIStoreFolderO
 
        mem_ctx = talloc_zero(NULL, TALLOC_CTX);
 
+       globals = get_PyMAPIStoreGlobals();
        if (start) {
-               if (!PyObject_IsInstance(start, datetime_datetime_class)) {
-                       PyErr_SetString(PyExc_TypeError, "'start' must either be a datetime.datetime instance of None");
+               if (!PyObject_IsInstance(start, globals->datetime_datetime_class)) {
+                       PyErr_SetString(PyExc_TypeError, "'start' must either be a datetime.datetime instance or None");
                        goto end;
                }
                start_tm = talloc_zero(mem_ctx, struct tm);
@@ -167,8 +171,8 @@ static PyObject *py_MAPIStoreFolder_fetch_freebusy_properties(PyMAPIStoreFolderO
        }
 
        if (end) {
-               if (!PyObject_IsInstance(end, datetime_datetime_class)) {
-                       PyErr_SetString(PyExc_TypeError, "'end' must either be a datetime.datetime instance of None");
+               if (!PyObject_IsInstance(end, globals->datetime_datetime_class)) {
+                       PyErr_SetString(PyExc_TypeError, "'end' must either be a datetime.datetime instance or None");
                        goto end;
                }
                end_tm = talloc_zero(mem_ctx, struct tm);
@@ -180,7 +184,7 @@ static PyObject *py_MAPIStoreFolder_fetch_freebusy_properties(PyMAPIStoreFolderO
 
        retval = mapistore_folder_fetch_freebusy_properties(self->context->mstore_ctx, self->context->context_id, self->folder_object, start_tm, end_tm, mem_ctx, &fb_props);
        if (retval != MAPISTORE_SUCCESS) {
-               PyErr_MAPIStore_IS_ERR_RAISE(retval);
+               PyErr_SetMAPIStoreError(retval);
                goto end;
        }
        result = (PyObject *) instantiate_freebusy_properties(fb_props);
@@ -189,8 +193,6 @@ end:
        talloc_free(mem_ctx);
 
        return result;
-/* enum mapistore_error mapistore_folder_fetch_freebusy_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, struct tm *start_tm, struct tm *end_tm, TALLOC_CTX *mem_ctx, struct mapistore_freebusy_properties **fb_props_p) */
-
 }
 
 static PyMethodDef mapistore_folder_methods[] = {
@@ -221,6 +223,7 @@ void initmapistore_folder(PyObject *m)
        if (PyType_Ready(&PyMAPIStoreFolder) < 0) {
                return;
        }
+       Py_INCREF(&PyMAPIStoreFolder);
 
        PyModule_AddObject(m, "FOLDER_GENERIC", PyInt_FromLong(0x1));
        PyModule_AddObject(m, "FOLDER_SEARCH", PyInt_FromLong(0x2));
index dd42625..c72f58e 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "pymapistore.h"
 
+static void py_MAPIStoreFreeBusyProperties_dealloc(PyObject *_self);
+
 struct PyMemberDef PyMAPIStoreFreeBusyProperties_members[] = {
        { "timestamp", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, timestamp), RO, "docstring of publish_start" },
 
@@ -54,16 +56,19 @@ PyTypeObject PyMAPIStoreFreeBusyProperties = {
        .tp_members = PyMAPIStoreFreeBusyProperties_members,
        .tp_basicsize = sizeof (PyMAPIStoreFreeBusyPropertiesObject),
        .tp_doc = "mapistore freebusy properties object",
+       .tp_dealloc = (destructor)py_MAPIStoreFreeBusyProperties_dealloc,
        .tp_flags = Py_TPFLAGS_DEFAULT,
 };
 
 static PyObject *make_datetime_from_nttime(NTTIME nt_time)
 {
        time_t          unix_time;
+       PyMAPIStoreGlobals *globals;
 
        unix_time = nt_time_to_unix(nt_time);
+       globals = get_PyMAPIStoreGlobals();
 
-       return PyObject_CallMethod(datetime_datetime_class, "utcfromtimestamp", "i", unix_time);
+       return PyObject_CallMethod(globals->datetime_datetime_class, "utcfromtimestamp", "i", unix_time);
 }
 
 static PyObject *make_datetime_from_filetime(struct FILETIME *filetime)
@@ -84,18 +89,38 @@ static PyObject *make_datetime_from_minutes(uint32_t minutes)
        return make_datetime_from_nttime(nt_time);
 }
 
-static PyObject *make_range_tuple_from_range(struct mapistore_freebusy_properties *fb_props, uint16_t *minutes_range_start)
+static PyObject *make_datetime_from_ymon_and_minutes(uint32_t ymon, uint16_t offset_mins)
+{
+       struct tm tm;
+       int year, hours;
+       time_t unix_time;
+       PyMAPIStoreGlobals *globals;
+
+       memset(&tm, 0, sizeof(struct tm));
+       year = ymon >> 4;
+       tm.tm_year = year - 1900;
+       tm.tm_mon = (ymon & 0x000f) - 1;
+
+       tm.tm_min = offset_mins % 60;
+       hours = offset_mins / 60;
+       tm.tm_mday = 1 + (hours / 24);
+       tm.tm_hour = hours % 24;
+
+       unix_time = mktime(&tm);
+
+       globals = get_PyMAPIStoreGlobals();
+
+       return PyObject_CallMethod(globals->datetime_datetime_class, "utcfromtimestamp", "i", unix_time);
+}
+
+static PyObject *make_range_tuple_from_range(uint32_t ymon, uint16_t *minutes_range_start)
 {
        PyObject *range_tuple, *datetime;
-       uint32_t date_min;
 
        range_tuple = PyTuple_New(2);
-       date_min = fb_props->publish_start + minutes_range_start[0];
-       datetime = make_datetime_from_minutes(date_min);
+       datetime = make_datetime_from_ymon_and_minutes(ymon, minutes_range_start[0]);
        PyTuple_SET_ITEM(range_tuple, 0, datetime);
-
-       date_min = fb_props->publish_start + minutes_range_start[1];
-       datetime = make_datetime_from_minutes(date_min);
+       datetime = make_datetime_from_ymon_and_minutes(ymon, minutes_range_start[1]);
        PyTuple_SET_ITEM(range_tuple, 1, datetime);
 
        return range_tuple;
@@ -103,18 +128,29 @@ static PyObject *make_range_tuple_from_range(struct mapistore_freebusy_propertie
 
 static PyObject *make_fb_tuple(struct mapistore_freebusy_properties *fb_props, struct Binary_r *ranges)
 {
-       int i, nbr_ranges;
+       int i, j, range_nbr, nbr_ranges, nbr_minute_ranges;
+       struct Binary_r *current_ranges;
        uint16_t *minutes_range_start;
        PyObject *tuple, *range_tuple;
 
-       nbr_ranges = ranges->cb / (2 * sizeof(uint16_t));
-       minutes_range_start = (uint16_t *) ranges->lpb;
+       nbr_ranges = 0;
+       for (i = 0; i < fb_props->nbr_months; i++) {
+               current_ranges = ranges + i;
+               nbr_ranges += (current_ranges->cb / (2 * sizeof(uint16_t)));
+       }
 
        tuple = PyTuple_New(nbr_ranges);
-       for (i = 0; i < nbr_ranges; i++) {
-               range_tuple = make_range_tuple_from_range(fb_props, minutes_range_start);
-               PyTuple_SET_ITEM(tuple, i, range_tuple);
-               minutes_range_start += 2;
+       range_nbr = 0;
+       for (i = 0; i < fb_props->nbr_months; i++) {
+               current_ranges = ranges + i;
+               minutes_range_start = (uint16_t *) current_ranges->lpb;
+               nbr_minute_ranges = (current_ranges->cb / (2 * sizeof(uint16_t)));
+               for (j = 0; j < nbr_minute_ranges; j++) {
+                       range_tuple = make_range_tuple_from_range(fb_props->months_ranges[i], minutes_range_start);
+                       PyTuple_SET_ITEM(tuple, range_nbr, range_tuple);
+                       minutes_range_start += 2;
+                       range_nbr++;
+               }
        }
 
        return tuple;
@@ -157,9 +193,26 @@ PyMAPIStoreFreeBusyPropertiesObject* instantiate_freebusy_properties(struct mapi
        return fb_props_object;
 }
 
+static void py_MAPIStoreFreeBusyProperties_dealloc(PyObject *_self)
+{
+       PyMAPIStoreFreeBusyPropertiesObject *self = (PyMAPIStoreFreeBusyPropertiesObject *)_self;
+
+       Py_XDECREF(self->timestamp);
+       Py_XDECREF(self->publish_start);
+       Py_XDECREF(self->publish_end);
+       Py_XDECREF(self->free);
+       Py_XDECREF(self->tentative);
+       Py_XDECREF(self->busy);
+       Py_XDECREF(self->away);
+       Py_XDECREF(self->merged);
+
+       PyObject_Del(_self);
+}
+
 void initmapistore_freebusy_properties(PyObject *parent_module)
 {
        if (PyType_Ready(&PyMAPIStoreFreeBusyProperties) < 0) {
                return;
        }
+       Py_INCREF(&PyMAPIStoreFreeBusyProperties);
 }
index 3009030..2beeea5 100644 (file)
@@ -22,8 +22,6 @@
 #include <Python.h>
 #include "pyopenchange/mapistore/pymapistore.h"
 
-void initmapistore_mgmt(void);
-
 static void py_MAPIStoreMGMT_dealloc(PyObject *_self)
 {
        PyMAPIStoreMGMTObject *self = (PyMAPIStoreMGMTObject *)_self;
@@ -31,7 +29,7 @@ static void py_MAPIStoreMGMT_dealloc(PyObject *_self)
        printf("deallocate MGMT object\n");
        mapistore_mgmt_release(self->mgmt_ctx);
 
-       Py_DECREF(self->parent);
+       Py_XDECREF(self->parent);
        PyObject_Del(_self);
 }
 
@@ -115,6 +113,7 @@ static PyObject *py_MAPIStoreMGMT_register_message(PyMAPIStoreMGMTObject *self,
        PyObject        *retlist;
        uint64_t        mid;
        int             ret;
+       PyMAPIStoreGlobals *globals;
 
        if (!PyArg_ParseTuple(args, "ssss", &backend, &user, &uri, &messageID)) {
                return NULL;
@@ -123,7 +122,8 @@ static PyObject *py_MAPIStoreMGMT_register_message(PyMAPIStoreMGMTObject *self,
        retlist = PyList_New(0);
 
        /* Gets a new message ID */
-       ret = openchangedb_get_new_folderID(self->parent->ocdb_ctx, &mid);
+       globals = get_PyMAPIStoreGlobals();
+       ret = openchangedb_get_new_folderID(globals->ocdb_ctx, &mid);
        if (ret) return (PyObject *)retlist;
 
        /* Register the message within specified user indexing database */
@@ -151,6 +151,7 @@ static PyObject *py_MAPIStoreMGMT_existing_users(PyMAPIStoreMGMTObject *self, Py
        const char      *folder;
        int             ret;
        int             i;
+       PyMAPIStoreGlobals *globals;
 
        if (!PyArg_ParseTuple(args, "sss", &backend, &vuser, &folder)) {
                return NULL;
@@ -167,7 +168,8 @@ static PyObject *py_MAPIStoreMGMT_existing_users(PyMAPIStoreMGMTObject *self, Py
        if (ret != MAPISTORE_SUCCESS) return (PyObject *)dict;
        printf("=> uri: %s\n", uri);
 
-       ret = openchangedb_get_users_from_partial_uri(self->mgmt_ctx, self->parent->ocdb_ctx, uri, 
+       globals = get_PyMAPIStoreGlobals();
+       ret = openchangedb_get_users_from_partial_uri(self->mgmt_ctx, globals->ocdb_ctx, uri, 
                                                      &count, &MAPIStoreURI, &users);
        printf("ret = 0x%x\n", ret);
        if (ret != MAPISTORE_SUCCESS) return (PyObject *)dict;
@@ -221,6 +223,7 @@ static PyObject *py_MAPIStoreMGMT_send_newmail(PyMAPIStoreMGMTObject *self, PyOb
        uint64_t        FolderID;
        uint64_t        MessageID;
        bool            softdeleted;
+       PyMAPIStoreGlobals *globals;
 
        if (!PyArg_ParseTuple(args, "ssss", &username, &storeuser, &FolderURI, &MessageURI)) {
                return NULL;
@@ -234,7 +237,8 @@ static PyObject *py_MAPIStoreMGMT_send_newmail(PyMAPIStoreMGMTObject *self, PyOb
        }
 
        /* Turn FolderURI into FolderID from openchangedb or indexing database */
-       ret = openchangedb_get_fid(self->parent->ocdb_ctx, FolderURI, &FolderID);
+       globals = get_PyMAPIStoreGlobals();
+       ret = openchangedb_get_fid(globals->ocdb_ctx, FolderURI, &FolderID);
        if (ret != MAPI_E_SUCCESS) {
                ret = mapistore_indexing_record_get_fmid(self->mgmt_ctx->mstore_ctx, username, FolderURI, false,
                                                         &FolderID, &softdeleted);
@@ -290,3 +294,11 @@ PyTypeObject PyMAPIStoreMGMT = {
        .tp_dealloc = (destructor)py_MAPIStoreMGMT_dealloc,
        .tp_flags = Py_TPFLAGS_DEFAULT,
 };
+
+void initmapistore_mgmt(PyObject *m)
+{
+       if (PyType_Ready(&PyMAPIStoreMGMT) < 0) {
+               return;
+       }
+       Py_INCREF(&PyMAPIStoreMGMT);
+}
index 89336a8..a85f560 100644 (file)
@@ -32,11 +32,7 @@ extern struct ldb_context *samdb_connect(TALLOC_CTX *, struct tevent_context *,
 
 void initmapistore(void);
 
-PyObject *datetime_module;
-PyObject *datetime_datetime_class;
-
-static struct ldb_context      *samdb_ctx = NULL;
-static struct ldb_context      *openchange_ldb_ctx = NULL;
+static PyMAPIStoreGlobals globals;
 
 void PyErr_SetMAPIStoreError(uint32_t retval)
 {
@@ -44,6 +40,11 @@ void PyErr_SetMAPIStoreError(uint32_t retval)
                        Py_BuildValue("(i, s)", retval, mapistore_errstr(retval)));
 }
 
+PyMAPIStoreGlobals *get_PyMAPIStoreGlobals()
+{
+       return &globals;
+}
+
 static void sam_ldb_init(const char *syspath)
 {
        TALLOC_CTX              *mem_ctx;
@@ -60,7 +61,7 @@ static void sam_ldb_init(const char *syspath)
        };
 
        /* Sanity checks */
-       if (samdb_ctx) return;
+       if (globals.samdb_ctx) return;
 
        mem_ctx = talloc_zero(NULL, TALLOC_CTX);
 
@@ -72,30 +73,32 @@ static void sam_ldb_init(const char *syspath)
 
        /* Step 2. Connect to the database */
        lp_ctx = loadparm_init_global(true);
-       samdb_ctx = samdb_connect(NULL, NULL, lp_ctx, system_session(lp_ctx), 0);
-       if (!samdb_ctx) goto end;
+       globals.samdb_ctx = samdb_connect(NULL, NULL, lp_ctx, system_session(lp_ctx), 0);
+       if (!globals.samdb_ctx) goto end;
 
        /* Step 3. Search for rootDSE record */
-       ret = ldb_search(samdb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, samdb_ctx, "@ROOTDSE"),
+       ret = ldb_search(globals.samdb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, globals.samdb_ctx, "@ROOTDSE"),
                         LDB_SCOPE_BASE, attrs, NULL);
        if (ret != LDB_SUCCESS) goto end;
        if (res->count != 1) goto end;
 
        /* Step 4. Set opaque naming */
-       tmp_dn = ldb_msg_find_attr_as_dn(samdb_ctx, samdb_ctx,
+       tmp_dn = ldb_msg_find_attr_as_dn(globals.samdb_ctx, globals.samdb_ctx,
                                         res->msgs[0], "rootDomainNamingContext");
-       ldb_set_opaque(samdb_ctx, "rootDomainNamingContext", tmp_dn);
+       ldb_set_opaque(globals.samdb_ctx, "rootDomainNamingContext", tmp_dn);
        
-       tmp_dn = ldb_msg_find_attr_as_dn(samdb_ctx, samdb_ctx,
+       tmp_dn = ldb_msg_find_attr_as_dn(globals.samdb_ctx, globals.samdb_ctx,
                                         res->msgs[0], "defaultNamingContext");
-       ldb_set_opaque(samdb_ctx, "defaultNamingContext", tmp_dn);
+       ldb_set_opaque(globals.samdb_ctx, "defaultNamingContext", tmp_dn);
 
 end:
        talloc_free(mem_ctx);
 }
 
-static void *openchange_ldb_init(TALLOC_CTX *mem_ctx, const char *syspath)
+static void openchange_ldb_init(const char *syspath)
 {
+       TALLOC_CTX              *mem_ctx;
+       struct ldb_context      *ldb_ctx;
        char                    *ldb_path;
        struct tevent_context   *ev;
        int                     ret;
@@ -108,38 +111,50 @@ static void *openchange_ldb_init(TALLOC_CTX *mem_ctx, const char *syspath)
        };
 
        /* Sanity checks */
-       if (openchange_ldb_ctx) return openchange_ldb_ctx;
+       if (globals.ocdb_ctx) return;
 
-       ev = tevent_context_init(talloc_autofree_context());
-       if (!ev) return NULL;
+       /* ev = tevent_context_init(talloc_autofree_context()); */
+       /* if (!ev) { */
+       /*      return NULL; */
+       /* } */
+       ev = NULL;
+
+       mem_ctx = talloc_zero(NULL, TALLOC_CTX);
 
        /* Step 1. Retrieve a LDB context pointer on openchange.ldb database */
-       ldb_path = talloc_asprintf(mem_ctx, "%s/openchange.ldb", syspath);
-       openchange_ldb_ctx = ldb_init(mem_ctx, ev);
-       if (!openchange_ldb_ctx) return NULL;
+       ldb_ctx = ldb_init(mem_ctx, ev);
+       if (!ldb_ctx) {
+               goto end;
+       }
 
        /* Step 2. Connect to the database */
-       ret = ldb_connect(openchange_ldb_ctx, ldb_path, 0, NULL);
-       talloc_free(ldb_path);
-       if (ret != LDB_SUCCESS) return NULL;
+       ldb_path = talloc_asprintf(mem_ctx, "%s/openchange.ldb", syspath);
+       ret = ldb_connect(ldb_ctx, ldb_path, 0, NULL);
+       if (ret != LDB_SUCCESS) {
+               goto end;
+       }
 
        /* Step 3. Search for rootDSE record */
-       ret = ldb_search(openchange_ldb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, openchange_ldb_ctx, "@ROOTDSE"),
+       ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, ldb_ctx, "@ROOTDSE"),
                         LDB_SCOPE_BASE, attrs, NULL);
-       if (ret != LDB_SUCCESS) return NULL;
-       if (res->count != 1) return NULL;
+       if (ret != LDB_SUCCESS || res->count != 1) {
+               goto end;
+       }
 
        /* Step 4. Set opaque naming */
-       tmp_dn = ldb_msg_find_attr_as_dn(openchange_ldb_ctx, openchange_ldb_ctx, 
+       tmp_dn = ldb_msg_find_attr_as_dn(ldb_ctx, ldb_ctx, 
                                         res->msgs[0], "rootDomainNamingContext");
-       ldb_set_opaque(openchange_ldb_ctx, "rootDomainNamingContext", tmp_dn);
+       ldb_set_opaque(ldb_ctx, "rootDomainNamingContext", tmp_dn);
        
-       tmp_dn = ldb_msg_find_attr_as_dn(openchange_ldb_ctx, openchange_ldb_ctx,
+       tmp_dn = ldb_msg_find_attr_as_dn(ldb_ctx, ldb_ctx,
                                         res->msgs[0], "defaultNamingContext");
-       ldb_set_opaque(openchange_ldb_ctx, "defaultNamingContext", tmp_dn);
-
-       return openchange_ldb_ctx;
+       ldb_set_opaque(ldb_ctx, "defaultNamingContext", tmp_dn);
 
+       globals.ocdb_ctx = ldb_ctx;
+       (void) talloc_reference(NULL, globals.ocdb_ctx);
+       
+end:
+       talloc_free(mem_ctx);
 }
 
 static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
@@ -151,7 +166,6 @@ static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *
        char                            *kwnames[] = { "syspath", "path", NULL };
        const char                      *path = NULL;
        const char                      *syspath = NULL;
-       struct ldb_context              *ocdb_ctx = NULL;
 
        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s", kwnames, &syspath, &path)) {
                return NULL;
@@ -159,7 +173,7 @@ static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *
 
        /* Initialize ldb context on sam.ldb */
        sam_ldb_init(syspath);
-       if (samdb_ctx == NULL) {
+       if (globals.samdb_ctx == NULL) {
                PyErr_SetString(PyExc_SystemError,
                                "error in sam_ldb_init");
                return NULL;
@@ -172,8 +186,8 @@ static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *
        }
 
        /* Initialize ldb context on openchange.ldb */
-       ocdb_ctx = openchange_ldb_init(mem_ctx, syspath);
-       if (ocdb_ctx == NULL) {
+       openchange_ldb_init(syspath);
+       if (globals.ocdb_ctx == NULL) {
                PyErr_SetString(PyExc_SystemError,
                                "error in openchange_ldb_init");
                talloc_free(mem_ctx);
@@ -196,8 +210,6 @@ static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *
        msobj = PyObject_New(PyMAPIStoreObject, &PyMAPIStore);
        msobj->mem_ctx = mem_ctx;
        msobj->mstore_ctx = mstore_ctx;
-       msobj->samdb_ctx = samdb_ctx;
-       msobj->ocdb_ctx = ocdb_ctx;
 
        return (PyObject *) msobj;
 }
@@ -218,13 +230,12 @@ static PyObject *py_MAPIStore_new_mgmt(PyMAPIStoreObject *self, PyObject *args)
        obj = PyObject_New(PyMAPIStoreMGMTObject, &PyMAPIStoreMGMT);
        obj->mgmt_ctx = mapistore_mgmt_init(self->mstore_ctx);
        if (obj->mgmt_ctx == NULL) {
-               PyErr_MAPIStore_IS_ERR_RAISE(MAPISTORE_ERR_NOT_INITIALIZED);
+               PyErr_SetMAPIStoreError(MAPISTORE_ERR_NOT_INITIALIZED);
                return NULL;
        }
        obj->mem_ctx = self->mem_ctx;
        obj->parent = self;
-
-       Py_INCREF(self);
+       Py_INCREF(obj->parent);
 
        return (PyObject *) obj;
 }
@@ -246,22 +257,22 @@ static PyObject *py_MAPIStore_add_context(PyMAPIStoreObject *self, PyObject *arg
        /* printf("Add context: %s\n", uri); */
 
        /* Initialize connection info */
-       ret = mapistore_set_connection_info(self->mstore_ctx, self->samdb_ctx, self->ocdb_ctx, username);
+       ret = mapistore_set_connection_info(self->mstore_ctx, globals.samdb_ctx, globals.ocdb_ctx, username);
        if (ret != MAPISTORE_SUCCESS) {
-               PyErr_MAPIStore_IS_ERR_RAISE(ret)
+               PyErr_SetMAPIStoreError(ret);
                return NULL;
        }
 
        /* Get FID given mapistore_uri and username */
-       ret = openchangedb_get_fid(self->ocdb_ctx, uri, &fid);
+       ret = openchangedb_get_fid(globals.ocdb_ctx, uri, &fid);
        if (ret != MAPISTORE_SUCCESS) {
-               PyErr_MAPIStore_IS_ERR_RAISE(ret)
+               PyErr_SetMAPIStoreError(ret);
                return NULL;
        }
 
        ret = mapistore_add_context(self->mstore_ctx, username, uri, fid, &context_id, &folder_object);
        if (ret != MAPISTORE_SUCCESS) {
-               PyErr_MAPIStore_IS_ERR_RAISE(ret)
+               PyErr_SetMAPIStoreError(ret);
                return NULL;
        }
 
@@ -278,19 +289,20 @@ static PyObject *py_MAPIStore_add_context(PyMAPIStoreObject *self, PyObject *arg
        return (PyObject *) context;
 }
 
-static PyObject *py_MAPIStore_delete_context(PyMAPIStoreObject *self, PyObject *args)
-{
-       PyMAPIStoreContextObject        *context;
-       int                             ret = MAPISTORE_SUCCESS;
+/* static PyObject *py_MAPIStore_delete_context(PyMAPIStoreObject *self, PyObject *args) */
+/* { */
+/*     PyMAPIStoreContextObject        *context; */
+/*     int                             ret = MAPISTORE_SUCCESS; */
 
-       if (!PyArg_ParseTuple(args, "O", &context)) {
-               return NULL;
-       }
+/*     if (!PyArg_ParseTuple(args, "O", &context)) { */
+/*             return NULL; */
+/*     } */
 
-       mapistore_del_context(context->mstore_ctx, context->context_id);
-       Py_CLEAR(context);
-       return PyInt_FromLong(ret);
-}
+/*     /\* mapistore_del_context(context->mstore_ctx, context->context_id); *\/ */
+/*     /\* Py_XDECREF(context); *\/ */
+
+/*     return PyInt_FromLong(ret); */
+/* } */
 
 /* static PyObject *py_MAPIStore_search_context_by_uri(PyMAPIStoreObject *self, PyObject *args) */
 /* { */
@@ -439,7 +451,7 @@ static PyObject *py_MAPIStore_delete_context(PyMAPIStoreObject *self, PyObject *
 static PyMethodDef mapistore_methods[] = {
        { "management", (PyCFunction)py_MAPIStore_new_mgmt, METH_VARARGS },
        { "add_context", (PyCFunction)py_MAPIStore_add_context, METH_VARARGS },
-       { "delete_context", (PyCFunction)py_MAPIStore_delete_context, METH_VARARGS },
+       /* { "delete_context", (PyCFunction)py_MAPIStore_delete_context, METH_VARARGS }, */
        /* { "search_context_by_uri", (PyCFunction)py_MAPIStore_search_context_by_uri, METH_VARARGS }, */
        /* { "add_context_ref_count", (PyCFunction)py_MAPIStore_add_context_ref_count, METH_VARARGS }, */
        /* { "create_folder", (PyCFunction)py_MAPIStore_create_folder, METH_VARARGS }, */
@@ -493,11 +505,15 @@ static void load_modules(void)
 {
        PyObject *datetime_dict;
 
-       datetime_module = PyImport_ImportModule("datetime");
-       if (datetime_module) {
-               datetime_dict = PyModule_GetDict(datetime_module);
-               datetime_datetime_class = PyDict_GetItemString(datetime_dict, "datetime");
-               if (!PyType_Check(datetime_datetime_class)) {
+       globals.datetime_module = PyImport_ImportModule("datetime");
+       Py_INCREF(globals.datetime_module);
+       if (globals.datetime_module) {
+               datetime_dict = PyModule_GetDict(globals.datetime_module);
+               globals.datetime_datetime_class = PyDict_GetItemString(datetime_dict, "datetime");
+               if (PyType_Check(globals.datetime_datetime_class)) {
+                       Py_INCREF(globals.datetime_datetime_class);
+               }
+               else {
                        fprintf (stderr, "failure loading datetime.datetime class\n");
                }
        }
@@ -510,21 +526,9 @@ void initmapistore(void)
 {
        PyObject        *m;
 
-       if (PyType_Ready(&PyMAPIStore) < 0) {
-               return;
-       }
+       memset(&globals, 0, sizeof(PyMAPIStoreGlobals));
 
-       if (PyType_Ready(&PyMAPIStoreMGMT) < 0) {
-               return;
-       }
-
-       if (PyType_Ready(&PyMAPIStoreContext) < 0) {
-               return;
-       }
-
-       if (PyType_Ready(&PyMAPIStoreTable) < 0) {
-               return;
-       }
+       load_modules();
 
        m = Py_InitModule3("mapistore", py_mapistore_global_methods,
                           "An interface to OpenChange MAPIStore");
@@ -532,13 +536,16 @@ void initmapistore(void)
                return;
        }
 
-       load_modules();
+       if (PyType_Ready(&PyMAPIStore) < 0) {
+               return;
+       }
+       Py_INCREF(&PyMAPIStore);
+       PyModule_AddObject(m, "MAPIStore", (PyObject *)&PyMAPIStore);
 
+       initmapistore_mgmt(m);
+       initmapistore_context(m);
        initmapistore_folder(m);
        initmapistore_freebusy_properties(m);
        initmapistore_errors(m);
-
-       Py_INCREF(&PyMAPIStore);
-
-       PyModule_AddObject(m, "MAPIStore", (PyObject *)&PyMAPIStore);
+       initmapistore_table(m);
 }
index 8432af1..e19091c 100644 (file)
 #include "mapiproxy/libmapiproxy/libmapiproxy.h"
 #include <tevent.h>
 
+typedef struct {
+       PyObject                *datetime_module;
+       PyObject                *datetime_datetime_class;
+       struct ldb_context      *samdb_ctx;
+       struct ldb_context      *ocdb_ctx;
+} PyMAPIStoreGlobals;
+
 typedef struct {
        PyObject_HEAD
        TALLOC_CTX                      *mem_ctx;
        struct mapistore_context        *mstore_ctx;
-       struct ldb_context              *samdb_ctx;
-       struct ldb_context              *ocdb_ctx;
 } PyMAPIStoreObject;
 
 typedef struct {
@@ -48,7 +53,6 @@ typedef struct {
        PyObject_HEAD
        TALLOC_CTX                      *mem_ctx;
        struct mapistore_context        *mstore_ctx;
-       struct ldb_context              *ocdb_ctx;
        uint64_t                        fid;
        void                            *folder_object;
        uint32_t                        context_id;
@@ -57,6 +61,7 @@ typedef struct {
 
 typedef struct {
        PyObject_HEAD
+       TALLOC_CTX                      *mem_ctx;
        PyMAPIStoreContextObject        *context;
        void                            *folder_object;
        uint64_t                        fid;
@@ -100,24 +105,20 @@ PyAPI_DATA(PyTypeObject)  PyMAPIStoreTable;
 
 __BEGIN_DECLS
 
-extern PyObject *datetime_module;
-extern PyObject *datetime_datetime_class;
-
 void PyErr_SetMAPIStoreError(uint32_t);
 
 /* internal calls */
+PyMAPIStoreGlobals *get_PyMAPIStoreGlobals(void);
+
+void initmapistore_context(PyObject *);
 void initmapistore_folder(PyObject *);
+void initmapistore_mgmt(PyObject *);
 void initmapistore_freebusy_properties(PyObject *);
+void initmapistore_table(PyObject *);
 void initmapistore_errors(PyObject *);
 
 PyMAPIStoreFreeBusyPropertiesObject* instantiate_freebusy_properties(struct mapistore_freebusy_properties *);
 
 __END_DECLS
 
-#define PyErr_MAPIStore_IS_ERR_RAISE(retval)           \
-       if (retval != MAPISTORE_SUCCESS) {              \
-               PyErr_SetMAPIStoreError(retval);        \
-               return NULL;                            \
-        }
-
 #endif /* ! __PYMAPISTORE_H_ */
index e2a1582..5c3fd47 100644 (file)
@@ -46,3 +46,11 @@ PyTypeObject PyMAPIStoreTable = {
        .tp_dealloc = (destructor)py_MAPIStoreTable_dealloc,
        .tp_flags = Py_TPFLAGS_DEFAULT,
 };
+
+void initmapistore_table(PyObject *m)
+{
+       if (PyType_Ready(&PyMAPIStoreTable) < 0) {
+               return;
+       }
+       Py_INCREF(&PyMAPIStoreTable);
+}