static int propfind_timezone(const xmlChar *name, xmlNsPtr ns,
			     struct propfind_ctx *fctx,
			     xmlNodePtr resp __attribute__((unused)),
			     struct propstat propstat[],
			     void *rock)
{
    xmlNodePtr prop = (xmlNodePtr) rock;
    const char *data = NULL, *msg_base = NULL;
    unsigned long datalen = 0;
    int r = 0;

    if (propstat) {
	const char *prop_annot =
	    ANNOT_NS "<" XML_NS_CALDAV ">calendar-timezone";
	struct buf attrib = BUF_INITIALIZER;

	if (fctx->mailbox && !fctx->record) {
	    r = annotatemore_lookupmask(fctx->mailbox->name,
					buf_cstring(&fctx->buf),
					httpd_userid, &attrib);
	}

	if (r) return HTTP_SERVER_ERROR;
	if (attrib.len)  {
	    data = buf_cstring(&attrib);
	    datalen = attrib.len;
	}
	else if ((namespace_calendar.allow & ALLOW_CAL_NOTZ)) {
	    /*  Check for CALDAV:calendar-timezone-id */
	    prop_annot = ANNOT_NS "<" XML_NS_CALDAV ">calendar-timezone-id";

	    r = annotatemore_lookupmask(fctx->mailbox->name, prop_annot,
					httpd_userid, &attrib);

	    if (r) return HTTP_SERVER_ERROR;
	    if (!attrib.len) return HTTP_NOT_FOUND;
	    else {
		const char *path;
		int fd;

		/* Open and mmap the timezone file */
		buf_reset(&fctx->buf);
		buf_printf(&fctx->buf, "%s%s/%s.ics",
			   config_dir, FNAME_ZONEINFODIR, buf_cstring(&attrib));

		path = buf_cstring(&fctx->buf);
		if ((fd = open(path, O_RDONLY)) == -1) return HTTP_SERVER_ERROR;

		map_refresh(fd, 1, &msg_base, &datalen,
			    MAP_UNKNOWN_LEN, path, NULL);
		close(fd);

		if (!msg_base) return HTTP_SERVER_ERROR;

		data = msg_base;
	    }
	}
	else return HTTP_NOT_FOUND;
    }

    r = propfind_getdata(name, ns, fctx, propstat, prop, caldav_mime_types,
			 CALDAV_SUPP_DATA, data, datalen);

    if (msg_base) map_free(&msg_base, &datalen);

    return r;
}
static int propfind_timezone(const xmlChar *name, xmlNsPtr ns,
			     struct propfind_ctx *fctx,
			     xmlNodePtr resp __attribute__((unused)),
			     struct propstat propstat[],
			     void *rock)
{
    xmlNodePtr prop = (xmlNodePtr) rock;
    const char *data = NULL, *msg_base = NULL;
    unsigned long datalen = 0;
    int r = 0;

    if (propstat) {
	const char *prop_annot =
	    ANNOT_NS "<" XML_NS_CALDAV ">calendar-timezone";
	struct buf attrib = BUF_INITIALIZER;

	if (fctx->mailbox && !fctx->record) {
	    r = annotatemore_lookupmask(fctx->mailbox->name,
					buf_cstring(&fctx->buf),
					httpd_userid, &attrib);
	}

	if (r) return HTTP_SERVER_ERROR;
	if (attrib.len)  {
	    data = buf_cstring(&attrib);
	    datalen = attrib.len;
	}
	else if ((namespace_calendar.allow & ALLOW_CAL_NOTZ)) {
	     
	    prop_annot = ANNOT_NS "<" XML_NS_CALDAV ">calendar-timezone-id";

	    r = annotatemore_lookupmask(fctx->mailbox->name, prop_annot,
					httpd_userid, &attrib);

	    if (r) return HTTP_SERVER_ERROR;
	    if (!attrib.len) return HTTP_NOT_FOUND;
	    else {
		const char *path;
		int fd;

		 
		buf_reset(&fctx->buf);
		buf_printf(&fctx->buf, "%s%s/%s.ics",
			   config_dir, FNAME_ZONEINFODIR, buf_cstring(&attrib));

		path = buf_cstring(&fctx->buf);
		if ((fd = open(path, O_RDONLY)) == -1) return HTTP_SERVER_ERROR;

		map_refresh(fd, 1, &msg_base, &datalen,
			    MAP_UNKNOWN_LEN, path, NULL);
		close(fd);

		if (!msg_base) return HTTP_SERVER_ERROR;

		data = msg_base;
	    }
	}
	else return HTTP_NOT_FOUND;
    }

    r = propfind_getdata(name, ns, fctx, propstat, prop, caldav_mime_types,
			 CALDAV_SUPP_DATA, data, datalen);

    if (msg_base) map_free(&msg_base, &datalen);

    return r;
}