<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/6493">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_calendar: Various fixes<br><br>* The way that we were looking at XML elements for CalDAV was extremely<br>  fragile, so use SAX2 for increased robustness.<br><br>* Don't complain about a 'channel' not be specified if autoreminder is<br>  not set. Assume that if 'channel' is not set, we don't want to be<br>  notified.<br><br>* Fix some truncated CLI output in 'calendar show calendar' and make the<br>  'Autoreminder' description a bit more clear<br><br>ASTERISK-24588 #close<br>Reported by: Stefan Gofferje<br><br>ASTERISK-25523 #close<br>Reported by: Jesper<br><br>Change-Id: I200d11afca6a47e7d97888f286977e2e69874b2c<br>---<br>M res/res_calendar.c<br>M res/res_calendar_caldav.c<br>2 files changed, 50 insertions(+), 13 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/res/res_calendar.c b/res/res_calendar.c<br>index e4c89df..bf385db 100644<br>--- a/res/res_calendar.c<br>+++ b/res/res_calendar.c<br>@@ -488,6 +488,13 @@<br>                 }<br>     }<br> <br>+ if (cal->autoreminder && ast_strlen_zero(cal->notify_channel)) {<br>+               ast_log(LOG_WARNING,<br>+                         "You have set 'autoreminder' but not 'channel' for calendar '%s.' "<br>+                                "Notifications will not occur.\n",<br>+                         cal->name);<br>+       }<br>+<br>  if (new_calendar) {<br>           cal->thread = AST_PTHREADT_NULL;<br>           ast_cond_init(&cal->unload, NULL);<br>@@ -495,7 +502,7 @@<br>                if (ast_pthread_create(&cal->thread, NULL, cal->tech->load_calendar, cal)) {<br>                     /* If we start failing to create threads, go ahead and return NULL<br>                     * and the tech module will be unregistered<br>-                   */ <br>+                  */<br>                   ao2_unlink(calendars, cal);<br>                   cal = unref_calendar(cal);<br>            }<br>@@ -954,7 +961,7 @@<br>        event = cmp_event ? cmp_event : old_event;<br> <br>         ao2_lock(event);<br>-     if (!cmp_event || old_event->alarm != event->alarm) {<br>+  if (!ast_strlen_zero(cal->notify_channel) && (!cmp_event || old_event->alarm != event->alarm)) {<br>             changed = 1;<br>          if (cal->autoreminder) {<br>                   alarm_notify_sched = (event->start - (60 * cal->autoreminder) - now.tv_sec) * 1000;<br>@@ -963,7 +970,7 @@<br>                }<br> <br>          /* For now, send the notification if we missed it, but the meeting hasn't happened yet */<br>-                if (event->start >=  now.tv_sec) {<br>+             if (event->start >= now.tv_sec) {<br>                       if (alarm_notify_sched <= 0) {<br>                             alarm_notify_sched = 1;<br>                       }<br>@@ -1596,7 +1603,7 @@<br> <br> static char *handle_show_calendar(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)<br> {<br>-#define FORMAT "%-17.17s : %-20.20s\n"<br>+#define FORMAT  "%-18.18s : %-20.20s\n"<br> #define FORMAT2 "%-12.12s: %-40.60s\n"<br>       struct ao2_iterator i;<br>        struct ast_calendar *cal;<br>@@ -1645,7 +1652,13 @@<br>     ast_cli(a->fd, FORMAT, "Notify appdata", cal->notify_appdata);<br>        ast_cli(a->fd, "%-17.17s : %d\n", "Refresh time", cal->refresh);<br>    ast_cli(a->fd, "%-17.17s : %d\n", "Timeframe", cal->timeframe);<br>-    ast_cli(a->fd, "%-17.17s : %d\n", "Autoreminder", cal->autoreminder);<br>+<br>+   if (cal->autoreminder) {<br>+          ast_cli(a->fd, "%-17.17s : %d minutes before event\n", "Autoreminder", cal->autoreminder);<br>+ } else {<br>+             ast_cli(a->fd, "%-17.17s : None\n", "Autoreminder");<br>+  }<br>+<br>  ast_cli(a->fd, "%s\n", "Events");<br>      ast_cli(a->fd, "%s\n", "------");<br> <br>diff --git a/res/res_calendar_caldav.c b/res/res_calendar_caldav.c<br>index 3c1c74a..b6822b0 100644<br>--- a/res/res_calendar_caldav.c<br>+++ b/res/res_calendar_caldav.c<br>@@ -156,6 +156,7 @@<br>         ne_add_response_body_reader(req, debug_response_handler, fetch_response_reader, &response);<br>       ne_set_request_body_buffer(req, ast_str_buffer(req_body), ast_str_strlen(req_body));<br>  ne_add_request_header(req, "Content-type", ast_strlen_zero(content_type) ? "text/xml" : content_type);<br>+   ne_add_request_header(req, "Depth", "1");<br> <br>      ret = ne_request_dispatch(req);<br>       ne_request_destroy(req);<br>@@ -476,17 +477,26 @@<br>       time_t end;<br> };<br> <br>-static void handle_start_element(void *data, const xmlChar *fullname, const xmlChar **atts)<br>+static const xmlChar *caldav_node_localname = BAD_CAST "calendar-data";<br>+static const xmlChar *caldav_node_nsuri     = BAD_CAST "urn:ietf:params:xml:ns:caldav";<br>+<br>+static void handle_start_element(void *data,<br>+                                                           const xmlChar *localname, const xmlChar *prefix, const xmlChar *uri,<br>+                                                                 int nb_namespaces, const xmlChar **namespaces,<br>+                                                               int nb_attributes, int nb_defaulted, const xmlChar **attributes)<br> {<br>         struct xmlstate *state = data;<br> <br>-    if (!xmlStrcasecmp(fullname, BAD_CAST "C:calendar-data") || !xmlStrcasecmp(fullname, BAD_CAST "caldav:calendar-data")) {<br>-         state->in_caldata = 1;<br>-            ast_str_reset(state->cdata);<br>+      if (xmlStrcmp(localname, caldav_node_localname) || xmlStrcmp(uri, caldav_node_nsuri)) {<br>+              return;<br>       }<br>+<br>+ state->in_caldata = 1;<br>+    ast_str_reset(state->cdata);<br> }<br> <br>-static void handle_end_element(void *data, const xmlChar *name)<br>+static void handle_end_element(void *data,<br>+                                                           const xmlChar *localname, const xmlChar *prefix, const xmlChar *uri)<br> {<br>   struct xmlstate *state = data;<br>        struct icaltimetype start, end;<br>@@ -494,7 +504,7 @@<br>  icalcomponent *iter;<br>  icalcomponent *comp;<br> <br>-      if (xmlStrcasecmp(name, BAD_CAST "C:calendar-data") && xmlStrcasecmp(name, BAD_CAST "caldav:calendar-data")) {<br>+   if (xmlStrcmp(localname, caldav_node_localname) || xmlStrcmp(uri, caldav_node_nsuri)) {<br>               return;<br>       }<br> <br>@@ -557,9 +567,23 @@<br>    state.start = start;<br>  state.end = end;<br> <br>+  /*<br>+    * We want SAX2, so you assume that we want to call xmlSAXVersion() here, and<br>+         * that certainly seems like the right thing to do, but the default SAX<br>+       * handling functions assume that the 'data' pointer is going to be a<br>+         * xmlParserCtxtPtr, not a user data pointer, so we have to make sure that we<br>+         * are only calling the handlers that we control.<br>+     *<br>+    * So instead we hack things up a bit, clearing the struct and then assigning<br>+         * the magic number manually.<br>+         *<br>+    * There may be a cleaner way to do this, but frankly the libxml2 docs are<br>+    * pretty sparse.<br>+     */<br>   memset(&saxHandler, 0, sizeof(saxHandler));<br>-      saxHandler.startElement = handle_start_element;<br>-      saxHandler.endElement = handle_end_element;<br>+  saxHandler.initialized = XML_SAX2_MAGIC;<br>+     saxHandler.startElementNs = handle_start_element;<br>+    saxHandler.endElementNs = handle_end_element;<br>         saxHandler.characters = handle_characters;<br> <br>         xmlSAXUserParseMemory(&saxHandler, &state, ast_str_buffer(response), ast_str_strlen(response));<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6493">change 6493</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/6493"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 15 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I200d11afca6a47e7d97888f286977e2e69874b2c </div>
<div style="display:none"> Gerrit-Change-Number: 6493 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean.bright@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>