$darkmode
Libical API Documentation 4.0 STABLE VERSION Visit the v3.0 documentation
icalmessage.c
Go to the documentation of this file.
1 /*======================================================================
2  FILE: icalmessage.c
3  CREATOR: ebusboom 07 Nov 2000
4 
5  SPDX-FileCopyrightText: 2000, Eric Busboom <eric@civicknowledge.com>
6  SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
7 ======================================================================*/
8 
14 #ifdef HAVE_CONFIG_H
15 #include <config.h>
16 #endif
17 
18 #include "icalmessage.h"
19 #include "icalerror_p.h"
20 #include "icalversion.h" /* for ICAL_PACKAGE, ICAL_VERSION */
21 
22 #include <ctype.h>
23 #include <stdlib.h>
24 
25 static icalcomponent *icalmessage_get_inner(const icalcomponent *comp)
26 {
29  } else {
30  return (icalcomponent *)comp;
31  }
32 }
33 
34 static char *lowercase(const char *str)
35 {
36  char *p = 0;
37  char *n = 0;
38 
39  if (str == 0) {
40  return 0;
41  }
42 
43  n = strdup(str);
44  if (!n) {
46  return 0;
47  }
48 
49  for (p = n; *p != 0; p++) {
50  *p = tolower((int)*p);
51  }
52 
53  return n;
54 }
55 
56 static icalproperty *icalmessage_find_attendee(const icalcomponent *comp, const char *user)
57 {
58  icalcomponent *inner = icalmessage_get_inner(comp);
59  icalproperty *p, *attendee = 0;
60 
61  for (p = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY);
62  p != 0;
63  p = icalcomponent_get_next_property(inner, ICAL_ATTENDEE_PROPERTY)) {
64  char *lattendee;
65 
66  lattendee = lowercase(icalproperty_get_attendee(p));
67  if (lattendee) {
68  if (strstr(lattendee, user) != 0) {
69  free(lattendee);
70  attendee = p;
71  break;
72  }
73 
74  free(lattendee);
75  }
76  }
77 
78  return attendee;
79 }
80 
81 static void icalmessage_copy_properties(const icalcomponent *to, const icalcomponent *from,
82  icalproperty_kind kind)
83 {
84  icalcomponent *to_inner = icalmessage_get_inner(to);
85  icalcomponent *from_inner = icalmessage_get_inner(from);
86 
87  if (to_inner == 0 && from_inner == 0) {
89  return;
90  }
91 
92  if (!icalcomponent_get_first_property(from_inner, kind)) {
93  return;
94  }
95 
97  to_inner,
99 }
100 
101 static icalcomponent *icalmessage_new_reply_base(const icalcomponent *c,
102  const char *user, const char *msg)
103 {
104  icalproperty *attendee;
105  char tmp[45];
106 
107  icalcomponent *reply =
109  ICAL_VCALENDAR_COMPONENT, icalproperty_new_method(ICAL_METHOD_REPLY),
112  icalproperty_new_dtstamp(icaltime_from_timet_with_zone(time(0), 0, NULL)),
113  (void *)0),
114  (void *)0);
115 
116  icalcomponent *inner = icalmessage_get_inner(reply);
117 
118  icalerror_check_arg_rz(c, "c");
119 
120  icalmessage_copy_properties(reply, c, ICAL_UID_PROPERTY);
121  icalmessage_copy_properties(reply, c, ICAL_ORGANIZER_PROPERTY);
122  icalmessage_copy_properties(reply, c, ICAL_RECURRENCEID_PROPERTY);
123  icalmessage_copy_properties(reply, c, ICAL_SUMMARY_PROPERTY);
124  icalmessage_copy_properties(reply, c, ICAL_SEQUENCE_PROPERTY);
125 
127 
128  if (msg != 0) {
129  icalcomponent_add_property(inner, icalproperty_new_comment(msg));
130  }
131 
132  /* Copy this user's attendee property */
133 
134  attendee = icalmessage_find_attendee(c, user);
135 
136  if (attendee == 0) {
138  icalcomponent_free(reply);
139  return 0;
140  }
141 
143 
144  /* Add PRODID and VERSION */
145 
146  icalcomponent_add_property(reply, icalproperty_new_version("2.0"));
147 
148  snprintf(tmp, sizeof(tmp), "-//SoftwareStudio//NONSGML %s %s //EN", ICAL_PACKAGE, ICAL_VERSION);
149 
150  icalcomponent_add_property(reply, icalproperty_new_prodid(tmp));
151 
152  return reply;
153 }
154 
155 icalcomponent *icalmessage_new_accept_reply(const icalcomponent *c, const char *user, const char *msg)
156 {
157  icalcomponent *reply;
158  icalproperty *attendee;
159  icalcomponent *inner;
160 
161  icalerror_check_arg_rz(c, "c");
162 
163  reply = icalmessage_new_reply_base(c, user, msg);
164 
165  if (reply == 0) {
166  return 0;
167  }
168 
169  inner = icalmessage_get_inner(reply);
170 
171  attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY);
172 
173  icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_ACCEPTED));
174 
175  return reply;
176 }
177 
178 icalcomponent *icalmessage_new_decline_reply(const icalcomponent *c, const char *user, const char *msg)
179 {
180  icalcomponent *reply;
181  icalproperty *attendee;
182  icalcomponent *inner;
183 
184  icalerror_check_arg_rz(c, "c");
185 
186  reply = icalmessage_new_reply_base(c, user, msg);
187  inner = icalmessage_get_inner(reply);
188  if (reply == 0) {
189  return 0;
190  }
191 
192  attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY);
193 
194  icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_DECLINED));
195 
196  return reply;
197 }
198 
199 /* New is modified version of old */
200 icalcomponent *icalmessage_new_counterpropose_reply(const icalcomponent *oldc,
201  const icalcomponent *newc,
202  const char *user, const char *msg)
203 {
204  icalcomponent *reply;
205 
206  icalerror_check_arg_rz(oldc, "oldc");
207  icalerror_check_arg_rz(newc, "newc");
208 
209  reply = icalmessage_new_reply_base(newc, user, msg);
210 
211  icalcomponent_set_method(reply, ICAL_METHOD_COUNTER);
212 
213  return reply;
214 }
215 
216 icalcomponent *icalmessage_new_delegate_reply(const icalcomponent *c,
217  const char *user,
218  const char *delegatee, const char *msg)
219 {
220  icalcomponent *reply;
221  icalproperty *attendee;
222  icalcomponent *inner;
223 
224  icalerror_check_arg_rz(c, "c");
225 
226  reply = icalmessage_new_reply_base(c, user, msg);
227  inner = icalmessage_get_inner(reply);
228  if (reply == 0) {
229  return 0;
230  }
231 
232  attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY);
233 
234  icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_DELEGATED));
235 
236  icalproperty_set_parameter(attendee, icalparameter_new_delegatedto(delegatee));
237 
238  return reply;
239 }
240 
241 icalcomponent *icalmessage_new_delegate_request(const icalcomponent *c,
242  const char *user,
243  const char *delegatee, const char *msg)
244 {
245  icalcomponent *reply;
246  icalproperty *attendee;
247  icalcomponent *inner;
248  icalparameter *delegateeParam;
249 
250  icalerror_check_arg_rz(c, "c");
251 
252  reply = icalmessage_new_reply_base(c, user, msg);
253  inner = icalmessage_get_inner(reply);
254 
255  if (reply == 0) {
256  return 0;
257  }
258 
259  icalcomponent_set_method(reply, ICAL_METHOD_REQUEST);
260 
261  attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY);
262 
263  icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_DELEGATED));
264 
265  icalproperty_set_parameter(attendee, icalparameter_new_delegatedto(delegatee));
266 
267  delegateeParam = icalparameter_new_delegatedfrom(icalproperty_get_attendee(attendee));
269  inner,
270  icalproperty_vanew_attendee(delegatee, delegateeParam, (void *)0));
271  icalparameter_free(delegateeParam);
272  return reply;
273 }
274 
275 icalcomponent *icalmessage_new_error_reply(const icalcomponent *c,
276  const char *user,
277  const char *msg,
278  const char *debug, icalrequeststatus code)
279 {
280  icalcomponent *reply;
281  icalcomponent *inner, *cinner;
282  struct icalreqstattype rs;
283 
284  icalerror_check_arg_rz(c, "c");
285 
286  memset(&rs, 0, sizeof(struct icalreqstattype));
287  reply = icalmessage_new_reply_base(c, user, msg);
288  inner = icalmessage_get_inner(reply);
289  cinner = icalmessage_get_inner(c);
290  if (reply == 0) {
291  return 0;
292  }
293 
294  if (code != ICAL_UNKNOWN_STATUS) {
295  rs.code = code;
296  rs.debug = debug;
297 
298  icalcomponent_add_property(inner, icalproperty_new_requeststatus(rs));
299  } else { /* code == ICAL_UNKNOWN_STATUS */
300 
301  /* Copy all of the request status properties */
302  icalproperty *p;
303 
304  for (p = icalcomponent_get_first_property(cinner, ICAL_REQUESTSTATUS_PROPERTY);
305  p != 0;
306  p = icalcomponent_get_next_property(cinner, ICAL_REQUESTSTATUS_PROPERTY)) {
308  }
309  }
310 
311  return reply;
312 }
void icalparameter_free(icalparameter *param)
Frees an icalparameter object.
Definition: icalparameter.c:58
icalproperty * icalcomponent_get_next_property(icalcomponent *c, icalproperty_kind kind)
void icalproperty_set_parameter(icalproperty *prop, icalparameter *parameter)
Definition: icalproperty.c:491
icalcomponent * icalcomponent_get_first_real_component(const icalcomponent *c)
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Definition: icalerror.c:90
icalcomponent * icalmessage_new_counterpropose_reply(const icalcomponent *oldc, const icalcomponent *newc, const char *user, const char *msg)
Definition: icalmessage.c:200
icalcomponent * icalmessage_new_error_reply(const icalcomponent *c, const char *user, const char *msg, const char *debug, icalrequeststatus code)
Definition: icalmessage.c:275
icalcomponent * icalmessage_new_delegate_reply(const icalcomponent *c, const char *user, const char *delegatee, const char *msg)
Definition: icalmessage.c:216
icalcomponent * icalcomponent_vanew(icalcomponent_kind kind,...)
void icalcomponent_set_dtstamp(icalcomponent *comp, struct icaltimetype v)
void icalcomponent_set_method(icalcomponent *comp, icalproperty_method method)
icalrequeststatus code
Definition: icaltypes.h:111
#define ICAL_VERSION
Definition: icalversion.h:24
Declares macros for determining the library version.
#define ICAL_PACKAGE
Definition: icalversion.h:20
const char * debug
Definition: icaltypes.h:113
struct icaltimetype icaltime_from_timet_with_zone(const icaltime_t tm, const bool is_date, const icaltimezone *zone)
Constructor.
Definition: icaltime.c:209
icalproperty * icalproperty_clone(const icalproperty *old)
Definition: icalproperty.c:100
icalcomponent_kind icalcomponent_isa(const icalcomponent *component)
icalcomponent * icalmessage_new_decline_reply(const icalcomponent *c, const char *user, const char *msg)
Definition: icalmessage.c:178
icalcomponent * icalmessage_new_accept_reply(const icalcomponent *c, const char *user, const char *msg)
Definition: icalmessage.c:155
icalrequeststatus
Definition: icalenums.h:78
void icalcomponent_free(icalcomponent *c)
void icalcomponent_add_property(icalcomponent *component, icalproperty *property)
Defines functions for creating component reply messages.
icalproperty * icalcomponent_get_first_property(icalcomponent *c, icalproperty_kind kind)