Fix a variety of memory leaks
[asterisk/asterisk.git] / res / res_calendar_exchange.c
index ec539e8..e7beeaf 100644 (file)
  */
 
 /*! \file
  */
 
 /*! \file
- * \brief Resource for handling iCalnedar calendars
+ * \brief Resource for handling MS Exchange calendars
  */
 
 /*** MODULEINFO
        <depend>neon</depend>
        <depend>ical</depend>
        <depend>iksemel</depend>
  */
 
 /*** MODULEINFO
        <depend>neon</depend>
        <depend>ical</depend>
        <depend>iksemel</depend>
+       <support_level>core</support_level>
 ***/
 ***/
+
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include <libical/ical.h>
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include <libical/ical.h>
-#include <neon/ne_session.h>
-#include <neon/ne_uri.h>
-#include <neon/ne_request.h>
-#include <neon/ne_auth.h>
+#include <ne_session.h>
+#include <ne_uri.h>
+#include <ne_request.h>
+#include <ne_auth.h>
+#include <ne_redirect.h>
 #include <iksemel.h>
 
 #include "asterisk/module.h"
 #include <iksemel.h>
 
 #include "asterisk/module.h"
@@ -212,11 +215,6 @@ static int parse_cdata(void *data, char *value, size_t len)
        return IKS_OK;
 }
 
        return IKS_OK;
 }
 
-static int cb_true(void *user_data, void *arg, int flags)
-{
-       return CMP_MATCH;
-}
-
 static void exchangecal_destructor(void *obj)
 {
        struct exchangecal_pvt *pvt = obj;
 static void exchangecal_destructor(void *obj)
 {
        struct exchangecal_pvt *pvt = obj;
@@ -227,7 +225,7 @@ static void exchangecal_destructor(void *obj)
        }
        ast_string_field_free_memory(pvt);
 
        }
        ast_string_field_free_memory(pvt);
 
-       ao2_callback(pvt->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, cb_true, NULL);
+       ao2_callback(pvt->events, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
 
        ao2_ref(pvt->events, -1);
 }
 
        ao2_ref(pvt->events, -1);
 }
@@ -407,6 +405,7 @@ static struct ast_str *exchangecal_request(struct exchangecal_pvt *pvt, const ch
        ne_add_request_header(req, "Content-type", "text/xml");
 
        ret = ne_request_dispatch(req);
        ne_add_request_header(req, "Content-type", "text/xml");
 
        ret = ne_request_dispatch(req);
+       ne_request_destroy(req);
 
        if (ret != NE_OK || !ast_str_strlen(response)) {
                ast_log(LOG_WARNING, "Unknown response to CalDAV calendar %s, request %s to %s: %s\n", pvt->owner->name, method, pvt->url, ne_get_error(pvt->session));
 
        if (ret != NE_OK || !ast_str_strlen(response)) {
                ast_log(LOG_WARNING, "Unknown response to CalDAV calendar %s, request %s to %s: %s\n", pvt->owner->name, method, pvt->url, ne_get_error(pvt->session));
@@ -434,9 +433,8 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
                return -1;
        }
        if (!(body = ast_str_create(512)) ||
                return -1;
        }
        if (!(body = ast_str_create(512)) ||
-               !(subdir = ast_str_create(32)) ||
-               !(response = ast_str_create(512))) {
-               ast_log(LOG_ERROR, "Could not allocate memory for request and response!\n");
+               !(subdir = ast_str_create(32))) {
+               ast_log(LOG_ERROR, "Could not allocate memory for request!\n");
                goto write_cleanup;
        }
 
                goto write_cleanup;
        }
 
@@ -506,9 +504,10 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
        ast_verb(0, "\n\n%s\n\n", ast_str_buffer(body));
        ast_str_set(&subdir, 0, "/Calendar/%s.eml", ast_str_buffer(uid));
 
        ast_verb(0, "\n\n%s\n\n", ast_str_buffer(body));
        ast_str_set(&subdir, 0, "/Calendar/%s.eml", ast_str_buffer(uid));
 
-       response = exchangecal_request(event->owner->tech_pvt, "PROPPATCH", body, subdir);
+       if ((response = exchangecal_request(event->owner->tech_pvt, "PROPPATCH", body, subdir))) {
+               ret = 0;
+       }
 
 
-       ret = 0;
 write_cleanup:
        if (uid) {
                ast_free(uid);
 write_cleanup:
        if (uid) {
                ast_free(uid);
@@ -619,11 +618,12 @@ static int update_exchangecal(struct exchangecal_pvt *pvt)
 static void *exchangecal_load_calendar(void *void_data)
 {
        struct exchangecal_pvt *pvt;
 static void *exchangecal_load_calendar(void *void_data)
 {
        struct exchangecal_pvt *pvt;
+       const struct ast_config *cfg;
        struct ast_variable *v;
        struct ast_calendar *cal = void_data;
        ast_mutex_t refreshlock;
 
        struct ast_variable *v;
        struct ast_calendar *cal = void_data;
        ast_mutex_t refreshlock;
 
-       if (!(cal && calendar_config)) {
+       if (!(cal && (cfg = ast_calendar_config_acquire()))) {
                ast_log(LOG_ERROR, "You must enable calendar support for res_exchangecal to load\n");
                return NULL;
        }
                ast_log(LOG_ERROR, "You must enable calendar support for res_exchangecal to load\n");
                return NULL;
        }
@@ -634,11 +634,13 @@ static void *exchangecal_load_calendar(void *void_data)
                } else {
                        ast_log(LOG_WARNING, "Could not lock calendar, aborting!\n");
                }
                } else {
                        ast_log(LOG_WARNING, "Could not lock calendar, aborting!\n");
                }
+               ast_calendar_config_release();
                return NULL;
        }
 
        if (!(pvt = ao2_alloc(sizeof(*pvt), exchangecal_destructor))) {
                ast_log(LOG_ERROR, "Could not allocate exchangecal_pvt structure for calendar: %s\n", cal->name);
                return NULL;
        }
 
        if (!(pvt = ao2_alloc(sizeof(*pvt), exchangecal_destructor))) {
                ast_log(LOG_ERROR, "Could not allocate exchangecal_pvt structure for calendar: %s\n", cal->name);
+               ast_calendar_config_release();
                return NULL;
        }
 
                return NULL;
        }
 
@@ -648,6 +650,7 @@ static void *exchangecal_load_calendar(void *void_data)
                ast_log(LOG_ERROR, "Could not allocate space for fetching events for calendar: %s\n", cal->name);
                pvt = unref_exchangecal(pvt);
                ao2_unlock(cal);
                ast_log(LOG_ERROR, "Could not allocate space for fetching events for calendar: %s\n", cal->name);
                pvt = unref_exchangecal(pvt);
                ao2_unlock(cal);
+               ast_calendar_config_release();
                return NULL;
        }
 
                return NULL;
        }
 
@@ -655,10 +658,11 @@ static void *exchangecal_load_calendar(void *void_data)
                ast_log(LOG_ERROR, "Couldn't allocate string field space for calendar: %s\n", cal->name);
                pvt = unref_exchangecal(pvt);
                ao2_unlock(cal);
                ast_log(LOG_ERROR, "Couldn't allocate string field space for calendar: %s\n", cal->name);
                pvt = unref_exchangecal(pvt);
                ao2_unlock(cal);
+               ast_calendar_config_release();
                return NULL;
        }
 
                return NULL;
        }
 
-       for (v = ast_variable_browse(calendar_config, cal->name); v; v = v->next) {
+       for (v = ast_variable_browse(cfg, cal->name); v; v = v->next) {
                if (!strcasecmp(v->name, "url")) {
                        ast_string_field_set(pvt, url, v->value);
                } else if (!strcasecmp(v->name, "user")) {
                if (!strcasecmp(v->name, "url")) {
                        ast_string_field_set(pvt, url, v->value);
                } else if (!strcasecmp(v->name, "user")) {
@@ -668,6 +672,8 @@ static void *exchangecal_load_calendar(void *void_data)
                }
        }
 
                }
        }
 
+       ast_calendar_config_release();
+
        if (ast_strlen_zero(pvt->url)) {
                ast_log(LOG_WARNING, "No URL was specified for Exchange calendar '%s' - skipping.\n", cal->name);
                pvt = unref_exchangecal(pvt);
        if (ast_strlen_zero(pvt->url)) {
                ast_log(LOG_WARNING, "No URL was specified for Exchange calendar '%s' - skipping.\n", cal->name);
                pvt = unref_exchangecal(pvt);
@@ -691,8 +697,9 @@ static void *exchangecal_load_calendar(void *void_data)
        }
 
        pvt->session = ne_session_create(pvt->uri.scheme, pvt->uri.host, pvt->uri.port);
        }
 
        pvt->session = ne_session_create(pvt->uri.scheme, pvt->uri.host, pvt->uri.port);
+       ne_redirect_register(pvt->session);
        ne_set_server_auth(pvt->session, auth_credentials, pvt);
        ne_set_server_auth(pvt->session, auth_credentials, pvt);
-       if (!strncasecmp(pvt->uri.scheme, "https", sizeof(pvt->uri.scheme))) {
+       if (!strcasecmp(pvt->uri.scheme, "https")) {
                ne_ssl_trust_default_ca(pvt->session);
        }
 
                ne_ssl_trust_default_ca(pvt->session);
        }
 
@@ -751,7 +758,8 @@ static int unload_module(void)
        return 0;
 }
 
        return 0;
 }
 
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk MS Exchange Calendar Integration",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Asterisk MS Exchange Calendar Integration",
                .load = load_module,
                .unload = unload_module,
                .load = load_module,
                .unload = unload_module,
+               .load_pri = AST_MODPRI_DEVSTATE_PLUGIN,
        );
        );