X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fcalendar%2Fserv_calendar.c;h=8fc0dbad1e351f3457a1a2a0d43942bf2dcfe4e7;hb=c4609169aa7baf208848e72c16d33a3f892353b8;hp=0d971d9d9677adbefc631acdd927254e6427f55b;hpb=951fbe7c1ee0b3554af22d6ae0d1d51c1642ae0f;p=citadel.git diff --git a/citadel/modules/calendar/serv_calendar.c b/citadel/modules/calendar/serv_calendar.c index 0d971d9d9..8fc0dbad1 100644 --- a/citadel/modules/calendar/serv_calendar.c +++ b/citadel/modules/calendar/serv_calendar.c @@ -3,22 +3,15 @@ * room on a Citadel server. It handles iCalendar objects using the * iTIP protocol. See RFCs 2445 and 2446. * + * Copyright (c) 1987-2015 by the citadel.org team * - * Copyright (c) 1987-2011 by the citadel.org team + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #define PRODID "-//Citadel//NONSGML Citadel Calendar//EN" @@ -30,8 +23,10 @@ #include "msgbase.h" #include "internet_addressing.h" #include "serv_calendar.h" +#include "room_ops.h" #include "euidindex.h" #include "ical_dezonify.h" +#include "config.h" @@ -98,6 +93,7 @@ icalcomponent *ical_encapsulate_subcomponent(icalcomponent *subcomp) { */ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { char *ser = NULL; + long serlen; icalcomponent *encaps = NULL; struct CtdlMessage *msg = NULL; icalcomponent *tmp=NULL; @@ -119,13 +115,15 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { ser = icalcomponent_as_ical_string_r(cal); if (ser == NULL) return; + serlen = strlen(ser); + /* If the caller supplied a user, write to that user's default calendar room */ if (u) { /* This handy API function does all the work for us. */ CtdlWriteObject(USERCALENDARROOM, /* which room */ "text/calendar", /* MIME type */ ser, /* data */ - strlen(ser)+1, /* length */ + serlen + 1, /* length */ u, /* which user */ 0, /* not binary */ 0, /* don't delete others of this type */ @@ -135,22 +133,28 @@ void ical_write_to_cal(struct ctdluser *u, icalcomponent *cal) { /* If the caller did not supply a user, write to the currently selected room */ if (!u) { + struct CitContext *CCC = CC; + StrBuf *MsgBody; + msg = malloc(sizeof(struct CtdlMessage)); memset(msg, 0, sizeof(struct CtdlMessage)); msg->cm_magic = CTDLMESSAGE_MAGIC; msg->cm_anon_type = MES_NORMAL; msg->cm_format_type = 4; - msg->cm_fields[eAuthor] = strdup(CC->user.fullname); - msg->cm_fields[eOriginalRoom] = strdup(CC->room.QRname); - msg->cm_fields[eNodeName] = strdup(config.c_nodename); - msg->cm_fields[eHumanNode] = strdup(config.c_humannode); - msg->cm_fields[eMesageText] = malloc(strlen(ser) + 40); - strcpy(msg->cm_fields[eMesageText], "Content-type: text/calendar\r\n\r\n"); - strcat(msg->cm_fields[eMesageText], ser); + CM_SetField(msg, eAuthor, CCC->user.fullname, strlen(CCC->user.fullname)); + CM_SetField(msg, eOriginalRoom, CCC->room.QRname, strlen(CCC->room.QRname)); + CM_SetField(msg, eNodeName, CtdlGetConfigStr("c_nodename"), strlen(CtdlGetConfigStr("c_nodename"))); + CM_SetField(msg, eHumanNode, CtdlGetConfigStr("c_humannode"), strlen(CtdlGetConfigStr("c_humannode"))); + + MsgBody = NewStrBufPlain(NULL, serlen + 100); + StrBufAppendBufPlain(MsgBody, HKEY("Content-type: text/calendar\r\n\r\n"), 0); + StrBufAppendBufPlain(MsgBody, ser, serlen, 0); + + CM_SetAsFieldSB(msg, eMesageText, &MsgBody); /* Now write the data */ CtdlSubmitMsg(msg, NULL, "", QP_EADDR); - CtdlFreeMessage(msg); + CM_Free(msg); } /* In either case, now we can free the serialized calendar object */ @@ -175,15 +179,15 @@ void ical_send_a_reply(icalcomponent *request, char *action) { icalproperty *summary = NULL; char summary_string[SIZ]; icalproperty *me_attend = NULL; - struct recptypes *recp = NULL; + recptypes *recp = NULL; icalparameter *partstat = NULL; char *serialized_reply = NULL; char *reply_message_text = NULL; const char *ch; struct CtdlMessage *msg = NULL; - struct recptypes *valid = NULL; + recptypes *valid = NULL; - strcpy(organizer_string, ""); + *organizer_string = '\0'; strcpy(summary_string, "Calendar item"); if (request == NULL) { @@ -302,7 +306,7 @@ void ical_send_a_reply(icalcomponent *request, char *action) { if (msg != NULL) { valid = validate_recipients(organizer_string, NULL, 0); CtdlSubmitMsg(msg, valid, "", QP_EADDR); - CtdlFreeMessage(msg); + CM_Free(msg); free_recipients(valid); } } @@ -365,7 +369,7 @@ void ical_respond(long msgnum, char *partnum, char *action) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + ILLEGAL_VALUE, @@ -376,18 +380,17 @@ void ical_respond(long msgnum, char *partnum, char *action) { memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, partnum); - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_locate_part, /* callback function */ - NULL, NULL, - (void *) &ird, /* user data */ - 0 + mime_parser(CM_RANGE(msg, eMesageText), + *ical_locate_part, /* callback function */ + NULL, NULL, + (void *) &ird, /* user data */ + 0 ); /* We're done with the incoming message, because we now have a * calendar object in memory. */ - CtdlFreeMessage(msg); + CM_Free(msg); /* * Here is the real meat of this function. Handle the event. @@ -627,19 +630,18 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) { * us the ability to load the event into memory so we can diddle the * attendees. */ - msg = CtdlFetchMessage(msgnum_being_replaced, 1); + msg = CtdlFetchMessage(msgnum_being_replaced, 1, 1); if (msg == NULL) { return(2); /* internal error */ } oec.c = NULL; - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_locate_original_event, /* callback function */ - NULL, NULL, - &oec, /* user data */ - 0 + mime_parser(CM_RANGE(msg, eMesageText), + *ical_locate_original_event, /* callback function */ + NULL, NULL, + &oec, /* user data */ + 0 ); - CtdlFreeMessage(msg); + CM_Free(msg); original_event = oec.c; if (original_event == NULL) { @@ -679,7 +681,7 @@ int ical_update_my_calendar_with_reply(icalcomponent *cal) { if (msg != NULL) { CIT_ICAL->avoid_sending_invitations = 1; CtdlSubmitMsg(msg, NULL, roomname, QP_EADDR); - CtdlFreeMessage(msg); + CM_Free(msg); CIT_ICAL->avoid_sending_invitations = 0; } } @@ -708,7 +710,7 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) { return; } - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found.\n", ERROR + ILLEGAL_VALUE, @@ -719,18 +721,17 @@ void ical_handle_rsvp(long msgnum, char *partnum, char *action) { memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, partnum); - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_locate_part, /* callback function */ - NULL, NULL, - (void *) &ird, /* user data */ - 0 - ); + mime_parser(CM_RANGE(msg, eMesageText), + *ical_locate_part, /* callback function */ + NULL, NULL, + (void *) &ird, /* user data */ + 0 + ); /* We're done with the incoming message, because we now have a * calendar object in memory. */ - CtdlFreeMessage(msg); + CM_Free(msg); /* * Here is the real meat of this function. Handle the event. @@ -905,11 +906,11 @@ int ical_conflicts_phase6(struct icaltimetype t1start, existing_msgnum, conflict_event_uid, conflict_event_summary, - ( ((strlen(compare_uid)>0) + ( (!IsEmptyStr(compare_uid) &&(!strcasecmp(compare_uid, conflict_event_uid))) ? 1 : 0 - ) - ); + ) + ); conflict_reported = 1; } @@ -1147,18 +1148,17 @@ void ical_hunt_for_conflicts_backend(long msgnum, void *data) { proposed_event = (icalcomponent *)data; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_locate_part, /* callback function */ - NULL, NULL, - (void *) &ird, /* user data */ - 0 + mime_parser(CM_RANGE(msg, eMesageText), + *ical_locate_part, /* callback function */ + NULL, NULL, + (void *) &ird, /* user data */ + 0 ); - CtdlFreeMessage(msg); + CM_Free(msg); if (ird.cal == NULL) return; @@ -1209,7 +1209,7 @@ void ical_conflicts(long msgnum, char *partnum) { struct CtdlMessage *msg = NULL; struct ical_respond_data ird; - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) { cprintf("%d Message %ld not found\n", ERROR + ILLEGAL_VALUE, @@ -1220,15 +1220,14 @@ void ical_conflicts(long msgnum, char *partnum) { memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, partnum); - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_locate_part, /* callback function */ - NULL, NULL, - (void *) &ird, /* user data */ - 0 - ); + mime_parser(CM_RANGE(msg, eMesageText), + *ical_locate_part, /* callback function */ + NULL, NULL, + (void *) &ird, /* user data */ + 0 + ); - CtdlFreeMessage(msg); + CM_Free(msg); if (ird.cal != NULL) { ical_hunt_for_conflicts(ird.cal); @@ -1397,18 +1396,17 @@ void ical_freebusy_backend(long msgnum, void *data) { fb = (icalcomponent *)data; /* User-supplied data will be the VFREEBUSY component */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_locate_part, /* callback function */ - NULL, NULL, - (void *) &ird, /* user data */ - 0 - ); - CtdlFreeMessage(msg); + mime_parser(CM_RANGE(msg, eMesageText), + *ical_locate_part, /* callback function */ + NULL, NULL, + (void *) &ird, /* user data */ + 0 + ); + CM_Free(msg); if (ird.cal) { ical_add_to_freebusy(fb, ird.cal); /* Add VEVENT times to VFREEBUSY */ @@ -1429,7 +1427,7 @@ void ical_freebusy(char *who) { icalcomponent *encaps = NULL; icalcomponent *fb = NULL; int found_user = (-1); - struct recptypes *recp = NULL; + recptypes *recp = NULL; char buf[256]; char host[256]; char type[256]; @@ -1456,7 +1454,7 @@ void ical_freebusy(char *who) { * primary FQDN of this Citadel node. */ if (found_user != 0) { - snprintf(buf, sizeof buf, "%s@%s", who, config.c_fqdn); + snprintf(buf, sizeof buf, "%s@%s", who, CtdlGetConfigStr("c_fqdn")); syslog(LOG_DEBUG, "Trying <%s>\n", buf); recp = validate_recipients(buf, NULL, 0); if (recp != NULL) { @@ -1528,7 +1526,7 @@ void ical_freebusy(char *who) { sprintf(buf, "MAILTO:%s", who); if (strchr(buf, '@') == NULL) { strcat(buf, "@"); - strcat(buf, config.c_fqdn); + strcat(buf, CtdlGetConfigStr("c_fqdn")); } for (i=0; buf[i]; ++i) { if (buf[i]==' ') buf[i] = '_'; @@ -1598,18 +1596,17 @@ void ical_getics_backend(long msgnum, void *data) { /* Look for the calendar event... */ - msg = CtdlFetchMessage(msgnum, 1); + msg = CtdlFetchMessage(msgnum, 1, 1); if (msg == NULL) return; memset(&ird, 0, sizeof ird); strcpy(ird.desired_partnum, "_HUNT_"); - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_locate_part, /* callback function */ - NULL, NULL, - (void *) &ird, /* user data */ - 0 + mime_parser(CM_RANGE(msg, eMesageText), + *ical_locate_part, /* callback function */ + NULL, NULL, + (void *) &ird, /* user data */ + 0 ); - CtdlFreeMessage(msg); + CM_Free(msg); if (ird.cal == NULL) return; @@ -1752,7 +1749,7 @@ void ical_putics(void) } cprintf("%d Transmit data now\n", SEND_LISTING); - calstream = CtdlReadMessageBody(HKEY("000"), config.c_maxmsglen, NULL, 0, 0); + calstream = CtdlReadMessageBody(HKEY("000"), CtdlGetConfigLong("c_maxmsglen"), NULL, 0, 0); if (calstream == NULL) { return; } @@ -1989,7 +1986,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal) icalcomponent *encaps = NULL; char *request_message_text = NULL; struct CtdlMessage *msg = NULL; - struct recptypes *valid = NULL; + recptypes *valid = NULL; char attendees_string[SIZ]; int num_attendees = 0; char this_attendee[256]; @@ -2201,7 +2198,7 @@ void ical_send_out_invitations(icalcomponent *top_level_cal, icalcomponent *cal) if (msg != NULL) { valid = validate_recipients(attendees_string, NULL, 0); CtdlSubmitMsg(msg, valid, "", QP_EADDR); - CtdlFreeMessage(msg); + CM_Free(msg); free_recipients(valid); } } @@ -2285,10 +2282,10 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *cbuserdata) { + const char* pch; icalcomponent *cal, *nested_event, *nested_todo, *whole_cal; icalproperty *p; char new_uid[256] = ""; - char buf[1024] = ""; struct CtdlMessage *msg = (struct CtdlMessage *) cbuserdata; if (!msg) return; @@ -2334,13 +2331,10 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, p = ical_ctdl_get_subprop(cal, ICAL_UID_PROPERTY); } if (p != NULL) { - safestrncpy(buf, icalproperty_get_comment(p), sizeof buf); - if (!IsEmptyStr(buf)) { - if (msg->cm_fields[eExclusiveID] != NULL) { - free(msg->cm_fields[eExclusiveID]); - } - msg->cm_fields[eExclusiveID] = strdup(buf); - syslog(LOG_DEBUG, "Saving calendar UID <%s>\n", buf); + pch = icalproperty_get_comment(p); + if (!IsEmptyStr(pch)) { + CM_SetField(msg, eExclusiveID, pch, strlen(pch)); + syslog(LOG_DEBUG, "Saving calendar UID <%s>\n", pch); } } @@ -2348,12 +2342,12 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, p = ical_ctdl_get_subprop(cal, ICAL_SUMMARY_PROPERTY); if (p != NULL) { - safestrncpy(buf, icalproperty_get_comment(p), sizeof buf); - if (!IsEmptyStr(buf)) { - if (msg->cm_fields[eMsgSubject] != NULL) { - free(msg->cm_fields[eMsgSubject]); - } - msg->cm_fields[eMsgSubject] = rfc2047encode(buf, strlen(buf)); + pch = icalproperty_get_comment(p); + if (!IsEmptyStr(pch)) { + char *subj; + + subj = rfc2047encode(pch, strlen(pch)); + CM_SetAsField(msg, eMsgSubject, &subj, strlen(subj)); } } @@ -2364,11 +2358,7 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, time_t idtstart; idtstart = icaltime_as_timet(icalproperty_get_dtstart(p)); if (idtstart > 0) { - if (msg->cm_fields[eTimestamp] != NULL) { - free(msg->cm_fields[eTimestamp]); - } - msg->cm_fields[eTimestamp] = strdup("000000000000000000"); - sprintf(msg->cm_fields[eTimestamp], "%ld", idtstart); + CM_SetFieldLONG(msg, eTimestamp, idtstart); } } @@ -2390,7 +2380,7 @@ void ical_obj_beforesave_backend(char *name, char *filename, char *partnum, * If the message is being saved, we also set various message header fields * using data found in the iCalendar object. */ -int ical_obj_beforesave(struct CtdlMessage *msg) +int ical_obj_beforesave(struct CtdlMessage *msg, recptypes *recp) { /* First determine if this is a calendar or tasks room */ if ( (CC->room.QRdefaultview != VIEW_CALENDAR) @@ -2405,18 +2395,17 @@ int ical_obj_beforesave(struct CtdlMessage *msg) return(1); /* You tried to save a non-RFC822 message! */ } - if (msg->cm_fields[eMesageText] == NULL) { + if (CM_IsEmpty(msg, eMesageText)) { return(1); /* You tried to save a null message! */ } /* Do all of our lovely back-end parsing */ - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_obj_beforesave_backend, - NULL, NULL, - (void *)msg, - 0 - ); + mime_parser(CM_RANGE(msg, eMesageText), + *ical_obj_beforesave_backend, + NULL, NULL, + (void *)msg, + 0 + ); return(0); } @@ -2458,7 +2447,7 @@ void ical_obj_aftersave_backend(char *name, char *filename, char *partnum, * (This will start back end tasks such as automatic generation of invitations, * if such actions are appropriate.) */ -int ical_obj_aftersave(struct CtdlMessage *msg) +int ical_obj_aftersave(struct CtdlMessage *msg, recptypes *recp) { char roomname[ROOMNAMELEN]; @@ -2476,16 +2465,15 @@ int ical_obj_aftersave(struct CtdlMessage *msg) if (msg->cm_format_type != 4) return(1); /* Reject null messages */ - if (msg->cm_fields[eMesageText] == NULL) return(1); + if (CM_IsEmpty(msg, eMesageText)) return(1); /* Now recurse through it looking for our icalendar data */ - mime_parser(msg->cm_fields[eMesageText], - NULL, - *ical_obj_aftersave_backend, - NULL, NULL, - NULL, - 0 - ); + mime_parser(CM_RANGE(msg, eMesageText), + *ical_obj_aftersave_backend, + NULL, NULL, + NULL, + 0 + ); return(0); }